@flipbyte/redux-datatable
v0.8.0
Published
React-Redux data table
Downloads
25
Readme
@flipbyte/redux-datatable
Datatable built using React and Redux to fetch JSON data asynchronously using REST API.
- Filterable columns by date ranges, numeric ranges and text.
- Pagination
- Sortable columns
- Configurable column widths
- Editable table
- Built in windowing to handle large dataset with thousands of rows
- Customizable limiter options
- Customizable toolbar with the ability to add custom renderers
- Easily configurable layout
- Custom row level actions
- Thunks to handle custom mass or row actions externally.
- Compatible with normalizr to handle externally managed states
- Easily styleable with styled-components and/or external css.
- Show or hide columns dynamically using the Columns item in the toolbar.
Installation
Run the following command to install using npm
npm i @flipbyte/redux-datatable
Usage
Add the table reducer and epics to your store
// Get the table reducer and epics as follows
import { reducer, epics } from '@flipbyte/redux-datatable';
// Add the above reducer and epics to your store.
Preparing your table config object
{
name: 'your_table_name', // this is the key used to set your table data inside the table reducer
height: 400,
rowHeight: 50,
editing: false,
primaryKey: 'id',
noResultsMessage: 'No row(s) found',
routes: { // You can add other routes and handle them using custom actions.
get: { // The route used to fetch data and it's params
route: '/{your_route}',
sort: 'id',
dir: 'asc',
resultPath: {
data: 'data'
},
params: {
...your_params_key_value_pair
}
},
...
},
entity: { // optional. Check example code in /demo.
state: '{your state path}',
responseSchema: // normalizr schema,
schema: // normal;izr schema
},
layout: [
['Editable'],
['MassActions', 'SimpleButton', 'ResetFilters', 'Spacer', 'Print', 'Columns'],
['Limiter', 'Spacer', 'ResultCount', 'Spacer', 'Pages'],
[{ id: 'Table', layout: [
['Header'],
['Filters'],
['Body'],
['Header']
]}],
['Limiter', 'Spacer', 'ResultCount', 'Spacer', 'Pages'],
],
components: {
Header: {
rowClassName: 'your custom class names',
colClassName: 'your custom class names',
className: 'your custom class names',
},
Body: {
rowClassName: 'your custom class names',
colClassName: 'your custom class names',
className: 'your custom class names',
},
Filters: {
rowClassName: 'your custom class names',
colClassName: 'your custom class names',
className: 'your custom class names',
},
Loader: {
styles: {
mask: { ... },
spinner: { ... }
}
},
ResultCount: {
className: 'your custom class names',
styles: { ... }
},
Pages: {
firstClassName: 'your custom class names',
lastClassName: 'your custom class names',
nextClassName: 'your custom class names',
prevClassName: 'your custom class names',
pageNumberClassName: 'your custom class names',
activeClassName: 'your custom class names',
styles: {
first: { ... },
last: { ... },
previous: { ... },
next: { ... },
pageNumber: { ... },
}
},
Editable: {
type: 'editable',
labels: {
show: 'Make editable',
hide: 'Hide editable',
save: 'Save',
},
classNames: {
show: 'your custom class names',
hide: 'your custom class names',
save: 'your custom class names',
},
save: ( config ) => ( dispatch, getState ) => {
const tableState = getState()[config.reducerName][config.name];
console.log('toolbar save click with modified data', config, tableState.modified);
config.action(MODIFY_DATA)({ clear: true });
// Dispatch MODIFY_DATA action with clear: true, to reset the modified data
// Dispatch REQUEST_DATA action "config.action(REQUEST_DATA)" to refresh data.
},
styles: {
show: { ... },
hide: { ... },
save: { ... }
}
// renderer: ( props ) => { ... }
},
MassActions: {
name: 'actions',
label: 'Actions',
id: 'dropdown',
className: 'your custom class names',
btnClassName: 'your custom class names',
menuClassName: 'your custom class names',
menuItemClassName: 'your custom class names',
activeClassName: 'your custom class names',
styles: {
button: { ... },
dropdownMenu: { ... },
dropdownItem: { ... }
}
options: [{
type: 'action',
name: 'delete',
label: 'Delete',
styles: { ... },
thunk: ( config ) => ( dispatch, getState ) => {
// Get current table state.
const tableState = getState()[config.reducerName][config.name];
console.log(config, tableState);
console.log(getItemIds(tableState.selection, tableState.items, config.primaryKey/*, config.entity.schema*/))
confirm('Are your sure you want to delete the selected items?')
? console.log('delete items', config, getState(), tableState)
: console.log(false);
// Filter your selected item ids here for deletion
// You can find the selection data in the selection key of the tableState.
// When all:true, exclude the ids in the selected object with value false and vice versa.
}
}, {
type: 'action',
name: 'edit',
label: 'Edit this field',
}, ...]
},
SimpleButton: {
type: 'button',
label: 'Simple Button',
className: 'your custom class names',
thunk: ( config ) => ( dispatch, getState ) => { ... },
styles: { ... }
},
ResetFilters: {
type: 'reset-filters',
label: 'Reset Filters',
className: 'your custom class names',
styles: { ... }
},
Print: {
type: 'print',
label: 'Print Table',
className: 'your custom class names',
styles: { ... }
},
Columns: {
name: 'columns',
type: 'columns',
label: 'Columns',
visible: true,
className: 'your custom class names',
btnClassName: 'your custom class names',
menuClassName: 'your custom class names',
menuItemClassName: 'your custom class names',
activeClassName: 'your custom class names',
styles: {
button: { ... },
dropdownMenu: { ... },
dropdownItem: { ... }
}
},
Limiter: {
type: 'limiter',
options: [10, 20, 50, 200, 2000, 0],
default: 200,
className: 'your custom class names',
selectClassName: 'your custom class names',
styles: { ... }
},
Table: {
className: 'your custom class names',
styles: {
table: { ... },
thead: { ... },
tbody: { ... },
filters: { ... },
tr: {
header: { ... },
filters: { ... },
body: { ... }
},
th: { ... },
td: {
filters: { ... },
body: { ... }
}
},
columns: [{
name: 'id',
label: '',
sortable: false,
type: 'selection',
width: 50,
}, {
label: 'ID',
type: 'number',
name: 'id',
sortable: true,
width: 150,
filterable: true,
sortable: true,
}, {
label: "Status",
type: "options",
name: "status",
sortable: true,
filterable: true,
textAlign: "center",
options: {
"published": {
label: "Published"
},
"draft": {
label: "Draft"
},
"archived": {
label: "Archived"
},
...
}
}, {
label: 'Avatar',
type: 'image',
name: 'avatar',
sortable: false,
textAlign: 'center',
width: 200,
filterable: false,
imgHeight: 50
}, {
label: 'First Name',
type: 'string',
name: 'first_name',
sortable: true,
textAlign: 'text-left',
width: 200,
filterable: true,
}, {
label: 'Actions',
type: 'actions',
name: 'actions',
width: 100,
items: [{
type: 'action',
name: 'edit',
label: 'Edit',
btnClass: 'btn btn-secondary',
icon: 'edit',
thunk: ( payload ) => ( dispatch, getState ) => {
console.log('edit', payload, getState());
},
style: { ... }
}, {
type: 'action',
name: 'delete',
label: 'Delete',
icon: 'trash-alt',
thunk: ( payload ) => ( dispatch, getState ) => {
confirm("Are your sure you want to delete this page?")
? console.log('delete', getState())
: console.log(false);
},
style: { ... }
},
...
]
},
...
]
}
}
}
Render table component
import ReduxDatatable from '@flipbyte/redux-datatable';
const YourComponent = () =>
<ReduxDatatable
reducerName={ /* The key used while combining reducers in the store */ }
config={ /*your table config object*/ }
/>
Table config props
| Key | Type | Required | Default | Description | | ---------------- | ------- | -------- | ------- | ------------------------------------------------------------------------------------------------ | | name | string | true | - | key in the row data whose value needs to be loaded for the column (does not have to be unique) | | height | integer | true | - | The maximum height of the table | | rowHeight | integer | true | - | The maximum height of each table body row | | routes | object | true | - | Routes definition to fetch data and other custom routes config for custom handling (Check below) | | components | object | true | - | All the components required for your table | | entity | object | false | - | Normalizr specification. Check below for details. | | layout | array | true | - | The layout of your table | | editing | boolean | false | false | Set the default state of the table to be in editing mode | | primaryKey | string | true | - | Set the primary key column of the table for actions like editing. | | noResultsMessage | string | true | - | Set the message to be displayed when table is empty |
Routes object
| Key | Type | Required | Default | Description | | ---------- | ------ | -------- | ------- | ---------------------------------------------------------------------------------------------------- | | get | object | true | - | The configuration for fetching data | | - get | | | | | | route | string | true | - | Your data fetching route | | sort | string | true | - | Your key to sort with | | dir | string | true | - | Sort by 'asc' or 'desc' order | | resultPath | object | true | - | The keys object to your data. Required { data: '{your data path in json response. Ex: result.data}'} | | params | object | false | - | Key-value pairs of additional params that you want to pass to the request |
Components object
Components can be defined within this object as key value pairs, where key
is the id of the component and needs to be unique and value
is a configuration object for the specific component.
All available components are listed below with their configuration. Custom components can be added and existing components can be overridden by using the key renderer
in the configuration object of the component.
Please check the example table config object above.
Layout array
An array of arrays where each inner array represents a row in the layout, within which components can be specified, which will be displayed in the frontend. Please check the example table config object above.
Entity array
All the fields are required when entity is defined (data normalized). However, entity key itself is optional in the table config.
| Key | Type | Required | Default | Description | | -------------- | ------ | -------- | ------- | --------------------------------------------------------------------------------------- | | state | object | true | - | Path to sub state in your top level redux state where the normalized data will be saved | | responseSchema | object | true | - | Define how the data is represented in your fetch data api response | | schema | object | true | - | Define how the data is represented in each row item of the table fetch repsonse | | selectors | object | true | - | Add the selectors that will be used by columns to fetch respective data |
Note: Check the example code.
Available Components
Common Properties
| Key | Type | Required | Default | Description | | --------- | -------- | -------- | ------- | -------------------------------------------------------------------------------------------------- | | styles | object | false | {} | styled-component styles object or key-value pairs with values being styled-component styles object | | renderer | function | false | - | returns a react component | | type | string | true | - | the type of the object | | className | string | true | varies | html class names for top-level html element in the component |
Loader
Note: This component cannot be added to the layout and does not have any other properties except styles.
Styles object properties
| Key | Type | Required | Default | Description | | ------- | ------ | -------- | ------- | ------------------------------ | | mask | object | false | {} | styled-component styles object | | spinner | object | false | {} | styled-component styles object |
ResultCount
No unique properties
Pages
Properties
| Key | Type | Required | Default | Description | | ------------------- | ------ | -------- | ------------ | ---------------- | | firstClassName | string | false | rdt-pg-first | html class names | | lastClassName | string | false | rdt-pg-last | html class names | | prevClassName | string | false | rdt-pg-prev | html class names | | nextClassName | string | false | rdt-pg-next | html class names | | pageNumberClassName | string | false | rdt-pg-num | html class names | | activeClassName | string | false | active | html class names |
Styles object properties
| Key | Type | Required | Default | Description | | ---------- | ------ | -------- | ------- | ------------------------------ | | first | object | false | {} | styled-component styles object | | last | object | false | {} | styled-component styles object | | previous | object | false | {} | styled-component styles object | | next | object | false | {} | styled-component styles object | | pageNumber | object | false | {} | styled-component styles object |
Editable (type: editable)
Toggles the table between editable and non-editable and shows a save button when the content of the table is modified
Properties
| Key | Type | Required | Default | Description | | ---------- | -------- | -------- | ----------- | ----------------------------------------------- | | labels | object | false | check below | check below | | save | function | false | - | ( config ) => ( dispatch, getState ) => { ... } | | classNames | object | false | check below | check below |
classNames object properties
| Key | Type | Required | Default | Description | | ---- | ------ | -------- | ---------------------- | ---------------- | | show | string | false | rdt-toolbar-button | html class names | | hide | string | false | rdt-toolbar-button | html class names | | save | string | false | Sardt-toolbar-buttonve | html class names |
Labels object properties
| Key | Type | Required | Default | Description | | ---- | ------ | -------- | ------------- | ----------------------------------------------- | | show | string | false | Make editable | Label for the button to show editable table | | hide | string | false | Hide editable | Label for the button to hide editable table | | save | string | false | Save | Label for the button to save the modified table |
Styles object properties
| Key | Type | Required | Default | Description | | ---- | ------ | -------- | ------- | ------------------------------ | | show | object | false | {} | styled-component styles object | | hide | object | false | {} | styled-component styles object | | save | object | false | {} | styled-component styles object |
Actions (type: mass-actions)
Properties
| Key | Type | Required | Default | Description | | ----------------- | ------ | -------- | ------------------ | ------------------------------------- | | options | array | true | [] | array of actions objects | | label | string | true | - | Label for the actions dropdown button | | btnClassName | string | false | rdt-toolbar-button | html class names | | menuClassName | string | false | rdt-toolbar-menu | html class names | | menuItemClassName | string | false | rdt-toolbar-item | html class names | | activeClassName | string | false | show | html class names |
Actions object properties
| Key | Type | Required | Default | Description | | ----- | -------- | -------- | ------- | ----------------------------------------------- | | type | string | true | - | action | | name | string | true | - | Unique name | | label | string | true | - | Label for the action item | | role | string | false | - | Add role 'menu-item' to hide dropdown on click | | thunk | function | true | - | ( config ) => ( dispatch, getState ) => { ... } |
Styles object properties
| Key | Type | Required | Default | Description | | ------------ | ------ | -------- | ------- | ------------------------------ | | button | object | false | {} | styled-component styles object | | dropdownMenu | object | false | {} | styled-component styles object | | dropdownItem | object | false | {} | styled-component styles object |
Button (type: button)
Properties
| Key | Type | Required | Default | Description | | ----- | ------ | -------- | ------- | ------------------------------------- | | label | string | required | - | Label for the actions dropdown button |
ResetFilters (type: reset-filters)
Properties
| Key | Type | Required | Default | Description | | ----- | ------ | -------- | ------- | ------------------------------------- | | label | string | required | - | Label for the actions dropdown button |
Print (type: print)
Makes the table printable.
Properties
| Key | Type | Required | Default | Description | | ----- | ------ | -------- | ------- | ------------------------------------- | | label | string | required | - | Label for the actions dropdown button |
Columns (type: columns)
Shows the columns toggling dropdown.
Properties
| Key | Type | Required | Default | Description | | ----------------- | ------ | -------- | ------------------ | ------------------------------------- | | label | string | required | - | Label for the actions dropdown button | | btnClassName | string | false | rdt-toolbar-button | html class names | | menuClassName | string | false | rdt-toolbar-menu | html class names | | menuItemClassName | string | false | rdt-toolbar-item | html class names | | activeClassName | string | false | show | html class names |
Styles object properties
| Key | Type | Required | Default | Description | | ------------ | ------ | -------- | ------- | ------------------------------ | | button | object | false | {} | styled-component styles object | | dropdownMenu | object | false | {} | styled-component styles object | | dropdownItem | object | false | {} | styled-component styles object |
Limiter (type: limiter)
| Key | Type | Required | Default | Description | | --------------- | ------- | -------- | ------------------ | --------------------------------------------------------------------- | | options | array | required | [] | array of limiter counts | | default | integer | required | [] | default limiter option (should be a value in the options array above) | | selectClassName | string | false | rdt-limiter-select | html class names |
Table (type: table)
| Key | Type | Required | Default | Description | | ------- | ----- | -------- | ------- | ----------------------------------------- | | columns | array | required | [] | array of object with column configuration |
Columns object properties
| Key | Type | Required | Default | Description | | | ------------------------------- | -------- | -------- | ------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | name | string | true | - | Unique name for the column | | | label | string | true | - | Label for the column | | | sortable | boolean | false | true | Whether the column is sortable | | | filterable | boolean | false | true | Whether the column is filterable | | | editable | boolean | false | false | When the table is set to be editable, set whether the respective column is among the editable | | | visible | boolean | false | true | Whether the column is visible on load | | | type | string | true | string | Available types: selection, number, date, string, image, options, actions | | | width | integer | true | - | Width of the column | | | textAlign | string | false | left | Text alignment in the column | | | renderer | function | false | - | Define a custom renderer for column body. | | | selector | string | object | false | - | Define a custom selector to pick the value for the column from the state. When string is used, the selector should be defined under entity.selectors | | type: actions | | | | | | | items | array | true | - | array of item configuration object | | | - item configuration object | | | | | | | name | string | true | - | Unique name for the action | | | label | string | true | - | Label for the action | | | thunk | function | true | - | An action creator which is dispatched on action click. Check demo schema. | |
Properties specific to column of type 'options'
| Key | Type | Required | Default | Description | | ------- | ------ | -------- | ------- | -------------------------------------------- | | options | object | true | - | Defines options for the column. Check below. |
options
key is an object with a unique key for each value object. The value object consists of a property label
used to define the label of the said option. Please check the following example:
options: {
active: {
label: 'Active'
},
inactive: {
label: 'Inactive'
}
...
}
Properties specific to column of type 'actions'
| Key | Type | Required | Default | Description | | ----- | ----- | -------- | ------- | ---------------------------------- | | items | array | true | - | array of item configuration object |
Properties for a single item of type 'actions'
| Key | Type | Required | Default | Description | | ------ | -------- | -------- | ------- | ------------------------------------------------------------------------------- | | name | string | true | - | Unique name for the action | | label | string | true | - | Label for the action | | thunk | function | true | - | An action creator which is dispatched on action click. Check the example below. | | styles | object | false | {} | styled-component styles object |
Example:
{
type: 'action',
name: 'edit',
label: 'Edit',
btnClass: 'btn btn-secondary',
icon: 'edit',
thunk: ( payload ) => ( dispatch, getState ) => {
console.log('edit', payload, getState());
},
styles: { ... }
}
Styles object properties
| Key | Type | Required | Default | Description | | ------- | ------ | -------- | ------- | ------------------------------ | | table | object | false | {} | styled-component styles object | | thead | object | false | {} | styled-component styles object | | tbody | object | false | {} | styled-component styles object | | filters | object | false | {} | styled-component styles object | | tr | object | false | {} | check below | | th | object | false | {} | styled-component styles object | | td | object | false | {} | check below |
tr Styles object properties
| Key | Type | Required | Default | Description | | ------- | ------ | -------- | ------- | ------------------------------ | | header | object | false | {} | styled-component styles object | | filters | object | false | {} | styled-component styles object | | body | object | false | {} | styled-component styles object |
td Styles object properties
| Key | Type | Required | Default | Description | | ------- | ------ | -------- | ------- | ------------------------------ | | filters | object | false | {} | styled-component styles object | | body | object | false | {} | styled-component styles object |
License
The MIT License (MIT)