forked from ddrilling/asb_cloud_front
164 lines
5.8 KiB
JavaScript
164 lines
5.8 KiB
JavaScript
import { useState, useEffect } from 'react'
|
||
import { Button, Form, Input, Popconfirm, Timeline } from 'antd'
|
||
import {
|
||
CheckSquareOutlined,
|
||
EditOutlined,
|
||
SaveOutlined,
|
||
PlusOutlined,
|
||
CloseCircleOutlined,
|
||
DeleteOutlined
|
||
} from '@ant-design/icons'
|
||
|
||
import LoaderPortal from '../../components/LoaderPortal'
|
||
import { MeasureService } from '../../services/api'
|
||
import { invokeWebApiWrapperAsync } from '../../components/factory'
|
||
|
||
import { View } from './View'
|
||
|
||
import '../../styles/index.css'
|
||
import '../../styles/measure.css'
|
||
import { formatDate } from '../../utils'
|
||
|
||
const createEditingColumns = (cols, renderDelegate) =>
|
||
cols.map(col => ({ render: renderDelegate, ...col }))
|
||
|
||
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()
|
||
|
||
useEffect(() => {
|
||
let data = [group.defaultValue]
|
||
if (group?.values?.length > 0)
|
||
data = 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
|
||
|
||
const editTable = (action) => {
|
||
setEditingActionName(action)
|
||
setIsTableEditing(true)
|
||
}
|
||
|
||
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 (
|
||
<>
|
||
<h2>{group.title}</h2>
|
||
<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 &&
|
||
<CheckSquareOutlined className={'timeline-clock-icon'} />
|
||
}
|
||
>
|
||
<span className={item?.id === displayedValues?.id ? 'selected-timeline' : undefined}>
|
||
{formatDate(item.timestamp, true) ?? 'Нет данных'}
|
||
</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>
|
||
</>
|
||
)
|
||
}
|