Skip to content

Latest commit

 

History

History
207 lines (168 loc) · 15.7 KB

README.md

File metadata and controls

207 lines (168 loc) · 15.7 KB

ODataGrid

NPM Version NPM Downloads NPM Bundle Size

ODataGrid is an extension to the MUI DataGrid React component which implements features such as sorting, pagination, column selection, and filtering using the OData Standard. This allows you to quickly create a powerful interface for browsing data with minimal back-end code.

ODataGrid in action

Features

  • Supports DataGrid and DataGridPro
  • (Almost) drop-in replacement for DataGrid
  • Fully customisable
  • Performant & responsive
  • Supports sorting, pagination, column selection and filtering (dynamic or static filter)
  • Powerful and intuitive filter/query builder built-in
  • Supports custom query string parameters for filtering to allow filters which are not natively supported by OData
  • Integrates with browser history - sorting, page navigation and filtering all create new browser history states which are restored when navigating back/forward.
  • Responsive column visibility - show or hide columns based on screen size

Demo

Coming soon!

Notes

ODataGrid is still in the fairly early stages of development. I'm not aware of any issues currently, but it hasn't been battle-tested. It also utilises Recoil for state management in the filter builder, which is still considered experimental by Facebook.

Please report any issues that you find, and feel free to make feature requests. This will help to make ODataGrid better.

Installation

ODataGrid can be installed using the appropriate npm package (o-data-grid or o-data-grid-pro).

The following mui packages must also be installed. I recommend using the latest versions where possible, the minimum required version for the data-grid packages is v5.8.0, but any of the other mui packages must be v5.x.x.

These are peer dependencies so won't be installed automatically.

  • @mui/system
  • @mui/material
  • @mui/x-date-pickers
  • @mui/x-data-grid (minimum v5.8.0) for o-data-grid
  • @mui/x-data-grid-pro (minimum v5.8.0) for o-data-grid-pro
  • @mui/icons-material

Usage

Usage is very similar to the regular DataGrid. For the most basic scenario simply change the DataGrid/DataGridPro to the corresponding ODataGrid/ODataGridPro component, add the url property, and remove any unsupported properties.

From there you can start to customise the grid to your needs using the properties available in the API below.

Note: like the DataGrid you should ensure that the columns property keeps the same reference between renders.

If the same reference is not kept, this may trigger duplicate OData requests.

Helpful Tips

  • Nested properties are supported, to define a column for a nested property flatten it as you would for the query string. E.g. to access Child from { Parent: { Child: "foo" } }, use Parent/Child as the value for field in the column definition. Strong typing is still supported through the result property of the row.

Examples

The demo site isn't ready yet, but you can see some examples of usage here on my GitHub:

API

The ODataGrid API is very similar to the standard DataGrid/DataGridPro APIs, with a few additions and removals.

ODataGridProps/ODataGridProProps

The props are the same as the standard DataGrid props with the following changes:

* = required property

Modifications

Name Change Description
columns* Type See ODataGridColDef
rows Removed Handled internally
autoPageSize Removed Not supported
columnVisibilityModel Type Changed to { [key: string]: boolean | Partial<Record<Breakpoint, boolean>> } to support responsive column visibility

Note: providing a value will cause the hide property to be ignored on all column definitions.
disableColumnFilter Removed Not supported - default filtering is replaced
filterMode Removed Not supported - default filtering is replaced
filterModel Removed Not supported - default filtering is replaced
loading Removed Handled internally
onFilterModelChange Removed Not supported - default filtering is replaced
onPageChange Removed Handled internally
onPageSizeChange Removed Handled internally
page Removed Handled internally
pageSize Removed Handled internally
paginationMode Removed Handled internally
rowCount Removed Handled internally
sortingMode Removed Handled internally
sortModel Removed Handled internally

New Properties

Name Type Default Description
url* string URL of the OData endpoint
alwaysSelect string[] Array of entity properties to add to the $select clause of the query, even if a column doesn't exist for that property or the column is not visible.

If you use the getRowId prop of the DataGrid, ensure that property is added here as well.
defaultPageSize number 10 The default page size to use.
defaultSortModel GridSortModel The default property/properties to sort by.
disableFilterBuilder boolean Disable the filter/query builder if set to true
disableHistory boolean Disable the browser history integration for sorting and pagination if set to true.
Note: this does not disable history integration for the filter builder.
$filter string Static value to use for the $filter clause of the query.

Note: this also has the effect of setting disableFilterBuilder to true.
filterBuilderProps FilterBuilderProps Props to be passed to the FilterBuilder.
requestOptions RequestInit Options to use in fetch() call to OData endpoint.

The column definition is again similar to the standard GridColDef.

Strong typing is supported through the TRow generic type. The original unflattened type can be accessed using the result property of the grid row parameters. Action columns are also supported using the ODataGridColumns<T> type.

The TDate generic type is also available to specify the date provider type for dateTime columns with a date picker filter.

Modifications

Name Change Description
filterOperators Type Type changed to Operation[]
hide Type Type changed to boolean | Partial<Record<Breakpoint, boolean>> to support responsive column hiding.

Note: usage not recommended, use columnVisibilityModel instead. This property will be deprecated in the future.
sortComparator Removed Not supported

New Properties

* = not applicable to collection fields

Name Type Default Description
autocompleteGroup string Group the field should be placed under in the field selection dropdown
caseSensitive boolean If set to true, all string operations on the field will be case sensitive. Otherwise tolower() is called on all string operations.
collection* boolean Indicates this column is a collection, i.e. is an array. Enables the "Any", "All" and "Count" options.
collectionFields ODataGridColDef Column definitions for the subfields of the collection. Any properties marked with * are not supported.
datePickerProps DatePickerProps Props to pass to the DatePicker component for columns with type date
dateTimePickerProps DateTimePickerProps Props to pass to the DateTimePicker component for columns with type datetime
expand Expand | Expand[] Include related entities using the $expand clause.
filterable boolean Hides the field and does not allow filtering in the FilterBuilder when set to false.
filterField string If the field name is different to the field which should be used for filtering, provide the field for filtering here. See also: filterType.
filterOnly boolean false Set to true if the field is for filtering only and cannot be displayed as a column in the datagrid.
filterOperators Operation[] ["eq", "ne", "gt", "lt", "ge", "le", "contains", "null", "notnull"] Array of supported filter operations for the field.
filterType string If the type of the field to be filtered is different to that of the displayed field, provide the type here. See also: filterField.
getCustomFilterString (op: Operation, value: any) => string | FilterCompute | boolean Function to generate a custom filter string for use in the $filter clause. Return false to skip and not add it to the $filter clause.

Also supports the use of the $compute clause by returning a FilterCompute. The computed property/properties can also be added to $select by returning a ComputeSelect.
getCustomQueryString (op: Operation, value: any) => ({ [key: string]: string }) Function to generate a custom set of query string values to add to the OData request.
label string Defaults to the same value as headerName or field Text to be displayed in the field selection dropdown.
nullable boolean Adds an "Unknown" option to the value dropdown for columns with type boolean if set to true.
select string Additional fields to add to the $select clause.
selectProps { selectProps?: SelectProps, formControlProps?: FormControlProps, label?: string } Props to pass to the Select, FormControl and Label components for this column in the filter. See also: textFieldProps.
sortField string If the name of the field to sort by is different to that of the displayed field, provide the name for sorting by here.
textFieldProps TextFieldProps Props to pass to the TextField component in the filter for this column. See also: selectProps.
renderCustomInput (value: any, setValue: (v: any) => void) => React.ReactNode Function to render a custom component for the "Value" input of the filter. The component should read the value from value and use setValue to change the value of the filter. See also: renderCustomFilter.
renderCustomFilter (value: any, setValue: (v: any) => void) => React.ReactNode Function to render a custom component for filter. The component should read the value from value and use setValue to change the value of the filter. This overrides the "Operation" input as well as the "Value" input. See also: renderCustomInput.
Name Type Default Description
autocompleteGroups string[] Array of groups for field selection dropdown (used for setting group order)
autocompleteProps AutocompleteProps Props to pass to the Autocomplete component used for the field and collection field dropdowns
datePickerProps DatePickerProps Props to pass to the DatePicker component used for the value input for columns of type date
datePickerProps DatePickerProps Props to pass to the DateTimePicker component used for the value input for columns of type datetime
disableHistory boolean Disables browser history integration if set to true
filter SerialisedGroup Allows setting the state of the FilterBuilder using a SerialisedGroup. You could use this to implement filter saving and restoring.

Changing the value of this property will cause restoreState to be called, but with the state property undefined.
localeText FilterBuilderLocaleText Localization strings for FilterBuilder (see Localization section)
localizationProviderProps LocalizationProviderProps Props to pass to the LocalizationProvider component for the DatePicker and DateTimePicker components
onSubmit (params: FilterParameters) => (void | any) Function called when FilterBuilder is submitted (e.g. when the search button is clicked). You should use this to trigger the OData request.

params.filter is the OData filter string, params.serialised is a serialised form of the query which can be used to load the query back into the filter builder.
onRestoreState (params: FilterParameters, state?: any) => void Function called when the state of the FilterBuilder is restored (e.g. from history navigation). You should also use this to trigger the OData request alongside the onSubmit callback.

state is the the value of history.state that the query was restored from. state will be undefined if the call is as a result of the filter property changing.
searchMenuItems ({ label: string, onClick: () => void })[] Array of entries to add to the dropdown menu next to the Search button of the FilterBuilder

Localization

The FilterBuilder component supports localization like the DataGrid through the localeText property. See below for the translation keys and their default values:

{
  and: "And",
  or: "Or",

  addCondition: "Add Condition",
  addGroup: "Add Group",

  field: "Field",
  operation: "Operation",
  value: "Value",
  collectionOperation: "Operation",
  collectionField: "Field",

  search: "Search",
  reset: "Reset",

  opAny: "Has at least one",
  opAll: "All have",
  opCount: "Count",

  opEq: "=",
  opNe: "≠",
  opGt: ">",
  opLt: "<",
  opGe: "≥",
  opLe: "≤",
  opContains: "Contains",
  opNull: "Is Blank",
  opNotNull: "Is Not Blank"
}

Development

ODataGrid is developed using pnpm. It will probably work fine with npm too, but this hasn't been tested.

To build and run the packages, you first need to install the development packages by running pnpm i in the packages directory. Once you have done that you can build or run the relevant package.

Building

Building is simple, just run pnpm build in packages/o-data-grid or packages/o-data-grid-pro.

The build output is in the build directory.

Running Locally

For ease of testing, each package has a basic dev site included. To start it run pnpm start. This is only a front-end server, you will have to modify the app in dev to point to an OData service of your choice, and add the correct column schema.