1.3.1 • Published 7 days ago

o-data-grid v1.3.1

Weekly downloads
-
License
GPL-3.0-or-later
Repository
github
Last release
7 days ago

ODataGrid

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.

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.

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

NameChangeDescription
columns*TypeSee ODataGridColDef
rowsRemovedHandled internally
autoPageSizeRemovedNot supported
columnVisibilityModelTypeChanged to { [key: string]: boolean \| Partial<Record<Breakpoint, boolean>> } to support responsive column visibilityNote: providing a value will cause the hide property to be ignored on all column definitions.
disableColumnFilterRemovedNot supported - default filtering is replaced
filterModeRemovedNot supported - default filtering is replaced
filterModelRemovedNot supported - default filtering is replaced
loadingRemovedHandled internally
onFilterModelChangeRemovedNot supported - default filtering is replaced
onPageChangeRemovedHandled internally
onPageSizeChangeRemovedHandled internally
pageRemovedHandled internally
pageSizeRemovedHandled internally
paginationModeRemovedHandled internally
rowCountRemovedHandled internally
sortingModeRemovedHandled internally
sortModelRemovedHandled internally

New Properties

NameTypeDefaultDescription
url*stringURL of the OData endpoint
alwaysSelectstring[]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.
defaultPageSizenumber10The default page size to use.
defaultSortModelGridSortModelThe default property/properties to sort by.
disableFilterBuilderbooleanDisable the filter/query builder if set to true
disableHistorybooleanDisable the browser history integration for sorting and pagination if set to true. Note: this does not disable history integration for the filter builder.
$filterstringStatic value to use for the $filter clause of the query.Note: this also has the effect of setting disableFilterBuilder to true.
filterBuilderPropsFilterBuilderPropsProps to be passed to the FilterBuilder.
requestOptionsRequestInitOptions to use in fetch() call to OData endpoint.

ODataGridColDef

The column definition is again similar to the standard GridColDef.

Modifications

NameChangeDescription
filterOperatorsTypeType changed to Operation[]
hideTypeType 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.
sortComparatorRemovedNot 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 | | 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. |

FilterBuilderProps

NameTypeDefaultDescription
autocompleteGroupsstring[]Array of groups for field selection dropdown (used for setting group order)
autocompletePropsAutocompletePropsProps to pass to the Autocomplete component used for the field and collection field dropdowns
datePickerPropsDatePickerPropsProps to pass to the DatePicker component used for the value input for columns of type date
datePickerPropsDatePickerPropsProps to pass to the DateTimePicker component used for the value input for columns of type datetime
disableHistorybooleanDisables browser history integration if set to true
filterSerialisedGroupAllows 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.
localeTextFilterBuilderLocaleTextLocalization strings for FilterBuilder (see Localization section)
localizationProviderPropsLocalizationProviderPropsProps 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) => voidFunction 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.

7.0.0-alpha.7

7 days ago

7.0.0-alpha.6

22 days ago

7.0.0-alpha.5

22 days ago

7.0.0-alpha.4

26 days ago

7.0.0-alpha.1

29 days ago

7.0.0-alpha.0

29 days ago

7.0.0-alpha.3

28 days ago

7.0.0-alpha.2

28 days ago

1.3.1

2 years ago

1.2.0

2 years ago

1.1.1

2 years ago

1.3.0

2 years ago

1.2.1

2 years ago

1.1.0

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.2.1

2 years ago

0.2.0

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago