diff --git a/src/pages/Telemetry/Operations/DrillerSchedule.jsx b/src/pages/Telemetry/Operations/DrillerSchedule.jsx new file mode 100644 index 0000000..c2d1e7a --- /dev/null +++ b/src/pages/Telemetry/Operations/DrillerSchedule.jsx @@ -0,0 +1,190 @@ +import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import { Button, Modal, Typography } from 'antd' + +import { useIdWell } from '@asb/context' +import { + makeTimeColumn, + makeGroupColumn, + makeDateColumn, + makeTextColumn, + EditableTable, + makeActionHandler, +} from '@components/Table' +import { invokeWebApiWrapperAsync } from '@components/factory' +import { DrillerService, ScheduleService } from '@api' +import { usePermissions } from '@utils/permissions' + +const reqRule = [{ message: 'Обязательное поле!', required: true }] + +const drillerColumns = [ + makeTextColumn('Фамилия', 'surname', undefined, undefined, undefined, { editable: true, formItemRules: reqRule }), + makeTextColumn('Имя', 'name', undefined, undefined, undefined, { editable: true, formItemRules: reqRule }), + makeTextColumn('Отчество', 'patronymic', undefined, undefined, undefined, { editable: true }), +] + +const scheduleColumns = [ + makeGroupColumn('Рабочий период', [ + makeDateColumn('Начало', 'drillStart', undefined, undefined, { editable: true, formItemRules: reqRule }), + makeDateColumn('Конец', 'drillEnd', undefined, undefined, { editable: true, formItemRules: reqRule }), + ]), + makeGroupColumn('Смена', [ + makeTimeColumn('Начало', 'shiftStart', undefined, undefined, { editable: true, formItemRules: reqRule }), + makeTimeColumn('Конец', 'shiftEnd', undefined, undefined, { editable: true, formItemRules: reqRule }), + ]), +] + +const drillerRowClassName = (record) => record.has ? 'driller_list_active' : '' + +export const DrillerSchedule = memo(() => { + const [modalVisible, setModalVisible] = useState(false) + const [showLoader, setShowLoader] = useState(false) + const [schedule, setSchedule] = useState([]) + const [drillers, setDrillers] = useState([]) + const [selectedDrillerId, setSelectedDrillerId] = useState(-1) + + const idWell = useIdWell() + + // const permissions = usePermissions( + // 'Driller.edit', + // 'Driller.delete', + // 'Schedule.edit', + // 'Schedule.delete' + // ) + + const permissions = { + driller: { edit: true, delete: true }, + schedule: { edit: true, delete: true }, + } + + const drillerSchedule = useMemo(() => + schedule.filter((v) => v.idDriller === selectedDrillerId) + , [schedule, selectedDrillerId]) + + const updateSchedule = useCallback(async () => invokeWebApiWrapperAsync( + async () => { + const schedule = await ScheduleService.getByIdWell(idWell) + setSchedule(schedule) + } + ), [idWell]) + + const updateList = useCallback(async () => invokeWebApiWrapperAsync( + async () => { + let drillers = await DrillerService.getAll() + drillers = drillers.map((val) => ({ + ...val, + has: schedule.findIndex((elm) => elm.idDriller === val.id) >= 0, + })) + drillers.sort((a, b) => +b.has - a.has) + setDrillers(drillers) + }, + setShowLoader, + 'Не удалось загрузить список бурильщиков', + 'Получение списка бурильщиков' + ), [schedule]) + + const onModalOpen = useCallback(() => { + setModalVisible(true) + }, []) + + const onModalCancel = useCallback(() => { + setModalVisible(false) + }, []) + + const onDrillerSelected = useCallback((selected) => { + setSelectedDrillerId(selected?.[0] ?? -1) + }, []) + + useEffect(() => { + updateSchedule() + }, [updateSchedule]) + + useEffect(() => { + updateList() + }, [updateList]) + + const drillerHandlerProps = useMemo(() => ({ + service: DrillerService, + setLoader: setShowLoader, + errorMsg: `Не удалось выполнить операцию`, + onComplete: updateSchedule, + }), [updateSchedule]) + + const scheduleHandlerProps = useMemo(() => ({ + service: ScheduleService, + setLoader: setShowLoader, + errorMsg: `Не удалось выполнить операцию`, + onComplete: updateSchedule, + }), [updateSchedule]) + + const newScheduleParser = useCallback((record) => ({ + ...record, + idWell, + idDriller: selectedDrillerId + }), [idWell, selectedDrillerId]) + + const actionHandlers = useMemo(() => ({ + driller: { + add: permissions.driller.edit && makeActionHandler('insert', drillerHandlerProps), + edit: permissions.driller.edit && makeActionHandler('update', drillerHandlerProps), + delete: permissions.driller.delete && makeActionHandler('delete', drillerHandlerProps), + }, + schedule: { + add: permissions.schedule.edit && makeActionHandler('insert', scheduleHandlerProps, newScheduleParser), + edit: permissions.schedule.edit && makeActionHandler('update', scheduleHandlerProps), + delete: permissions.schedule.delete && makeActionHandler('delete', scheduleHandlerProps), + }, + }), [permissions, drillerHandlerProps, scheduleHandlerProps, newScheduleParser]) + + return ( + <> + +
+
+ Список бурильщиков + +
+
+ Смены бурильщика + = 0 && actionHandlers.schedule.add} + onRowEdit={actionHandlers.schedule.edit} + onRowDelete={actionHandlers.schedule.delete} + /> +
+
+
+ + + ) +}) + +export default DrillerSchedule diff --git a/src/pages/Telemetry/Operations/index.jsx b/src/pages/Telemetry/Operations/index.jsx index f6f57fc..62699c8 100644 --- a/src/pages/Telemetry/Operations/index.jsx +++ b/src/pages/Telemetry/Operations/index.jsx @@ -1,14 +1,15 @@ -import { memo, useCallback, useContext, useEffect, useState } from 'react' +import { memo, useCallback, useEffect, useState } from 'react' import { InputNumber } from 'antd' import moment from 'moment' -import { IdWellContext } from '@asb/context' +import { useIdWell } from '@asb/context' import LoaderPortal from '@components/LoaderPortal' import { DateRangeWrapper } from '@components/Table' import { invokeWebApiWrapperAsync } from '@components/factory' import { DetectedOperationService, TelemetryDataSaubService } from '@api' import { range } from '@utils' +import DrillerSchedule from './DrillerSchedule' import OperationsChart from './OperationsChart' import OperationsTable from './OperationsTable' @@ -21,7 +22,7 @@ export const Operations = memo(() => { const [dates, setDates] = useState() const [data, setData] = useState([]) - const idWell = useContext(IdWellContext) + const idWell = useIdWell() const disabledDates = useCallback((current) => current && !moment(current).isBetween(...dateRange, 'day', '[]'), [dateRange]) @@ -77,6 +78,7 @@ export const Operations = memo(() => { addonBefore={'Верхняя граница'} style={{ marginRight: '10px' }} /> +
diff --git a/src/styles/detected_operations.less b/src/styles/detected_operations.less index 2ecf598..bcadd38 100644 --- a/src/styles/detected_operations.less +++ b/src/styles/detected_operations.less @@ -4,4 +4,46 @@ margin: 10px; } -} \ No newline at end of file +} + +.drill_schedule { + display: flex; + width: 100%; + height: 75vh; + align-items: stretch; + + & > .list { + flex: 1; + height: 100%; + display: flex; + flex-direction: column; + + & > .ant-list, .ant-table { + flex: 1; + } + + & > .buttons { + display: flex; + + & > * { + flex: 1; + } + } + } + + & > .driller_list { + flex: 2; + width: 10vw; + margin-right: 15px; + + .driller_list_active { + background-color: rgba(0, 255, 0, .25); + } + } + + & > .schedule_list { + width: 10vw; + flex: 3; + margin-left: 15px; + } +}