asb_cloud_front/src/pages/Measure/MeasureTable.jsx

162 lines
5.9 KiB
React
Raw Normal View History

2021-10-06 13:57:04 +05:00
import { useState, useEffect } from 'react'
import { Button, Form, Input, Popconfirm, Timeline } from 'antd'
import moment from 'moment'
import {
CheckSquareOutlined,
EditOutlined,
SaveOutlined,
PlusOutlined,
CloseCircleOutlined,
DeleteOutlined
} from '@ant-design/icons'
import { View } from './View'
2021-10-06 13:57:04 +05:00
import LoaderPortal from '../../components/LoaderPortal'
import { MeasureService } from '../../services/api'
import '../../styles/index.css'
import '../../styles/measure.css'
import { invokeWebApiWrapperAsync } from '../../components/factory'
const dateFormat = 'YYYY.MM.DD HH:mm'
export const formatDate = (date) => date ? moment.utc(date).local().format(dateFormat) : 'Нет данных'
export const MeasureTable = ({idWell, group, updateMeasuresFunc, additionalButtons}) => {
const [showLoader, setShowLoader] = useState(false)
const [displayedValues, setDisplayedValues] = useState({})
const [editingColumns, setEditingColumns] = useState(group.columns)
const [isTableEditing, setIsTableEditing] = useState(false)
const [editingActionName, setEditingActionName] = useState('')
const [data, setData] = useState([])
const [measuresForm] = Form.useForm()
2021-10-06 13:57:04 +05:00
const createEditingColumns = (cols, renderDelegate) =>
cols.map(col => ({ render: renderDelegate, ...col }))
useEffect(() => {
const data = [group.defaultValue].concat(group.values ?? [])
setData(data)
setDisplayedValues(data.at(-1))
}, [group.defaultValue, group.values])
useEffect(() => {
const switchableColumns = createEditingColumns(
group.columns,
isTableEditing ? () => <Input className={'w-100 measure-input'} /> : null
)
if(editingActionName === 'edit')
measuresForm.setFieldsValue(displayedValues?.data)
else if(editingActionName === 'add')
measuresForm.resetFields()
setEditingColumns(switchableColumns)
}, [isTableEditing, group.columns, editingActionName, displayedValues?.data, measuresForm])
const markMeasuresAsDeleted = async () => await invokeWebApiWrapperAsync(
async () => {
await MeasureService.markAsDelete(idWell, displayedValues.id)
updateMeasuresFunc()
},
setShowLoader,
`Не удалось удалить запись ${displayedValues.id} для скважины "${idWell}"`
)
const isDataDefault = () => !!displayedValues?.isDefaultData
2021-10-06 13:57:04 +05:00
const editTable = (action) => {
setEditingActionName(action)
setIsTableEditing(true)
2021-10-06 13:57:04 +05:00
}
2021-08-28 22:32:13 +05:00
const handleSubmitMeasuresForm = async (formData) => await invokeWebApiWrapperAsync(
async () => {
measuresForm.validateFields()
const measureParams = {
idWell: idWell,
idCategory: group.idCategory,
timestamp: new Date().toISOString(),
data: formData
}
if(editingActionName === 'add') {
await MeasureService.insert(idWell, measureParams)
} else if (editingActionName === 'edit') {
measureParams.id = displayedValues.id
measureParams.timestamp = displayedValues.timestamp
await MeasureService.update(idWell, measureParams)
}
setIsTableEditing(false)
updateMeasuresFunc()
},
setShowLoader,
`Не удалось добавить/изменить запись для скаважины "${idWell}"`
)
return (
<>
&nbsp;<h2>{group.title}</h2>&nbsp;
<div className={'d-flex'}>
<div className={'flex-direction-column'}>
<div className={'measure-buttons-container'}>
<div className={'w-300px mt-8px d-flex'} style={{ alignItems: 'stretch' }}>
{ isTableEditing ? (
<>
<Button key={'confirm'} className={'flex-1'} onClick={() => measuresForm.submit()}>
<SaveOutlined />
</Button>
<Button key={'decline'} className={'flex-1'} onClick={() => setIsTableEditing(false)}>
<CloseCircleOutlined />
</Button>
</>
) : (
<>
<Button key={'add'} className={'flex-1'} onClick={() => editTable('add')}>
<PlusOutlined />
</Button>
<Button key={'edit'} className={'flex-1'} onClick={() => editTable('edit')} disabled={isDataDefault()}>
<EditOutlined />
</Button>
<Popconfirm style={{flex: '1'}} title={'Удалить данные?'} onConfirm={markMeasuresAsDeleted} disabled={isDataDefault()}>
<Button key={'delete'} onClick={() => setEditingActionName('delete')} disabled={isDataDefault()} >
<DeleteOutlined style={{ margin:'auto 28px' }}/>
</Button>
</Popconfirm>
</>
)}
{additionalButtons?.(isTableEditing)}
</div>
</div>
<div className={'measure-dates mt-20px'}>
<Timeline className={'mt-12px ml-10px'}>
{data.map((item, index) =>
<Timeline.Item
key={index}
className={'measure-button'}
onClick={() => setDisplayedValues(item)}
dot={item?.id !== displayedValues?.id ? null :
<CheckSquareOutlined className={'timeline-clock-icon'} />
}
>
<span className={item?.id === displayedValues?.id ? 'selected-timeline' : ''}>
{formatDate(item.timestamp)}
</span>
</Timeline.Item>
)}
</Timeline>
</div>
</div>
<div className={'w-100'}>
<LoaderPortal show={showLoader}>
<Form form={measuresForm} onFinish={handleSubmitMeasuresForm}>
<View item={displayedValues?.data ?? {}} columns={editingColumns} />
</Form>
</LoaderPortal>
</div>
</div>
</>
)
}