sm-react-crud
Version:
Common frontend CRUD components for SM
362 lines (307 loc) • 9.65 kB
Markdown
This library contains few components to Create, Read, Update and Delete data.
## Installing
``` npm i sm-react-crud ```
Then you have to connect reducer and saga from the package
```
import {reducer as crudReducers} from 'sm-react-crud'
...
const store = createStore(
combineReducers({
...reducers,
...crudReducers
}),
composeEnhancers(applyMiddleware(...middlewares))
);
...
```
```
...
import {saga as crudSagas} from 'sm-react-crud'
...
export default function* devSaga() {
yield all([
...
crudSagas(),
...
]);
}
```
## CrudFull
Renders a list of items with a button to create new one. Items can be sorted/filtred by the each sorted/filtred column.
## FRONTEND API
##### crudCreate
an URL to make a creating item request.
##### crudRead
an URL to fetch items.
##### modelName
a name of model, unique identification key for this component.
##### customActionsFunc
provides a function to customazing action handling
##### createButtonTitle
create button label
##### createFormOptions:
options to create form - fields key is required
##### submitShape
provides a function to set a shape of submit payload
```form => {data: form, model: 'modelName'}```
##### updateShape
provides a function to set shape of updating payload
```form => {data: form, model: 'updateModelName'}```
##### createDisabled
disables create mode
##### iconsProvider
provides a function to choose an icon by id
```
(id) => {
switch (id) {
case 'update':
return 'edit';
...
```
##### btnStyle
styles object for default button component
##### ButtonComponent
custom button component
##### tableStyle
style object for table
##### tableWrapper
component to wrap the table
##### fixActionColumn
bool prop to fix action column on the right side
##### iconTheme
antd icon theme (default: 'outline')
##### size
antd table size (default: 'default')
##### tdClass
specify class for td tag
##### initialModal
provides an object to initialize modal form
##### scrollX
scroll size whian actions column is fixed (default: 1300)
##### pageSize
items count on one page (default: 20)
#### getChildrenUrl
url to fetch children
#### Example
./createFormFields
```
export default [
{
name: 'name',
type: 'text',
placeholder: 'Enter a name',
label: <strong>Name</strong>,
validateFunc: (values, errors) => {
if(!values.name) errors.name = 'You shoul fill this field';
return errors;
},
}, {
name: 'description',
type: 'text',
placeholder: 'Enter a description',
label: <strong>Description</strong>,
}, {
name: 'status_id',
type: 'select',
placeholder: 'Enter a status',
label: <strong>Status</strong>,
options: [
{id: 1, name: 'Да'},
{id: 2, name: 'Нет'}
],
component: props => <Status {...props} />
}]
```
Use case
```
import createFormFileds from './createFormFileds'
import {crudFull} from 'sm-react-crud'
const objects = <CrudFull
crudRead={'https://api/object/list'}
crudCreate={'https://api/object/create'}
modelName={'objectsName'}
createDisabled={false}
createButtonTitle={"New object"}
createFormOptions={{
fields: createFormFileds,
title: 'Create new',
editTitle: 'Edit object',
}}
submitShape={form => ({
name: form.name.toUpperCase(),
description: form.description.toLowerCase()
})}
updateShape={record => ({
name: record.name,
description: record.description.toLowerCase()
})}
customActionsFunc={(action, object) => {
switch(action.id) {
case 'took':
//some action
break;
case 'return':
//some action
break;
default:
return null;
}
}}
/>
```
#### requestSaga && apiAdress
You have to define apiAdress in your store to use requestSaga for requests.
It can be used for fetching data or creating a new record.
### Modal form logic
#### Field object
Field object may contains following
name: string - input name,
type: string - input type,
placeholder: string - placeholder text,
label: string or html - label,
component: react class or function - renderer for input,
dropdownRender: react class or function - antd dropdown for input,
optionsKey: string - key in store to get input options arr.
Available field types: text, textarea, number, date, select, checkbox
#### Redux Store Key
You can specify store key to set options property for select or another data for your field.
```
...
{
name: 'status_id',
type: 'select',
placeholder: 'Enter a status',
label: <strong>Status</strong>,
component: props => <Status {...props} />
optionsKey: 'statusOptions'
},
...
```
#### Dynamics
Sometimes you need to change fields array dynamically depending on the usability logic.
To impliment it, use createFormOptions and provide modified fields array by the 'fields' key:
```
createFormOptions={{
fields: modifiedCreateFormFileds,
title: 'Create record',
editTitle: 'Edit record',
}}
```
## BACKEND API
Backend response must contains four fields at least:
- columns : array;
- count : number;
- filter : object;
- items : array.
#### Columns
Columns is an array of columns() you want to render into the table. Each column includes several fields:
- id : number, uniq identificator, which is matched with key in record;
- title: string, text you want to render as a column name;
- type: string, type of the data you send under the key;
- order: object, inlides fields 'can' (setting order available or not) and 'orders' (an array of available orders ).
- filter: object, inlides fields:
- can (setting filter available or not),
- type (type of filter input),
- defaultValue (default filter input value)
- query (url to fetch filter options)
Available filter types:
- input_number (input type 'number')
- input_text (input type 'text')
- date_picker ( antd date picker)
- select_one (select, can select one option)
- select (miltiple select)
- boolean (checkbox)
#### Items
It's an array of records and a main table info. It must includes keys that are matched with culumns ids and contains
the same type of data that are specified in columns type. Example is below.
```
{"response":
{
"items":[
{
"objectType": 'room',
"object":{
"id":22,
"name":"Ул. Чапаевская 210 / Вилоновская 10, кв 3 (Квартира)"
},
"worker":{
"id":44,
"name":"var1232enik163_yandex_ru"
},
"description":"hh",
"action_date":1549224000,
"updated_at":1549280956,
},
{
"objectType": 'flat',
"object":{
"id":22,
"name":"Ул. Чапаевская 210 / Вилоновская 10, кв 3 (Квартира)"},
"worker":{
"id":25,
"name":"DSTS"
},
"description":"ghjgh",
"action_date":1549137600,
"updated_at":1549186595,
}
],
"columns":[
{
"id":"objectType",
"title":"Тип",
"type":"string",
"filter": {
"can":true,
"type":"select_one",
"defaultValue":"",
"query":"/v1/owner/tenant/filter/action-types"
},
"order":{
"can":true,
"orders":[
"SORT_ASC",
"SORT_DESC"
]
}
},{
"id":"object",
"title":"Объект",
"type":"object",
"filter":{
"can":true,
"type":"select_one",
"defaultValue":"",
"query":"/v1/owner/tenant/filter/objects"
},
"order":{
"can":false,
"orders":[]
}
}
],
count: 2,
filter: {}
}
}
```
You can see that column with id 'objectType' has field 'type' with value 'string'. In item object
we have a field 'objectType' which is string, what is matched with column field 'type'.
There is a ralation column id -> items key.
##### ArrayCell
You can specify 'array_ext' column type to render an array data as you wish using following parameters:
- "values", data you wont to render
- "type", data type ("text", "date", "array_ext"), default 'text'
- "isHtml", indicates whether the data is html, default 'false'
- "delimiter", separator for "values" item, default none
- "dateFormat", indicates format of rendering date, for example 'DD-MM-YYYY', default: 'DD.MM.YYYY'
- "style", style object for item
Example:
```
users: {
values: ['<div><strong><a>Alex</a></strong></div>', '<div><em><a>Masha</a></em></div>'],
isHtml: true,
type: 'text',
delimiter: '----'
}
```