0.8.0 • Published 5 years ago

@flipbyte/redux-datatable v0.8.0

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

@flipbyte/redux-datatable

Developed by Flipbyte

npm package Codacy Badge

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

KeyTypeRequiredDefaultDescription
namestringtrue-key in the row data whose value needs to be loaded for the column (does not have to be unique)
heightintegertrue-The maximum height of the table
rowHeightintegertrue-The maximum height of each table body row
routesobjecttrue-Routes definition to fetch data and other custom routes config for custom handling (Check below)
componentsobjecttrue-All the components required for your table
entityobjectfalse-Normalizr specification. Check below for details.
layoutarraytrue-The layout of your table
editingbooleanfalsefalseSet the default state of the table to be in editing mode
primaryKeystringtrue-Set the primary key column of the table for actions like editing.
noResultsMessagestringtrue-Set the message to be displayed when table is empty

Routes object

KeyTypeRequiredDefaultDescription
getobjecttrue-The configuration for fetching data
- get
routestringtrue-Your data fetching route
sortstringtrue-Your key to sort with
dirstringtrue-Sort by 'asc' or 'desc' order
resultPathobjecttrue-The keys object to your data. Required { data: '{your data path in json response. Ex: result.data}'}
paramsobjectfalse-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.

KeyTypeRequiredDefaultDescription
stateobjecttrue-Path to sub state in your top level redux state where the normalized data will be saved
responseSchemaobjecttrue-Define how the data is represented in your fetch data api response
schemaobjecttrue-Define how the data is represented in each row item of the table fetch repsonse
selectorsobjecttrue-Add the selectors that will be used by columns to fetch respective data

Note: Check the example code.

Available Components

Common Properties

KeyTypeRequiredDefaultDescription
stylesobjectfalse{}styled-component styles object or key-value pairs with values being styled-component styles object
rendererfunctionfalse-returns a react component
typestringtrue-the type of the object
classNamestringtruevarieshtml 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

KeyTypeRequiredDefaultDescription
maskobjectfalse{}styled-component styles object
spinnerobjectfalse{}styled-component styles object
ResultCount

No unique properties

Pages

Properties

KeyTypeRequiredDefaultDescription
firstClassNamestringfalserdt-pg-firsthtml class names
lastClassNamestringfalserdt-pg-lasthtml class names
prevClassNamestringfalserdt-pg-prevhtml class names
nextClassNamestringfalserdt-pg-nexthtml class names
pageNumberClassNamestringfalserdt-pg-numhtml class names
activeClassNamestringfalseactivehtml class names

Styles object properties

KeyTypeRequiredDefaultDescription
firstobjectfalse{}styled-component styles object
lastobjectfalse{}styled-component styles object
previousobjectfalse{}styled-component styles object
nextobjectfalse{}styled-component styles object
pageNumberobjectfalse{}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

KeyTypeRequiredDefaultDescription
labelsobjectfalsecheck belowcheck below
savefunctionfalse-( config ) => ( dispatch, getState ) => { ... }
classNamesobjectfalsecheck belowcheck below

classNames object properties

KeyTypeRequiredDefaultDescription
showstringfalserdt-toolbar-buttonhtml class names
hidestringfalserdt-toolbar-buttonhtml class names
savestringfalseSardt-toolbar-buttonvehtml class names

Labels object properties

KeyTypeRequiredDefaultDescription
showstringfalseMake editableLabel for the button to show editable table
hidestringfalseHide editableLabel for the button to hide editable table
savestringfalseSaveLabel for the button to save the modified table

Styles object properties

KeyTypeRequiredDefaultDescription
showobjectfalse{}styled-component styles object
hideobjectfalse{}styled-component styles object
saveobjectfalse{}styled-component styles object
Actions (type: mass-actions)

Properties

KeyTypeRequiredDefaultDescription
optionsarraytrue[]array of actions objects
labelstringtrue-Label for the actions dropdown button
btnClassNamestringfalserdt-toolbar-buttonhtml class names
menuClassNamestringfalserdt-toolbar-menuhtml class names
menuItemClassNamestringfalserdt-toolbar-itemhtml class names
activeClassNamestringfalseshowhtml class names

Actions object properties

KeyTypeRequiredDefaultDescription
typestringtrue-action
namestringtrue-Unique name
labelstringtrue-Label for the action item
rolestringfalse-Add role 'menu-item' to hide dropdown on click
thunkfunctiontrue-( config ) => ( dispatch, getState ) => { ... }

Styles object properties

KeyTypeRequiredDefaultDescription
buttonobjectfalse{}styled-component styles object
dropdownMenuobjectfalse{}styled-component styles object
dropdownItemobjectfalse{}styled-component styles object
Button (type: button)

Properties

KeyTypeRequiredDefaultDescription
labelstringrequired-Label for the actions dropdown button
ResetFilters (type: reset-filters)

Properties

KeyTypeRequiredDefaultDescription
labelstringrequired-Label for the actions dropdown button
Print (type: print)

Makes the table printable.

Properties

KeyTypeRequiredDefaultDescription
labelstringrequired-Label for the actions dropdown button
Columns (type: columns)

Shows the columns toggling dropdown.

Properties

KeyTypeRequiredDefaultDescription
labelstringrequired-Label for the actions dropdown button
btnClassNamestringfalserdt-toolbar-buttonhtml class names
menuClassNamestringfalserdt-toolbar-menuhtml class names
menuItemClassNamestringfalserdt-toolbar-itemhtml class names
activeClassNamestringfalseshowhtml class names

Styles object properties

KeyTypeRequiredDefaultDescription
buttonobjectfalse{}styled-component styles object
dropdownMenuobjectfalse{}styled-component styles object
dropdownItemobjectfalse{}styled-component styles object
Limiter (type: limiter)
KeyTypeRequiredDefaultDescription
optionsarrayrequired[]array of limiter counts
defaultintegerrequired[]default limiter option (should be a value in the options array above)
selectClassNamestringfalserdt-limiter-selecthtml class names
Table (type: table)
KeyTypeRequiredDefaultDescription
columnsarrayrequired[]array of object with column configuration

Columns object properties

KeyTypeRequiredDefaultDescription
namestringtrue-Unique name for the column
labelstringtrue-Label for the column
sortablebooleanfalsetrueWhether the column is sortable
filterablebooleanfalsetrueWhether the column is filterable
editablebooleanfalsefalseWhen the table is set to be editable, set whether the respective column is among the editable
visiblebooleanfalsetrueWhether the column is visible on load
typestringtruestringAvailable types: selection, number, date, string, image, options, actions
widthintegertrue-Width of the column
textAlignstringfalseleftText alignment in the column
rendererfunctionfalse-Define a custom renderer for column body.
selectorstringobjectfalse-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
itemsarraytrue-array of item configuration object
- item configuration object
namestringtrue-Unique name for the action
labelstringtrue-Label for the action
thunkfunctiontrue-An action creator which is dispatched on action click. Check demo schema.

Properties specific to column of type 'options'

KeyTypeRequiredDefaultDescription
optionsobjecttrue-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'

KeyTypeRequiredDefaultDescription
itemsarraytrue-array of item configuration object

Properties for a single item of type 'actions'

KeyTypeRequiredDefaultDescription
namestringtrue-Unique name for the action
labelstringtrue-Label for the action
thunkfunctiontrue-An action creator which is dispatched on action click. Check the example below.
stylesobjectfalse{}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

KeyTypeRequiredDefaultDescription
tableobjectfalse{}styled-component styles object
theadobjectfalse{}styled-component styles object
tbodyobjectfalse{}styled-component styles object
filtersobjectfalse{}styled-component styles object
trobjectfalse{}check below
thobjectfalse{}styled-component styles object
tdobjectfalse{}check below

tr Styles object properties

KeyTypeRequiredDefaultDescription
headerobjectfalse{}styled-component styles object
filtersobjectfalse{}styled-component styles object
bodyobjectfalse{}styled-component styles object

td Styles object properties

KeyTypeRequiredDefaultDescription
filtersobjectfalse{}styled-component styles object
bodyobjectfalse{}styled-component styles object

License

The MIT License (MIT)

0.8.0

5 years ago

0.7.14

5 years ago

0.7.13

5 years ago

0.7.12

5 years ago

0.7.11

5 years ago

0.7.10

5 years ago

0.7.9

5 years ago

0.7.8

5 years ago

0.7.7

5 years ago

0.7.6

5 years ago

0.7.5

5 years ago

0.7.4

5 years ago

0.7.3

5 years ago

0.7.2

5 years ago

0.7.1

5 years ago

0.7.0

5 years ago

0.6.4

5 years ago

0.6.3

5 years ago

0.6.2

5 years ago

0.6.1

5 years ago

0.6.0

5 years ago

0.5.4

5 years ago

0.5.3

5 years ago

0.5.2

5 years ago

0.5.1

5 years ago

0.5.0

5 years ago

0.4.1

5 years ago

0.4.0

5 years ago

0.3.0

5 years ago

0.2.2

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago

0.1.0

5 years ago