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 { Button, Timeline } from 'antd'
import { useState, useEffect } from 'react'
import { Button, Form, Timeline } from 'antd'
import moment from 'moment'
import { ExclamationCircleOutlined } from '@ant-design/icons'
import { View } from './View'
import LoaderPortal from '../../components/LoaderPortal'
import '../../styles/index.css'
import '../../styles/measure.css'
@ -13,9 +14,58 @@ export const MeasureTable = ({title, columns, values}) => {
? values[values.length-1]
: []
const [showLoader, setShowLoader] = useState(false);
const [displayedValues, setDisplayedValues] = useState([]);
const [editingColumns, setEditingColumns] = useState(columns);
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(() => {
setDisplayedValues(defaultDisplay)
@ -23,44 +73,26 @@ export const MeasureTable = ({title, columns, values}) => {
useEffect(() => {
let switchableColumns = []
if(isTableEditing) {
switchableColumns = columns.map(col =>
({ render: () => <input className='w-100'></input>,
...col
})
)
} else {
switchableColumns = columns.map(col =>
({ render: null,
...col
})
)
}
isTableEditing && editingActionName !== 'Удалить'
? switchableColumns = createEditingColumns(columns, () => <input className='w-100'></input>)
: switchableColumns = createEditingColumns(columns, null)
setEditingColumns(switchableColumns)
}, [isTableEditing])
const createButtons = (buttonNames, buttonContainerStyle, isEditing) => {
return <div className={buttonContainerStyle}>
{buttonNames.map(name =>
<Button key={name} className='w-100' onClick={()=> setIsTableEditing(isEditing)}>{name}</Button>
)}
</div>
let handleSubmitMeasuresForm = async (formData) => {
// if(isTableEditing)
// measuresForm.setFieldsValue({
// ...displayedValues
// });
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 <>
&nbsp;
<h3>{title}</h3>
@ -85,8 +117,7 @@ export const MeasureTable = ({title, columns, values}) => {
onClick={() => setDisplayedValues(values.find(el => el.id === item.id))}
dot={item.id === displayedValues.id
? <ExclamationCircleOutlined className="timeline-clock-icon" />
: null}
value={moment.utc(item.timestamp).local().format(format)}
: null}
>
{moment.utc(item.timestamp).local().format(format)}
</Timeline.Item>
@ -95,10 +126,17 @@ export const MeasureTable = ({title, columns, values}) => {
</div>
</div>
<div className='w-100'>
<View
item={displayedValues.data}
columns={editingColumns}
/>
<LoaderPortal show={showLoader}>
<Form
form={measuresForm}
onFinish={handleSubmitMeasuresForm}
>
<View
item={displayedValues.data}
columns={editingColumns}
/>
</Form>
</LoaderPortal>
</div>
</div>
</>

View File

@ -1,5 +1,22 @@
import { Empty } from 'antd';
import { Empty, Form } from 'antd';
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}) => {
if (!item || !columns?.length)
@ -11,29 +28,30 @@ export const View = ({columns, item}) => {
const colb = i % colsCount
return <>
<GridItem
row={row}
col={colb*2 + 1}
style={{background:'#00000005',
//width: '300px',
border:'1px solid black'
}}
>
{column.title}
</GridItem>
<GridItem
row={row}
col={colb*2 + 2}
style={{background:'#00000005',
//width: '150px',
border:'1px solid black',
justifyContent:'right',
marginRight:'16px',
fontWeight:'bold',
textAlign:'right'}}
>
{column.render ? column.render(item[column.dataIndex]) : item[column.dataIndex]}
</GridItem>
<GridItem
row={row}
col={colb*2 + 1}
style={{background:'#00000005',
//width: '300px',
border:'1px solid black'
}}
>
{column.title}
</GridItem>
<GridItem
row={row}
col={colb*2 + 2}
style={{background:'#00000005',
//width: '150px',
border:'1px solid black',
justifyContent:'right',
marginRight:'16px',
fontWeight:'bold',
textAlign:'right'}}
>
{renderSwitchableColumn(column, item)}
</GridItem>
</>
})

View File

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

View File

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