diff --git a/src/pages/TelemetryView/SetpointSender.jsx b/src/pages/TelemetryView/SetpointSender.jsx new file mode 100644 index 0000000..6ad3b2e --- /dev/null +++ b/src/pages/TelemetryView/SetpointSender.jsx @@ -0,0 +1,113 @@ +import { useState } from 'react' +import { Select, Modal, Input, InputNumber } from 'antd' +import { SetpointsService } from '../../services/api' +import LoaderPortal from '../../components/LoaderPortal' +import { invokeWebApiWrapperAsync } from '../../components/factory' +import { makeNumericRender, EditableTable, makeNumericInput } from '../../components/Table' +import { PeriodPicker, defaultPeriod } from '../../components/PeriodPicker' +import { Grid, GridItem } from '../../components/Grid' + +export const SetpointSender = ({ idWell, onClose, visible, setpointNames }) => { + const [expirePeriod, setExpirePeriod] = useState(defaultPeriod) + const [comment, setComment] = useState('') + const [setpoints, setSetpoints] = useState([]) + const [isLoading, setIsLoading] = useState(false) + + const addingColumns = [ + { + title: 'Наименование уставки', + dataIndex: 'name', + editable: true, + isRequired: true, + width: 200, + input: , + render: (val) => setpointNames.find((name) => name.value === val)?.label + }, { + title: 'Значение', + dataIndex: 'value', + editable: true, + isRequired: true, + width: 125, + input: `${value}`.replace(',', '.')}/>, + render: makeNumericRender(1), + align: 'right' + } + ] + + const onAdd = async (sp) => setSetpoints((prevSp) => { + sp.key = Date.now() + prevSp.push(sp) + return prevSp + }) + + const onEdit = async (sp) => setSetpoints((prevSp) => { + const idx = prevSp.findIndex((val) => val.key === sp.key) + prevSp[idx] = sp + return prevSp + }) + + const onDelete = async (sp) => setSetpoints((prevSp) => { + const idx = prevSp.findIndex((val) => val.key === sp.key) + prevSp.splice(idx, 1) + return prevSp + }) + + const onModalOk = () => invokeWebApiWrapperAsync( + async () => { + const setpointsObject = setpoints.reduce((obj, sp) => (obj[sp.name] = sp.value, obj), {}) + const request = { + uploadDate: new Date(), + obsolescenceSec: expirePeriod, + setpoints: setpointsObject, + comment: comment + } + await SetpointsService.insert(idWell, request) + onClose(true) + }, + setIsLoading, + `Не удалось отправить уставки по скважине "${idWell}"` + ) + + return ( + + + + Период актуальности рекомендаций: + + + + + Комментарий: + + setComment(e.target.value)} + value={comment} + required + /> + + + + + + + + + ) +} diff --git a/src/pages/TelemetryView/SetpointViewer.jsx b/src/pages/TelemetryView/SetpointViewer.jsx new file mode 100644 index 0000000..feb2240 --- /dev/null +++ b/src/pages/TelemetryView/SetpointViewer.jsx @@ -0,0 +1,77 @@ +import moment from 'moment' +import { memo } from 'react' +import { Modal, Input } from 'antd' +import { Table } from '../../components/Table' +import { UserView } from '../../components/UserView' +import { Grid, GridItem } from '../../components/Grid' +import { periodToString } from '../../utils/datetime' + +export const setpointStatus = { + 0: 'Неизвестно', + 1: 'Ожидает отправки', + 2: 'Отправлено', + 3: 'Принято оператором', + 4: 'Отклонено оператором', + 5: 'Устарело', +} + +export const getSetpointStatus = (id) => { + if (!id || Object.keys(setpointStatus).every((idx) => Number(idx) !== id)) + return setpointStatus[0] + return setpointStatus[id] +} + +const columns = [ + { title: 'Название', dataIndex: 'name' }, + { title: 'Значение', dataIndex: 'value' }, +] + +export const SetpointViewer = memo(({ setpoint, visible, onClose, setpointNames }) => { + let date = moment(setpoint?.uploadDate).format('DD MMM YYYY, HH:mm:ss') + let setpoints = [] + if (setpoint) { + setpoints = Object.keys(setpoint?.setpoints).map((name) => ({ + name: setpointNames.find(spName => spName.value === name)?.label, + value: setpoint.setpoints[name] + })) + } + + return ( + + + Дата рекомендаций: + {date} + + Автор: + + + Статус: + {getSetpointStatus(setpoint?.idState)} + + Период актуальности рекомендаций: + {periodToString(setpoint?.obsolescenceSec)} + + Комментарий: + + + + + + + + + + ) +}) diff --git a/src/pages/TelemetryView/Setpoints.jsx b/src/pages/TelemetryView/Setpoints.jsx index ad2701e..1f6846a 100644 --- a/src/pages/TelemetryView/Setpoints.jsx +++ b/src/pages/TelemetryView/Setpoints.jsx @@ -1,41 +1,25 @@ -import { Button, Input, Modal, Select } from 'antd' -import { useState } from 'react' -import { invokeWebApiWrapperAsync } from '../../components/factory' +import moment from 'moment' +import { Button, Modal } from 'antd' +import { useState, useEffect } from 'react' +import { Table } from '../../components/Table' +import { UserView } from '../../components/UserView' import LoaderPortal from '../../components/LoaderPortal' -import PeriodPicker, { defaultPeriod } from '../../components/PeriodPicker' -import { EditableTable, makeNumericRender } from '../../components/Table' +import { invokeWebApiWrapperAsync } from '../../components/factory' +import { makeStringCutter } from '../../utils/string' import { SetpointsService } from '../../services/api' +import { SetpointSender } from './SetpointSender' +import { SetpointViewer, getSetpointStatus } from './SetpointViewer' export const Setpoints = ({ idWell, ...other }) => { - const [isModalShown, setIsModalShown] = useState(false) + const [isModalVisible, setIsModalVisible] = useState(false) + const [isSenderVisible, setIsSenderVisible] = useState(false) + const [isViewerVisible, setIsViewerVisible] = useState(false) const [isLoading, setIsLoading] = useState(false) - const [isUploading, setIsUploading] = useState(false) - const [setpointNames, setSetpointNames] = useState([]) const [setpoints, setSetpoints] = useState([]) - const [comment, setComment] = useState('') - const [expirePeriod, setExpirePeriod] = useState(defaultPeriod) + const [selected, setSelected] = useState(null) + const [setpointNames, setSetpointNames] = useState([]) - const columns = [ - { - title: 'Наименование установки', - dataIndex: 'name', - editable: true, - isRequired: true, - width: 200, - input: , - render: (val) => setpointNames.find((name) => name.value === val)?.label - }, { - title: 'Значение', - dataIndex: 'value', - editable: true, - isRequired: true, - width: 125, - render: makeNumericRender(7), - align: 'right' - } - ] - - const onOpenClick = () => invokeWebApiWrapperAsync( + useEffect(() => invokeWebApiWrapperAsync( async () => { const names = await SetpointsService.getSetpointsNamesByIdWell(idWell) if (!names) throw Error('Setpoints not found') @@ -44,84 +28,79 @@ export const Setpoints = ({ idWell, ...other }) => { value: spn.name, tooltip: spn.comment }))) - setIsModalShown(true) + }, + setIsLoading, + `Не удалось загрузить список имёт уставок по скважине "${idWell}"` + ), [idWell]) + + const showMore = (id) => { + const selected = setpoints.find((sp) => sp.id === id) + setSelected(selected ?? {}) + setIsViewerVisible(true) + } + + const historyColumns = [ + { title: 'Дата', dataIndex: 'uploadDate', render: item => moment(item).format('DD MMM YYYY, HH:mm:ss') }, + { title: 'Автор', dataIndex: 'author', render: (user) => }, + { title: 'Комментарий', dataIndex: 'comment', render: makeStringCutter() }, + { title: 'Статус', dataIndex: 'idState', render: (id) => getSetpointStatus(parseInt(id)) }, + { dataIndex: 'id', render: (id) => showMore(id)}>Подробнее }, + ] + + const updateTable = () => invokeWebApiWrapperAsync( + async () => { + const setpoints = await SetpointsService.getByIdWell(idWell) + setSetpoints(setpoints) }, setIsLoading, `Не удалось загрузить список для скважины "${idWell}"` ) - const onModalOk = () => invokeWebApiWrapperAsync( - async () => { - // eslint-disable-next-line no-sequences - const setpointsObject = setpoints.reduce((obj, sp) => (obj[sp.name] = sp.value, obj), {}) - const request = { - uploadDate: new Date(), - obsolescenceSec: expirePeriod, - setpoints: setpointsObject, - comment: comment - } - await SetpointsService.insert(idWell, request) - setIsModalShown(false) - }, - setIsUploading, - `Не удалось отправить рекомендации по скважине "${idWell}"` - ) + useEffect(updateTable, [idWell]) - const onAdd = async (setpoint) => setSetpoints((prevSetpoints) => { - setpoint.key = Date.now() - prevSetpoints.push(setpoint) - return prevSetpoints - }) - - const onEdit = async (setpoint) => setSetpoints((prevSetpoints) => { - const idx = prevSetpoints.findIndex((val) => val.key === setpoint.key) - prevSetpoints[idx] = setpoint - return prevSetpoints - }) - - const onDelete = async (setpoint) => setSetpoints((prevSetpoints) => { - const idx = prevSetpoints.findIndex((val) => val.key === setpoint.key) - prevSetpoints.splice(idx, 1) - return prevSetpoints - }) + const onSenderClose = (pushed) => { + if (pushed) updateTable() + setIsSenderVisible(false) + } return ( - - Рекомендовать установки + setIsModalVisible(true)} loading={isLoading}> + Рекомендованные уставки setIsModalShown(false)} - onOk={onModalOk} - okText={'Отправить'} + width={1200} + title={'Рекомендованные уставки'} + visible={isModalVisible} + onCancel={() => setIsModalVisible(false)} + footer={ + setIsSenderVisible(true)}> + Рекомендовать + + } > - - - Период актуальности рекомендаций: - - - + - Комментарий: - setComment(e.value)} - value={comment} - required /> + + setIsViewerVisible(false)} + /> ) }