CF2-49: Added form in 'Measures' table

This commit is contained in:
KharchenkoVV 2021-10-06 13:57:04 +05:00
parent 05b891b15f
commit cf0b3161f0
4 changed files with 128 additions and 64 deletions

View File

@ -1,8 +1,9 @@
import { useState, useEffect } from "react" import { useState, useEffect } from 'react'
import { Button, Timeline } from 'antd' import { Button, Form, Timeline } from 'antd'
import moment from 'moment' import moment from 'moment'
import { ExclamationCircleOutlined } from '@ant-design/icons' import { ExclamationCircleOutlined } from '@ant-design/icons'
import { View } from './View' import { View } from './View'
import LoaderPortal from '../../components/LoaderPortal'
import '../../styles/index.css' import '../../styles/index.css'
import '../../styles/measure.css' import '../../styles/measure.css'
@ -13,9 +14,58 @@ export const MeasureTable = ({title, columns, values}) => {
? values[values.length-1] ? values[values.length-1]
: [] : []
const [showLoader, setShowLoader] = useState(false);
const [displayedValues, setDisplayedValues] = useState([]); const [displayedValues, setDisplayedValues] = useState([]);
const [editingColumns, setEditingColumns] = useState(columns); const [editingColumns, setEditingColumns] = useState(columns);
const [isTableEditing, setIsTableEditing] = useState(false); const [isTableEditing, setIsTableEditing] = useState(false);
const [editingActionName, setEditingActionName] = useState('');
const [measuresForm] = Form.useForm();
const buttonsConfig = [
{name:'Добавить', key:'add'},
{name:'Редактировать', key:'edit'},
{name:'Удалить', key:'delete'}
]
const createButtons = (config, onClickDelegate) => {
return (
<div className='w-300px mt-12px'>
{config.map(c => {
return (
<Button
key={c.key}
className='w-100'
onClick={onClickDelegate}
>
{c.name}
</Button>
)
})}
</div>
)
}
const crudButtons = createButtons(buttonsConfig, (e)=> {
setEditingActionName(e.target.innerText)
setIsTableEditing(true)
})
const confirmButtons =
<div className='w-300px'>
<h3 style={{textAlign: 'center'}}>{editingActionName} данные?</h3>
<div className='d-flex mt-20px'>
<Button key='confirm' className='w-100' onClick={()=> measuresForm.submit()}>Да</Button>
<Button key='decline' className='w-100' onClick={()=> setIsTableEditing(false)}>Нет</Button>
</div>
</div>
const createEditingColumns = (cols, renderDelegate) =>
cols.map(col =>
({ render: renderDelegate,
...col
})
)
useEffect(() => { useEffect(() => {
setDisplayedValues(defaultDisplay) setDisplayedValues(defaultDisplay)
@ -23,44 +73,26 @@ export const MeasureTable = ({title, columns, values}) => {
useEffect(() => { useEffect(() => {
let switchableColumns = [] let switchableColumns = []
if(isTableEditing) { isTableEditing && editingActionName !== 'Удалить'
switchableColumns = columns.map(col => ? switchableColumns = createEditingColumns(columns, () => <input className='w-100'></input>)
({ render: () => <input className='w-100'></input>, : switchableColumns = createEditingColumns(columns, null)
...col
})
)
} else {
switchableColumns = columns.map(col =>
({ render: null,
...col
})
)
}
setEditingColumns(switchableColumns) setEditingColumns(switchableColumns)
}, [isTableEditing]) }, [isTableEditing])
const createButtons = (buttonNames, buttonContainerStyle, isEditing) => {
return <div className={buttonContainerStyle}> let handleSubmitMeasuresForm = async (formData) => {
{buttonNames.map(name => // if(isTableEditing)
<Button key={name} className='w-100' onClick={()=> setIsTableEditing(isEditing)}>{name}</Button> // measuresForm.setFieldsValue({
)} // ...displayedValues
</div> // });
measuresForm.validateFields()
setShowLoader(true)
setShowLoader(false)
} }
const crudButtons =
<div className='w-300px mt-12px'>
<Button key='add' className='w-100' onClick={()=> setIsTableEditing(true)}>Добавить</Button>
<Button key='edit' className='w-100' onClick={()=> setIsTableEditing(true)}>Редактировать</Button>
<Button key='delete' className='w-100' onClick={()=> setIsTableEditing(true)}>Удалить</Button>
</div>
const confirmButtons =
<div className='w-300px d-flex mt-12px'>
<Button key='confirm' className='w-100' onClick={()=> setIsTableEditing(false)}>Да</Button>
<Button key='decline' className='w-100' onClick={()=> setIsTableEditing(false)}>Нет</Button>
</div>
return <> return <>
&nbsp; &nbsp;
<h3>{title}</h3> <h3>{title}</h3>
@ -86,7 +118,6 @@ export const MeasureTable = ({title, columns, values}) => {
dot={item.id === displayedValues.id dot={item.id === displayedValues.id
? <ExclamationCircleOutlined className="timeline-clock-icon" /> ? <ExclamationCircleOutlined className="timeline-clock-icon" />
: null} : null}
value={moment.utc(item.timestamp).local().format(format)}
> >
{moment.utc(item.timestamp).local().format(format)} {moment.utc(item.timestamp).local().format(format)}
</Timeline.Item> </Timeline.Item>
@ -95,10 +126,17 @@ export const MeasureTable = ({title, columns, values}) => {
</div> </div>
</div> </div>
<div className='w-100'> <div className='w-100'>
<View <LoaderPortal show={showLoader}>
item={displayedValues.data} <Form
columns={editingColumns} form={measuresForm}
/> onFinish={handleSubmitMeasuresForm}
>
<View
item={displayedValues.data}
columns={editingColumns}
/>
</Form>
</LoaderPortal>
</div> </div>
</div> </div>
</> </>

View File

@ -1,5 +1,22 @@
import { Empty } from 'antd'; import { Empty, Form } from 'antd';
import {Grid, GridItem} from '../../components/Grid' import {Grid, GridItem} from '../../components/Grid'
import '../../styles/index.css'
const renderSwitchableColumn = (column, itm) => {
if(column.render) {
return (
<Form.Item
name={column.dataIndex}
style={{margin: 0}}
rules={column.formItemRules}
>
{column.render(itm[column.dataIndex])}
</Form.Item>
)
}
return <p className='m-5px-auto'>{itm[column.dataIndex]}</p>
}
export const View = ({columns, item}) => { export const View = ({columns, item}) => {
if (!item || !columns?.length) if (!item || !columns?.length)
@ -11,29 +28,30 @@ export const View = ({columns, item}) => {
const colb = i % colsCount const colb = i % colsCount
return <> return <>
<GridItem <GridItem
row={row} row={row}
col={colb*2 + 1} col={colb*2 + 1}
style={{background:'#00000005', style={{background:'#00000005',
//width: '300px', //width: '300px',
border:'1px solid black' border:'1px solid black'
}} }}
> >
{column.title} {column.title}
</GridItem> </GridItem>
<GridItem
row={row} <GridItem
col={colb*2 + 2} row={row}
style={{background:'#00000005', col={colb*2 + 2}
//width: '150px', style={{background:'#00000005',
border:'1px solid black', //width: '150px',
justifyContent:'right', border:'1px solid black',
marginRight:'16px', justifyContent:'right',
fontWeight:'bold', marginRight:'16px',
textAlign:'right'}} fontWeight:'bold',
> textAlign:'right'}}
{column.render ? column.render(item[column.dataIndex]) : item[column.dataIndex]} >
</GridItem> {renderSwitchableColumn(column, item)}
</GridItem>
</> </>
}) })

View File

@ -31,6 +31,10 @@ body {
width: 100% width: 100%
} }
.m-0 {
margin: 0;
}
.mt-8px { .mt-8px {
margin-top: 8px; margin-top: 8px;
} }

View File

@ -25,6 +25,10 @@
cursor: pointer; cursor: pointer;
} }
.m-5px-auto {
margin: 5px auto;
}
.mt-12px { .mt-12px {
margin-top: 12px; margin-top: 12px;
} }