From 82183532b810e69494a68a7eb62de98cad94f490 Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Mon, 28 Mar 2022 16:15:43 +0500 Subject: [PATCH 01/49] =?UTF-8?q?=D0=9C=D0=BE=D0=BD=D0=B8=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3,=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=20=D0=B0=D1=80=D1=85=D0=B8?= =?UTF-8?q?=D0=B2=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=B2=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF=D1=83=20=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D0=B5=D0=BC=D0=B5=D1=82=D1=80=D0=B8=D1=8F.=20?= =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD=D0=B0=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=BC=D0=BE=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20Setpoints,?= =?UTF-8?q?=20=D1=82=D0=B0=D0=BA=20=D0=B6=D0=B5=20=D0=BE=D0=BD=D0=B8=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D1=8B=20=D0=B2=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=89=D1=83=D1=8E=20=D0=B4=D0=B8=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B8=D1=8E=20=D0=B2=20TelemetryView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Telemetry/Archive/ArchiveColumn.jsx | 31 +++ .../Telemetry/Archive/ArchiveDisplay.jsx | 66 +++++++ src/pages/Telemetry/Archive/index.jsx | 185 ++++++++++++++++++ src/pages/{ => Telemetry}/Messages.jsx | 0 .../TelemetryView/ActiveMessagesOnline.jsx | 2 +- .../TelemetryView/ChartTimeOnlineFooter.jsx | 0 .../TelemetryView/CustomColumn.jsx | 0 .../TelemetryView/ModeDisplay.jsx | 0 .../TelemetryView/MonitoringColumn.jsx | 0 .../TelemetryView/RigMnemo.jsx | 0 .../Setpoints}/SetpointSender.jsx | 30 +-- .../Setpoints}/SetpointViewer.jsx | 2 + .../TelemetryView/Setpoints/index.jsx} | 40 ++-- .../TelemetryView/UserOfWells.jsx | 0 .../{ => Telemetry}/TelemetryView/index.jsx | 0 src/pages/Telemetry/index.jsx | 52 +++++ src/pages/Well.jsx | 22 +-- src/utils/permissions.ts | 8 +- 18 files changed, 383 insertions(+), 55 deletions(-) create mode 100644 src/pages/Telemetry/Archive/ArchiveColumn.jsx create mode 100644 src/pages/Telemetry/Archive/ArchiveDisplay.jsx create mode 100644 src/pages/Telemetry/Archive/index.jsx rename src/pages/{ => Telemetry}/Messages.jsx (100%) rename src/pages/{ => Telemetry}/TelemetryView/ActiveMessagesOnline.jsx (97%) rename src/pages/{ => Telemetry}/TelemetryView/ChartTimeOnlineFooter.jsx (100%) rename src/pages/{ => Telemetry}/TelemetryView/CustomColumn.jsx (100%) rename src/pages/{ => Telemetry}/TelemetryView/ModeDisplay.jsx (100%) rename src/pages/{ => Telemetry}/TelemetryView/MonitoringColumn.jsx (100%) rename src/pages/{ => Telemetry}/TelemetryView/RigMnemo.jsx (100%) rename src/pages/{TelemetryView => Telemetry/TelemetryView/Setpoints}/SetpointSender.jsx (85%) rename src/pages/{TelemetryView => Telemetry/TelemetryView/Setpoints}/SetpointViewer.jsx (98%) rename src/pages/{TelemetryView/Setpoints.jsx => Telemetry/TelemetryView/Setpoints/index.jsx} (84%) rename src/pages/{ => Telemetry}/TelemetryView/UserOfWells.jsx (100%) rename src/pages/{ => Telemetry}/TelemetryView/index.jsx (100%) create mode 100644 src/pages/Telemetry/index.jsx diff --git a/src/pages/Telemetry/Archive/ArchiveColumn.jsx b/src/pages/Telemetry/Archive/ArchiveColumn.jsx new file mode 100644 index 0000000..6f7ebfb --- /dev/null +++ b/src/pages/Telemetry/Archive/ArchiveColumn.jsx @@ -0,0 +1,31 @@ +import { memo, useMemo } from 'react' + +import { Grid, GridItem } from '@components/Grid' +import { Column } from '@components/charts/Column' + +export const ArchiveColumn = memo(({ lineGroup, data, interval, style, headerHeight, yStart }) => { + const lgws = useMemo(() => lineGroup.filter(cfg => !cfg.isShape), [lineGroup]) + const pv = useMemo(() => lgws.filter(line => line.showLabels).map(line => ({ + color: line.color, + label: line.label + })), [lgws]) + + return ( +
+ + {pv?.map((v, idx) => ( + {v.label} + ))} + + +
+ ) +}) + +export default ArchiveColumn diff --git a/src/pages/Telemetry/Archive/ArchiveDisplay.jsx b/src/pages/Telemetry/Archive/ArchiveDisplay.jsx new file mode 100644 index 0000000..c3310ba --- /dev/null +++ b/src/pages/Telemetry/Archive/ArchiveDisplay.jsx @@ -0,0 +1,66 @@ +import { memo, useMemo } from 'react' + +import { Grid, GridItem } from '@components/Grid' + +import { paramsGroups } from '../TelemetryView' +import { ArchiveColumn } from './ArchiveColumn' + +const interpolationSearch = (data, begin, end, accessor) => { + const fy = (i) => new Date(data[i]?.[accessor] ?? 0) + const fx = (y, b, e) => Math.round(b + (y - fy(b)) * (e - b) / (fy(e) - fy(b))) + const findIdx = (val, startIdx, c) => { + let x = startIdx + let endIdx = data.length - 1 + if(val < fy(startIdx)) + return startIdx + if(val > fy(endIdx)) + return endIdx + for(let i = 0; i < c; i++){ + x = fx(val, startIdx, endIdx) + if(fy(x) < val) + startIdx = x + else + endIdx = x + if ((startIdx === endIdx)||(fy(startIdx) === fy(endIdx))) + return x + } + return x + } + let x0 = findIdx(begin, 0, 5) + let x1 = findIdx(end, x0, 3) + return { start: x0, end: x1, count: x1 - x0 } +} + +export const cutData = (data, beginDate, endDate) => { + if (data?.length > 0) { + let { start, end } = interpolationSearch(data, beginDate, endDate, 'date') + if (start > 0) start-- + if (end + 1 < end.length) end++ + return data.slice(start, end) + } + return data +} + +export const ArchiveDisplay = memo(({data, startDate, interval, onWheel}) => { + const endDate = useMemo(() => new Date(+startDate + interval), [startDate, interval]) + const chartData = useMemo(() => cutData(data, startDate, endDate), [data, startDate, endDate]) + + return ( + + {paramsGroups.map((group, index) => ( + + + + ))} + + ) +}) + +export default ArchiveDisplay diff --git a/src/pages/Telemetry/Archive/index.jsx b/src/pages/Telemetry/Archive/index.jsx new file mode 100644 index 0000000..4c37e9f --- /dev/null +++ b/src/pages/Telemetry/Archive/index.jsx @@ -0,0 +1,185 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +import { useState, useEffect, memo, useCallback } from 'react' + +import { Flex } from '@components/Grid' +import LoaderPortal from '@components/LoaderPortal' +import { invokeWebApiWrapperAsync } from '@components/factory' +import { DatePickerWrapper, makeDateSorter } from '@components/Table' +import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker' +import { TelemetryDataSaubService } from '@api' + +import { normalizeData } from '../TelemetryView' +import { ArchiveDisplay, cutData } from './ArchiveDisplay' + +const DATA_COUNT = 2048 // Колличество точек на подгрузку графика +const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков +const LOADING_TRIGGER = 0.5 +const WHEEL_SENSITIVITY = 1 / 530 + +const getLoadingInterval = (loaded, startDate, interval) => { + // Если данные загружены и дата не заходит за тригер дозагрузка не требуется + if ( + loaded && + +startDate - interval * LOADING_TRIGGER > loaded.start && + +startDate + interval * (LOADING_TRIGGER + 1) < loaded.end + ) + return { loadingStartDate: startDate, newLoaded: loaded, loadingInterval: 0 } + + let loadingStartDate = +startDate - interval * ADDITIVE_PAGES + let loadingEndDate = +startDate + interval * (ADDITIVE_PAGES + 1) + + const newLoaded = { + start: loadingStartDate, + end: loadingEndDate + } + + if (loaded) { + if (loadingStartDate >= loaded.start) + loadingStartDate = loaded.end + if (loadingEndDate <= loaded.end) + loadingEndDate = loaded.start + newLoaded.start = Math.min(loaded.start, loadingStartDate) + newLoaded.end = Math.max(loaded.end, loadingEndDate) + } + + const loadingInterval = Math.trunc((loadingEndDate - loadingStartDate) / 1000) + + return { + loadingStartDate: new Date(loadingStartDate), + newLoaded: { + start: new Date(newLoaded.start), + end: new Date(newLoaded.end) + }, + loadingInterval + } +} + +const range = (start, end) => { + const result = [] + for (let i = start; i < end; i++) + result.push(i) + return result +} + +export const Archive = memo(({ idWell }) => { + const [dataSaub, setDataSaub] = useState([]) + const [dateLimit, setDateLimit] = useState({ from: 0, to: new Date() }) + const [chartInterval, setChartInterval] = useState(parseInt(defaultPeriod) * 1000) + const [startDate, setStartDate] = useState(new Date(Date.now() - chartInterval)) + const [showLoader, setShowLoader] = useState(false) + const [loaded, setLoaded] = useState(null) + + const onGraphWheel = useCallback((e) => { + if (loaded && dateLimit.from && dateLimit.to) { + setStartDate((prevStartDate) => { + const offset = e.deltaY * chartInterval * WHEEL_SENSITIVITY + const nextStartDate = +prevStartDate + offset + const firstPossibleDate = Math.max(loaded.start, dateLimit.from) + const lastPossibleDate = Math.min(dateLimit.to, (loaded.end ?? Date.now())) - chartInterval + return new Date(Math.max(firstPossibleDate, Math.min(nextStartDate, lastPossibleDate))) + }) + } + }, [loaded, dateLimit, chartInterval]) + + const isDateDisabled = useCallback((date) => { + if (!date) return false + const dt = new Date(date).setHours(0, 0, 0, 0) + return dt < dateLimit.from || dt > +dateLimit.to - chartInterval + }, [dateLimit]) + + const isDateTimeDisabled = useCallback((date) => ({ + disabledHours: () => range(0, 24).filter(h => { + if (!date) return false + const dt = +new Date(date).setHours(h) + return dt < dateLimit.from || dt > +dateLimit.to - chartInterval + }), + disabledMinutes: () => range(0, 60).filter(m => { + if (!date) return false + const dt = +new Date(date).setMinutes(m) + return dt < dateLimit.from || dt > +dateLimit.to - chartInterval + }), + disabledSeconds: () => range(0, 60).filter(s => { + if (!date) return false + const dt = +new Date(date).setSeconds(s) + return dt < dateLimit.from || dt > +dateLimit.to - chartInterval + }) + }), [dateLimit]) + + useEffect(() => invokeWebApiWrapperAsync( + async () => { + let dates = await TelemetryDataSaubService.getDataDatesRange(idWell) + dates = { + from: new Date(dates?.from ?? 0), + to: new Date(dates?.to ?? 0) + } + setDateLimit(dates) + setStartDate(new Date(Math.max(dates.from, +dates.to - chartInterval))) + }, + setShowLoader, + `Не удалось загрузить диапозон телеметрии для скважины "${idWell}"`, + 'Загрузка диапозона телеметрии' + ), []) + + useEffect(() => { + setStartDate((startDate) => new Date(Math.min(Date.now() - chartInterval, startDate))) + setDataSaub([]) + }, [chartInterval]) + + useEffect(() => { + if (showLoader) return + const { loadingStartDate, loadingInterval, newLoaded } = getLoadingInterval(loaded, startDate, chartInterval) + if (loadingInterval <= 0) return + invokeWebApiWrapperAsync( + async () => { + const data = await TelemetryDataSaubService.getData(idWell, loadingStartDate.toISOString(), loadingInterval, DATA_COUNT) + + const loadedStartDate = new Date(Math.max(+newLoaded.start, +startDate - chartInterval * ADDITIVE_PAGES)) + const loadedEndDate = new Date(Math.min(+newLoaded.end, +startDate + chartInterval * (ADDITIVE_PAGES + 1))) + setLoaded({ start: loadedStartDate, end: loadedEndDate }) + + if (data) { + data.forEach(elm => elm.date = new Date(elm.date)) + setDataSaub((prevDataSaub) => { + const newData = [...prevDataSaub, ...normalizeData(data)] + newData.sort(makeDateSorter('date')) + return cutData(newData, loadedStartDate, loadedEndDate) + }) + } + + }, + setShowLoader, + `Не удалось загрузить данные по скважине "${idWell}" c ${startDate.toISOString()} по ${new Date(+startDate + chartInterval).toISOString()}`, + 'Загрузка телеметрий в диапозоне' + ) + }, [idWell, chartInterval, loaded, startDate]) + + return ( + <> + +
+ Начальная дата:  + setStartDate(new Date(startDate))} + /> +
+
+ Период:  + setChartInterval(val * 1000)} /> +
+
+ + + + + ) +}) + +export default Archive diff --git a/src/pages/Messages.jsx b/src/pages/Telemetry/Messages.jsx similarity index 100% rename from src/pages/Messages.jsx rename to src/pages/Telemetry/Messages.jsx diff --git a/src/pages/TelemetryView/ActiveMessagesOnline.jsx b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx similarity index 97% rename from src/pages/TelemetryView/ActiveMessagesOnline.jsx rename to src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx index ec888ea..db5c547 100644 --- a/src/pages/TelemetryView/ActiveMessagesOnline.jsx +++ b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx @@ -6,7 +6,7 @@ import { invokeWebApiWrapperAsync } from '@components/factory' import { Subscribe } from '@services/signalr' import { MessageService } from '@api' -import { columns } from '@pages/Messages' +import { columns } from '../Messages' import '@styles/message.css' diff --git a/src/pages/TelemetryView/ChartTimeOnlineFooter.jsx b/src/pages/Telemetry/TelemetryView/ChartTimeOnlineFooter.jsx similarity index 100% rename from src/pages/TelemetryView/ChartTimeOnlineFooter.jsx rename to src/pages/Telemetry/TelemetryView/ChartTimeOnlineFooter.jsx diff --git a/src/pages/TelemetryView/CustomColumn.jsx b/src/pages/Telemetry/TelemetryView/CustomColumn.jsx similarity index 100% rename from src/pages/TelemetryView/CustomColumn.jsx rename to src/pages/Telemetry/TelemetryView/CustomColumn.jsx diff --git a/src/pages/TelemetryView/ModeDisplay.jsx b/src/pages/Telemetry/TelemetryView/ModeDisplay.jsx similarity index 100% rename from src/pages/TelemetryView/ModeDisplay.jsx rename to src/pages/Telemetry/TelemetryView/ModeDisplay.jsx diff --git a/src/pages/TelemetryView/MonitoringColumn.jsx b/src/pages/Telemetry/TelemetryView/MonitoringColumn.jsx similarity index 100% rename from src/pages/TelemetryView/MonitoringColumn.jsx rename to src/pages/Telemetry/TelemetryView/MonitoringColumn.jsx diff --git a/src/pages/TelemetryView/RigMnemo.jsx b/src/pages/Telemetry/TelemetryView/RigMnemo.jsx similarity index 100% rename from src/pages/TelemetryView/RigMnemo.jsx rename to src/pages/Telemetry/TelemetryView/RigMnemo.jsx diff --git a/src/pages/TelemetryView/SetpointSender.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx similarity index 85% rename from src/pages/TelemetryView/SetpointSender.jsx rename to src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx index 27bceae..0073b9d 100644 --- a/src/pages/TelemetryView/SetpointSender.jsx +++ b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { memo, useCallback, useMemo, useState } from 'react' import { Select, Modal, Input, InputNumber } from 'antd' import { SetpointsService } from '@api' @@ -8,13 +8,13 @@ import { invokeWebApiWrapperAsync } from '@components/factory' import { makeNumericRender, EditableTable } from '@components/Table' import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker' -export const SetpointSender = ({ idWell, onClose, visible, setpointNames }) => { +export const SetpointSender = memo(({ idWell, onClose, visible, setpointNames }) => { const [expirePeriod, setExpirePeriod] = useState(defaultPeriod) const [comment, setComment] = useState('') const [setpoints, setSetpoints] = useState([]) const [isLoading, setIsLoading] = useState(false) - const addingColumns = [ + const addingColumns = useMemo(() => [ { title: 'Наименование уставки', dataIndex: 'name', @@ -33,27 +33,27 @@ export const SetpointSender = ({ idWell, onClose, visible, setpointNames }) => { render: makeNumericRender(1), align: 'right' } - ] + ], [setpointNames]) - const onAdd = async (sp) => setSetpoints((prevSp) => { + const onAdd = useCallback(async (sp) => setSetpoints((prevSp) => { sp.key = Date.now() prevSp.push(sp) return prevSp - }) + }), []) - const onEdit = async (sp) => setSetpoints((prevSp) => { + const onEdit = useCallback(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 onDelete = useCallback(async (sp) => setSetpoints((prevSp) => { const idx = prevSp.findIndex((val) => val.key === sp.key) prevSp.splice(idx, 1) return prevSp - }) + }), []) - const onModalOk = () => invokeWebApiWrapperAsync( + const onModalOk = useCallback(() => invokeWebApiWrapperAsync( async () => { const setpointsObject = setpoints.reduce((obj, sp) => { obj[sp.name] = sp.value @@ -66,12 +66,12 @@ export const SetpointSender = ({ idWell, onClose, visible, setpointNames }) => { comment: comment } await SetpointsService.insert(idWell, request) - onClose(true) + await onClose(true) }, setIsLoading, `Не удалось отправить уставки по скважине "${idWell}"`, `Рекомендация новыой уставки` - ) + ), [idWell, setpoints, comment, expirePeriod, onClose]) return ( { ) -} +}) + +export default SetpointSender diff --git a/src/pages/TelemetryView/SetpointViewer.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointViewer.jsx similarity index 98% rename from src/pages/TelemetryView/SetpointViewer.jsx rename to src/pages/Telemetry/TelemetryView/Setpoints/SetpointViewer.jsx index 7a0fa75..d22ccf2 100644 --- a/src/pages/TelemetryView/SetpointViewer.jsx +++ b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointViewer.jsx @@ -72,3 +72,5 @@ export const SetpointViewer = memo(({ setpoint, visible, onClose, setpointNames ) }) + +export default SetpointViewer diff --git a/src/pages/TelemetryView/Setpoints.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx similarity index 84% rename from src/pages/TelemetryView/Setpoints.jsx rename to src/pages/Telemetry/TelemetryView/Setpoints/index.jsx index a74f9e5..2339ea2 100644 --- a/src/pages/TelemetryView/Setpoints.jsx +++ b/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx @@ -1,19 +1,19 @@ -import moment from 'moment' import { Button, Modal } from 'antd' -import { useState, useEffect } from 'react' +import { useState, useEffect, memo, useCallback, useMemo } from 'react' import { Table } from '@components/Table' import { UserView } from '@components/views' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' +import { hasPermission } from '@utils/permissions' import { makeStringCutter } from '@utils/string' +import { formatDate } from '@utils' import { SetpointsService } from '@api' -import { SetpointSender } from './SetpointSender' +import SetpointSender from './SetpointSender' import { SetpointViewer, getSetpointStatus } from './SetpointViewer' -import { hasPermission } from '@asb/utils/permissions' -export const Setpoints = ({ idWell, ...other }) => { +export const Setpoints = memo(({ idWell, ...other }) => { const [isModalVisible, setIsModalVisible] = useState(false) const [isSenderVisible, setIsSenderVisible] = useState(false) const [isViewerVisible, setIsViewerVisible] = useState(false) @@ -37,21 +37,21 @@ export const Setpoints = ({ idWell, ...other }) => { 'Получение списка имён уставок' ), [idWell]) - const showMore = (id) => { + const showMore = useCallback((id) => { const selected = setpoints.find((sp) => sp.id === id) setSelected(selected ?? {}) setIsViewerVisible(true) - } + }, [setpoints]) - const historyColumns = [ - { title: 'Дата', dataIndex: 'uploadDate', render: item => moment(item).format('DD MMM YYYY, HH:mm:ss') }, + const historyColumns = useMemo(() => [ + { title: 'Дата', dataIndex: 'uploadDate', render: item => formatDate(item) }, { title: 'Автор', dataIndex: 'author', render: (user) => }, { title: 'Комментарий', dataIndex: 'comment', render: makeStringCutter() }, { title: 'Статус', dataIndex: 'idState', render: (id) => getSetpointStatus(parseInt(id)) }, { dataIndex: 'id', render: (id) => }, - ] + ], [showMore]) - const updateTable = async () => await invokeWebApiWrapperAsync( + const updateTable = useCallback(async () => await invokeWebApiWrapperAsync( async () => { const setpoints = await SetpointsService.getByIdWell(idWell) setSetpoints(setpoints) @@ -59,19 +59,19 @@ export const Setpoints = ({ idWell, ...other }) => { setIsLoading, `Не удалось загрузить список для скважины "${idWell}"`, 'Получение списка скважин' - ) + ), [idWell]) - const onOpenClick = async () => { + const onOpenClick = useCallback(async () => { await updateTable() setIsModalVisible(true) - } + }, [updateTable]) - const onSenderClose = (pushed) => { - if (pushed) updateTable() + const onSenderClose = useCallback(async (pushed) => { + if (pushed) await updateTable() setIsSenderVisible(false) - } + }, [updateTable]) - return hasPermission('Setpoints.get') && ( + return !hasPermission('Setpoints.get') ? null : (
) -} +}) + +export default Setpoints diff --git a/src/pages/TelemetryView/UserOfWells.jsx b/src/pages/Telemetry/TelemetryView/UserOfWells.jsx similarity index 100% rename from src/pages/TelemetryView/UserOfWells.jsx rename to src/pages/Telemetry/TelemetryView/UserOfWells.jsx diff --git a/src/pages/TelemetryView/index.jsx b/src/pages/Telemetry/TelemetryView/index.jsx similarity index 100% rename from src/pages/TelemetryView/index.jsx rename to src/pages/Telemetry/TelemetryView/index.jsx diff --git a/src/pages/Telemetry/index.jsx b/src/pages/Telemetry/index.jsx new file mode 100644 index 0000000..551cbfb --- /dev/null +++ b/src/pages/Telemetry/index.jsx @@ -0,0 +1,52 @@ +import { Switch, useParams } from 'react-router-dom' +import { memo, useMemo } from 'react' +import { Layout, Menu } from 'antd' +import { AlertOutlined, FundViewOutlined, DatabaseOutlined } from '@ant-design/icons' + +import { PrivateRoute, PrivateDefaultRoute, PrivateMenuItem } from '@components/Private' + +import Archive from './Archive' +import Messages from './Messages' +import TelemetryView from './TelemetryView' + +import '@styles/index.css' + +const { Content } = Layout + +export const Telemetry = memo(({ idWell }) => { + const { tab } = useParams() + const rootPath = useMemo(() => `/well/${idWell}/telemetry`, [idWell]) + + return ( + + + } title={'Мониторинг'}/> + } title={'Сообщения'} /> + } title={'Архив'} /> + + + + + + + + + + + + + + + + + + + + ) +}) + +export default Telemetry diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index 5df9768..8c4aab8 100644 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -2,9 +2,7 @@ import { memo, useMemo } from 'react' import { FolderOutlined, FundViewOutlined, - AlertOutlined, FilePdfOutlined, - DatabaseOutlined, ExperimentOutlined, DeploymentUnitOutlined, } from '@ant-design/icons' @@ -14,12 +12,10 @@ import { Switch, useParams } from 'react-router-dom' import { PrivateRoute, PrivateDefaultRoute, PrivateMenuItem } from '@components/Private' import Report from './Report' -import Archive from './Archive' import Measure from './Measure' -import Messages from './Messages' import Analytics from './Analytics' import Documents from './Documents' -import TelemetryView from './TelemetryView' +import Telemetry from './Telemetry' import WellOperations from './WellOperations' import DrillingProgram from './DrillingProgram' import TelemetryAnalysis from './TelemetryAnalysis' @@ -35,12 +31,10 @@ export const Well = memo(() => { return ( - } title={'Мониторинг'}/> - } title={'Сообщения'} /> + } title={'Телеметрия'}/> } title={'Рапорт'} /> } title={'Аналитика'} /> } title={'Операции по скважине'} /> - } title={'Архив'} /> {/* } title={'Операции по телеметрии'} /> */} } title={'Документы'} /> } title={'Измерения'} /> @@ -50,11 +44,8 @@ export const Well = memo(() => { - - - - - + + @@ -65,9 +56,6 @@ export const Well = memo(() => { - - - @@ -82,11 +70,9 @@ export const Well = memo(() => { Date: Mon, 28 Mar 2022 17:36:58 +0500 Subject: [PATCH 02/49] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=B0=20=D0=BA=20=D1=84=D0=B0?= =?UTF-8?q?=D0=B9=D0=BB=D0=B0=D0=BC=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BF=D0=BE=D0=B4=20NTFS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 0 .vscode/launch.json | 0 .vscode/settings.json | 0 README.md | 0 TODO.md | 0 concept/ImagesSrc/logo_32_Asb.png | Bin concept/ImagesSrc/logo_32_naftagaz.png | Bin concept/ImagesSrc/logo_Asb.svg | 0 concept/SludgeDiagram.jsx | 0 concept/Smbo/EquipmentDetails.jsx | 0 concept/Smbo/SmboPlate.jsx | 0 concept/Smbo/images/RigPlan2.png | Bin concept/Smbo/images/TopDrive_Dummy.png | Bin concept/Smbo/index.jsx | 0 concept/TelemetryAnalysis.jsx | 0 concept/WellStat.jsx | 0 concept/WellTelemetryAnalysis.jsx | 0 concept/readme.md | 0 craco.config.js | 0 doc/MSE_and_torqueStab_info.txt | 0 package-lock.json | 0 package.json | 0 public/favicon.ico | Bin public/images/logo_32.png | Bin public/index.html | 0 public/manifest.json | 0 public/robots.txt | 0 src/App.js | 0 src/components/AnalysisOperationTime.jsx | 0 src/components/ChangePassword.tsx | 0 src/components/Display.jsx | 0 src/components/DownloadLink.tsx | 0 src/components/ErrorFetch.js | 0 src/components/Grid.tsx | 0 src/components/Layout/AdminLayoutPortal.tsx | 0 src/components/Layout/LayoutPortal.tsx | 0 src/components/Layout/index.ts | 0 src/components/LoaderPortal.tsx | 0 src/components/PageHeader.tsx | 0 src/components/Private/PrivateContent.tsx | 0 src/components/Private/PrivateDefaultRoute.tsx | 0 src/components/Private/PrivateMenuItem.tsx | 0 src/components/Private/PrivateRoute.tsx | 0 src/components/Private/index.ts | 0 src/components/Table/Columns/date.tsx | 0 src/components/Table/Columns/index.ts | 0 src/components/Table/Columns/numeric.tsx | 0 src/components/Table/Columns/plan_fact.tsx | 0 src/components/Table/Columns/select.tsx | 0 src/components/Table/Columns/tag.tsx | 0 src/components/Table/Columns/text.tsx | 0 src/components/Table/Columns/timezone.tsx | 0 src/components/Table/DatePickerWrapper.tsx | 0 src/components/Table/DateRangeWrapper.tsx | 0 src/components/Table/EditableCell.tsx | 0 src/components/Table/EditableTable.jsx | 0 src/components/Table/Table.tsx | 0 src/components/Table/TableSettingsChanger.tsx | 0 src/components/Table/index.tsx | 0 src/components/Table/sorters.ts | 0 src/components/UploadForm.jsx | 0 src/components/UserMenu.tsx | 0 src/components/charts/ChartOperationTime.jsx | 0 src/components/charts/ChartOperationTimeBase.tsx | 0 src/components/charts/ChartTelemetryDepthToDay.jsx | 0 .../charts/ChartTelemetryDepthToInterval.jsx | 0 .../charts/ChartTelemetryOperationsSummary.jsx | 0 src/components/charts/ChartTimeBase.tsx | 0 src/components/charts/Column.tsx | 0 src/components/factory.ts | 0 src/components/icons/Loader.tsx | 0 src/components/icons/PointerIcon.tsx | 0 src/components/icons/WellIcon.tsx | 0 src/components/icons/index.ts | 0 src/components/selectors/PeriodPicker.tsx | 0 src/components/selectors/Poprompt.tsx | 0 src/components/selectors/TelemetrySelect.tsx | 0 src/components/selectors/WellSelector.jsx | 0 src/components/selectors/WellTreeSelector.tsx | 0 src/components/views/CompanyView.tsx | 0 src/components/views/PermissionView.tsx | 0 src/components/views/RoleView.tsx | 0 src/components/views/TelemetryView.tsx | 0 src/components/views/UserView.tsx | 0 src/components/views/index.ts | 0 src/context/Context.js | 0 src/images/ClusterIcon.svg | 0 src/images/DempherOff.png | Bin src/images/DempherOn.png | Bin src/images/DepositIcon.svg | 0 src/images/Logo.tsx | 0 src/images/SpinDisabled.png | Bin src/images/SpinEnabled.png | Bin src/images/las.png | Bin src/index.js | 0 src/pages/AccessDenied.jsx | 0 src/pages/AdminPanel/ClusterController.jsx | 0 src/pages/AdminPanel/CompanyController.jsx | 0 src/pages/AdminPanel/CompanyTypeController.jsx | 0 src/pages/AdminPanel/DepositController.jsx | 0 src/pages/AdminPanel/PermissionController.jsx | 0 src/pages/AdminPanel/RoleController.jsx | 0 src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx | 0 src/pages/AdminPanel/Telemetry/TelemetryViewer.jsx | 0 src/pages/AdminPanel/Telemetry/index.jsx | 0 src/pages/AdminPanel/UserController/RoleTag.jsx | 0 src/pages/AdminPanel/UserController/index.jsx | 0 src/pages/AdminPanel/VisitLog.jsx | 0 src/pages/AdminPanel/WellController/index.jsx | 0 src/pages/AdminPanel/index.jsx | 0 src/pages/Analytics/Statistics.jsx | 0 .../WellCompositeEditor/WellCompositeSections.jsx | 0 src/pages/Analytics/WellCompositeEditor/index.jsx | 0 src/pages/Analytics/index.jsx | 0 src/pages/Archive/ArchiveColumn.jsx | 0 src/pages/Archive/ArchiveDisplay.jsx | 0 src/pages/Archive/index.jsx | 0 src/pages/Cluster/ClusterWells.jsx | 0 src/pages/Cluster/WellOperationsTable.jsx | 0 src/pages/Cluster/index.jsx | 0 src/pages/Deposit.jsx | 0 src/pages/Documents/DocumentsTemplate.jsx | 0 src/pages/Documents/index.jsx | 0 src/pages/DrillingProgram/CategoryAdder.jsx | 0 src/pages/DrillingProgram/CategoryEditor.jsx | 0 src/pages/DrillingProgram/CategoryHistory.jsx | 0 src/pages/DrillingProgram/CategoryRender.jsx | 0 src/pages/DrillingProgram/MarksCard.jsx | 0 src/pages/DrillingProgram/index.jsx | 0 src/pages/Login.jsx | 0 src/pages/Main.jsx | 0 src/pages/Measure/InclinometryTable.jsx | 0 src/pages/Measure/MeasureTable.jsx | 0 src/pages/Measure/View.jsx | 0 src/pages/Measure/columnsCommon.js | 0 src/pages/Measure/drillingFluidData.js | 0 src/pages/Measure/index.jsx | 0 src/pages/Measure/mudDiagramData.js | 0 src/pages/Measure/nnbData.js | 0 src/pages/Register.jsx | 0 src/pages/Report/ReportCreationNotify.jsx | 0 src/pages/Report/Reports.jsx | 0 src/pages/Report/index.jsx | 0 src/pages/SuspenseFallback.tsx | 0 src/pages/Telemetry/Archive/ArchiveColumn.jsx | 0 src/pages/Telemetry/Archive/ArchiveDisplay.jsx | 0 src/pages/Telemetry/Archive/index.jsx | 0 src/pages/Telemetry/Messages.jsx | 0 .../TelemetryView/ActiveMessagesOnline.jsx | 0 .../TelemetryView/ChartTimeOnlineFooter.jsx | 0 src/pages/Telemetry/TelemetryView/CustomColumn.jsx | 0 src/pages/Telemetry/TelemetryView/ModeDisplay.jsx | 0 .../Telemetry/TelemetryView/MonitoringColumn.jsx | 0 src/pages/Telemetry/TelemetryView/RigMnemo.jsx | 0 .../TelemetryView/Setpoints/SetpointSender.jsx | 0 .../TelemetryView/Setpoints/SetpointViewer.jsx | 0 .../Telemetry/TelemetryView/Setpoints/index.jsx | 0 src/pages/Telemetry/TelemetryView/UserOfWells.jsx | 0 src/pages/Telemetry/TelemetryView/index.jsx | 0 src/pages/Telemetry/index.jsx | 0 .../TelemetryAnalysisDepthToDay.jsx | 0 .../TelemetryAnalysisDepthToInterval.jsx | 0 .../TelemetryAnalysisOperationsSummary.jsx | 0 .../TelemetryAnalysisOperationsToInterval.jsx | 0 src/pages/TelemetryAnalysis/index.jsx | 0 src/pages/Well.jsx | 0 src/pages/WellOperations/DrillProcessFlow.jsx | 0 src/pages/WellOperations/ImportExportBar.jsx | 0 src/pages/WellOperations/ImportOperations.jsx | 0 src/pages/WellOperations/Tvd/AdditionalTables.jsx | 0 src/pages/WellOperations/Tvd/NetGraphExport.jsx | 0 src/pages/WellOperations/Tvd/NptTable.jsx | 0 src/pages/WellOperations/Tvd/index.jsx | 0 src/pages/WellOperations/WellDrillParams.jsx | 0 src/pages/WellOperations/WellOperationsEditor.jsx | 0 src/pages/WellOperations/WellSectionsStat.jsx | 0 src/pages/WellOperations/index.jsx | 0 src/react-app-env.d.ts | 0 src/reportWebVitals.js | 0 src/services/AutoGenerateApi.md | 0 src/services/UidGenerator.ts | 0 src/services/signalr/index.ts | 0 src/styles/App.less | 0 src/styles/charts.less | 0 src/styles/components/telemetry_select.less | 0 src/styles/display.css | 0 src/styles/drilling_program.less | 0 src/styles/equipment_details.css | 0 src/styles/index.css | 0 src/styles/loader.css | 0 src/styles/measure.css | 0 src/styles/message.css | 0 src/styles/message_telemetry.css | 0 src/styles/smbo.css | 0 src/styles/statistics.less | 0 src/styles/tvd.less | 0 src/styles/wellTreeSelect.css | 0 src/utils/datetime.ts | 0 src/utils/functions.tsx | 0 src/utils/index.ts | 0 src/utils/permissions.ts | 0 src/utils/storage.ts | 0 src/utils/string.ts | 0 src/utils/table.ts | 0 src/utils/table_settings.ts | 0 src/utils/validationRules.ts | 0 tsconfig.json | 0 tsconfig.paths.json | 0 208 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 .vscode/launch.json mode change 100644 => 100755 .vscode/settings.json mode change 100644 => 100755 README.md mode change 100644 => 100755 TODO.md mode change 100644 => 100755 concept/ImagesSrc/logo_32_Asb.png mode change 100644 => 100755 concept/ImagesSrc/logo_32_naftagaz.png mode change 100644 => 100755 concept/ImagesSrc/logo_Asb.svg mode change 100644 => 100755 concept/SludgeDiagram.jsx mode change 100644 => 100755 concept/Smbo/EquipmentDetails.jsx mode change 100644 => 100755 concept/Smbo/SmboPlate.jsx mode change 100644 => 100755 concept/Smbo/images/RigPlan2.png mode change 100644 => 100755 concept/Smbo/images/TopDrive_Dummy.png mode change 100644 => 100755 concept/Smbo/index.jsx mode change 100644 => 100755 concept/TelemetryAnalysis.jsx mode change 100644 => 100755 concept/WellStat.jsx mode change 100644 => 100755 concept/WellTelemetryAnalysis.jsx mode change 100644 => 100755 concept/readme.md mode change 100644 => 100755 craco.config.js mode change 100644 => 100755 doc/MSE_and_torqueStab_info.txt mode change 100644 => 100755 package-lock.json mode change 100644 => 100755 package.json mode change 100644 => 100755 public/favicon.ico mode change 100644 => 100755 public/images/logo_32.png mode change 100644 => 100755 public/index.html mode change 100644 => 100755 public/manifest.json mode change 100644 => 100755 public/robots.txt mode change 100644 => 100755 src/App.js mode change 100644 => 100755 src/components/AnalysisOperationTime.jsx mode change 100644 => 100755 src/components/ChangePassword.tsx mode change 100644 => 100755 src/components/Display.jsx mode change 100644 => 100755 src/components/DownloadLink.tsx mode change 100644 => 100755 src/components/ErrorFetch.js mode change 100644 => 100755 src/components/Grid.tsx mode change 100644 => 100755 src/components/Layout/AdminLayoutPortal.tsx mode change 100644 => 100755 src/components/Layout/LayoutPortal.tsx mode change 100644 => 100755 src/components/Layout/index.ts mode change 100644 => 100755 src/components/LoaderPortal.tsx mode change 100644 => 100755 src/components/PageHeader.tsx mode change 100644 => 100755 src/components/Private/PrivateContent.tsx mode change 100644 => 100755 src/components/Private/PrivateDefaultRoute.tsx mode change 100644 => 100755 src/components/Private/PrivateMenuItem.tsx mode change 100644 => 100755 src/components/Private/PrivateRoute.tsx mode change 100644 => 100755 src/components/Private/index.ts mode change 100644 => 100755 src/components/Table/Columns/date.tsx mode change 100644 => 100755 src/components/Table/Columns/index.ts mode change 100644 => 100755 src/components/Table/Columns/numeric.tsx mode change 100644 => 100755 src/components/Table/Columns/plan_fact.tsx mode change 100644 => 100755 src/components/Table/Columns/select.tsx mode change 100644 => 100755 src/components/Table/Columns/tag.tsx mode change 100644 => 100755 src/components/Table/Columns/text.tsx mode change 100644 => 100755 src/components/Table/Columns/timezone.tsx mode change 100644 => 100755 src/components/Table/DatePickerWrapper.tsx mode change 100644 => 100755 src/components/Table/DateRangeWrapper.tsx mode change 100644 => 100755 src/components/Table/EditableCell.tsx mode change 100644 => 100755 src/components/Table/EditableTable.jsx mode change 100644 => 100755 src/components/Table/Table.tsx mode change 100644 => 100755 src/components/Table/TableSettingsChanger.tsx mode change 100644 => 100755 src/components/Table/index.tsx mode change 100644 => 100755 src/components/Table/sorters.ts mode change 100644 => 100755 src/components/UploadForm.jsx mode change 100644 => 100755 src/components/UserMenu.tsx mode change 100644 => 100755 src/components/charts/ChartOperationTime.jsx mode change 100644 => 100755 src/components/charts/ChartOperationTimeBase.tsx mode change 100644 => 100755 src/components/charts/ChartTelemetryDepthToDay.jsx mode change 100644 => 100755 src/components/charts/ChartTelemetryDepthToInterval.jsx mode change 100644 => 100755 src/components/charts/ChartTelemetryOperationsSummary.jsx mode change 100644 => 100755 src/components/charts/ChartTimeBase.tsx mode change 100644 => 100755 src/components/charts/Column.tsx mode change 100644 => 100755 src/components/factory.ts mode change 100644 => 100755 src/components/icons/Loader.tsx mode change 100644 => 100755 src/components/icons/PointerIcon.tsx mode change 100644 => 100755 src/components/icons/WellIcon.tsx mode change 100644 => 100755 src/components/icons/index.ts mode change 100644 => 100755 src/components/selectors/PeriodPicker.tsx mode change 100644 => 100755 src/components/selectors/Poprompt.tsx mode change 100644 => 100755 src/components/selectors/TelemetrySelect.tsx mode change 100644 => 100755 src/components/selectors/WellSelector.jsx mode change 100644 => 100755 src/components/selectors/WellTreeSelector.tsx mode change 100644 => 100755 src/components/views/CompanyView.tsx mode change 100644 => 100755 src/components/views/PermissionView.tsx mode change 100644 => 100755 src/components/views/RoleView.tsx mode change 100644 => 100755 src/components/views/TelemetryView.tsx mode change 100644 => 100755 src/components/views/UserView.tsx mode change 100644 => 100755 src/components/views/index.ts mode change 100644 => 100755 src/context/Context.js mode change 100644 => 100755 src/images/ClusterIcon.svg mode change 100644 => 100755 src/images/DempherOff.png mode change 100644 => 100755 src/images/DempherOn.png mode change 100644 => 100755 src/images/DepositIcon.svg mode change 100644 => 100755 src/images/Logo.tsx mode change 100644 => 100755 src/images/SpinDisabled.png mode change 100644 => 100755 src/images/SpinEnabled.png mode change 100644 => 100755 src/images/las.png mode change 100644 => 100755 src/index.js mode change 100644 => 100755 src/pages/AccessDenied.jsx mode change 100644 => 100755 src/pages/AdminPanel/ClusterController.jsx mode change 100644 => 100755 src/pages/AdminPanel/CompanyController.jsx mode change 100644 => 100755 src/pages/AdminPanel/CompanyTypeController.jsx mode change 100644 => 100755 src/pages/AdminPanel/DepositController.jsx mode change 100644 => 100755 src/pages/AdminPanel/PermissionController.jsx mode change 100644 => 100755 src/pages/AdminPanel/RoleController.jsx mode change 100644 => 100755 src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx mode change 100644 => 100755 src/pages/AdminPanel/Telemetry/TelemetryViewer.jsx mode change 100644 => 100755 src/pages/AdminPanel/Telemetry/index.jsx mode change 100644 => 100755 src/pages/AdminPanel/UserController/RoleTag.jsx mode change 100644 => 100755 src/pages/AdminPanel/UserController/index.jsx mode change 100644 => 100755 src/pages/AdminPanel/VisitLog.jsx mode change 100644 => 100755 src/pages/AdminPanel/WellController/index.jsx mode change 100644 => 100755 src/pages/AdminPanel/index.jsx mode change 100644 => 100755 src/pages/Analytics/Statistics.jsx mode change 100644 => 100755 src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx mode change 100644 => 100755 src/pages/Analytics/WellCompositeEditor/index.jsx mode change 100644 => 100755 src/pages/Analytics/index.jsx mode change 100644 => 100755 src/pages/Archive/ArchiveColumn.jsx mode change 100644 => 100755 src/pages/Archive/ArchiveDisplay.jsx mode change 100644 => 100755 src/pages/Archive/index.jsx mode change 100644 => 100755 src/pages/Cluster/ClusterWells.jsx mode change 100644 => 100755 src/pages/Cluster/WellOperationsTable.jsx mode change 100644 => 100755 src/pages/Cluster/index.jsx mode change 100644 => 100755 src/pages/Deposit.jsx mode change 100644 => 100755 src/pages/Documents/DocumentsTemplate.jsx mode change 100644 => 100755 src/pages/Documents/index.jsx mode change 100644 => 100755 src/pages/DrillingProgram/CategoryAdder.jsx mode change 100644 => 100755 src/pages/DrillingProgram/CategoryEditor.jsx mode change 100644 => 100755 src/pages/DrillingProgram/CategoryHistory.jsx mode change 100644 => 100755 src/pages/DrillingProgram/CategoryRender.jsx mode change 100644 => 100755 src/pages/DrillingProgram/MarksCard.jsx mode change 100644 => 100755 src/pages/DrillingProgram/index.jsx mode change 100644 => 100755 src/pages/Login.jsx mode change 100644 => 100755 src/pages/Main.jsx mode change 100644 => 100755 src/pages/Measure/InclinometryTable.jsx mode change 100644 => 100755 src/pages/Measure/MeasureTable.jsx mode change 100644 => 100755 src/pages/Measure/View.jsx mode change 100644 => 100755 src/pages/Measure/columnsCommon.js mode change 100644 => 100755 src/pages/Measure/drillingFluidData.js mode change 100644 => 100755 src/pages/Measure/index.jsx mode change 100644 => 100755 src/pages/Measure/mudDiagramData.js mode change 100644 => 100755 src/pages/Measure/nnbData.js mode change 100644 => 100755 src/pages/Register.jsx mode change 100644 => 100755 src/pages/Report/ReportCreationNotify.jsx mode change 100644 => 100755 src/pages/Report/Reports.jsx mode change 100644 => 100755 src/pages/Report/index.jsx mode change 100644 => 100755 src/pages/SuspenseFallback.tsx mode change 100644 => 100755 src/pages/Telemetry/Archive/ArchiveColumn.jsx mode change 100644 => 100755 src/pages/Telemetry/Archive/ArchiveDisplay.jsx mode change 100644 => 100755 src/pages/Telemetry/Archive/index.jsx mode change 100644 => 100755 src/pages/Telemetry/Messages.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/ChartTimeOnlineFooter.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/CustomColumn.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/ModeDisplay.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/MonitoringColumn.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/RigMnemo.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/Setpoints/SetpointViewer.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/Setpoints/index.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/UserOfWells.jsx mode change 100644 => 100755 src/pages/Telemetry/TelemetryView/index.jsx mode change 100644 => 100755 src/pages/Telemetry/index.jsx mode change 100644 => 100755 src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx mode change 100644 => 100755 src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx mode change 100644 => 100755 src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx mode change 100644 => 100755 src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx mode change 100644 => 100755 src/pages/TelemetryAnalysis/index.jsx mode change 100644 => 100755 src/pages/Well.jsx mode change 100644 => 100755 src/pages/WellOperations/DrillProcessFlow.jsx mode change 100644 => 100755 src/pages/WellOperations/ImportExportBar.jsx mode change 100644 => 100755 src/pages/WellOperations/ImportOperations.jsx mode change 100644 => 100755 src/pages/WellOperations/Tvd/AdditionalTables.jsx mode change 100644 => 100755 src/pages/WellOperations/Tvd/NetGraphExport.jsx mode change 100644 => 100755 src/pages/WellOperations/Tvd/NptTable.jsx mode change 100644 => 100755 src/pages/WellOperations/Tvd/index.jsx mode change 100644 => 100755 src/pages/WellOperations/WellDrillParams.jsx mode change 100644 => 100755 src/pages/WellOperations/WellOperationsEditor.jsx mode change 100644 => 100755 src/pages/WellOperations/WellSectionsStat.jsx mode change 100644 => 100755 src/pages/WellOperations/index.jsx mode change 100644 => 100755 src/react-app-env.d.ts mode change 100644 => 100755 src/reportWebVitals.js mode change 100644 => 100755 src/services/AutoGenerateApi.md mode change 100644 => 100755 src/services/UidGenerator.ts mode change 100644 => 100755 src/services/signalr/index.ts mode change 100644 => 100755 src/styles/App.less mode change 100644 => 100755 src/styles/charts.less mode change 100644 => 100755 src/styles/components/telemetry_select.less mode change 100644 => 100755 src/styles/display.css mode change 100644 => 100755 src/styles/drilling_program.less mode change 100644 => 100755 src/styles/equipment_details.css mode change 100644 => 100755 src/styles/index.css mode change 100644 => 100755 src/styles/loader.css mode change 100644 => 100755 src/styles/measure.css mode change 100644 => 100755 src/styles/message.css mode change 100644 => 100755 src/styles/message_telemetry.css mode change 100644 => 100755 src/styles/smbo.css mode change 100644 => 100755 src/styles/statistics.less mode change 100644 => 100755 src/styles/tvd.less mode change 100644 => 100755 src/styles/wellTreeSelect.css mode change 100644 => 100755 src/utils/datetime.ts mode change 100644 => 100755 src/utils/functions.tsx mode change 100644 => 100755 src/utils/index.ts mode change 100644 => 100755 src/utils/permissions.ts mode change 100644 => 100755 src/utils/storage.ts mode change 100644 => 100755 src/utils/string.ts mode change 100644 => 100755 src/utils/table.ts mode change 100644 => 100755 src/utils/table_settings.ts mode change 100644 => 100755 src/utils/validationRules.ts mode change 100644 => 100755 tsconfig.json mode change 100644 => 100755 tsconfig.paths.json diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.vscode/launch.json b/.vscode/launch.json old mode 100644 new mode 100755 diff --git a/.vscode/settings.json b/.vscode/settings.json old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/TODO.md b/TODO.md old mode 100644 new mode 100755 diff --git a/concept/ImagesSrc/logo_32_Asb.png b/concept/ImagesSrc/logo_32_Asb.png old mode 100644 new mode 100755 diff --git a/concept/ImagesSrc/logo_32_naftagaz.png b/concept/ImagesSrc/logo_32_naftagaz.png old mode 100644 new mode 100755 diff --git a/concept/ImagesSrc/logo_Asb.svg b/concept/ImagesSrc/logo_Asb.svg old mode 100644 new mode 100755 diff --git a/concept/SludgeDiagram.jsx b/concept/SludgeDiagram.jsx old mode 100644 new mode 100755 diff --git a/concept/Smbo/EquipmentDetails.jsx b/concept/Smbo/EquipmentDetails.jsx old mode 100644 new mode 100755 diff --git a/concept/Smbo/SmboPlate.jsx b/concept/Smbo/SmboPlate.jsx old mode 100644 new mode 100755 diff --git a/concept/Smbo/images/RigPlan2.png b/concept/Smbo/images/RigPlan2.png old mode 100644 new mode 100755 diff --git a/concept/Smbo/images/TopDrive_Dummy.png b/concept/Smbo/images/TopDrive_Dummy.png old mode 100644 new mode 100755 diff --git a/concept/Smbo/index.jsx b/concept/Smbo/index.jsx old mode 100644 new mode 100755 diff --git a/concept/TelemetryAnalysis.jsx b/concept/TelemetryAnalysis.jsx old mode 100644 new mode 100755 diff --git a/concept/WellStat.jsx b/concept/WellStat.jsx old mode 100644 new mode 100755 diff --git a/concept/WellTelemetryAnalysis.jsx b/concept/WellTelemetryAnalysis.jsx old mode 100644 new mode 100755 diff --git a/concept/readme.md b/concept/readme.md old mode 100644 new mode 100755 diff --git a/craco.config.js b/craco.config.js old mode 100644 new mode 100755 diff --git a/doc/MSE_and_torqueStab_info.txt b/doc/MSE_and_torqueStab_info.txt old mode 100644 new mode 100755 diff --git a/package-lock.json b/package-lock.json old mode 100644 new mode 100755 diff --git a/package.json b/package.json old mode 100644 new mode 100755 diff --git a/public/favicon.ico b/public/favicon.ico old mode 100644 new mode 100755 diff --git a/public/images/logo_32.png b/public/images/logo_32.png old mode 100644 new mode 100755 diff --git a/public/index.html b/public/index.html old mode 100644 new mode 100755 diff --git a/public/manifest.json b/public/manifest.json old mode 100644 new mode 100755 diff --git a/public/robots.txt b/public/robots.txt old mode 100644 new mode 100755 diff --git a/src/App.js b/src/App.js old mode 100644 new mode 100755 diff --git a/src/components/AnalysisOperationTime.jsx b/src/components/AnalysisOperationTime.jsx old mode 100644 new mode 100755 diff --git a/src/components/ChangePassword.tsx b/src/components/ChangePassword.tsx old mode 100644 new mode 100755 diff --git a/src/components/Display.jsx b/src/components/Display.jsx old mode 100644 new mode 100755 diff --git a/src/components/DownloadLink.tsx b/src/components/DownloadLink.tsx old mode 100644 new mode 100755 diff --git a/src/components/ErrorFetch.js b/src/components/ErrorFetch.js old mode 100644 new mode 100755 diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx old mode 100644 new mode 100755 diff --git a/src/components/Layout/AdminLayoutPortal.tsx b/src/components/Layout/AdminLayoutPortal.tsx old mode 100644 new mode 100755 diff --git a/src/components/Layout/LayoutPortal.tsx b/src/components/Layout/LayoutPortal.tsx old mode 100644 new mode 100755 diff --git a/src/components/Layout/index.ts b/src/components/Layout/index.ts old mode 100644 new mode 100755 diff --git a/src/components/LoaderPortal.tsx b/src/components/LoaderPortal.tsx old mode 100644 new mode 100755 diff --git a/src/components/PageHeader.tsx b/src/components/PageHeader.tsx old mode 100644 new mode 100755 diff --git a/src/components/Private/PrivateContent.tsx b/src/components/Private/PrivateContent.tsx old mode 100644 new mode 100755 diff --git a/src/components/Private/PrivateDefaultRoute.tsx b/src/components/Private/PrivateDefaultRoute.tsx old mode 100644 new mode 100755 diff --git a/src/components/Private/PrivateMenuItem.tsx b/src/components/Private/PrivateMenuItem.tsx old mode 100644 new mode 100755 diff --git a/src/components/Private/PrivateRoute.tsx b/src/components/Private/PrivateRoute.tsx old mode 100644 new mode 100755 diff --git a/src/components/Private/index.ts b/src/components/Private/index.ts old mode 100644 new mode 100755 diff --git a/src/components/Table/Columns/date.tsx b/src/components/Table/Columns/date.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/Columns/index.ts b/src/components/Table/Columns/index.ts old mode 100644 new mode 100755 diff --git a/src/components/Table/Columns/numeric.tsx b/src/components/Table/Columns/numeric.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/Columns/plan_fact.tsx b/src/components/Table/Columns/plan_fact.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/Columns/select.tsx b/src/components/Table/Columns/select.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/Columns/tag.tsx b/src/components/Table/Columns/tag.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/Columns/text.tsx b/src/components/Table/Columns/text.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/Columns/timezone.tsx b/src/components/Table/Columns/timezone.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/DatePickerWrapper.tsx b/src/components/Table/DatePickerWrapper.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/DateRangeWrapper.tsx b/src/components/Table/DateRangeWrapper.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/EditableCell.tsx b/src/components/Table/EditableCell.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/EditableTable.jsx b/src/components/Table/EditableTable.jsx old mode 100644 new mode 100755 diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/TableSettingsChanger.tsx b/src/components/Table/TableSettingsChanger.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx old mode 100644 new mode 100755 diff --git a/src/components/Table/sorters.ts b/src/components/Table/sorters.ts old mode 100644 new mode 100755 diff --git a/src/components/UploadForm.jsx b/src/components/UploadForm.jsx old mode 100644 new mode 100755 diff --git a/src/components/UserMenu.tsx b/src/components/UserMenu.tsx old mode 100644 new mode 100755 diff --git a/src/components/charts/ChartOperationTime.jsx b/src/components/charts/ChartOperationTime.jsx old mode 100644 new mode 100755 diff --git a/src/components/charts/ChartOperationTimeBase.tsx b/src/components/charts/ChartOperationTimeBase.tsx old mode 100644 new mode 100755 diff --git a/src/components/charts/ChartTelemetryDepthToDay.jsx b/src/components/charts/ChartTelemetryDepthToDay.jsx old mode 100644 new mode 100755 diff --git a/src/components/charts/ChartTelemetryDepthToInterval.jsx b/src/components/charts/ChartTelemetryDepthToInterval.jsx old mode 100644 new mode 100755 diff --git a/src/components/charts/ChartTelemetryOperationsSummary.jsx b/src/components/charts/ChartTelemetryOperationsSummary.jsx old mode 100644 new mode 100755 diff --git a/src/components/charts/ChartTimeBase.tsx b/src/components/charts/ChartTimeBase.tsx old mode 100644 new mode 100755 diff --git a/src/components/charts/Column.tsx b/src/components/charts/Column.tsx old mode 100644 new mode 100755 diff --git a/src/components/factory.ts b/src/components/factory.ts old mode 100644 new mode 100755 diff --git a/src/components/icons/Loader.tsx b/src/components/icons/Loader.tsx old mode 100644 new mode 100755 diff --git a/src/components/icons/PointerIcon.tsx b/src/components/icons/PointerIcon.tsx old mode 100644 new mode 100755 diff --git a/src/components/icons/WellIcon.tsx b/src/components/icons/WellIcon.tsx old mode 100644 new mode 100755 diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts old mode 100644 new mode 100755 diff --git a/src/components/selectors/PeriodPicker.tsx b/src/components/selectors/PeriodPicker.tsx old mode 100644 new mode 100755 diff --git a/src/components/selectors/Poprompt.tsx b/src/components/selectors/Poprompt.tsx old mode 100644 new mode 100755 diff --git a/src/components/selectors/TelemetrySelect.tsx b/src/components/selectors/TelemetrySelect.tsx old mode 100644 new mode 100755 diff --git a/src/components/selectors/WellSelector.jsx b/src/components/selectors/WellSelector.jsx old mode 100644 new mode 100755 diff --git a/src/components/selectors/WellTreeSelector.tsx b/src/components/selectors/WellTreeSelector.tsx old mode 100644 new mode 100755 diff --git a/src/components/views/CompanyView.tsx b/src/components/views/CompanyView.tsx old mode 100644 new mode 100755 diff --git a/src/components/views/PermissionView.tsx b/src/components/views/PermissionView.tsx old mode 100644 new mode 100755 diff --git a/src/components/views/RoleView.tsx b/src/components/views/RoleView.tsx old mode 100644 new mode 100755 diff --git a/src/components/views/TelemetryView.tsx b/src/components/views/TelemetryView.tsx old mode 100644 new mode 100755 diff --git a/src/components/views/UserView.tsx b/src/components/views/UserView.tsx old mode 100644 new mode 100755 diff --git a/src/components/views/index.ts b/src/components/views/index.ts old mode 100644 new mode 100755 diff --git a/src/context/Context.js b/src/context/Context.js old mode 100644 new mode 100755 diff --git a/src/images/ClusterIcon.svg b/src/images/ClusterIcon.svg old mode 100644 new mode 100755 diff --git a/src/images/DempherOff.png b/src/images/DempherOff.png old mode 100644 new mode 100755 diff --git a/src/images/DempherOn.png b/src/images/DempherOn.png old mode 100644 new mode 100755 diff --git a/src/images/DepositIcon.svg b/src/images/DepositIcon.svg old mode 100644 new mode 100755 diff --git a/src/images/Logo.tsx b/src/images/Logo.tsx old mode 100644 new mode 100755 diff --git a/src/images/SpinDisabled.png b/src/images/SpinDisabled.png old mode 100644 new mode 100755 diff --git a/src/images/SpinEnabled.png b/src/images/SpinEnabled.png old mode 100644 new mode 100755 diff --git a/src/images/las.png b/src/images/las.png old mode 100644 new mode 100755 diff --git a/src/index.js b/src/index.js old mode 100644 new mode 100755 diff --git a/src/pages/AccessDenied.jsx b/src/pages/AccessDenied.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/ClusterController.jsx b/src/pages/AdminPanel/ClusterController.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/CompanyController.jsx b/src/pages/AdminPanel/CompanyController.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/CompanyTypeController.jsx b/src/pages/AdminPanel/CompanyTypeController.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/DepositController.jsx b/src/pages/AdminPanel/DepositController.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/PermissionController.jsx b/src/pages/AdminPanel/PermissionController.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/RoleController.jsx b/src/pages/AdminPanel/RoleController.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx b/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/Telemetry/TelemetryViewer.jsx b/src/pages/AdminPanel/Telemetry/TelemetryViewer.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/Telemetry/index.jsx b/src/pages/AdminPanel/Telemetry/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/UserController/RoleTag.jsx b/src/pages/AdminPanel/UserController/RoleTag.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/UserController/index.jsx b/src/pages/AdminPanel/UserController/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/VisitLog.jsx b/src/pages/AdminPanel/VisitLog.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/WellController/index.jsx b/src/pages/AdminPanel/WellController/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/AdminPanel/index.jsx b/src/pages/AdminPanel/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Analytics/Statistics.jsx b/src/pages/Analytics/Statistics.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Analytics/WellCompositeEditor/index.jsx b/src/pages/Analytics/WellCompositeEditor/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Analytics/index.jsx b/src/pages/Analytics/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Archive/ArchiveColumn.jsx b/src/pages/Archive/ArchiveColumn.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Archive/ArchiveDisplay.jsx b/src/pages/Archive/ArchiveDisplay.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Archive/index.jsx b/src/pages/Archive/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Cluster/ClusterWells.jsx b/src/pages/Cluster/ClusterWells.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Cluster/WellOperationsTable.jsx b/src/pages/Cluster/WellOperationsTable.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Cluster/index.jsx b/src/pages/Cluster/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Deposit.jsx b/src/pages/Deposit.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Documents/DocumentsTemplate.jsx b/src/pages/Documents/DocumentsTemplate.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Documents/index.jsx b/src/pages/Documents/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/DrillingProgram/CategoryAdder.jsx b/src/pages/DrillingProgram/CategoryAdder.jsx old mode 100644 new mode 100755 diff --git a/src/pages/DrillingProgram/CategoryEditor.jsx b/src/pages/DrillingProgram/CategoryEditor.jsx old mode 100644 new mode 100755 diff --git a/src/pages/DrillingProgram/CategoryHistory.jsx b/src/pages/DrillingProgram/CategoryHistory.jsx old mode 100644 new mode 100755 diff --git a/src/pages/DrillingProgram/CategoryRender.jsx b/src/pages/DrillingProgram/CategoryRender.jsx old mode 100644 new mode 100755 diff --git a/src/pages/DrillingProgram/MarksCard.jsx b/src/pages/DrillingProgram/MarksCard.jsx old mode 100644 new mode 100755 diff --git a/src/pages/DrillingProgram/index.jsx b/src/pages/DrillingProgram/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Main.jsx b/src/pages/Main.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Measure/InclinometryTable.jsx b/src/pages/Measure/InclinometryTable.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Measure/MeasureTable.jsx b/src/pages/Measure/MeasureTable.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Measure/View.jsx b/src/pages/Measure/View.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Measure/columnsCommon.js b/src/pages/Measure/columnsCommon.js old mode 100644 new mode 100755 diff --git a/src/pages/Measure/drillingFluidData.js b/src/pages/Measure/drillingFluidData.js old mode 100644 new mode 100755 diff --git a/src/pages/Measure/index.jsx b/src/pages/Measure/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Measure/mudDiagramData.js b/src/pages/Measure/mudDiagramData.js old mode 100644 new mode 100755 diff --git a/src/pages/Measure/nnbData.js b/src/pages/Measure/nnbData.js old mode 100644 new mode 100755 diff --git a/src/pages/Register.jsx b/src/pages/Register.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Report/ReportCreationNotify.jsx b/src/pages/Report/ReportCreationNotify.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Report/Reports.jsx b/src/pages/Report/Reports.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Report/index.jsx b/src/pages/Report/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/SuspenseFallback.tsx b/src/pages/SuspenseFallback.tsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/Archive/ArchiveColumn.jsx b/src/pages/Telemetry/Archive/ArchiveColumn.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/Archive/ArchiveDisplay.jsx b/src/pages/Telemetry/Archive/ArchiveDisplay.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/Archive/index.jsx b/src/pages/Telemetry/Archive/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/Messages.jsx b/src/pages/Telemetry/Messages.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/ChartTimeOnlineFooter.jsx b/src/pages/Telemetry/TelemetryView/ChartTimeOnlineFooter.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/CustomColumn.jsx b/src/pages/Telemetry/TelemetryView/CustomColumn.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/ModeDisplay.jsx b/src/pages/Telemetry/TelemetryView/ModeDisplay.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/MonitoringColumn.jsx b/src/pages/Telemetry/TelemetryView/MonitoringColumn.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/RigMnemo.jsx b/src/pages/Telemetry/TelemetryView/RigMnemo.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/Setpoints/SetpointViewer.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointViewer.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/UserOfWells.jsx b/src/pages/Telemetry/TelemetryView/UserOfWells.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/TelemetryView/index.jsx b/src/pages/Telemetry/TelemetryView/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Telemetry/index.jsx b/src/pages/Telemetry/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx old mode 100644 new mode 100755 diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx old mode 100644 new mode 100755 diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx old mode 100644 new mode 100755 diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx old mode 100644 new mode 100755 diff --git a/src/pages/TelemetryAnalysis/index.jsx b/src/pages/TelemetryAnalysis/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/DrillProcessFlow.jsx b/src/pages/WellOperations/DrillProcessFlow.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/ImportExportBar.jsx b/src/pages/WellOperations/ImportExportBar.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/ImportOperations.jsx b/src/pages/WellOperations/ImportOperations.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/Tvd/AdditionalTables.jsx b/src/pages/WellOperations/Tvd/AdditionalTables.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/Tvd/NetGraphExport.jsx b/src/pages/WellOperations/Tvd/NetGraphExport.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/Tvd/NptTable.jsx b/src/pages/WellOperations/Tvd/NptTable.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/Tvd/index.jsx b/src/pages/WellOperations/Tvd/index.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/WellDrillParams.jsx b/src/pages/WellOperations/WellDrillParams.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/WellOperationsEditor.jsx b/src/pages/WellOperations/WellOperationsEditor.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/WellSectionsStat.jsx b/src/pages/WellOperations/WellSectionsStat.jsx old mode 100644 new mode 100755 diff --git a/src/pages/WellOperations/index.jsx b/src/pages/WellOperations/index.jsx old mode 100644 new mode 100755 diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts old mode 100644 new mode 100755 diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js old mode 100644 new mode 100755 diff --git a/src/services/AutoGenerateApi.md b/src/services/AutoGenerateApi.md old mode 100644 new mode 100755 diff --git a/src/services/UidGenerator.ts b/src/services/UidGenerator.ts old mode 100644 new mode 100755 diff --git a/src/services/signalr/index.ts b/src/services/signalr/index.ts old mode 100644 new mode 100755 diff --git a/src/styles/App.less b/src/styles/App.less old mode 100644 new mode 100755 diff --git a/src/styles/charts.less b/src/styles/charts.less old mode 100644 new mode 100755 diff --git a/src/styles/components/telemetry_select.less b/src/styles/components/telemetry_select.less old mode 100644 new mode 100755 diff --git a/src/styles/display.css b/src/styles/display.css old mode 100644 new mode 100755 diff --git a/src/styles/drilling_program.less b/src/styles/drilling_program.less old mode 100644 new mode 100755 diff --git a/src/styles/equipment_details.css b/src/styles/equipment_details.css old mode 100644 new mode 100755 diff --git a/src/styles/index.css b/src/styles/index.css old mode 100644 new mode 100755 diff --git a/src/styles/loader.css b/src/styles/loader.css old mode 100644 new mode 100755 diff --git a/src/styles/measure.css b/src/styles/measure.css old mode 100644 new mode 100755 diff --git a/src/styles/message.css b/src/styles/message.css old mode 100644 new mode 100755 diff --git a/src/styles/message_telemetry.css b/src/styles/message_telemetry.css old mode 100644 new mode 100755 diff --git a/src/styles/smbo.css b/src/styles/smbo.css old mode 100644 new mode 100755 diff --git a/src/styles/statistics.less b/src/styles/statistics.less old mode 100644 new mode 100755 diff --git a/src/styles/tvd.less b/src/styles/tvd.less old mode 100644 new mode 100755 diff --git a/src/styles/wellTreeSelect.css b/src/styles/wellTreeSelect.css old mode 100644 new mode 100755 diff --git a/src/utils/datetime.ts b/src/utils/datetime.ts old mode 100644 new mode 100755 diff --git a/src/utils/functions.tsx b/src/utils/functions.tsx old mode 100644 new mode 100755 diff --git a/src/utils/index.ts b/src/utils/index.ts old mode 100644 new mode 100755 diff --git a/src/utils/permissions.ts b/src/utils/permissions.ts old mode 100644 new mode 100755 diff --git a/src/utils/storage.ts b/src/utils/storage.ts old mode 100644 new mode 100755 diff --git a/src/utils/string.ts b/src/utils/string.ts old mode 100644 new mode 100755 diff --git a/src/utils/table.ts b/src/utils/table.ts old mode 100644 new mode 100755 diff --git a/src/utils/table_settings.ts b/src/utils/table_settings.ts old mode 100644 new mode 100755 diff --git a/src/utils/validationRules.ts b/src/utils/validationRules.ts old mode 100644 new mode 100755 diff --git a/tsconfig.json b/tsconfig.json old mode 100644 new mode 100755 diff --git a/tsconfig.paths.json b/tsconfig.paths.json old mode 100644 new mode 100755 From 66ba02c14ab1f5acbc0f38d1227a499257eb7791 Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Tue, 29 Mar 2022 14:25:31 +0500 Subject: [PATCH 03/49] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=D0=B7=20=D1=85=D0=BE?= =?UTF-8?q?=D1=82=D1=84=D0=B8=D0=BA=D1=81=D0=B0=20=D0=BC=D0=B0=D1=81=D1=82?= =?UTF-8?q?=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WellCompositeEditor/WellCompositeSections.jsx | 9 ++++++--- src/pages/DrillingProgram/CategoryEditor.jsx | 4 ++-- src/pages/WellOperations/Tvd/index.jsx | 6 +++--- src/styles/tvd.less | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx index 6276ecf..0c55a33 100755 --- a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx +++ b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx @@ -39,11 +39,10 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection const [isTVDModalVisible, setIsTVDModalVisible] = useState(false) const [isOpsModalVisible, setIsOpsModalVisible] = useState(false) const [isParamsModalVisible, setIsParamsModalVisible] = useState(false) + const [paramsColumns, setParamsColumns] = useState([]) const location = useLocation() - const paramsColumns = useMemo(async() => await getColumns(idWell), [idWell]) - const rows = useMemo(() => { const rows = [] statsWells?.forEach((well) => { @@ -102,6 +101,10 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection return rows }, [statsWells]) + useEffect(() => invokeWebApiWrapperAsync( + async () => setParamsColumns(await getColumns(idWell)) + ), [idWell]) + useEffect(() => { if (isOpsModalVisible || selectedWellId <= 0) return invokeWebApiWrapperAsync( @@ -252,7 +255,7 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection width={1500} footer={null} > - + const changeUserStatus = useCallback((user, status) => invokeWebApiWrapperAsync( async () => { const userIdx = users?.findIndex(({ user: u }) => u.id === user.id) - if (!userIdx) return + if (userIdx <= -1) return if (status === 0) { await DrillingProgramService.removeUser(idWell, user.id, category.idFileCategory, users[userIdx].status) @@ -102,7 +102,7 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => } setUsers((prevUsers) => { prevUsers[userIdx].status = status - return prevUsers + return [...prevUsers] }) }, setShowLoader, diff --git a/src/pages/WellOperations/Tvd/index.jsx b/src/pages/WellOperations/Tvd/index.jsx index e0e2784..c35a2d3 100755 --- a/src/pages/WellOperations/Tvd/index.jsx +++ b/src/pages/WellOperations/Tvd/index.jsx @@ -114,7 +114,7 @@ const makeDataset = (data, label, color, borderWidth = 1.5, borderDash) => ({ borderDash, }) -export const Tvd = memo(({ idWell, title }) => { +export const Tvd = memo(({ idWell, title, ...other }) => { const [chart, setChart] = useState() const [xLabel, setXLabel] = useState('day') const [operations, setOperations] = useState({}) @@ -187,7 +187,7 @@ export const Tvd = memo(({ idWell, title }) => { chart.canvas.parentNode.style.width = '0' chart.resize() } - }, [chart, operations, xLabel, onPointClick]) + }, [chart, operations, xLabel, onPointClick, other]) const toogleTable = useCallback(() => { setOperations(pre => ({ ...pre })) @@ -195,7 +195,7 @@ export const Tvd = memo(({ idWell, title }) => { }, []) return ( -
+

{title || 'График Глубина-день'}

diff --git a/src/styles/tvd.less b/src/styles/tvd.less index 2b51e90..a1d51b0 100755 --- a/src/styles/tvd.less +++ b/src/styles/tvd.less @@ -25,7 +25,7 @@ > div { position: absolute; //pointer-events: none; - transition: all .25s ease-out; + transition: opacity .25s ease-out; opacity: 1; &:hover { From 0d6e46d91f64c6ed3315c74a37327144e07c8c15 Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Tue, 29 Mar 2022 16:09:47 +0500 Subject: [PATCH 04/49] =?UTF-8?q?=D0=A1=D0=BF=D0=B8=D1=81=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=BC=D0=BE=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D1=8B,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=BE=D0=BA=D0=BE=D0=BD=20=D1=81=D0=BE=D0=B3=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F/=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=BB=D0=BE=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/DrillingProgram/CategoryRender.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/DrillingProgram/CategoryRender.jsx b/src/pages/DrillingProgram/CategoryRender.jsx index 50316be..d3a168e 100755 --- a/src/pages/DrillingProgram/CategoryRender.jsx +++ b/src/pages/DrillingProgram/CategoryRender.jsx @@ -45,6 +45,8 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist } = partData ?? {} const uploadUrl = useMemo(() => `/api/well/${idWell}/drillingProgram/part/${idFileCategory}`, [idWell, idFileCategory]) + const approvedMarks = useMemo(() => file?.fileMarks?.filter((mark) => mark.idMarkType === 1), [file]) + const rejectMarks = useMemo(() => file?.fileMarks?.filter((mark) => mark.idMarkType === 0), [file]) const [isUploading, setIsUploading] = useState(false) const [isDeleting, setIsDeleting] = useState(false) @@ -149,13 +151,13 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist {permissionToApprove && ( )} - mark.idMarkType === 1)} /> +
{permissionToApprove && ( )} - mark.idMarkType === 0)} /> +
)} From c44195229ed00dc4717813e4c277298bf4ecd75c Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Tue, 29 Mar 2022 16:16:18 +0500 Subject: [PATCH 05/49] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D0=BC=D0=B5=D1=82=D0=BE=D0=BA?= =?UTF-8?q?=20=D0=B2=20=D0=B8=D1=81=D1=82=D0=BE=D1=80=D0=B8=D0=B8=20=D0=9F?= =?UTF-8?q?=D0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/DrillingProgram/CategoryHistory.jsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/pages/DrillingProgram/CategoryHistory.jsx b/src/pages/DrillingProgram/CategoryHistory.jsx index 2be6695..1df55ad 100755 --- a/src/pages/DrillingProgram/CategoryHistory.jsx +++ b/src/pages/DrillingProgram/CategoryHistory.jsx @@ -39,12 +39,15 @@ export const historyColumns = [ return (
-
- -
-
- -
+ {approved.length > 0 ? ( +
+ +
+ ) : rejected.length > 0 ? ( +
+ +
+ ) : 'Нет отметок'}
) } From 54ada2298c8c6c46cb08737616999c9883c6544b Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Tue, 29 Mar 2022 16:36:04 +0500 Subject: [PATCH 06/49] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D0=BC=D0=B8=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=BF=D0=BE=D0=B4=D0=B3=D1=80=D1=83=D0=B7=D0=BA?= =?UTF-8?q?=D0=B5=20=D0=BD=D0=B0=20=D0=BA=D0=BE=D0=BC=D0=BF.=20=D1=81?= =?UTF-8?q?=D0=BA=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Analytics/WellCompositeEditor/WellCompositeSections.jsx | 4 +++- src/pages/Analytics/WellCompositeEditor/index.jsx | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx index 0c55a33..9dbe389 100755 --- a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx +++ b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx @@ -25,6 +25,8 @@ const filtersMinMax = [ { text: 'max', value: 'max' }, ] +const sortBySectionId = (a, b) => a.sectionId - b.sectionId + const filtersSectionsType = [] const DAY_IN_MS = 1000 * 60 * 60 * 24 @@ -130,7 +132,7 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection makeTextColumn('скв №', 'caption', null, null, (text, item) => {text ?? '-'} ), - makeTextColumn('Секция', 'sectionType', filtersSectionsType, null, (text) => text ?? '-'), + makeTextColumn('Секция', 'sectionType', filtersSectionsType, sortBySectionId, (text) => text ?? '-'), makeNumericColumnPlanFact('Глубина, м', 'sectionWellDepth', filtersMinMax, makeFilterMinMaxFunction), makeNumericColumnPlanFact('Продолжительность, ч', 'sectionBuildDays', filtersMinMax, makeFilterMinMaxFunction), makeNumericColumnPlanFact('МСП, м/ч', 'sectionRateOfPenetration', filtersMinMax, makeFilterMinMaxFunction), diff --git a/src/pages/Analytics/WellCompositeEditor/index.jsx b/src/pages/Analytics/WellCompositeEditor/index.jsx index cd2de0d..80f3534 100755 --- a/src/pages/Analytics/WellCompositeEditor/index.jsx +++ b/src/pages/Analytics/WellCompositeEditor/index.jsx @@ -42,13 +42,14 @@ export const WellCompositeEditor = memo(({ idWell, rootPath }) => { useEffect(() => { const wellIds = selectedSections.map((value) => value.idWellSrc) + .filter((id, idx, arr) => arr.lastIndexOf(id) === idx) setSelectedIdWells(wellIds) }, [selectedSections]) useEffect(() => invokeWebApiWrapperAsync( async () => { - const stats = await OperationStatService.getWellsStat(selectedIdWells) - setStatsWells(arrayOrDefault(stats)) + const stats = arrayOrDefault(await OperationStatService.getWellsStat(selectedIdWells)) + setStatsWells(stats) }, setShowTabLoader, 'Не удалось загрузить статистику по скважинам/секциям', From 76d7ac9949158f737b8925550a509091158d47e9 Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Tue, 29 Mar 2022 17:03:04 +0500 Subject: [PATCH 07/49] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D1=81=D0=B5=D0=BA=D1=86=D0=B8=D0=B8=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=BF.=20=D1=81=D0=BA=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WellCompositeEditor/NewParamsTable.jsx | 79 ++++++++++++++ .../WellCompositeSections.jsx | 101 ++++-------------- src/pages/WellOperations/WellDrillParams.jsx | 8 +- 3 files changed, 105 insertions(+), 83 deletions(-) create mode 100755 src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx diff --git a/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx b/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx new file mode 100755 index 0000000..6998087 --- /dev/null +++ b/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx @@ -0,0 +1,79 @@ +import { memo, useCallback, useEffect, useState } from 'react' +import { Button, Modal, Popconfirm } from 'antd' + +import { Table } from '@components/Table' +import LoaderPortal from '@components/LoaderPortal' +import { invokeWebApiWrapperAsync } from '@components/factory' +import { DrillParamsService } from '@api' + +import { getColumns } from '@pages/WellOperations/WellDrillParams' + +export const NewParamsTable = memo(({ idWell, selectedWellsKeys }) => { + const [params, setParams] = useState([]) + const [paramsColumns, setParamsColumns] = useState([]) + const [showParamsLoader, setShowParamsLoader] = useState(false) + const [isParamsModalVisible, setIsParamsModalVisible] = useState(false) + + useEffect(() => invokeWebApiWrapperAsync( + async () => setParamsColumns(await getColumns(idWell)) + ), [idWell]) + + useEffect(() => console.log(paramsColumns), [paramsColumns]) + + const onParamButtonClick = useCallback(() => invokeWebApiWrapperAsync( + async () => { + setIsParamsModalVisible(true) + const params = await DrillParamsService.getCompositeAll(idWell) + setParams(params) + }, + setShowParamsLoader, + `Не удалось загрузить список режимов для скважины "${idWell}"`, + 'Получение списка режимов скважины' + ), [idWell]) + + const onParamsAddClick = useCallback(() => invokeWebApiWrapperAsync( + async () => { + await DrillParamsService.save(idWell, params) + setIsParamsModalVisible(false) + }, + setShowParamsLoader, + `Не удалось добавить режимы в список скважины "${idWell}"`, + 'Добавление режима скважины' + ), [idWell, params]) + + return ( + <> + + setIsParamsModalVisible(false)} + width={1700} + footer={( + + + + )} + > + + + + + + ) +}) + +export default NewParamsTable diff --git a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx index 9dbe389..7e1505a 100755 --- a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx +++ b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx @@ -1,13 +1,13 @@ import { Link, useLocation } from 'react-router-dom' -import { useState, useEffect, memo, useCallback, useMemo } from 'react' +import { useState, useEffect, memo, useMemo } from 'react' import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons' -import { Table, Tag, Button, Badge, Divider, Modal, Row, Col, Popconfirm } from 'antd' +import { Table, Tag, Button, Badge, Divider, Modal, Row, Col } from 'antd' import { CompanyView } from '@components/views' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' import { makeTextColumn, makeNumericColumnPlanFact } from '@components/Table' -import { DrillParamsService, WellCompositeService } from '@api' +import { WellCompositeService } from '@api' import { hasPermission } from '@utils/permissions' import { calcAndUpdateStatsBySections, @@ -16,9 +16,8 @@ import { } from '@utils/functions' import { Tvd } from '@pages/WellOperations/Tvd' -import { getColumns } from '@pages/WellOperations/WellDrillParams' import WellOperationsTable from '@pages/Cluster/WellOperationsTable' - +import NewParamsTable from './NewParamsTable' const filtersMinMax = [ { text: 'min', value: 'min' }, @@ -31,17 +30,13 @@ const filtersSectionsType = [] const DAY_IN_MS = 1000 * 60 * 60 * 24 export const WellCompositeSections = memo(({ idWell, statsWells, selectedSections }) => { - const [params, setParams] = useState([]) const [selectedWells, setSelectedWells] = useState([]) const [wellOperations, setWellOperations] = useState([]) const [selectedWellsKeys, setSelectedWellsKeys] = useState([]) const [selectedWellId, setSelectedWellId] = useState(0) const [showLoader, setShowLoader] = useState(false) - const [showParamsLoader, setShowParamsLoader] = useState(false) const [isTVDModalVisible, setIsTVDModalVisible] = useState(false) const [isOpsModalVisible, setIsOpsModalVisible] = useState(false) - const [isParamsModalVisible, setIsParamsModalVisible] = useState(false) - const [paramsColumns, setParamsColumns] = useState([]) const location = useLocation() @@ -103,10 +98,6 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection return rows }, [statsWells]) - useEffect(() => invokeWebApiWrapperAsync( - async () => setParamsColumns(await getColumns(idWell)) - ), [idWell]) - useEffect(() => { if (isOpsModalVisible || selectedWellId <= 0) return invokeWebApiWrapperAsync( @@ -128,6 +119,22 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection setSelectedWellsKeys(selected.map((row) => row.key)) }, [rows, selectedSections]) + const rowSelection = useMemo(() => hasPermission('WellOperation.edit') && { + selectedRowKeys: selectedWellsKeys, + onChange: (keys, items) => invokeWebApiWrapperAsync( + async () => { + const selectedSections = items.map((row) => ({idWell, idWellSrc: row.id, idWellSectionType: row.sectionId})) + await WellCompositeService.save(idWell, selectedSections) + + setSelectedWells(items) + setSelectedWellsKeys(keys) + }, + setShowLoader, + `Не удалось сохранить изменения выбранных секций для композитной скважины "${idWell}"`, + 'Изменение выбранных секций скважины' + ) + }, [idWell, selectedWellsKeys]) + const columns = useMemo(() => [ makeTextColumn('скв №', 'caption', null, null, (text, item) => {text ?? '-'} @@ -176,43 +183,6 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection }, ], [location.pathname]) - const rowSelection = useMemo(() => hasPermission('WellOperation.edit') && { - selectedRowKeys: selectedWellsKeys, - onChange: (keys, items) => invokeWebApiWrapperAsync( - async () => { - const selectedSections = items.map((row) => ({idWell, idWellSrc: row.id, idWellSectionType: row.sectionId})) - await WellCompositeService.save(idWell, selectedSections) - - setSelectedWells(items) - setSelectedWellsKeys(keys) - }, - setShowParamsLoader, - `Не удалось сохранить изменения выбранных секций для композитной скважины "${idWell}"`, - 'Изменение выбранных секций скважины' - ) - }, [idWell, selectedWellsKeys]) - - const onParamButtonClick = useCallback(() => invokeWebApiWrapperAsync( - async () => { - setIsParamsModalVisible(true) - const params = await DrillParamsService.getCompositeAll(idWell) - setParams(params) - }, - setShowParamsLoader, - `Не удалось загрузить список режимов для скважины "${idWell}"`, - 'Получение списка режимов скважины' - ), [idWell]) - - const onParamsAddClick = useCallback(() => invokeWebApiWrapperAsync( - async () => { - await DrillParamsService.save(idWell, params) - setIsParamsModalVisible(false) - }, - setShowLoader, - `Не удалось добавить режимы в список скважины "${idWell}"`, - 'Добавление режима скважины' - ), [idWell, params]) - return ( <>
- + @@ -272,29 +236,6 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection - - setIsParamsModalVisible(false)} - width={1700} - footer={( - - - - )} - > - -
- - ) }) diff --git a/src/pages/WellOperations/WellDrillParams.jsx b/src/pages/WellOperations/WellDrillParams.jsx index 8db51b6..b113209 100755 --- a/src/pages/WellOperations/WellDrillParams.jsx +++ b/src/pages/WellOperations/WellDrillParams.jsx @@ -5,6 +5,7 @@ import { makeSelectColumn, makeActionHandler, makeNumericAvgRange, + makeNumericSorter, } from '@components/Table' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' @@ -14,15 +15,16 @@ import { arrayOrDefault } from '@utils' export const getColumns = async (idWell) => { let sectionTypes = await WellOperationService.getSectionTypes(idWell) - sectionTypes = Object.keys(sectionTypes).map((id) => ({ - label: sectionTypes[id], - value: id, + sectionTypes = Object.entries(sectionTypes).map(([id, value]) => ({ + label: value, + value: parseInt(id), })) return [ makeSelectColumn('Конструкция секции','idWellSectionType', sectionTypes, null, { editable: true, width: 160, + sorter: makeNumericSorter('idWellSectionType'), }), makeNumericAvgRange('Нагрузка, т', 'axialLoad', 1), makeNumericAvgRange('Давление, атм', 'pressure', 1), From 8107a4a3a5b202a77006a7c7a1cc42dbc240a3d7 Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Tue, 29 Mar 2022 17:04:14 +0500 Subject: [PATCH 08/49] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D1=91=D0=BD=20?= =?UTF-8?q?=D0=BB=D0=B8=D1=88=D0=B8=D0=B9=20=D1=8D=D0=BA=D0=B7=D0=B5=D0=BC?= =?UTF-8?q?=D0=BF=D0=BB=D1=8F=D1=80=20=D0=B0=D1=80=D1=85=D0=B8=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Archive/ArchiveColumn.jsx | 31 ----- src/pages/Archive/ArchiveDisplay.jsx | 66 ---------- src/pages/Archive/index.jsx | 185 --------------------------- 3 files changed, 282 deletions(-) delete mode 100755 src/pages/Archive/ArchiveColumn.jsx delete mode 100755 src/pages/Archive/ArchiveDisplay.jsx delete mode 100755 src/pages/Archive/index.jsx diff --git a/src/pages/Archive/ArchiveColumn.jsx b/src/pages/Archive/ArchiveColumn.jsx deleted file mode 100755 index 6f7ebfb..0000000 --- a/src/pages/Archive/ArchiveColumn.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import { memo, useMemo } from 'react' - -import { Grid, GridItem } from '@components/Grid' -import { Column } from '@components/charts/Column' - -export const ArchiveColumn = memo(({ lineGroup, data, interval, style, headerHeight, yStart }) => { - const lgws = useMemo(() => lineGroup.filter(cfg => !cfg.isShape), [lineGroup]) - const pv = useMemo(() => lgws.filter(line => line.showLabels).map(line => ({ - color: line.color, - label: line.label - })), [lgws]) - - return ( -
- - {pv?.map((v, idx) => ( - {v.label} - ))} - - -
- ) -}) - -export default ArchiveColumn diff --git a/src/pages/Archive/ArchiveDisplay.jsx b/src/pages/Archive/ArchiveDisplay.jsx deleted file mode 100755 index c4bae7e..0000000 --- a/src/pages/Archive/ArchiveDisplay.jsx +++ /dev/null @@ -1,66 +0,0 @@ -import { memo, useMemo } from 'react' - -import { Grid, GridItem } from '@components/Grid' - -import { paramsGroups } from '@pages/TelemetryView' -import { ArchiveColumn } from './ArchiveColumn' - -const interpolationSearch = (data, begin, end, accessor) => { - const fy = (i) => new Date(data[i]?.[accessor] ?? 0) - const fx = (y, b, e) => Math.round(b + (y - fy(b)) * (e - b) / (fy(e) - fy(b))) - const findIdx = (val, startIdx, c) => { - let x = startIdx - let endIdx = data.length - 1 - if(val < fy(startIdx)) - return startIdx - if(val > fy(endIdx)) - return endIdx - for(let i = 0; i < c; i++){ - x = fx(val, startIdx, endIdx) - if(fy(x) < val) - startIdx = x - else - endIdx = x - if ((startIdx === endIdx)||(fy(startIdx) === fy(endIdx))) - return x - } - return x - } - let x0 = findIdx(begin, 0, 5) - let x1 = findIdx(end, x0, 3) - return { start: x0, end: x1, count: x1 - x0 } -} - -export const cutData = (data, beginDate, endDate) => { - if (data?.length > 0) { - let { start, end } = interpolationSearch(data, beginDate, endDate, 'date') - if (start > 0) start-- - if (end + 1 < end.length) end++ - return data.slice(start, end) - } - return data -} - -export const ArchiveDisplay = memo(({data, startDate, interval, onWheel}) => { - const endDate = useMemo(() => new Date(+startDate + interval), [startDate, interval]) - const chartData = useMemo(() => cutData(data, startDate, endDate), [data, startDate, endDate]) - - return ( - - {paramsGroups.map((group, index) => ( - - - - ))} - - ) -}) - -export default ArchiveDisplay diff --git a/src/pages/Archive/index.jsx b/src/pages/Archive/index.jsx deleted file mode 100755 index f969709..0000000 --- a/src/pages/Archive/index.jsx +++ /dev/null @@ -1,185 +0,0 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import { useState, useEffect, memo, useCallback } from 'react' - -import { Flex } from '@components/Grid' -import LoaderPortal from '@components/LoaderPortal' -import { invokeWebApiWrapperAsync } from '@components/factory' -import { DatePickerWrapper, makeDateSorter } from '@components/Table' -import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker' -import { TelemetryDataSaubService } from '@api' - -import { normalizeData } from '@pages/TelemetryView' -import { ArchiveDisplay, cutData } from './ArchiveDisplay' - -const DATA_COUNT = 2048 // Колличество точек на подгрузку графика -const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков -const LOADING_TRIGGER = 0.5 -const WHEEL_SENSITIVITY = 1 / 530 - -const getLoadingInterval = (loaded, startDate, interval) => { - // Если данные загружены и дата не заходит за тригер дозагрузка не требуется - if ( - loaded && - +startDate - interval * LOADING_TRIGGER > loaded.start && - +startDate + interval * (LOADING_TRIGGER + 1) < loaded.end - ) - return { loadingStartDate: startDate, newLoaded: loaded, loadingInterval: 0 } - - let loadingStartDate = +startDate - interval * ADDITIVE_PAGES - let loadingEndDate = +startDate + interval * (ADDITIVE_PAGES + 1) - - const newLoaded = { - start: loadingStartDate, - end: loadingEndDate - } - - if (loaded) { - if (loadingStartDate >= loaded.start) - loadingStartDate = loaded.end - if (loadingEndDate <= loaded.end) - loadingEndDate = loaded.start - newLoaded.start = Math.min(loaded.start, loadingStartDate) - newLoaded.end = Math.max(loaded.end, loadingEndDate) - } - - const loadingInterval = Math.trunc((loadingEndDate - loadingStartDate) / 1000) - - return { - loadingStartDate: new Date(loadingStartDate), - newLoaded: { - start: new Date(newLoaded.start), - end: new Date(newLoaded.end) - }, - loadingInterval - } -} - -const range = (start, end) => { - const result = [] - for (let i = start; i < end; i++) - result.push(i) - return result -} - -export const Archive = memo(({ idWell }) => { - const [dataSaub, setDataSaub] = useState([]) - const [dateLimit, setDateLimit] = useState({ from: 0, to: new Date() }) - const [chartInterval, setChartInterval] = useState(parseInt(defaultPeriod) * 1000) - const [startDate, setStartDate] = useState(new Date(Date.now() - chartInterval)) - const [showLoader, setShowLoader] = useState(false) - const [loaded, setLoaded] = useState(null) - - const onGraphWheel = useCallback((e) => { - if (loaded && dateLimit.from && dateLimit.to) { - setStartDate((prevStartDate) => { - const offset = e.deltaY * chartInterval * WHEEL_SENSITIVITY - const nextStartDate = +prevStartDate + offset - const firstPossibleDate = Math.max(loaded.start, dateLimit.from) - const lastPossibleDate = Math.min(dateLimit.to, (loaded.end ?? Date.now())) - chartInterval - return new Date(Math.max(firstPossibleDate, Math.min(nextStartDate, lastPossibleDate))) - }) - } - }, [loaded, dateLimit, chartInterval]) - - const isDateDisabled = useCallback((date) => { - if (!date) return false - const dt = new Date(date).setHours(0, 0, 0, 0) - return dt < dateLimit.from || dt > +dateLimit.to - chartInterval - }, [dateLimit]) - - const isDateTimeDisabled = useCallback((date) => ({ - disabledHours: () => range(0, 24).filter(h => { - if (!date) return false - const dt = +new Date(date).setHours(h) - return dt < dateLimit.from || dt > +dateLimit.to - chartInterval - }), - disabledMinutes: () => range(0, 60).filter(m => { - if (!date) return false - const dt = +new Date(date).setMinutes(m) - return dt < dateLimit.from || dt > +dateLimit.to - chartInterval - }), - disabledSeconds: () => range(0, 60).filter(s => { - if (!date) return false - const dt = +new Date(date).setSeconds(s) - return dt < dateLimit.from || dt > +dateLimit.to - chartInterval - }) - }), [dateLimit]) - - useEffect(() => invokeWebApiWrapperAsync( - async () => { - let dates = await TelemetryDataSaubService.getDataDatesRange(idWell) - dates = { - from: new Date(dates?.from ?? 0), - to: new Date(dates?.to ?? 0) - } - setDateLimit(dates) - setStartDate(new Date(Math.max(dates.from, +dates.to - chartInterval))) - }, - setShowLoader, - `Не удалось загрузить диапозон телеметрии для скважины "${idWell}"`, - 'Загрузка диапозона телеметрии' - ), []) - - useEffect(() => { - setStartDate((startDate) => new Date(Math.min(Date.now() - chartInterval, startDate))) - setDataSaub([]) - }, [chartInterval]) - - useEffect(() => { - if (showLoader) return - const { loadingStartDate, loadingInterval, newLoaded } = getLoadingInterval(loaded, startDate, chartInterval) - if (loadingInterval <= 0) return - invokeWebApiWrapperAsync( - async () => { - const data = await TelemetryDataSaubService.getData(idWell, loadingStartDate.toISOString(), loadingInterval, DATA_COUNT) - - const loadedStartDate = new Date(Math.max(+newLoaded.start, +startDate - chartInterval * ADDITIVE_PAGES)) - const loadedEndDate = new Date(Math.min(+newLoaded.end, +startDate + chartInterval * (ADDITIVE_PAGES + 1))) - setLoaded({ start: loadedStartDate, end: loadedEndDate }) - - if (data) { - data.forEach(elm => elm.date = new Date(elm.date)) - setDataSaub((prevDataSaub) => { - const newData = [...prevDataSaub, ...normalizeData(data)] - newData.sort(makeDateSorter('date')) - return cutData(newData, loadedStartDate, loadedEndDate) - }) - } - - }, - setShowLoader, - `Не удалось загрузить данные по скважине "${idWell}" c ${startDate.toISOString()} по ${new Date(+startDate + chartInterval).toISOString()}`, - 'Загрузка телеметрий в диапозоне' - ) - }, [idWell, chartInterval, loaded, startDate]) - - return ( - <> - -
- Начальная дата:  - setStartDate(new Date(startDate))} - /> -
-
- Период:  - setChartInterval(val * 1000)} /> -
-
- - - - - ) -}) - -export default Archive From b94561aa62c00fcecfcf72ba461f3a248c669eb1 Mon Sep 17 00:00:00 2001 From: avsirotkin Date: Tue, 5 Apr 2022 10:56:30 +0500 Subject: [PATCH 09/49] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=86=D0=B5=20=D0=B2=D1=85=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Login.jsx | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index ff53576..239cf08 100755 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -32,29 +32,31 @@ export const Login = memo(() => { ), [history, location]) return ( - +
- -
- - } /> - - - } /> - - -
- + + + + + } /> + + + } /> + + +
+ +
+
+
+ Отправить заявку на регистрацию
- -
- Отправить заявку на регистрацию -
- -
+ + +
- +
) }) From fcb264b1228b2b50c25a0f89c1c1bc644d721469 Mon Sep 17 00:00:00 2001 From: avsirotkin Date: Tue, 5 Apr 2022 11:25:57 +0500 Subject: [PATCH 10/49] =?UTF-8?q?=D0=9A=D0=BD=D0=BE=D0=BF=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D1=80=D0=B8=20=D0=BE=D1=82=D1=81=D1=83?= =?UTF-8?q?=D1=82=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D1=83=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=B2=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Telemetry/TelemetryView/Setpoints/SetpointSender.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx index 0073b9d..12006ea 100755 --- a/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx +++ b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx @@ -37,20 +37,19 @@ export const SetpointSender = memo(({ idWell, onClose, visible, setpointNames }) const onAdd = useCallback(async (sp) => setSetpoints((prevSp) => { sp.key = Date.now() - prevSp.push(sp) - return prevSp + return [...prevSp, sp] }), []) const onEdit = useCallback(async (sp) => setSetpoints((prevSp) => { const idx = prevSp.findIndex((val) => val.key === sp.key) prevSp[idx] = sp - return prevSp + return [...prevSp] }), []) const onDelete = useCallback(async (sp) => setSetpoints((prevSp) => { const idx = prevSp.findIndex((val) => val.key === sp.key) prevSp.splice(idx, 1) - return prevSp + return [...prevSp] }), []) const onModalOk = useCallback(() => invokeWebApiWrapperAsync( @@ -81,6 +80,7 @@ export const SetpointSender = memo(({ idWell, onClose, visible, setpointNames }) onCancel={onClose} onOk={onModalOk} okText={'Отправить'} + okButtonProps={{ disabled: setpoints.length <= 0 }} > From d37ceeb68feae6c05a83c96f8ae8417ead3e3460 Mon Sep 17 00:00:00 2001 From: goodmice Date: Tue, 12 Apr 2022 10:22:31 +0500 Subject: [PATCH 11/49] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BE=D1=82=D1=81=D1=83=D1=82=D1=81?= =?UTF-8?q?=D1=82=D0=B2=D0=B8=D0=B5=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=81=D0=BB=D0=B8=D1=8F=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D0=B5=D0=BC=D0=B5=D1=82=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx b/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx index 31991d9..c97333e 100755 --- a/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx +++ b/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx @@ -59,14 +59,13 @@ export const TelemetryMerger = memo(() => { const mergeTelemetry = useCallback(() => invokeWebApiWrapperAsync( async () => { - await new Promise(res => setTimeout(res, 1000)) - /// await AdminTelemetryService.mergeTelemetries(secondary.id, primary.id) + await AdminTelemetryService.mergeTelemetries(secondary.id, primary.id) await updateTelemetry() }, setIsMerging, 'Не удалось объединить телеметрии', 'Объединение телеметрий', - ), [updateTelemetry]) + ), [updateTelemetry, secondary.id, primary.id]) useEffect(() => updateTelemetry(), [updateTelemetry]) @@ -76,7 +75,6 @@ export const TelemetryMerger = memo(() => { const secondaryId = parseInt(query.get('secondary') ?? null) const primary = isNaN(primaryId) ? null : telemetry.find((t) => t.id === primaryId) const secondary = isNaN(secondaryId) ? null : telemetry.find((t) => t.id === secondaryId) - console.log([primary, secondary]) setPrimary(primary) setSecondary(secondary) }, [location, telemetry]) From dd781e41d32048dcba1d5d5e653e9f18a22c95d7 Mon Sep 17 00:00:00 2001 From: goodmice Date: Tue, 12 Apr 2022 10:23:03 +0500 Subject: [PATCH 12/49] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D1=81=D0=BD=D0=BE=D1=81=D0=BA=D0=B0=20"?= =?UTF-8?q?=D0=A2=D0=B0=D0=BB=D0=B5=D0=B2=D1=8B=D0=B9=20=D0=BA=D0=B0=D0=BD?= =?UTF-8?q?=D0=B0=D1=82"=20=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=86=D1=83=20=D0=BC=D0=BE=D0=BD=D0=B8=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/views/WirelineView.tsx | 50 +++++++++++++++++++ src/components/views/index.ts | 4 +- .../TelemetryView/WirelineRunOut.jsx | 35 +++++++++++++ src/pages/Telemetry/TelemetryView/index.jsx | 2 + 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/components/views/WirelineView.tsx create mode 100644 src/pages/Telemetry/TelemetryView/WirelineRunOut.jsx diff --git a/src/components/views/WirelineView.tsx b/src/components/views/WirelineView.tsx new file mode 100644 index 0000000..5ea9bd0 --- /dev/null +++ b/src/components/views/WirelineView.tsx @@ -0,0 +1,50 @@ +import { Fragment, memo } from 'react' +import { Button, ButtonProps, Tooltip, TooltipProps } from 'antd' + +import { TelemetryWirelineRunOutDto } from '@api' +import { Grid, GridItem } from '../Grid' +import { formatDate } from '@utils' + +const lables: Record any, +}> = { + dateTime: { label: 'Данные актуальны на', formatter: formatDate }, + hauling: 'Наработка талевого каната с момента перетяжки каната, т*км', + haulingWarnSp: 'Наработка талевого каната до сигнализации о необходимости перетяжки, т*км', + replace: 'Наработка талевого каната с момента замены каната, т*км', + replaceWarnSp: 'Наработка талевого каната до сигнализации о необходимости замены, т*км', +} + +export type WirelineViewProps = TooltipProps & { + wireline?: TelemetryWirelineRunOutDto + buttonProps?: ButtonProps +} + +export const WirelineView = memo(({ wireline, buttonProps, ...other }) => ( + + {(Object.keys(wireline) as Array).map((key, i) => { + const label = lables[key] + return typeof label === 'string' ? ( + + {label}: + {wireline[key]} + + ) : ( + + {label?.label ?? key}: + {label?.formatter?.(wireline?.[key]) ?? wireline?.[key]} + + ) + })} + + ) : 'Нет данных'} + > + + +)) + +export default WirelineView diff --git a/src/components/views/index.ts b/src/components/views/index.ts index b535f0e..2c5e1b0 100755 --- a/src/components/views/index.ts +++ b/src/components/views/index.ts @@ -3,9 +3,11 @@ export type { TelemetryViewProps } from './TelemetryView' export type { CompanyViewProps } from './CompanyView' export type { RoleViewProps } from './RoleView' export type { UserViewProps } from './UserView' +export type { WirelineViewProps } from './WirelineView' export { PermissionView } from './PermissionView' export { TelemetryView, getTelemetryLabel } from './TelemetryView' export { CompanyView } from './CompanyView' export { RoleView } from './RoleView' -export { UserView } from './UserView' \ No newline at end of file +export { UserView } from './UserView' +export { WirelineView } from './WirelineView' diff --git a/src/pages/Telemetry/TelemetryView/WirelineRunOut.jsx b/src/pages/Telemetry/TelemetryView/WirelineRunOut.jsx new file mode 100644 index 0000000..81b31af --- /dev/null +++ b/src/pages/Telemetry/TelemetryView/WirelineRunOut.jsx @@ -0,0 +1,35 @@ +import { memo, useCallback, useEffect, useState } from 'react' + +import { TelemetryWirelineRunOutService } from '@api' +import { invokeWebApiWrapperAsync } from '@components/factory' +import { WirelineView } from '@components/views' + +export const WirelineRunOut = memo(({ idWell }) => { + const [twro, setTwro] = useState({}) + const [isLoading, setIsLoading] = useState(false) + + const update = useCallback(() => invokeWebApiWrapperAsync( + async () => { + const twro = await TelemetryWirelineRunOutService.getData(idWell) + setTwro(twro) + }, + setIsLoading, + 'Не удалось получить данные по талевому канату' + ), [idWell]) + + const onTooltipVisibleChanged = useCallback((visible) => { + if (visible) update() + }, [update]) + + useEffect(update, [update]) + + return ( + + ) +}) + +export default WirelineRunOut diff --git a/src/pages/Telemetry/TelemetryView/index.jsx b/src/pages/Telemetry/TelemetryView/index.jsx index 3a9f28e..87370e6 100755 --- a/src/pages/Telemetry/TelemetryView/index.jsx +++ b/src/pages/Telemetry/TelemetryView/index.jsx @@ -29,6 +29,7 @@ import SpinPicEnabled from '@images/SpinEnabled.png' import SpinPicDisabled from '@images/SpinDisabled.png' import '@styles/message.css' +import WirelineRunOut from './WirelineRunOut' const { Option } = Select @@ -393,6 +394,7 @@ export default function TelemetryView({ idWell }) {
  + {'TorqueMaster'} {'SpinMaster'}

MSE

From 0e519ea03fa661140a5d4aa68ae191fa9b98e9c2 Mon Sep 17 00:00:00 2001 From: goodmice Date: Thu, 14 Apr 2022 11:06:07 +0500 Subject: [PATCH 13/49] =?UTF-8?q?=D0=9C=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20si?= =?UTF-8?q?gnalr=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BF=D0=B8=D1=81=D0=B0=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D1=81=20?= =?UTF-8?q?=D0=BC=D0=BD=D0=BE=D0=B6=D0=B5=D1=81=D1=82=D0=B2=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=87=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=20=D0=B8=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Report/index.jsx | 10 +- .../TelemetryView/ActiveMessagesOnline.jsx | 5 +- src/pages/Telemetry/TelemetryView/index.jsx | 12 +-- src/services/signalr/index.ts | 101 +++++++++--------- 4 files changed, 66 insertions(+), 62 deletions(-) diff --git a/src/pages/Report/index.jsx b/src/pages/Report/index.jsx index ce8a0d4..866ecdf 100755 --- a/src/pages/Report/index.jsx +++ b/src/pages/Report/index.jsx @@ -69,12 +69,10 @@ export const Report = memo(({ idWell }) => { } } - const unSubscribeReportHub = Subscribe( - 'hubs/reports', - 'GetReportProgress', - `Report_${taskId}`, - handleReportProgress - ) + const unSubscribeReportHub = Subscribe('hubs/reports', `Report_${taskId}`, { + methodName: 'GetReportProgress', + handler: handleReportProgress, + }) }, setShowLoader, `Не удалось создать отчет по скважине (${idWell}) c diff --git a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx index db5c547..b2fd566 100755 --- a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx +++ b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx @@ -29,7 +29,10 @@ export const ActiveMessagesOnline = memo(({ idWell }) => { `Не удалось загрузить сообщения по скважине "${idWell}"`, 'Получение списка сообщений' ) - return Subscribe('hubs/telemetry','ReceiveMessages', `well_${idWell}`, handleReceiveMessages) + return Subscribe('hubs/telemetry',`well_${idWell}`, { + methodName: 'ReceiveMessages', + handler: handleReceiveMessages, + }) }, [idWell, handleReceiveMessages]) return ( diff --git a/src/pages/Telemetry/TelemetryView/index.jsx b/src/pages/Telemetry/TelemetryView/index.jsx index 87370e6..c11ae6f 100755 --- a/src/pages/Telemetry/TelemetryView/index.jsx +++ b/src/pages/Telemetry/TelemetryView/index.jsx @@ -323,8 +323,11 @@ export default function TelemetryView({ idWell }) { const handleDataSpin = useCallback((data) => data && setDataSpin(data), []) useEffect(() => { - const unsubscribeSaub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleDataSaub) - const unsubscribeSpin = Subscribe('hubs/telemetry', 'ReceiveDataSpin', `well_${idWell}`, handleDataSpin) + const unsubscribe = Subscribe( + 'hubs/telemetry', `well_${idWell}`, + { methodName: 'ReceiveDataSaub', handler: handleDataSaub }, + { methodName: 'ReceiveDataSpin', handler: handleDataSpin } + ) invokeWebApiWrapperAsync( async () => { const flowChart = await DrillFlowChartService.get(idWell) @@ -338,10 +341,7 @@ export default function TelemetryView({ idWell }) { `Не удалось получить данные по скважине "${idWell}"`, 'Получение данных по скважине' ) - return () => { - unsubscribeSaub() - unsubscribeSpin() - } + return unsubscribe }, [idWell, chartInterval, handleDataSpin, handleDataSaub]) useEffect(() => invokeWebApiWrapperAsync( diff --git a/src/services/signalr/index.ts b/src/services/signalr/index.ts index a87a5e3..b55982a 100755 --- a/src/services/signalr/index.ts +++ b/src/services/signalr/index.ts @@ -1,25 +1,22 @@ -import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr'; +import { getUserToken } from '@asb/utils/storage' +import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr' // SignalR js api: //https://docs.microsoft.com/ru-ru/javascript/api/@aspnet/signalr/?view=signalr-js-latest const ConnectionOptions = { - accessTokenFactory: () => localStorage['token'], - transport:1, + accessTokenFactory: () => getUserToken() ?? '', + transport: 1, } -type ConnectionsDict = { - [route: string]: HubConnection; -}; +type ConnectionsDict = Record //var baseUrl = `http://192.168.1.70:5000` -var baseUrl = process.env.NODE_ENV === 'development' - ? require('../../../package.json').proxy - :'' +const baseUrl = process.env.NODE_ENV === 'development' ? require('../../../package.json').proxy : '' const Connections: ConnectionsDict = { 'hubs/telemetry': new HubConnectionBuilder() - .withUrl(`${baseUrl}/hubs/telemetry`, ConnectionOptions)// + .withUrl(`${baseUrl}/hubs/telemetry`, ConnectionOptions) .withAutomaticReconnect() .build(), @@ -31,57 +28,67 @@ const Connections: ConnectionsDict = { let connectionPromise: Promise -const GetConnectionAsync = async (hubUrl: string) => { +export const GetConnectionAsync = async (hubUrl: string): Promise => { + const Connection: HubConnection = Connections[hubUrl] - let Connection: HubConnection = Connections[hubUrl]; + if (Connection.state === HubConnectionState.Disconnected) + connectionPromise = Connection.start() - if (Connection.state === HubConnectionState.Disconnected) - connectionPromise = Connection.start() - - if (Connection.state !== HubConnectionState.Connected) - await connectionPromise - - return Connection - } + if (Connection.state !== HubConnectionState.Connected) + await connectionPromise -type handlerFunction = (...args: any[]) => void; + return Connection +} -type cleanFunction = (...args: any[]) => void; +type handlerFunction = (...args: any[]) => void +type cleanFunction = (...args: any[]) => void + +export type SubscribeGroup = { + methodName: string, + handler: handlerFunction, +} const MakeUnsubscribeFunction = ( connection: HubConnection, - methodName: string, - groupName: (string|null)):cleanFunction => { - return async() => { - if(connection.state === HubConnectionState.Connected) - { - if(groupName) - await connection.send('RemoveFromGroup', groupName) - connection.off(methodName) + groupName: string[] | string | null, + ...groups: SubscribeGroup[] +): cleanFunction => async() => { + if(connection.state === HubConnectionState.Connected) { + if (groupName) { + if (Array.isArray(groupName)) { + for (const g of groupName) + await connection.send('RemoveFromGroup', g) + } else await connection.send('RemoveFromGroup', groupName) } - connection.stop() + for (const g of groups) + connection.off(g.methodName) } + connection.stop() } /** Subscribe on some SignalR method (topic). - * @example useEffect(() => Subscribe('methodName', `${id}`, handleNewData), [id]); - * @param {string} methodName name of the method - * @param {string} groupName name of the group - * @param {handlerFunction} handler fires when got new data by subscription + * @example useEffect(() => SubscribeMultiple('/url/', `${id}`, { methodName: 'methodName', handler: handleNewData }), [id]); + * @param {string[] | string} groupName name of the group(-s) + * @param {SubscribeGroup} groups groups obtains method name and handler which fires when got new data by subscription * @return {cleanFunction} unsubscribe function for useEffect cleanup. */ -const Subscribe = ( +export const Subscribe = ( hubUrl: string, - methodName: string, - groupName: string = '', - handler: handlerFunction ):cleanFunction=>{ + groupName: string[] | string = '', + ...groups: SubscribeGroup[] +): cleanFunction => { GetConnectionAsync(hubUrl).then(async connection => { - if(groupName) - await connection.send('AddToGroup', groupName) - connection.on(methodName, handler) + if (groupName) { + if (Array.isArray(groupName)) { + for (const g of groupName) + await connection.send('AddToGroup', g) + } else await connection.send('AddToGroup', groupName) + } + for (const g of groups) + connection.on(g.methodName, g.handler) }) - return MakeUnsubscribeFunction(Connections[hubUrl],methodName,groupName) + return MakeUnsubscribeFunction(Connections[hubUrl], groupName, ...groups) } /** Invokes some SignalR method. @@ -89,13 +96,9 @@ const Subscribe = ( * @param {any[]} args methods arguments * @return {Promise} Promise */ -const InvokeAsync = async (methodName:string, hubUrl: string, ...args:any[]) => { +export const InvokeAsync = async (methodName: string, hubUrl: string, ...args: any[]) => { await GetConnectionAsync(hubUrl) await Connections[hubUrl].send(methodName, ...args) } -export { - Subscribe, - InvokeAsync, - GetConnectionAsync, -} \ No newline at end of file +export default Subscribe From 7c3d46893a3daf58d37b203c63dc9f7988697805 Mon Sep 17 00:00:00 2001 From: goodmice Date: Fri, 15 Apr 2022 17:17:34 +0500 Subject: [PATCH 14/49] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=B4=D0=B0=D1=88=D0=B1=D0=BE=D1=80=D0=B4=20?= =?UTF-8?q?=D1=81=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=BE=D0=BC=20=D0=BF?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82=D1=80=D0=BE=D0=B2=20=D0=9D?= =?UTF-8?q?=D0=9D=D0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/widgets/BaseWidget.tsx | 67 +++++ .../widgets/WidgetSettingsWindow.tsx | 65 +++++ src/components/widgets/index.ts | 5 + .../Telemetry/DashboardNNB/AddGroupWindow.jsx | 18 ++ .../DashboardNNB/AddWidgetWindow.jsx | 52 ++++ src/pages/Telemetry/DashboardNNB/index.jsx | 255 ++++++++++++++++++ src/pages/Telemetry/index.jsx | 6 + src/styles/dashboard_nnb.less | 29 ++ src/styles/widgets/base.less | 56 ++++ src/utils/index.ts | 7 +- src/utils/storage.ts | 56 ++-- 11 files changed, 591 insertions(+), 25 deletions(-) create mode 100644 src/components/widgets/BaseWidget.tsx create mode 100644 src/components/widgets/WidgetSettingsWindow.tsx create mode 100644 src/components/widgets/index.ts create mode 100644 src/pages/Telemetry/DashboardNNB/AddGroupWindow.jsx create mode 100644 src/pages/Telemetry/DashboardNNB/AddWidgetWindow.jsx create mode 100644 src/pages/Telemetry/DashboardNNB/index.jsx create mode 100644 src/styles/dashboard_nnb.less create mode 100644 src/styles/widgets/base.less diff --git a/src/components/widgets/BaseWidget.tsx b/src/components/widgets/BaseWidget.tsx new file mode 100644 index 0000000..c17ff10 --- /dev/null +++ b/src/components/widgets/BaseWidget.tsx @@ -0,0 +1,67 @@ +import { Button } from 'antd' +import { memo, ReactNode, useMemo } from 'react' +import { CloseOutlined, SettingOutlined } from '@ant-design/icons' + +import '@styles/widgets/base.less' + +export type WidgetSettings = { + id?: number, + unit?: string, + label?: string, + formatter?: ((v: T) => ReactNode) | null, + defaultValue?: ReactNode, + + labelColor?: string, + valueColor?: string, + backgroundColor?: string, + unitColor?: string, +} + +export const defaultSettings: WidgetSettings = { + unit: '----', + label: 'Виджет', + formatter: v => isNaN(v) ? v : parseFloat(v).toFixed(2), + + labelColor: '#000000', + valueColor: '#000000', + backgroundColor: '#f6f6f6', + unitColor: '#a0a0a0', +} + +export type BaseWidgetProps = WidgetSettings & { + value: T, + onRemove: (settings: WidgetSettings) => void, + onEdit: (settings: WidgetSettings) => void, +} + +export const BaseWidget = memo(({ value, onRemove, onEdit, ...settings }) => { + const sets = useMemo(() => ({ ...defaultSettings, ...settings }), [settings]) + + return ( +
+
+
+
+
+ {(sets.formatter === null ? value : sets.formatter?.(value)) ?? sets.defaultValue ?? '----'} +
+
{sets.unit}
+ + ) +}) + +export default BaseWidget diff --git a/src/components/widgets/WidgetSettingsWindow.tsx b/src/components/widgets/WidgetSettingsWindow.tsx new file mode 100644 index 0000000..16b70be --- /dev/null +++ b/src/components/widgets/WidgetSettingsWindow.tsx @@ -0,0 +1,65 @@ +import { memo, useEffect } from 'react' +import { Form, Input, Modal, ModalProps } from 'antd' + +import { WidgetSettings } from './BaseWidget' + +export type WidgetSettingsWindowProps = ModalProps & { + settings: WidgetSettings + onEdit: (settings: WidgetSettings) => void +} + +const { Item } = Form + +export const WidgetSettingsWindow = memo(({ settings, onEdit, ...other }) => { + const [form] = Form.useForm() + + useEffect(() => { + if (settings) form.setFieldsValue(settings) + }, [form, settings]) + + return ( + + Настройка виджета {settings?.label ? `"${settings?.label}"` : ''} + (id: {settings?.id}) + + )} + onOk={form.submit} + getContainer={false} + > +
+ + + + + + + + + + + + + + + + + + + + +
+ ) +}) + +export default WidgetSettingsWindow diff --git a/src/components/widgets/index.ts b/src/components/widgets/index.ts new file mode 100644 index 0000000..c73bcc7 --- /dev/null +++ b/src/components/widgets/index.ts @@ -0,0 +1,5 @@ +export { WidgetSettingsWindow } from './WidgetSettingsWindow' +export { BaseWidget } from './BaseWidget' + +export type { WidgetSettingsWindowProps } from './WidgetSettingsWindow' +export type { WidgetSettings, BaseWidgetProps } from './BaseWidget' diff --git a/src/pages/Telemetry/DashboardNNB/AddGroupWindow.jsx b/src/pages/Telemetry/DashboardNNB/AddGroupWindow.jsx new file mode 100644 index 0000000..96ce88e --- /dev/null +++ b/src/pages/Telemetry/DashboardNNB/AddGroupWindow.jsx @@ -0,0 +1,18 @@ +import { PlusOutlined } from '@ant-design/icons' +import { Form, Input } from 'antd' +import { memo } from 'react' + +import Poprompt from '@components/selectors/Poprompt' + +const addGroupRules = [{ required: true, message: 'Пожалуйста, введите название группы' }] +const addGroupButtonProps = { type: 'link', className: 'add_group', icon: } + +export const AddGroupWindow = memo(({ addGroup, initialValue = 'Новая группа' }) => ( + + + + + +)) + +export default AddGroupWindow diff --git a/src/pages/Telemetry/DashboardNNB/AddWidgetWindow.jsx b/src/pages/Telemetry/DashboardNNB/AddWidgetWindow.jsx new file mode 100644 index 0000000..1cd15cd --- /dev/null +++ b/src/pages/Telemetry/DashboardNNB/AddWidgetWindow.jsx @@ -0,0 +1,52 @@ +import { PlusOutlined } from '@ant-design/icons' +import { Form, Select } from 'antd' +import { memo, useCallback, useMemo } from 'react' + +import Poprompt from '@components/selectors/Poprompt' + +export const createWidgetId = (witsRecord, dt = false) => `${witsRecord.recordId}_${witsRecord.itemId}` + (dt ? `_${Date.now()}` : '') + +export const makeWidgetFromWits = (witsRecord) => ({ + id: createWidgetId(witsRecord, true), + witsId: witsRecord.longMnemonic.toLowerCase(), + recordId: witsRecord.recordId, + unit: witsRecord.metricUnits, + label: witsRecord.longMnemonic, +}) + +const addWidgetRules = [{ required: true, message: 'Пожалуйста, выберите виджет' }] +const addWidgetButtonProps = { type: 'link', className: 'add_group', icon: } + +export const AddWidgetWindow = memo(({ witsInfo, onAdded }) => { + const options = useMemo(() => witsInfo?.map((witsRecord) => ({ + label: `Record #${witsRecord.recordId}: ${witsRecord.longMnemonic}`, + value: createWidgetId(witsRecord), + })) ?? [], [witsInfo]) + + const onFormFinish = useCallback((value) => { + if (!value?.widget) return + const record = witsInfo.find((witsRecord) => createWidgetId(witsRecord) === value.widget) + if (record) + onAdded?.(makeWidgetFromWits(record)) + }, [onAdded, witsInfo]) + + return ( + + + ) }) diff --git a/src/components/Table/DatePickerWrapper.tsx b/src/components/Table/DatePickerWrapper.tsx index a453fbc..9fa14d1 100755 --- a/src/components/Table/DatePickerWrapper.tsx +++ b/src/components/Table/DatePickerWrapper.tsx @@ -18,7 +18,7 @@ export const DatePickerWrapper = memo(({ value, onChange format={defaultFormat} defaultValue={moment()} onChange={(date) => onChange?.(date)} - value={isUTC ? moment.utc(value).local() : moment(value)} + value={value && (isUTC ? moment.utc(value).local() : moment(value))} {...other} /> )) From e9eaa96388555c1ef0e7ed1b4f3daa9336e689b7 Mon Sep 17 00:00:00 2001 From: goodmice Date: Mon, 18 Apr 2022 17:36:57 +0500 Subject: [PATCH 19/49] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2=D0=B0=D1=8F?= =?UTF-8?q?=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8E=20=D1=81=D1=83=D1=82?= =?UTF-8?q?=D0=BE=D1=87=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=80=D0=B0=D0=BF=D0=BE?= =?UTF-8?q?=D1=80=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reports/DailyReport/ReportEditor.jsx | 155 ++++++++++++++++++ src/pages/Reports/DailyReport/index.jsx | 97 +++++++++++ .../DiagramReport}/ReportCreationNotify.jsx | 0 .../DiagramReport}/Reports.jsx | 4 +- .../DiagramReport}/index.jsx | 10 +- src/pages/Reports/index.jsx | 44 +++++ src/pages/Well.jsx | 8 +- src/utils/permissions.ts | 5 +- 8 files changed, 311 insertions(+), 12 deletions(-) create mode 100644 src/pages/Reports/DailyReport/ReportEditor.jsx create mode 100644 src/pages/Reports/DailyReport/index.jsx rename src/pages/{Report => Reports/DiagramReport}/ReportCreationNotify.jsx (100%) mode change 100755 => 100644 rename src/pages/{Report => Reports/DiagramReport}/Reports.jsx (100%) mode change 100755 => 100644 rename src/pages/{Report => Reports/DiagramReport}/index.jsx (97%) mode change 100755 => 100644 create mode 100644 src/pages/Reports/index.jsx diff --git a/src/pages/Reports/DailyReport/ReportEditor.jsx b/src/pages/Reports/DailyReport/ReportEditor.jsx new file mode 100644 index 0000000..383df80 --- /dev/null +++ b/src/pages/Reports/DailyReport/ReportEditor.jsx @@ -0,0 +1,155 @@ +import { useForm } from 'antd/lib/form/Form' +import { ConfigProvider, Descriptions, Divider, Form, Input, InputNumber, Modal, Select, Space, Table, Tag } from 'antd' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' + +import LoaderPortal from '@components/LoaderPortal' +import { invokeWebApiWrapperAsync } from '@components/factory' +import { DatePickerWrapper, makeColumn, makeGroupColumn } from '@components/Table' +import { formatDate } from '@utils' + +const { Item } = Form +const { Summary } = Table + +const table1Columns = [ + makeGroupColumn('Отчётный период', [ + makeColumn('От (дата, время)', 'dateStart', { width: 200, render: (date) => formatDate(date) ?? '---' }), + ]), + makeGroupColumn('Забой за отчётный период, м', [ + makeColumn('От', 'depthStart', { width: 200, render: () => ( + + + + )}), + makeColumn('До', 'depthEnd', { width: 200, render: () => ( + + + + )}), + ]) +] + +const table2Columns = [ + makeColumn('Работа модулей САУБ', 'label', { width: 500 }), + makeColumn('Часов:', 'hours', { width: 200, render: (data) => ( + + + + )}), + makeColumn('Метров:', 'meters', { width: 200, render: (data) => ( + + + + )}), +] + +const table2Data = [ + { label: 'АПД (автоматическая подача долота), ч/м:', hours: 'workTimeSaub', meters: 'drilledMetersSaub' }, + { label: 'Спин Мастер (осцилляция), ч/м:', hours: 'workTimeSpinMaster', meters: 'drilledMetersSpinMaster' }, + { label: 'Торк Мастер (демпфирование), ч/м:', hours: 'workTimeTorkMaster', meters: 'drilledMetersTorkMaster' }, +] + +const table2Summary = () => ( + + МСЕ, колличество запусков, раз: + + + + + + +) + +export const ReportEditor = memo(({ visible, data, onDone, onCancel }) => { + const [form] = useForm() + const [isInvalid, setIsInvalid] = useState(false) + const [isLoading, setIsLoading] = useState(false) + + useEffect(() => form.setFieldsValue(data), [data]) + + const onFormChange = useCallback(async () => await form.validateFields() + .then(() => setIsInvalid(false)) + .catch(() => setIsInvalid(true)) + , [form]) + + const onFormFinish = useCallback((data) => invokeWebApiWrapperAsync( + async () => { + onDone?.(data) + }, + setIsLoading, + 'Не удалось сохранить суточный рапорт', + 'Сохранение суточного рапорта', + ), [onDone]) + + const table1Data = useMemo(() => [{ dateStart: form.getFieldValue('reportDate') }], [form]) + + return ( + + +
+ + + + +

Суточная сводка бурения скважины № {data?.wellName} куст № {data?.clusterName}

+ + +
+ + + +
+ + + + + + + + + + + + + + + + ) +}) + +export default ReportEditor diff --git a/src/pages/Reports/DailyReport/index.jsx b/src/pages/Reports/DailyReport/index.jsx new file mode 100644 index 0000000..c67a3be --- /dev/null +++ b/src/pages/Reports/DailyReport/index.jsx @@ -0,0 +1,97 @@ +import moment from 'moment' +import { Button } from 'antd' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import { FileExcelOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons' + +import LoaderPortal from '@components/LoaderPortal' +import DateRangeWrapper from '@components/Table/DateRangeWrapper' +import { Table, makeDateColumn, makeColumn } from '@components/Table' +import { download, invokeWebApiWrapperAsync } from '@components/factory' +import { arrayOrDefault } from '@utils' + +import ReportEditor from './ReportEditor' + +export const DailyReport = memo(({ idWell }) => { + const [data, setData] = useState([]) + const [isLoading, setIsLoading] = useState(false) + const [searchDate, setSearchDate] = useState(null) + const [selectedReport, setSelectedReport] = useState(null) + const [isEditorVisible, setIsEditorVisible] = useState(true) + + useEffect(() => invokeWebApiWrapperAsync( + async () => { + const data = [{ date: '2022-10-01' }] // arrayOrDefault(await DailyreportService.getData(idWell)) + setData(data) + }, + setIsLoading, + 'Не удалось загрузить список суточных рапортов', + 'Получение списка суточных рапортов', + ), [idWell]) + + const columns = useMemo(() => [ + makeDateColumn('Дата', 'date', undefined, undefined, { width: 300 }), + makeColumn('', '', { width: 200, render: (_, report, idx) => ( + <> + + + + )}), + ], []) + + const filteredData = useMemo(() => { + if (!searchDate) return data + return data.filter((row) => moment(row.date).isBetween(...searchDate)) + }, [data, searchDate]) + + return ( + <> + +
+
+
+
Диапозон дат отчёта
+ +
+
+
+
+
+
+ + setIsEditorVisible(false)} + /> + + ) +}) + +export default DailyReport diff --git a/src/pages/Report/ReportCreationNotify.jsx b/src/pages/Reports/DiagramReport/ReportCreationNotify.jsx old mode 100755 new mode 100644 similarity index 100% rename from src/pages/Report/ReportCreationNotify.jsx rename to src/pages/Reports/DiagramReport/ReportCreationNotify.jsx diff --git a/src/pages/Report/Reports.jsx b/src/pages/Reports/DiagramReport/Reports.jsx old mode 100755 new mode 100644 similarity index 100% rename from src/pages/Report/Reports.jsx rename to src/pages/Reports/DiagramReport/Reports.jsx index cf44431..71db9e9 --- a/src/pages/Report/Reports.jsx +++ b/src/pages/Reports/DiagramReport/Reports.jsx @@ -2,11 +2,11 @@ import { Button, Tooltip } from 'antd' import { useState, useEffect, memo } from 'react' import { FilePdfOutlined, FileTextOutlined } from '@ant-design/icons' -import { ReportService } from '@api' -import { formatDate, periodToString } from '@utils' import LoaderPortal from '@components/LoaderPortal' import { Table, makeDateSorter, makeNumericSorter } from '@components/Table' import { invokeWebApiWrapperAsync, downloadFile } from '@components/factory' +import { formatDate, periodToString } from '@utils' +import { ReportService } from '@api' const imgPaths = { '.pdf': , diff --git a/src/pages/Report/index.jsx b/src/pages/Reports/DiagramReport/index.jsx old mode 100755 new mode 100644 similarity index 97% rename from src/pages/Report/index.jsx rename to src/pages/Reports/DiagramReport/index.jsx index 866ecdf..ce3637f --- a/src/pages/Report/index.jsx +++ b/src/pages/Reports/DiagramReport/index.jsx @@ -3,11 +3,11 @@ import moment from 'moment' import { useState, useEffect, memo, useCallback } from 'react' import { Radio, Button, Select, notification } from 'antd' -import { ReportService } from '@api' -import { Subscribe } from '@services/signalr' import { LoaderPortal } from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' -import { DateRangeWrapper } from 'components/Table/DateRangeWrapper' +import { DateRangeWrapper } from '@components/Table/DateRangeWrapper' +import { Subscribe } from '@services/signalr' +import { ReportService } from '@api' import { Reports } from './Reports' import { ReportCreationNotify } from './ReportCreationNotify' @@ -32,7 +32,7 @@ const reportFormats = [ { value: 1, label: 'LAS' }, ] -export const Report = memo(({ idWell }) => { +export const DiagramReport = memo(({ idWell }) => { const [aviableDateRange, setAviableDateRange] = useState([moment(), moment()]) const [filterDateRange, setFilterDateRange] = useState([ moment().subtract(1, 'days').startOf('day'), @@ -171,4 +171,4 @@ export const Report = memo(({ idWell }) => { ) }) -export default Report +export default DiagramReport diff --git a/src/pages/Reports/index.jsx b/src/pages/Reports/index.jsx new file mode 100644 index 0000000..056eb9b --- /dev/null +++ b/src/pages/Reports/index.jsx @@ -0,0 +1,44 @@ +import { Switch, useParams } from 'react-router-dom' +import { memo, useMemo } from 'react' +import { Layout, Menu } from 'antd' +import { FilePdfOutlined } from '@ant-design/icons' + +import { PrivateMenuItemLink, PrivateRoute, PrivateDefaultRoute } from '@components/Private' + +import DailyReport from './DailyReport' +import DiagramReport from './DiagramReport' + +const { Content } = Layout + +export const Reports = memo(({ idWell }) => { + const { tab } = useParams() + const rootPath = useMemo(() => `/well/${idWell}/reports`, [idWell]) + + return ( + + + } title={'Диаграмма'}/> + + + + + + + + + + + + + + + + + + ) +}) + +export default Reports diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index 8c4aab8..4ef9496 100755 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -11,8 +11,8 @@ import { Switch, useParams } from 'react-router-dom' import { PrivateRoute, PrivateDefaultRoute, PrivateMenuItem } from '@components/Private' -import Report from './Report' import Measure from './Measure' +import Reports from './Reports' import Analytics from './Analytics' import Documents from './Documents' import Telemetry from './Telemetry' @@ -32,7 +32,7 @@ export const Well = memo(() => { } title={'Телеметрия'}/> - } title={'Рапорт'} /> + } title={'Рапорта'} /> } title={'Аналитика'} /> } title={'Операции по скважине'} /> {/* } title={'Операции по телеметрии'} /> */} @@ -47,8 +47,8 @@ export const Well = memo(() => { - - + + diff --git a/src/utils/permissions.ts b/src/utils/permissions.ts index 09f3d86..4618a07 100755 --- a/src/utils/permissions.ts +++ b/src/utils/permissions.ts @@ -98,7 +98,10 @@ export const requirements: PermissionRecord = { messages: ['Deposit.get', 'TelemetryDataSaub.get'], dashboard_nnb: ['Deposit.get'], //'WitsInfo.get', 'WitsRecord1.get', 'WitsRecord7.get', 'WitsRecord8.get', 'WitsRecord50.get', 'WitsRecord60.get', 'WitsRecord61.get'], }, - report: ['Deposit.get', 'Report.get'], + reports: { + diagram_report: ['Deposit.get', 'Report.get'], + daily_report: ['Deposit.get'], + }, analytics: { composite: { wells: ['Deposit.get', 'OperationStat.get', 'WellComposite.get'], From 4b55f0e8912ad69c9cfc122fbbc7166644337c11 Mon Sep 17 00:00:00 2001 From: goodmice Date: Tue, 19 Apr 2022 12:51:30 +0500 Subject: [PATCH 20/49] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=80=D0=BE=D1=83=D1=82=D0=B8=D0=BD=D0=B3.=20=D0=94?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=20PrivateMenu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Private/PrivateMenu.tsx | 45 +++++++++++++++++++ src/components/Private/PrivateMenuItem.tsx | 10 ++--- src/components/Private/index.ts | 10 +++-- src/pages/AdminPanel/Telemetry/index.jsx | 12 ++--- src/pages/AdminPanel/index.jsx | 28 ++++++------ .../Analytics/WellCompositeEditor/index.jsx | 12 ++--- src/pages/Analytics/index.jsx | 12 ++--- src/pages/Documents/index.jsx | 12 +++-- src/pages/Telemetry/index.jsx | 17 +++---- src/pages/TelemetryAnalysis/index.jsx | 17 ++++--- src/pages/Well.jsx | 24 +++++----- src/pages/WellOperations/index.jsx | 20 ++++----- 12 files changed, 132 insertions(+), 87 deletions(-) create mode 100644 src/components/Private/PrivateMenu.tsx diff --git a/src/components/Private/PrivateMenu.tsx b/src/components/Private/PrivateMenu.tsx new file mode 100644 index 0000000..1a06311 --- /dev/null +++ b/src/components/Private/PrivateMenu.tsx @@ -0,0 +1,45 @@ +import { join } from 'path' +import { Menu, MenuItemProps, MenuProps } from 'antd' +import { Children, cloneElement, memo, ReactElement } from 'react' +import { Link, useLocation } from 'react-router-dom' + +import { isURLAvailable } from '@utils/permissions' + +export type PrivateMenuProps = MenuProps & { root?: string } + +export type PrivateMenuLinkProps = MenuItemProps & { + tabName?: string + path?: string + title: string + visible?: boolean +} + +export const PrivateMenuLink = memo(({ tabName = '', path = '', title, ...other }) => { + const location = useLocation() + return ( + + {title} + + ) +}) + +const PrivateMenuMain = memo(({ root = '', children, ...other }) => { + const items = Children.toArray(children).map((child) => { + const element = child as ReactElement + let key = element.key?.toString() + const visible: boolean | undefined = element.props.visible + if (key && visible !== false) { + key = key.slice(key.lastIndexOf('$') + 1) // Ключ автоматический преобразуется в "(.+)\$ключ" + const path = join(root, key) + if (visible || isURLAvailable(path)) + return cloneElement(element, { key, path, tabName: key }) + } + return null + }) + + return +}) + +export const PrivateMenu = Object.assign(PrivateMenuMain, { Link: PrivateMenuLink }) + +export default PrivateMenu diff --git a/src/components/Private/PrivateMenuItem.tsx b/src/components/Private/PrivateMenuItem.tsx index fd48ee9..1d0d101 100755 --- a/src/components/Private/PrivateMenuItem.tsx +++ b/src/components/Private/PrivateMenuItem.tsx @@ -1,22 +1,22 @@ import { join } from 'path' import { Menu, MenuItemProps } from 'antd' import { memo, NamedExoticComponent } from 'react' +import { Link, useLocation } from 'react-router-dom' import { isURLAvailable } from '@utils/permissions' -import { Link, useLocation } from 'react-router-dom' export type PrivateMenuItemProps = MenuItemProps & { root: string path: string } -export type PrivateMenuLinkProps = MenuItemProps & { +export type PrivateMenuItemLinkProps = MenuItemProps & { root?: string path: string title: string } -export const PrivateMenuItemLink = memo(({ root = '', path, title, ...other }) => { +export const PrivateMenuItemLink = memo(({ root = '', path, title, ...other }) => { const location = useLocation() return ( @@ -26,9 +26,9 @@ export const PrivateMenuItemLink = memo(({ root = '', path }) export const PrivateMenuItem: NamedExoticComponent & { - Link: NamedExoticComponent + Link: NamedExoticComponent } = Object.assign(memo(({ root, path, ...other }) => - isURLAvailable(join(root, path)) ? : null + - - - - + + + + diff --git a/src/pages/Analytics/index.jsx b/src/pages/Analytics/index.jsx index bac5683..bbe5243 100755 --- a/src/pages/Analytics/index.jsx +++ b/src/pages/Analytics/index.jsx @@ -1,8 +1,8 @@ import { memo, useMemo } from 'react' -import { Layout, Menu } from 'antd' +import { Layout } from 'antd' import { Switch, useParams } from 'react-router-dom' -import { PrivateDefaultRoute, PrivateMenuItemLink, PrivateRoute } from '@components/Private' +import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private' import WellCompositeEditor from './WellCompositeEditor' import Statistics from './Statistics' @@ -13,10 +13,10 @@ export const Analytics = memo(({ idWell }) => { return ( - - - - + + + + diff --git a/src/pages/Documents/index.jsx b/src/pages/Documents/index.jsx index 5452d63..e429b20 100755 --- a/src/pages/Documents/index.jsx +++ b/src/pages/Documents/index.jsx @@ -1,10 +1,10 @@ import { join } from 'path' import { memo, useMemo } from 'react' -import { Layout, Menu } from 'antd' +import { Layout } from 'antd' import { FolderOutlined } from '@ant-design/icons' import { Switch, useParams } from 'react-router-dom' -import { PrivateDefaultRoute, PrivateMenuItemLink, PrivateRoute } from '@components/Private' +import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private' import DocumentsTemplate from './DocumentsTemplate' @@ -29,18 +29,16 @@ export const MenuDocuments = memo(({ idWell }) => { return ( <> - + {documentCategories.map(category => ( - } title={category.title} /> ))} - + diff --git a/src/pages/Telemetry/index.jsx b/src/pages/Telemetry/index.jsx index 524fef1..77026e1 100755 --- a/src/pages/Telemetry/index.jsx +++ b/src/pages/Telemetry/index.jsx @@ -1,9 +1,10 @@ import { Switch, useParams } from 'react-router-dom' import { memo, useMemo } from 'react' -import { Layout, Menu } from 'antd' +import { Layout } from 'antd' import { AlertOutlined, FundViewOutlined, DatabaseOutlined } from '@ant-design/icons' -import { PrivateRoute, PrivateDefaultRoute, PrivateMenuItem } from '@components/Private' +import PrivateMenu from '@components/Private/PrivateMenu' +import { PrivateRoute, PrivateDefaultRoute } from '@components/Private' import Archive from './Archive' import Messages from './Messages' @@ -20,12 +21,12 @@ export const Telemetry = memo(({ idWell }) => { return ( - - } title={'Мониторинг'}/> - } title={'Сообщения'} /> - } title={'Архив'} /> - - + + } title={'Мониторинг'}/> + } title={'Сообщения'} /> + } title={'Архив'} /> + + diff --git a/src/pages/TelemetryAnalysis/index.jsx b/src/pages/TelemetryAnalysis/index.jsx index 3c7e8ca..1cd423c 100755 --- a/src/pages/TelemetryAnalysis/index.jsx +++ b/src/pages/TelemetryAnalysis/index.jsx @@ -1,10 +1,9 @@ import { memo } from 'react' -import { Layout, Menu } from 'antd' +import { Layout } from 'antd' import { FolderOutlined } from '@ant-design/icons' import { Switch, useParams } from 'react-router-dom' -import { PrivateDefaultRoute, PrivateRoute } from '@components/Private' -import { PrivateMenuItemLink } from '@components/Private/PrivateMenuItem' +import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private' import TelemetryAnalysisDepthToDay from './TelemetryAnalysisDepthToDay' import TelemetryAnalysisDepthToInterval from './TelemetryAnalysisDepthToInterval' @@ -19,12 +18,12 @@ export const TelemetryAnalysis = memo(({ idWell }) => { return ( <> - - } key={'depthToDay'} path={'depthToDay'} title={'Глубина-день'} /> - } key={'depthToInterval'} path={'depthToInterval'} title={'Глубина-интервал'} /> - } key={'operationsSummary'} path={'operationsSummary'} title={'Все операции'} /> - } key={'operationsToInterval'} path={'operationsToInterval'} title={'Операции-интервал'} /> - + + } key={'depthToDay'} title={'Глубина-день'} /> + } key={'depthToInterval'} title={'Глубина-интервал'} /> + } key={'operationsSummary'} title={'Все операции'} /> + } key={'operationsToInterval'} title={'Операции-интервал'} /> + diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index 8c4aab8..41bae5e 100755 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -6,10 +6,10 @@ import { ExperimentOutlined, DeploymentUnitOutlined, } from '@ant-design/icons' -import { Layout, Menu } from 'antd' +import { Layout } from 'antd' import { Switch, useParams } from 'react-router-dom' -import { PrivateRoute, PrivateDefaultRoute, PrivateMenuItem } from '@components/Private' +import { PrivateRoute, PrivateDefaultRoute, PrivateMenu } from '@components/Private' import Report from './Report' import Measure from './Measure' @@ -30,16 +30,16 @@ export const Well = memo(() => { return ( - - } title={'Телеметрия'}/> - } title={'Рапорт'} /> - } title={'Аналитика'} /> - } title={'Операции по скважине'} /> - {/* } title={'Операции по телеметрии'} /> */} - } title={'Документы'} /> - } title={'Измерения'} /> - } title={'Программа бурения'} /> - + + } title={'Телеметрия'}/> + } title={'Рапорт'} /> + } title={'Аналитика'} /> + } title={'Операции по скважине'} /> + {/* } title={'Операции по телеметрии'} /> */} + } title={'Документы'} /> + } title={'Измерения'} /> + } title={'Программа бурения'} /> + diff --git a/src/pages/WellOperations/index.jsx b/src/pages/WellOperations/index.jsx index cedad37..5e14dd3 100755 --- a/src/pages/WellOperations/index.jsx +++ b/src/pages/WellOperations/index.jsx @@ -1,5 +1,5 @@ import { memo, useCallback } from 'react' -import { Layout, Menu } from 'antd' +import { Layout } from 'antd' import { Switch, useParams, useHistory, useLocation } from 'react-router-dom' import { BarChartOutlined, @@ -9,7 +9,7 @@ import { TableOutlined, } from '@ant-design/icons' -import { PrivateDefaultRoute, PrivateRoute, PrivateMenuItemLink } from '@components/Private' +import { PrivateDefaultRoute, PrivateRoute, PrivateMenu } from '@components/Private' import { Tvd } from './Tvd' import { ImportExportBar } from './ImportExportBar' @@ -36,14 +36,14 @@ export const WellOperations = memo(({ idWell }) => { return( <> - - } key={'tvd'} path={'tvd'} title={'TVD'} /> - } key={'sections'} path={'sections'} title={'Секции'} /> - } key={'plan'} path={'plan'} title={'План'} /> - } key={'fact'} path={'fact'} title={'Факт'} /> - } key={'drillProcessFlow'} path={'drillProcessFlow'} title={'РТК'} /> - } key={'params'} path={'params'} title={'Режимы'} /> - + + } key={'tvd'} title={'TVD'} /> + } key={'sections'} title={'Секции'} /> + } key={'plan'} title={'План'} /> + } key={'fact'} title={'Факт'} /> + } key={'drillProcessFlow'} title={'РТК'} /> + } key={'params'} title={'Режимы'} /> + From 30f33e407657bbb487f6c7799ee0225b7deb98bb Mon Sep 17 00:00:00 2001 From: goodmice Date: Tue, 19 Apr 2022 15:38:53 +0500 Subject: [PATCH 21/49] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=BA=D1=81=D1=82?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20rootPath=20=D0=B8=20idWell?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- concept/Smbo/EquipmentDetails.jsx | 8 +- src/components/Private/PrivateMenu.tsx | 14 ++- src/components/Private/PrivateSwitch.tsx | 75 +++++++++++++++ src/components/Private/index.ts | 2 + src/pages/AdminPanel/Telemetry/index.jsx | 48 +++++----- src/pages/AdminPanel/UserController/index.jsx | 2 +- src/pages/AdminPanel/index.jsx | 88 ++++++++---------- src/pages/Analytics/Statistics.jsx | 8 +- .../WellCompositeEditor/NewParamsTable.jsx | 7 +- .../WellCompositeSections.jsx | 11 ++- .../Analytics/WellCompositeEditor/index.jsx | 36 +++----- src/pages/Analytics/index.jsx | 45 +++++---- src/pages/Documents/DocumentsTemplate.jsx | 9 +- src/pages/Documents/index.jsx | 34 +++---- src/pages/DrillingProgram/CategoryAdder.jsx | 8 +- src/pages/DrillingProgram/CategoryEditor.jsx | 8 +- src/pages/DrillingProgram/CategoryHistory.jsx | 7 +- src/pages/DrillingProgram/CategoryRender.jsx | 7 +- src/pages/DrillingProgram/index.jsx | 16 ++-- src/pages/Main.jsx | 58 ++++++------ src/pages/Measure/MeasureTable.jsx | 7 +- src/pages/Measure/index.jsx | 8 +- src/pages/Report/Reports.jsx | 7 +- src/pages/Report/index.jsx | 9 +- src/pages/Telemetry/Archive/index.jsx | 7 +- src/pages/Telemetry/DashboardNNB/index.jsx | 20 ++-- src/pages/Telemetry/Messages.jsx | 49 +++------- .../TelemetryView/ActiveMessagesOnline.jsx | 7 +- .../Setpoints/SetpointSender.jsx | 8 +- .../TelemetryView/Setpoints/index.jsx | 8 +- .../TelemetryView/WirelineRunOut.jsx | 8 +- src/pages/Telemetry/TelemetryView/index.jsx | 13 ++- src/pages/Telemetry/index.jsx | 63 ++++++------- .../TelemetryAnalysisDepthToDay.jsx | 8 +- .../TelemetryAnalysisDepthToInterval.jsx | 12 ++- .../TelemetryAnalysisOperationsSummary.jsx | 8 +- .../TelemetryAnalysisOperationsToInterval.jsx | 2 +- src/pages/TelemetryAnalysis/index.jsx | 46 ++++------ src/pages/Well.jsx | 92 ++++++++----------- src/pages/WellOperations/DrillProcessFlow.jsx | 8 +- src/pages/WellOperations/Tvd/index.jsx | 8 +- src/pages/WellOperations/WellDrillParams.jsx | 8 +- .../WellOperations/WellOperationsEditor.jsx | 8 +- src/pages/WellOperations/WellSectionsStat.jsx | 10 +- src/pages/WellOperations/index.jsx | 61 +++++------- 45 files changed, 530 insertions(+), 446 deletions(-) create mode 100644 src/components/Private/PrivateSwitch.tsx diff --git a/concept/Smbo/EquipmentDetails.jsx b/concept/Smbo/EquipmentDetails.jsx index 5178236..24b18a7 100755 --- a/concept/Smbo/EquipmentDetails.jsx +++ b/concept/Smbo/EquipmentDetails.jsx @@ -1,8 +1,10 @@ import {Row, Col} from 'antd' -import Documents from '../Documents/DocumentsTemplate' -import '../../styles/equipment_details.css' -export default function EquipmentDetails({id, equipmentTimers, equipmentSensors}) { +import Documents from '../Documents/DocumentsTemplate' + +import '@styles/equipment_details.css' + +export default function EquipmentDetails({ id, equipmentTimers, equipmentSensors }) { let stateOfEquipmentDetails = equipmentTimers.map(timer => { return(

{timer.label}: {timer.value} {timer.unit}

diff --git a/src/components/Private/PrivateMenu.tsx b/src/components/Private/PrivateMenu.tsx index 1a06311..6894518 100644 --- a/src/components/Private/PrivateMenu.tsx +++ b/src/components/Private/PrivateMenu.tsx @@ -1,9 +1,10 @@ import { join } from 'path' import { Menu, MenuItemProps, MenuProps } from 'antd' -import { Children, cloneElement, memo, ReactElement } from 'react' +import { Children, cloneElement, memo, ReactElement, useContext, useMemo } from 'react' import { Link, useLocation } from 'react-router-dom' import { isURLAvailable } from '@utils/permissions' +import { RootPathContext } from '@pages/Main' export type PrivateMenuProps = MenuProps & { root?: string } @@ -23,19 +24,22 @@ export const PrivateMenuLink = memo(({ tabName = '', path ) }) -const PrivateMenuMain = memo(({ root = '', children, ...other }) => { - const items = Children.toArray(children).map((child) => { +const PrivateMenuMain = memo(({ root, children, ...other }) => { + const rootContext = useContext(RootPathContext) + const rootPath = useMemo(() => root ?? rootContext ?? '', [root, rootContext]) + + const items = useMemo(() => Children.toArray(children).map((child) => { const element = child as ReactElement let key = element.key?.toString() const visible: boolean | undefined = element.props.visible if (key && visible !== false) { key = key.slice(key.lastIndexOf('$') + 1) // Ключ автоматический преобразуется в "(.+)\$ключ" - const path = join(root, key) + const path = join(rootPath, key) if (visible || isURLAvailable(path)) return cloneElement(element, { key, path, tabName: key }) } return null - }) + }), [children, rootPath]) return }) diff --git a/src/components/Private/PrivateSwitch.tsx b/src/components/Private/PrivateSwitch.tsx new file mode 100644 index 0000000..57911ed --- /dev/null +++ b/src/components/Private/PrivateSwitch.tsx @@ -0,0 +1,75 @@ +import { join } from 'path' +import { Location } from 'history' +import { Children, cloneElement, memo, ReactElement, ReactNode, useCallback, useContext, useMemo } from 'react' + +import { Redirect, Route, Switch, SwitchProps, useLocation } from 'react-router-dom' +import { isURLAvailable } from '@utils/permissions' +import { getUserId } from '@utils/storage' + +import { RootPathContext } from '@pages/Main' + +export type PrivateSwitchProps = SwitchProps & { + root?: string + redirect?: (location?: Location) => ReactNode + elseRedirect?: string | string[] +} + +const getDefaultRedirectPath = () => getUserId() ? '/access_denied' : '/login' + +export const defaultRedirect = (location?: Location) => ( + +) + +export const PrivateSwitch = memo(({ root, elseRedirect, redirect = defaultRedirect, children }) => { + const rootContext = useContext(RootPathContext) + const rootPath = useMemo(() => root ?? rootContext ?? '', [root, rootContext]) + + const location = useLocation() + + const toAbsolute = useCallback((path: string) => path.startsWith('/') ? path : join(rootPath, path), [rootPath]) + + const items = useMemo(() => Children.toArray(children).map((child) => { + const element = child as ReactElement + let key = element.key?.toString() + if (!key) return null + key = key.slice(key.lastIndexOf('$') + 1).replaceAll('=2', ':') + // Ключ автоматический преобразуется в "(.+)\$ключ" + // Все ":" в ключе заменяются на "=2" + // TODO: улучшить метод нормализации ключа + const path = toAbsolute(key) + return ( + isURLAvailable(path) ? cloneElement(element) : redirect(location)} + /> + ) + }), [children, redirect, toAbsolute]) + + const defaultRoute = useMemo(() => { + if (!elseRedirect) { + const path = items.map((elm) => elm?.props.path).find((path) => path && isURLAvailable(path)) + if (path) return path + } else if (Array.isArray(elseRedirect)) { + const path = elseRedirect.find((path) => { + if (!path) return false + return isURLAvailable(toAbsolute(path)) + }) + if (path) return toAbsolute(path) + } else if(elseRedirect && isURLAvailable(toAbsolute(elseRedirect))) { + return toAbsolute(elseRedirect) + } + return getDefaultRedirectPath() + }, [items, elseRedirect, toAbsolute]) + + return ( + + {items} + + + + + ) +}) + +export default PrivateSwitch diff --git a/src/components/Private/index.ts b/src/components/Private/index.ts index 61de54c..b9cd980 100755 --- a/src/components/Private/index.ts +++ b/src/components/Private/index.ts @@ -3,9 +3,11 @@ export { PrivateContent } from './PrivateContent' // TODO: Remove export { PrivateMenuItem, PrivateMenuItemLink } from './PrivateMenuItem' // TODO: Remove export { PrivateDefaultRoute } from './PrivateDefaultRoute' export { PrivateMenu, PrivateMenuLink } from './PrivateMenu' +export { PrivateSwitch } from './PrivateSwitch' export type { PrivateRouteProps } from './PrivateRoute' export type { PrivateContentProps } from './PrivateContent' // TODO: Remove export type { PrivateMenuItemProps, PrivateMenuItemLinkProps } from './PrivateMenuItem' // TODO: Remove export type { PrivateDefaultRouteProps } from './PrivateDefaultRoute' export type { PrivateMenuProps, PrivateMenuLinkProps } from './PrivateMenu' +export type { PrivateSwitchProps } from './PrivateSwitch' diff --git a/src/pages/AdminPanel/Telemetry/index.jsx b/src/pages/AdminPanel/Telemetry/index.jsx index 7ad8b46..9a145e0 100755 --- a/src/pages/AdminPanel/Telemetry/index.jsx +++ b/src/pages/AdminPanel/Telemetry/index.jsx @@ -1,41 +1,41 @@ import { Layout } from 'antd' -import { lazy, memo, Suspense } from 'react' -import { Switch, useParams } from 'react-router-dom' +import { lazy, memo, Suspense, useContext, useMemo } from 'react' +import { useParams } from 'react-router-dom' -import { PrivateRoute, PrivateDefaultRoute, PrivateMenu } from '@components/Private' +import { PrivateMenu, PrivateSwitch } from '@components/Private' import { SuspenseFallback } from '@pages/SuspenseFallback' +import { RootPathContext } from '@pages/Main' const TelemetryViewer = lazy(() => import('./TelemetryViewer')) const TelemetryMerger = lazy(() => import('./TelemetryMerger')) -const rootPath = '/admin/telemetry' - export const Telemetry = memo(() => { const { tab } = useParams() - return ( - - - - - + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/telemetry`, [root]) + return ( + - - }> - - - - - - - + + + + + + + + }> + + + + + + + - + ) }) diff --git a/src/pages/AdminPanel/UserController/index.jsx b/src/pages/AdminPanel/UserController/index.jsx index 2152cd4..c090d73 100755 --- a/src/pages/AdminPanel/UserController/index.jsx +++ b/src/pages/AdminPanel/UserController/index.jsx @@ -188,7 +188,7 @@ export const UserController = memo(() => { allowClear placeholder={'Введите текст для поиска (по всем полям за исключением ролей)...'} onChange={onSearchTextChange} - style={{ marginBottom: '15px' }} + style={{ margin: '15px 0' }} loading={isSearching} /> import( './ClusterController')) @@ -17,57 +18,48 @@ const PermissionController = lazy(() => import( './PermissionController')) const TelemetrySection = lazy(() => import( './Telemetry')) const VisitLog = lazy(() => import( './VisitLog')) -const rootPath = '/admin' - export const AdminPanel = memo(() => { const { tab } = useParams() - return ( - - - - - - - - - - - - - + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/admin`, [root]) + return ( + - - }> - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + }> + + + + + + + + + + + + + + + - + ) }) diff --git a/src/pages/Analytics/Statistics.jsx b/src/pages/Analytics/Statistics.jsx index c0ad71d..fabd3c1 100755 --- a/src/pages/Analytics/Statistics.jsx +++ b/src/pages/Analytics/Statistics.jsx @@ -1,5 +1,5 @@ import { Table as RawTable, Typography } from 'antd' -import { Fragment, memo, useCallback, useEffect, useState } from 'react' +import { Fragment, memo, useCallback, useContext, useEffect, useState } from 'react' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' @@ -8,6 +8,8 @@ import { makeGroupColumn, makeNumericColumn, makeNumericRender, makeTextColumn, import { OperationStatService, WellOperationService } from '@api' import { arrayOrDefault } from '@utils' +import { IdWellContext } from '../Well' + import '@styles/index.css' import '@styles/statistics.less' @@ -62,7 +64,7 @@ const getWellData = async (wellsList) => { return wellData } -export const Statistics = memo(({ idWell }) => { +export const Statistics = memo(() => { const [sectionTypes, setSectionTypes] = useState([]) const [avgColumns, setAvgColumns] = useState(defaultColumns) const [cmpColumns, setCmpColumns] = useState(defaultColumns) @@ -75,6 +77,8 @@ export const Statistics = memo(({ idWell }) => { const [cmpData, setCmpData] = useState([]) const [avgRow, setAvgRow] = useState({}) + const idWell = useContext(IdWellContext) + const cmpSpeedRender = useCallback((key) => (section) => { let spanClass = '' // Дополнительная проверка на "null" необходима, чтобы значение "0" не стало исключением diff --git a/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx b/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx index 6998087..c353e4d 100755 --- a/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx +++ b/src/pages/Analytics/WellCompositeEditor/NewParamsTable.jsx @@ -1,4 +1,4 @@ -import { memo, useCallback, useEffect, useState } from 'react' +import { memo, useCallback, useContext, useEffect, useState } from 'react' import { Button, Modal, Popconfirm } from 'antd' import { Table } from '@components/Table' @@ -6,14 +6,17 @@ import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' import { DrillParamsService } from '@api' +import { IdWellContext } from '@pages/Well' import { getColumns } from '@pages/WellOperations/WellDrillParams' -export const NewParamsTable = memo(({ idWell, selectedWellsKeys }) => { +export const NewParamsTable = memo(({ selectedWellsKeys }) => { const [params, setParams] = useState([]) const [paramsColumns, setParamsColumns] = useState([]) const [showParamsLoader, setShowParamsLoader] = useState(false) const [isParamsModalVisible, setIsParamsModalVisible] = useState(false) + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => setParamsColumns(await getColumns(idWell)) ), [idWell]) diff --git a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx index 7e1505a..38aa452 100755 --- a/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx +++ b/src/pages/Analytics/WellCompositeEditor/WellCompositeSections.jsx @@ -1,5 +1,5 @@ import { Link, useLocation } from 'react-router-dom' -import { useState, useEffect, memo, useMemo } from 'react' +import { useState, useEffect, memo, useMemo, useContext } from 'react' import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons' import { Table, Tag, Button, Badge, Divider, Modal, Row, Col } from 'antd' @@ -15,6 +15,7 @@ import { getOperations } from '@utils/functions' +import { IdWellContext } from '@pages/Well' import { Tvd } from '@pages/WellOperations/Tvd' import WellOperationsTable from '@pages/Cluster/WellOperationsTable' import NewParamsTable from './NewParamsTable' @@ -29,7 +30,7 @@ const sortBySectionId = (a, b) => a.sectionId - b.sectionId const filtersSectionsType = [] const DAY_IN_MS = 1000 * 60 * 60 * 24 -export const WellCompositeSections = memo(({ idWell, statsWells, selectedSections }) => { +export const WellCompositeSections = memo(({ statsWells, selectedSections }) => { const [selectedWells, setSelectedWells] = useState([]) const [wellOperations, setWellOperations] = useState([]) const [selectedWellsKeys, setSelectedWellsKeys] = useState([]) @@ -38,6 +39,8 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection const [isTVDModalVisible, setIsTVDModalVisible] = useState(false) const [isOpsModalVisible, setIsOpsModalVisible] = useState(false) + const idWell = useContext(IdWellContext) + const location = useLocation() const rows = useMemo(() => { @@ -208,9 +211,7 @@ export const WellCompositeSections = memo(({ idWell, statsWells, selectedSection pagination={false} /> -
- - + { +export const WellCompositeEditor = memo(({ rootPath }) => { const { tab } = useParams() + const idWell = useContext(IdWellContext) const [statsWells, setStatsWells] = useState([]) const [showLoader, setShowLoader] = useState(false) @@ -68,27 +67,18 @@ export const WellCompositeEditor = memo(({ idWell, rootPath }) => { - - + + - - - - - - - - - + + + + diff --git a/src/pages/Analytics/index.jsx b/src/pages/Analytics/index.jsx index bbe5243..1a38c6a 100755 --- a/src/pages/Analytics/index.jsx +++ b/src/pages/Analytics/index.jsx @@ -1,36 +1,35 @@ -import { memo, useMemo } from 'react' +import { memo, useContext, useMemo } from 'react' +import { useParams } from 'react-router-dom' import { Layout } from 'antd' -import { Switch, useParams } from 'react-router-dom' -import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private' +import { PrivateMenu, PrivateSwitch } from '@components/Private' -import WellCompositeEditor from './WellCompositeEditor' import Statistics from './Statistics' +import WellCompositeEditor from './WellCompositeEditor' +import { RootPathContext } from '@pages/Main' -export const Analytics = memo(({ idWell }) => { +export const Analytics = memo(() => { const { tab } = useParams() - const rootPath = useMemo(() => `/well/${idWell}/analytics`, [idWell]) + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/analytics`, [root]) return ( - - - - - + - - - - - - - - - - - + + + + + + + + + + + + - + ) }) diff --git a/src/pages/Documents/DocumentsTemplate.jsx b/src/pages/Documents/DocumentsTemplate.jsx index f786551..dc98a2e 100755 --- a/src/pages/Documents/DocumentsTemplate.jsx +++ b/src/pages/Documents/DocumentsTemplate.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useMemo, useCallback } from 'react' +import { useState, useEffect, useMemo, useCallback, useContext } from 'react' import { DatePicker, Button, Input } from 'antd' import { FileService } from '@api' @@ -9,6 +9,8 @@ import { EditableTable, makeColumn, makeDateColumn, makeNumericColumn, makePagin import { invokeWebApiWrapperAsync, downloadFile, formatBytes } from '@components/factory' import { hasPermission } from '@utils/permissions' +import { IdWellContext } from '@pages/Well' + const pageSize = 12 const { RangePicker } = DatePicker const { Search } = Input @@ -30,7 +32,7 @@ const columns = [ makeColumn('Компания', 'company', { render: (_, record) => }) ] -export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, customColumns, beforeTable, onChange, tableName }) => { +export const DocumentsTemplate = ({ idCategory, idWell: wellId, accept, headerChild, customColumns, beforeTable, onChange, tableName }) => { const [page, setPage] = useState(1) const [filterDataRange, setFilterDataRange] = useState([]) const [filterCompanyName, setFilterCompanyName] = useState([]) @@ -39,6 +41,9 @@ export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, cus const [files, setFiles] = useState([]) const [showLoader, setShowLoader] = useState(false) + const idwellContext = useContext(IdWellContext) + const idWell = useMemo(() => wellId ?? idwellContext, [wellId]) + const uploadUrl = useMemo(() => `/api/well/${idWell}/files/?idCategory=${idCategory}`, [idWell, idCategory]) const mergedColumns = useMemo(() => [...columns, ...(customColumns ?? [])], [customColumns]) diff --git a/src/pages/Documents/index.jsx b/src/pages/Documents/index.jsx index e429b20..3c79213 100755 --- a/src/pages/Documents/index.jsx +++ b/src/pages/Documents/index.jsx @@ -1,12 +1,12 @@ -import { join } from 'path' -import { memo, useMemo } from 'react' -import { Layout } from 'antd' +import { useParams } from 'react-router-dom' +import { memo, useContext, useMemo } from 'react' import { FolderOutlined } from '@ant-design/icons' -import { Switch, useParams } from 'react-router-dom' +import { Layout } from 'antd' -import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private' +import { PrivateMenu, PrivateSwitch } from '@components/Private' import DocumentsTemplate from './DocumentsTemplate' +import { RootPathContext } from '@pages/Main' const { Content } = Layout @@ -23,13 +23,14 @@ export const documentCategories = [ { id: 9, key: 'closingService', title: 'Сервис по заканчиванию скважины' }, ] -export const MenuDocuments = memo(({ idWell }) => { +export const MenuDocuments = memo(() => { const { category } = useParams() - const root = useMemo(() => `/well/${idWell}/document`, [idWell]) + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/document`, [root]) return ( - <> - + + {documentCategories.map(category => ( { - + cat.key)}> {documentCategories.map(category => ( - - - + ))} - join(root, cat.key))}/> - + - + ) }) diff --git a/src/pages/DrillingProgram/CategoryAdder.jsx b/src/pages/DrillingProgram/CategoryAdder.jsx index dd45dad..66534e7 100755 --- a/src/pages/DrillingProgram/CategoryAdder.jsx +++ b/src/pages/DrillingProgram/CategoryAdder.jsx @@ -1,11 +1,13 @@ import { Form, Select } from 'antd' import { FileAddOutlined } from '@ant-design/icons' -import { memo, useCallback, useEffect, useState } from 'react' +import { memo, useCallback, useContext, useEffect, useState } from 'react' import Poprompt from '@components/selectors/Poprompt' import { invokeWebApiWrapperAsync } from '@components/factory' import { DrillingProgramService } from '@api' +import { IdWellContext } from '@pages/Well' + import '@styles/drilling_program.less' const catSelectorRules = [{ @@ -13,12 +15,14 @@ const catSelectorRules = [{ message: 'Пожалуйста, выберите категории' }] -export const CategoryAdder = memo(({ categories, idWell, onUpdate, className, ...other }) => { +export const CategoryAdder = memo(({ categories, onUpdate, className, ...other }) => { const [options, setOptions] = useState([]) const [value, setValue] = useState([]) const [showLoader, setShowLoader] = useState(false) const [showCatLoader, setShowCatLoader] = useState(false) + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => { setOptions(categories.map((category) => ({ diff --git a/src/pages/DrillingProgram/CategoryEditor.jsx b/src/pages/DrillingProgram/CategoryEditor.jsx index 5a01b67..4bedc5e 100755 --- a/src/pages/DrillingProgram/CategoryEditor.jsx +++ b/src/pages/DrillingProgram/CategoryEditor.jsx @@ -1,5 +1,5 @@ import { Input, Modal, Radio } from 'antd' -import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import { memo, useCallback, useContext, useEffect, useMemo, useState } from 'react' import { BehaviorSubject, debounceTime, distinctUntilChanged, filter, map } from 'rxjs' import { UserView } from '@components/views' @@ -9,6 +9,8 @@ import { makeColumn, makeNumericSorter, Table } from '@components/Table' import { DrillingProgramService } from '@api' import { arrayOrDefault } from '@utils' +import { IdWellContext } from '@pages/Well' + const userRules = [ { label: 'Нет', value: 0 }, { label: 'Публикатор', value: 1 }, @@ -17,7 +19,7 @@ const userRules = [ const SEARCH_TIMEOUT = 400 -export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => { +export const CategoryEditor = memo(({ visible, category, onClosed }) => { const [title, setTitle] = useState() const [users, setUsers] = useState([]) const [allUsers, setAllUsers] = useState([]) @@ -27,6 +29,8 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => const [searchValue, setSearchValue] = useState('') const [subject, setSubject] = useState(null) + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => { const filteredUsers = users.filter(({ user }) => user && [ diff --git a/src/pages/DrillingProgram/CategoryHistory.jsx b/src/pages/DrillingProgram/CategoryHistory.jsx index 1df55ad..b9f1424 100755 --- a/src/pages/DrillingProgram/CategoryHistory.jsx +++ b/src/pages/DrillingProgram/CategoryHistory.jsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react' +import { useCallback, useContext, useEffect, useState } from 'react' import { Button, DatePicker, Input, Modal } from 'antd' import { CompanyView } from '@components/views' @@ -10,6 +10,7 @@ import { arrayOrDefault, formatDate } from '@utils' import { FileService } from '@api' import MarksCard from './MarksCard' +import { IdWellContext } from '@pages/Well' import '@styles/drilling_program.less' @@ -54,7 +55,7 @@ export const historyColumns = [ }) ] -export const CategoryHistory = ({ idWell, idCategory, visible, onClose }) => { +export const CategoryHistory = ({ idCategory, visible, onClose }) => { const [data, setData] = useState([]) const [page, setPage] = useState(1) const [total, setTotal] = useState(0) @@ -64,6 +65,8 @@ export const CategoryHistory = ({ idWell, idCategory, visible, onClose }) => { const [isLoading, setIsLoading] = useState(false) const [companyName, setCompanyName] = useState('') + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => { if (!visible) return diff --git a/src/pages/DrillingProgram/CategoryRender.jsx b/src/pages/DrillingProgram/CategoryRender.jsx index d3a168e..92f6e27 100755 --- a/src/pages/DrillingProgram/CategoryRender.jsx +++ b/src/pages/DrillingProgram/CategoryRender.jsx @@ -1,4 +1,4 @@ -import { memo, useCallback, useMemo, useState } from 'react' +import { memo, useCallback, useContext, useMemo, useState } from 'react' import { Button, Input, Popconfirm, Form } from 'antd' import { DeleteOutlined, @@ -16,6 +16,7 @@ import { DrillingProgramService } from '@api' import { formatDate } from '@utils' import MarksCard from './MarksCard' +import { IdWellContext } from '@pages/Well' import '@styles/drilling_program.less' @@ -34,7 +35,7 @@ const CommentPrompt = memo(({ isRequired = true, ...props }) => ( )) -export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHistory, setIsLoading, ...other }) => { +export const CategoryRender = memo(({ partData, onUpdate, onEdit, onHistory, setIsLoading, ...other }) => { const { idFileCategory, name: title, // Название категории @@ -44,6 +45,8 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist file // Информация о файле } = partData ?? {} + const idWell = useContext(IdWellContext) + const uploadUrl = useMemo(() => `/api/well/${idWell}/drillingProgram/part/${idFileCategory}`, [idWell, idFileCategory]) const approvedMarks = useMemo(() => file?.fileMarks?.filter((mark) => mark.idMarkType === 1), [file]) const rejectMarks = useMemo(() => file?.fileMarks?.filter((mark) => mark.idMarkType === 0), [file]) diff --git a/src/pages/DrillingProgram/index.jsx b/src/pages/DrillingProgram/index.jsx index 303d240..1b08c73 100755 --- a/src/pages/DrillingProgram/index.jsx +++ b/src/pages/DrillingProgram/index.jsx @@ -8,7 +8,7 @@ import { ReloadOutlined, WarningOutlined, } from '@ant-design/icons' -import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import { memo, useCallback, useContext, useEffect, useMemo, useState } from 'react' import LoaderPortal from '@components/LoaderPortal' import { downloadFile, formatBytes, invokeWebApiWrapperAsync } from '@components/factory' @@ -19,6 +19,7 @@ import CategoryAdder from './CategoryAdder' import CategoryRender from './CategoryRender' import CategoryEditor from './CategoryEditor' import CategoryHistory from './CategoryHistory' +import { IdWellContext } from '@pages/Well' import '@styles/drilling_program.less' @@ -38,7 +39,7 @@ const stateString = { [idStateUnknown]: { icon: WarningOutlined, text: 'Неизвестно' }, } -export const DrillingProgram = memo(({ idWell }) => { +export const DrillingProgram = memo(() => { const [selectedCategory, setSelectedCategory] = useState() const [historyVisible, setHistoryVisible] = useState(false) const [editorVisible, setEditorVisible] = useState(false) @@ -46,6 +47,8 @@ export const DrillingProgram = memo(({ idWell }) => { const [categories, setCategories] = useState([]) const [data, setData] = useState({}) + const idWell = useContext(IdWellContext) + const { idState, permissionToEdit, @@ -99,11 +102,7 @@ export const DrillingProgram = memo(({ idWell }) => {

Программа бурения

{permissionToEdit && (
- +
)} @@ -143,7 +142,6 @@ export const DrillingProgram = memo(({ idWell }) => { {parts?.map?.((part, idx) => part && ( { {permissionToEdit && ( <> part.idFileCategory === selectedCategory) ?? {}} @@ -163,7 +160,6 @@ export const DrillingProgram = memo(({ idWell }) => { )} setHistoryVisible(false)} visible={historyVisible} diff --git a/src/pages/Main.jsx b/src/pages/Main.jsx index e090edf..183da19 100755 --- a/src/pages/Main.jsx +++ b/src/pages/Main.jsx @@ -1,4 +1,4 @@ -import { memo } from 'react' +import { createContext, memo } from 'react' import { Route, Switch } from 'react-router-dom' import { AdminLayoutPortal, LayoutPortal } from '@components/Layout' @@ -10,33 +10,37 @@ import Deposit from './Deposit' import AdminPanel from './AdminPanel' import AccessDenied from './AccessDenied' +export const RootPathContext = createContext('') + export const Main = memo(() => ( - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + )) export default Main diff --git a/src/pages/Measure/MeasureTable.jsx b/src/pages/Measure/MeasureTable.jsx index 25e7fd5..32bd830 100755 --- a/src/pages/Measure/MeasureTable.jsx +++ b/src/pages/Measure/MeasureTable.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, memo, useMemo, useCallback } from 'react' +import { useState, useEffect, memo, useMemo, useCallback, useContext } from 'react' import { Button, Form, Input, Popconfirm, Timeline } from 'antd' import { CheckSquareOutlined, @@ -16,6 +16,7 @@ import { formatDate } from '@utils' import { MeasureService } from '@api' import { View } from './View' +import { IdWellContext } from '@pages/Well' import '@styles/index.css' import '@styles/measure.css' @@ -25,13 +26,15 @@ const createEditingColumns = (cols, renderDelegate) => const disabled = !hasPermission('Measure.edit') -export const MeasureTable = memo(({ idWell, group, updateMeasuresFunc, additionalButtons }) => { +export const MeasureTable = memo(({ 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 idWell = useContext(IdWellContext) + const [measuresForm] = Form.useForm() const data = useMemo(() => group?.values?.length > 0 ? group.values : [group?.defaultValue], [group?.defaultValue, group?.values]) diff --git a/src/pages/Measure/index.jsx b/src/pages/Measure/index.jsx index adf6b4c..af15e53 100755 --- a/src/pages/Measure/index.jsx +++ b/src/pages/Measure/index.jsx @@ -1,5 +1,5 @@ import { Button } from 'antd' -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useContext } from 'react' import { TableOutlined } from '@ant-design/icons' import { MeasureService } from '@api' @@ -11,6 +11,7 @@ import { InclinometryTable } from './InclinometryTable' import { columnsNnb, nnbDefaultData } from './nnbData' import { columnsMudDiagram, mudDiagramDefaultData } from './mudDiagramData' import { columnsDrillingFluid, drillingFluidDefaultData } from './drillingFluidData' +import { IdWellContext } from '@pages/Well' const defaultData = [ { @@ -41,12 +42,14 @@ const defaultData = [ } ] -export const Measure = memo(({ idWell }) => { +export const Measure = memo(() => { const [showLoader, setShowLoader] = useState(false) const [isMeasuresUpdating, setIsMeasuresUpdating] = useState(true) const [data, setData] = useState(defaultData) const [tableIdx, setTableIdx] = useState(-1) + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => { if (!isMeasuresUpdating) return @@ -73,7 +76,6 @@ export const Measure = memo(({ idWell }) => { {data.map((group, idx) => ( setIsMeasuresUpdating(true)} additionalButtons={group.additionalButtons?.(group, idx, setTableIdx)} diff --git a/src/pages/Report/Reports.jsx b/src/pages/Report/Reports.jsx index cf44431..c5fb7ca 100755 --- a/src/pages/Report/Reports.jsx +++ b/src/pages/Report/Reports.jsx @@ -1,5 +1,5 @@ import { Button, Tooltip } from 'antd' -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useContext } from 'react' import { FilePdfOutlined, FileTextOutlined } from '@ant-design/icons' import { ReportService } from '@api' @@ -7,6 +7,7 @@ import { formatDate, periodToString } from '@utils' import LoaderPortal from '@components/LoaderPortal' import { Table, makeDateSorter, makeNumericSorter } from '@components/Table' import { invokeWebApiWrapperAsync, downloadFile } from '@components/factory' +import { IdWellContext } from '@pages/Well' const imgPaths = { '.pdf': , @@ -55,10 +56,12 @@ const columns = [ }, ] -export const Reports = memo(({ idWell }) => { +export const Reports = memo(() => { const [reports, setReports] = useState([]) const [showLoader, setShowLoader] = useState(false) + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => { const reportsResponse = await ReportService.getAllReportsNamesByWell(idWell) diff --git a/src/pages/Report/index.jsx b/src/pages/Report/index.jsx index 866ecdf..0c1f2e0 100755 --- a/src/pages/Report/index.jsx +++ b/src/pages/Report/index.jsx @@ -1,6 +1,6 @@ import 'moment/locale/ru' import moment from 'moment' -import { useState, useEffect, memo, useCallback } from 'react' +import { useState, useEffect, memo, useCallback, useContext } from 'react' import { Radio, Button, Select, notification } from 'antd' import { ReportService } from '@api' @@ -11,6 +11,7 @@ import { DateRangeWrapper } from 'components/Table/DateRangeWrapper' import { Reports } from './Reports' import { ReportCreationNotify } from './ReportCreationNotify' +import { IdWellContext } from '../Well' const timePeriodNames = [ { label: '1 секунда', value: 1 }, @@ -32,7 +33,7 @@ const reportFormats = [ { value: 1, label: 'LAS' }, ] -export const Report = memo(({ idWell }) => { +export const Report = memo(() => { const [aviableDateRange, setAviableDateRange] = useState([moment(), moment()]) const [filterDateRange, setFilterDateRange] = useState([ moment().subtract(1, 'days').startOf('day'), @@ -43,6 +44,8 @@ export const Report = memo(({ idWell }) => { const [pagesCount, setPagesCount] = useState(0) const [showLoader, setShowLoader] = useState(false) + const idWell = useContext(IdWellContext) + const handleReportCreation = useCallback(async () => await invokeWebApiWrapperAsync( async () => { const taskId = await ReportService.createReport( @@ -166,7 +169,7 @@ export const Report = memo(({ idWell }) => { - + ) }) diff --git a/src/pages/Telemetry/Archive/index.jsx b/src/pages/Telemetry/Archive/index.jsx index 4c37e9f..1a45d4e 100755 --- a/src/pages/Telemetry/Archive/index.jsx +++ b/src/pages/Telemetry/Archive/index.jsx @@ -1,5 +1,5 @@ /* eslint-disable react-hooks/exhaustive-deps */ -import { useState, useEffect, memo, useCallback } from 'react' +import { useState, useEffect, memo, useCallback, useContext } from 'react' import { Flex } from '@components/Grid' import LoaderPortal from '@components/LoaderPortal' @@ -8,6 +8,7 @@ import { DatePickerWrapper, makeDateSorter } from '@components/Table' import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker' import { TelemetryDataSaubService } from '@api' +import { IdWellContext } from '@pages/Well' import { normalizeData } from '../TelemetryView' import { ArchiveDisplay, cutData } from './ArchiveDisplay' @@ -61,7 +62,7 @@ const range = (start, end) => { return result } -export const Archive = memo(({ idWell }) => { +export const Archive = memo(() => { const [dataSaub, setDataSaub] = useState([]) const [dateLimit, setDateLimit] = useState({ from: 0, to: new Date() }) const [chartInterval, setChartInterval] = useState(parseInt(defaultPeriod) * 1000) @@ -69,6 +70,8 @@ export const Archive = memo(({ idWell }) => { const [showLoader, setShowLoader] = useState(false) const [loaded, setLoaded] = useState(null) + const idWell = useContext(IdWellContext) + const onGraphWheel = useCallback((e) => { if (loaded && dateLimit.from && dateLimit.to) { setStartDate((prevStartDate) => { diff --git a/src/pages/Telemetry/DashboardNNB/index.jsx b/src/pages/Telemetry/DashboardNNB/index.jsx index eb5f8b8..cf16bcf 100644 --- a/src/pages/Telemetry/DashboardNNB/index.jsx +++ b/src/pages/Telemetry/DashboardNNB/index.jsx @@ -1,4 +1,4 @@ -import { memo, useCallback, useEffect, useMemo, useReducer, useState } from 'react' +import { memo, useCallback, useContext, useEffect, useMemo, useReducer, useState } from 'react' import { useHistory, useParams } from 'react-router-dom' import { CloseOutlined } from '@ant-design/icons' import { Button, Menu, Popconfirm } from 'antd' @@ -19,10 +19,12 @@ import { WitsRecord61Service, } from '@api' +import { IdWellContext } from '@pages/Well' +import { RootPathContext } from '@pages/Main' +import AddGroupWindow from './AddGroupWindow' import AddWidgetWindow, { makeWidgetFromWits } from './AddWidgetWindow' import '@styles/dashboard_nnb.less' -import AddGroupWindow from './AddGroupWindow' const getWitsInfo = async () => { // TODO: Добавить expire с принудительным обновлением @@ -105,19 +107,21 @@ const groupsReducer = (groups, action) => { return newGroups } -export const DashboardNNB = memo(({ idWell }) => { +export const DashboardNNB = memo(() => { const [groups, dispatchGroups] = useReducer(groupsReducer, []) const [witsInfo, setWitsInfo] = useState([]) const [isLoading, setIsLoading] = useState(false) const [selectedSettings, setSelectedSettings] = useState(null) const [values, setValues] = useState({}) - const root = useMemo(() => `/well/${idWell}/telemetry/dashboard_nnb`, [idWell]) + const idWell = useContext(IdWellContext) + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/dashboard_nnb`, [root]) const history = useHistory() const { tab: selectedGroup } = useParams() if (!selectedGroup && groups?.length > 0) - history.push(`${root}/${groups[0].id}`) + history.push(`${rootPath}/${groups[0].id}`) const group = useMemo(() => ({ @@ -172,8 +176,8 @@ export const DashboardNNB = memo(({ idWell }) => { const removeGroup = useCallback((id) => { dispatchGroups({ type: 'remove_group', groupId: `${id}` }) - if (id === selectedGroup) history.push(`${root}`) - }, [root, history, selectedGroup]) + if (id === selectedGroup) history.push(`${rootPath}`) + }, [rootPath, history, selectedGroup]) const addWidget = useCallback((settings) => dispatchGroups({ type: 'add_widget', @@ -226,7 +230,7 @@ export const DashboardNNB = memo(({ idWell }) => { + ))} diff --git a/src/pages/Telemetry/Messages.jsx b/src/pages/Telemetry/Messages.jsx index 2500ada..e97732b 100755 --- a/src/pages/Telemetry/Messages.jsx +++ b/src/pages/Telemetry/Messages.jsx @@ -1,10 +1,12 @@ -import moment from 'moment' -import { useState, useEffect, memo, useCallback } from 'react' +import { useState, useEffect, memo, useCallback, useContext } from 'react' import { Table, Select, DatePicker, Input } from 'antd' -import { MessageService } from '@api' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' +import { makeColumn, makeDateColumn, makeNumericSorter } from '@components/Table' +import { MessageService } from '@api' + +import { IdWellContext } from '../Well' import '@styles/message.css' @@ -22,41 +24,18 @@ const categoryDictionary = { // Конфигурация таблицы export const columns = [ - { + makeDateColumn('Дата', 'date', undefined, undefined, { width: '10rem' }), + makeColumn('Глубина', 'wellDepth', { width: '10rem', render: depth => {depth.toFixed(2)} м. }), + makeColumn('Категория', 'categoryId', { width: '10rem', - title: 'Дата', - key: 'date', - dataIndex: 'date', - render: item => moment(item).format('DD MMM YYYY, HH:mm:ss'), - sorter: (a, b) => new Date(b.date) - new Date(a.date), - sortDirections: ['descend', 'ascend'], - }, { - width: '10rem', - title: 'Глубина', - key: 'wellDepth', - dataIndex: 'wellDepth', - render: depth => {depth.toFixed(2)} м., - }, { - width: '10rem', - title: 'Категория', - key: 'categoryId', - dataIndex: 'categoryId', render: (_, item) => categoryDictionary[item.categoryId].title, style: (_, item) => categoryDictionary[item.categoryId]?.style, - sorter: (a, b) => a.categoryId - b.categoryId, + sorter: makeNumericSorter('categoryId'), sortDirections: ['descend', 'ascend'], ellipsis: true, - }, { - title: 'Сообщение', - key: 'message', - dataIndex: 'message', - onFilter: (value, record) => record.name.indexOf(value) === 0, - }, { - width: '10rem', - title: 'Пользователь', - key: 'user', - dataIndex: 'user', - }, + }), + makeColumn('Сообщение', 'message', { onFilter: (value, record) => record.name.indexOf(value) === 0 }), + makeColumn('Пользователь', 'user', { width: '10rem' }), ] const filterOptions = [ @@ -68,7 +47,7 @@ const filterOptions = [ const children = filterOptions.map((line) => ) // Данные для таблицы -export const Messages = memo(({ idWell }) => { +export const Messages = memo(() => { const [messages, setMessages] = useState([]) const [pagination, setPagination] = useState(null) const [page, setPage] = useState(1) @@ -77,6 +56,8 @@ export const Messages = memo(({ idWell }) => { const [searchString, setSearchString] = useState('') const [showLoader, setShowLoader] = useState(false) + const idWell = useContext(IdWellContext) + const onChangeSearchString = useCallback((message) => setSearchString(message.length > 2 ? message : ''), []) useEffect(() => invokeWebApiWrapperAsync( diff --git a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx index b2fd566..f839c02 100755 --- a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx +++ b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx @@ -1,5 +1,5 @@ import { Table } from 'antd' -import { useState, useEffect, useCallback, memo } from 'react' +import { useState, useEffect, useCallback, memo, useContext } from 'react' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' @@ -7,13 +7,16 @@ import { Subscribe } from '@services/signalr' import { MessageService } from '@api' import { columns } from '../Messages' +import { IdWellContext } from '@pages/Well' import '@styles/message.css' -export const ActiveMessagesOnline = memo(({ idWell }) => { +export const ActiveMessagesOnline = memo(() => { const [messages, setMessages] = useState([]) const [loader, setLoader] = useState(false) + const idWell = useContext(IdWellContext) + const handleReceiveMessages = useCallback((messages) => { if (messages) setMessages(messages.items.splice(0, 4)) diff --git a/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx index 12006ea..985dd96 100755 --- a/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx +++ b/src/pages/Telemetry/TelemetryView/Setpoints/SetpointSender.jsx @@ -1,4 +1,4 @@ -import { memo, useCallback, useMemo, useState } from 'react' +import { memo, useCallback, useContext, useMemo, useState } from 'react' import { Select, Modal, Input, InputNumber } from 'antd' import { SetpointsService } from '@api' @@ -8,12 +8,16 @@ import { invokeWebApiWrapperAsync } from '@components/factory' import { makeNumericRender, EditableTable } from '@components/Table' import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker' -export const SetpointSender = memo(({ idWell, onClose, visible, setpointNames }) => { +import { IdWellContext } from '@pages/Well' + +export const SetpointSender = memo(({ onClose, visible, setpointNames }) => { const [expirePeriod, setExpirePeriod] = useState(defaultPeriod) const [comment, setComment] = useState('') const [setpoints, setSetpoints] = useState([]) const [isLoading, setIsLoading] = useState(false) + const idWell = useContext(IdWellContext) + const addingColumns = useMemo(() => [ { title: 'Наименование уставки', diff --git a/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx b/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx index 2339ea2..bf54c98 100755 --- a/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx +++ b/src/pages/Telemetry/TelemetryView/Setpoints/index.jsx @@ -1,5 +1,5 @@ import { Button, Modal } from 'antd' -import { useState, useEffect, memo, useCallback, useMemo } from 'react' +import { useState, useEffect, memo, useCallback, useMemo, useContext } from 'react' import { Table } from '@components/Table' import { UserView } from '@components/views' @@ -10,10 +10,11 @@ import { makeStringCutter } from '@utils/string' import { formatDate } from '@utils' import { SetpointsService } from '@api' +import { IdWellContext } from '@pages/Well' import SetpointSender from './SetpointSender' import { SetpointViewer, getSetpointStatus } from './SetpointViewer' -export const Setpoints = memo(({ idWell, ...other }) => { +export const Setpoints = memo(({ ...other }) => { const [isModalVisible, setIsModalVisible] = useState(false) const [isSenderVisible, setIsSenderVisible] = useState(false) const [isViewerVisible, setIsViewerVisible] = useState(false) @@ -22,6 +23,8 @@ export const Setpoints = memo(({ idWell, ...other }) => { const [selected, setSelected] = useState(null) const [setpointNames, setSetpointNames] = useState([]) + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => { const names = await SetpointsService.getSetpointsNamesByIdWell(idWell) @@ -102,7 +105,6 @@ export const Setpoints = memo(({ idWell, ...other }) => { { +import { IdWellContext } from '@pages/Well' + +export const WirelineRunOut = memo(() => { const [twro, setTwro] = useState({}) const [isLoading, setIsLoading] = useState(false) + const idWell = useContext(IdWellContext) + const update = useCallback(() => invokeWebApiWrapperAsync( async () => { const twro = await TelemetryWirelineRunOutService.getData(idWell) diff --git a/src/pages/Telemetry/TelemetryView/index.jsx b/src/pages/Telemetry/TelemetryView/index.jsx index c11ae6f..aa0083a 100755 --- a/src/pages/Telemetry/TelemetryView/index.jsx +++ b/src/pages/Telemetry/TelemetryView/index.jsx @@ -1,5 +1,5 @@ import { Select } from 'antd' -import { useState, useEffect, useCallback } from 'react' +import { useState, useEffect, useCallback, useContext } from 'react' import { DrillFlowChartService, @@ -22,6 +22,8 @@ import ActiveMessagesOnline from './ActiveMessagesOnline' import { ModeDisplay } from './ModeDisplay' import { UserOfWell } from './UserOfWells' import { Setpoints } from './Setpoints' +import WirelineRunOut from './WirelineRunOut' +import { IdWellContext } from '@pages/Well' import MomentStabPicEnabled from '@images/DempherOn.png' import MomentStabPicDisabled from '@images/DempherOff.png' @@ -29,7 +31,6 @@ import SpinPicEnabled from '@images/SpinEnabled.png' import SpinPicDisabled from '@images/SpinDisabled.png' import '@styles/message.css' -import WirelineRunOut from './WirelineRunOut' const { Option } = Select @@ -303,7 +304,7 @@ export const normalizeData = (data) => data?.map(item => ({ blockSpeed: Math.abs(item.blockSpeed) })) ?? [] -export default function TelemetryView({ idWell }) { +export default function TelemetryView() { const [dataSaub, setDataSaub] = useState([]) const [dataSpin, setDataSpin] = useState([]) const [chartInterval, setChartInterval] = useState(defaultPeriod) @@ -312,6 +313,8 @@ export default function TelemetryView({ idWell }) { const [flowChartData, setFlowChartData] = useState([]) const [rop, setRop] = useState(null) + const idWell = useContext(IdWellContext) + const handleDataSaub = useCallback((data) => { if (data) { const dataSaub = normalizeData(data) @@ -392,9 +395,9 @@ export default function TelemetryView({ idWell }) { - +   - + {'TorqueMaster'} {'SpinMaster'}

MSE

diff --git a/src/pages/Telemetry/index.jsx b/src/pages/Telemetry/index.jsx index 77026e1..85189ba 100755 --- a/src/pages/Telemetry/index.jsx +++ b/src/pages/Telemetry/index.jsx @@ -1,58 +1,47 @@ -import { Switch, useParams } from 'react-router-dom' -import { memo, useMemo } from 'react' +import { useParams } from 'react-router-dom' +import { memo, useContext, useMemo } from 'react' import { Layout } from 'antd' import { AlertOutlined, FundViewOutlined, DatabaseOutlined } from '@ant-design/icons' -import PrivateMenu from '@components/Private/PrivateMenu' -import { PrivateRoute, PrivateDefaultRoute } from '@components/Private' +import { PrivateSwitch, PrivateMenu } from '@components/Private' import Archive from './Archive' import Messages from './Messages' import DashboardNNB from './DashboardNNB' import TelemetryView from './TelemetryView' +import { RootPathContext } from '@pages/Main' import '@styles/index.css' const { Content } = Layout -export const Telemetry = memo(({ idWell }) => { +export const Telemetry = memo(() => { const { tab } = useParams() - const rootPath = useMemo(() => `/well/${idWell}/telemetry`, [idWell]) + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/telemetry`, [root]) return ( - - - } title={'Мониторинг'}/> - } title={'Сообщения'} /> - } title={'Архив'} /> - - - + - - - - - - - - - - - - - - - - - + + } title={'Мониторинг'}/> + } title={'Сообщения'} /> + } title={'Архив'} /> + + + + + + + + + + + + + - + ) }) diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx index 904b966..f679a67 100755 --- a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx +++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx @@ -1,15 +1,19 @@ -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useContext } from 'react' import { TelemetryAnalyticsService } from '@api' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' import { ChartTelemetryDepthToDay } from '@components/charts/ChartTelemetryDepthToDay' -export const TelemetryAnalysisDepthToDay = memo(({ idWell }) => { +import { IdWellContext } from '@pages/Well' + +export const TelemetryAnalysisDepthToDay = memo(() => { const [depthData, setDepthData] = useState([]) const [bitPositionData, setBitPositionData] = useState([]) const [loader, setLoader] = useState(false) + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => { const depthToDayData = await TelemetryAnalyticsService.getWellDepthToDay(idWell) diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx index 989165f..c5cb90e 100755 --- a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx +++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToInterval.jsx @@ -1,11 +1,13 @@ import { Select } from 'antd' -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useContext } from 'react' -import { arrayOrDefault } from '@utils' -import { TelemetryAnalyticsService } from '@api' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' import { ChartTelemetryDepthToInterval } from '@components/charts/ChartTelemetryDepthToInterval' +import { TelemetryAnalyticsService } from '@api' +import { arrayOrDefault } from '@utils' + +import { IdWellContext } from '@pages/Well' const timePeriodCollection = [ { value: '3600', label: '1 час' }, @@ -14,11 +16,13 @@ const timePeriodCollection = [ { value: '86400', label: '24 часа' } ] -export const TelemetryAnalysisDepthToInterval = memo(({ idWell }) => { +export const TelemetryAnalysisDepthToInterval = memo(() => { const [depthToIntervalData, setDepthToIntervalData] = useState([]) const [chartInterval, setChartInterval] = useState(86400) const [loader, setLoader] = useState(false) + const idWell = useContext(IdWellContext) + useEffect(() => invokeWebApiWrapperAsync( async () => { const depthToIntervalData = await TelemetryAnalyticsService.getWellDepthToInterval(idWell, chartInterval) diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx index 9337c78..37e35b5 100755 --- a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx +++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsSummary.jsx @@ -1,20 +1,24 @@ import moment from 'moment' import { Form, DatePicker } from 'antd' -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useContext } from 'react' import { TelemetryAnalyticsService } from '@api' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' import { ChartTelemetryOperationsSummary } from '@components/charts/ChartTelemetryOperationsSummary' +import { IdWellContext } from '@pages/Well' + const { RangePicker } = DatePicker -export const TelemetryAnalysisOperationsSummary = memo(({ idWell }) => { +export const TelemetryAnalysisOperationsSummary = memo(() => { const [avilableDatesRange, setAviableDatesRange] = useState([moment(),moment()]) const [filterDateRange, setFilterDateRange] = useState([moment().subtract(1, 'days'),moment()]) const [operationsData, setOperationsData] = useState([]) const [loader, setLoader] = useState(false) + const idWell = useContext(IdWellContext) + const disabledDate = (current) => current < avilableDatesRange[0] || current > avilableDatesRange[1] useEffect(() => invokeWebApiWrapperAsync( diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx index e37da57..460ccd1 100755 --- a/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx +++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisOperationsToInterval.jsx @@ -1,5 +1,5 @@ import { memo } from 'react' -export const TelemetryAnalysisOperationsToInterval = memo(({ idWell }) => (<>{idWell} 123)) +export const TelemetryAnalysisOperationsToInterval = memo(() => (<>123)) export default TelemetryAnalysisOperationsToInterval diff --git a/src/pages/TelemetryAnalysis/index.jsx b/src/pages/TelemetryAnalysis/index.jsx index 1cd423c..54bae03 100755 --- a/src/pages/TelemetryAnalysis/index.jsx +++ b/src/pages/TelemetryAnalysis/index.jsx @@ -1,24 +1,26 @@ -import { memo } from 'react' -import { Layout } from 'antd' +import { useParams } from 'react-router-dom' +import { memo, useContext, useMemo } from 'react' import { FolderOutlined } from '@ant-design/icons' -import { Switch, useParams } from 'react-router-dom' +import { Layout } from 'antd' -import { PrivateDefaultRoute, PrivateMenu, PrivateRoute } from '@components/Private' +import { PrivateMenu, PrivateSwitch } from '@components/Private' import TelemetryAnalysisDepthToDay from './TelemetryAnalysisDepthToDay' import TelemetryAnalysisDepthToInterval from './TelemetryAnalysisDepthToInterval' import TelemetryAnalysisOperationsSummary from './TelemetryAnalysisOperationsSummary' import TelemetryAnalysisOperationsToInterval from './TelemetryAnalysisOperationsToInterval' +import { RootPathContext } from '@pages/Main' const { Content } = Layout -export const TelemetryAnalysis = memo(({ idWell }) => { +export const TelemetryAnalysis = memo(() => { const { tab } = useParams() - const rootPath = `/well/${idWell}/telemetryAnalysis` + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/telemetryAnalysis`, [root]) return ( - <> - + + } key={'depthToDay'} title={'Глубина-день'} /> } key={'depthToInterval'} title={'Глубина-интервал'} /> } key={'operationsSummary'} title={'Все операции'} /> @@ -27,29 +29,15 @@ export const TelemetryAnalysis = memo(({ idWell }) => { - - - - - - - - - - - - - - - + + + + + + - + ) }) diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index 41bae5e..f3aa58c 100755 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -1,4 +1,4 @@ -import { memo, useMemo } from 'react' +import { createContext, memo, useContext, useMemo } from 'react' import { FolderOutlined, FundViewOutlined, @@ -7,9 +7,9 @@ import { DeploymentUnitOutlined, } from '@ant-design/icons' import { Layout } from 'antd' -import { Switch, useParams } from 'react-router-dom' +import { useParams } from 'react-router-dom' -import { PrivateRoute, PrivateDefaultRoute, PrivateMenu } from '@components/Private' +import { PrivateMenu, PrivateSwitch } from '@components/Private' import Report from './Report' import Measure from './Measure' @@ -19,69 +19,51 @@ import Telemetry from './Telemetry' import WellOperations from './WellOperations' import DrillingProgram from './DrillingProgram' import TelemetryAnalysis from './TelemetryAnalysis' +import { RootPathContext } from './Main' import '@styles/index.css' const { Content } = Layout +export const IdWellContext = createContext(null) + export const Well = memo(() => { const { idWell, tab } = useParams() - const rootPath = useMemo(() => `/well/${idWell}`, [idWell]) + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/well/${idWell}`, [root, idWell]) return ( - - - } title={'Телеметрия'}/> - } title={'Рапорт'} /> - } title={'Аналитика'} /> - } title={'Операции по скважине'} /> - {/* } title={'Операции по телеметрии'} /> */} - } title={'Документы'} /> - } title={'Измерения'} /> - } title={'Программа бурения'} /> - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + } title={'Телеметрия'}/> + } title={'Рапорт'} /> + } title={'Аналитика'} /> + } title={'Операции по скважине'} /> + {/* } title={'Операции по телеметрии'} /> */} + } title={'Документы'} /> + } title={'Измерения'} /> + } title={'Программа бурения'} /> + + + + + + + + + + + + + + + + + + - + ) }) diff --git a/src/pages/WellOperations/DrillProcessFlow.jsx b/src/pages/WellOperations/DrillProcessFlow.jsx index 878d410..b451c25 100755 --- a/src/pages/WellOperations/DrillProcessFlow.jsx +++ b/src/pages/WellOperations/DrillProcessFlow.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, memo } from 'react' +import { useState, useEffect, memo, useContext } from 'react' import { EditableTable, @@ -11,6 +11,8 @@ import { invokeWebApiWrapperAsync } from '@components/factory' import { hasPermission } from '@utils/permissions' import { arrayOrDefault } from '@utils' +import { IdWellContext } from '../Well' + const columns = [ makeNumericStartEnd('Глубина, м', 'depth'), makeNumericMinMax('Нагрузка, т', 'axialLoad'), @@ -20,10 +22,12 @@ const columns = [ makeNumericMinMax('Расход, л/с', 'flow') ] -export const DrillProcessFlow = memo(({ idWell }) => { +export const DrillProcessFlow = memo(() => { const [flows, setFlows] = useState([]) const [showLoader, setShowLoader] = useState(false) + const idWell = useContext(IdWellContext) + const updateFlows = () => invokeWebApiWrapperAsync( async () => { const flows = await DrillFlowChartService.get(idWell) diff --git a/src/pages/WellOperations/Tvd/index.jsx b/src/pages/WellOperations/Tvd/index.jsx index c35a2d3..6f61e78 100755 --- a/src/pages/WellOperations/Tvd/index.jsx +++ b/src/pages/WellOperations/Tvd/index.jsx @@ -1,5 +1,5 @@ import { useHistory } from 'react-router-dom' -import { memo, useState, useRef, useEffect, useCallback } from 'react' +import { memo, useState, useRef, useEffect, useCallback, useContext, useMemo } from 'react' import { DoubleLeftOutlined, DoubleRightOutlined } from '@ant-design/icons' import { Switch, Button } from 'antd' @@ -27,6 +27,7 @@ import AdditionalTables from './AdditionalTables' import '@styles/index.css' import '@styles/tvd.less' +import { IdWellContext } from '@asb/pages/Well' Chart.register( TimeScale, @@ -114,13 +115,16 @@ const makeDataset = (data, label, color, borderWidth = 1.5, borderDash) => ({ borderDash, }) -export const Tvd = memo(({ idWell, title, ...other }) => { +export const Tvd = memo(({ idWell: wellId, title, ...other }) => { const [chart, setChart] = useState() const [xLabel, setXLabel] = useState('day') const [operations, setOperations] = useState({}) const [tableVisible, setTableVisible] = useState(false) const [isLoading, setIsLoading] = useState(false) + const idWellContext = useContext(IdWellContext) + const idWell = useMemo(() => wellId ?? idWellContext, [wellId, idWellContext]) + const chartRef = useRef(null) const history = useHistory() diff --git a/src/pages/WellOperations/WellDrillParams.jsx b/src/pages/WellOperations/WellDrillParams.jsx index b113209..79b7e63 100755 --- a/src/pages/WellOperations/WellDrillParams.jsx +++ b/src/pages/WellOperations/WellDrillParams.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, memo, useMemo } from 'react' +import { useState, useEffect, useCallback, memo, useMemo, useContext } from 'react' import { EditableTable, @@ -13,6 +13,8 @@ import { DrillParamsService, WellOperationService } from '@api' import { hasPermission } from '@utils/permissions' import { arrayOrDefault } from '@utils' +import { IdWellContext } from '../Well' + export const getColumns = async (idWell) => { let sectionTypes = await WellOperationService.getSectionTypes(idWell) sectionTypes = Object.entries(sectionTypes).map(([id, value]) => ({ @@ -34,11 +36,13 @@ export const getColumns = async (idWell) => { ] } -export const WellDrillParams = memo(({ idWell }) => { +export const WellDrillParams = memo(() => { const [params, setParams] = useState([]) const [showLoader, setShowLoader] = useState(false) const [columns, setColumns] = useState([]) + const idWell = useContext(IdWellContext) + const updateParams = useCallback(async () => await invokeWebApiWrapperAsync( async () => { const params = arrayOrDefault(await DrillParamsService.getAll(idWell)) diff --git a/src/pages/WellOperations/WellOperationsEditor.jsx b/src/pages/WellOperations/WellOperationsEditor.jsx index 033a6f0..6c50d0f 100755 --- a/src/pages/WellOperations/WellOperationsEditor.jsx +++ b/src/pages/WellOperations/WellOperationsEditor.jsx @@ -1,7 +1,7 @@ import moment from 'moment' import { Input } from 'antd' import { useLocation } from 'react-router-dom' -import { useState, useEffect, memo, useMemo, useCallback } from 'react' +import { useState, useEffect, memo, useMemo, useCallback, useContext } from 'react' import { EditableTable, @@ -21,6 +21,8 @@ import { hasPermission } from '@utils/permissions' import { arrayOrDefault } from '@utils' import { WellOperationService } from '@api' +import { IdWellContext } from '../Well' + const { TextArea } = Input const basePageSize = 160 @@ -52,12 +54,14 @@ const generateColumns = (showNpt = false, categories = [], sectionTypes = []) => makeTextColumn('Комментарий', 'comment', null, null, null, { editable: true, input: