diff --git a/src/components/views/TelemetryView.tsx b/src/components/views/TelemetryView.tsx index 30401ff..702ebd2 100644 --- a/src/components/views/TelemetryView.tsx +++ b/src/components/views/TelemetryView.tsx @@ -4,7 +4,7 @@ import { Tooltip } from 'antd' import { TelemetryDto, TelemetryInfoDto } from '@api' import { Grid, GridItem } from '@components/Grid' -const lables: Record = { +export const lables: Record = { timeZoneId: 'Временная зона', timeZoneOffsetTotalHours: 'Сдвиг временной зоны', drillingStartDate: 'Начало бурения', diff --git a/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx b/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx new file mode 100644 index 0000000..67761e8 --- /dev/null +++ b/src/pages/AdminPanel/Telemetry/TelemetryMerger.jsx @@ -0,0 +1,136 @@ +import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import { useLocation } from 'react-router-dom' +import { PullRequestOutlined } from '@ant-design/icons' +import { Button, Descriptions, Popconfirm } from 'antd' + +import { Grid, GridItem } from '@components/Grid' +import LoaderPortal from '@components/LoaderPortal' +import { lables } from '@components/views/TelemetryView' +import { invokeWebApiWrapperAsync } from '@components/factory' +import TelemetrySelect from '@components/selectors/TelemetrySelect' +import { AdminTelemetryService } from '@api' +import { arrayOrDefault } from '@utils' + +const { Item } = Descriptions + +export const TelemetryInfo = memo(({ info, danger, ...other }) => ( + + {Object.keys({ ...lables, ...info }).map(key => ( + {info?.[key] ?? '-'} + ))} + +)) + +export const TelemetryMerger = memo(() => { + const [primary, setPrimary] = useState(null) + const [secondary, setSecondary] = useState(null) + const [telemetry, setTelemetry] = useState([]) + const [isLoading, setIsLoading] = useState(false) + const [isMerging, setIsMerging] = useState(false) + + const location = useLocation() + + const danger = useMemo(() => [ + primary?.info?.well !== secondary?.info?.well && 'well', + primary?.info?.cluster !== secondary?.info?.cluster && 'cluster', + primary?.info?.deposit !== secondary?.info?.deposit && 'deposit', + ], [primary, secondary]) + + const updateTelemetry = useCallback(async () => await invokeWebApiWrapperAsync( + async () => { + const telemetry = arrayOrDefault(await AdminTelemetryService.getAll()) + setTelemetry(telemetry) + }, + setIsLoading, + 'Не удалось загрузить список телеметрий', + 'Получение списка телеметрий', + ), []) + + const mergeTelemetry = useCallback(() => invokeWebApiWrapperAsync( + async () => { + await new Promise(res => setTimeout(res, 1000)) + /// await AdminTelemetryService.mergeTelemetries(secondary.id, primary.id) + await updateTelemetry() + }, + setIsMerging, + 'Не удалось объединить телеметрии', + 'Объединение телеметрий', + ), [primary, secondary]) + + useEffect(() => updateTelemetry(), []) + + useEffect(() => { + const query = new URLSearchParams(location.search) + const primaryId = parseInt(query.get('primary') ?? null) + 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]) + + return ( + +
{ + ///TODO: Добавить описание + }
+ + Результирующая телеметрия + Исходная телеметрия + + + + + + + + + + + + + + + + + + +
+ ) +}) + +export default TelemetryMerger diff --git a/src/pages/AdminPanel/TelemetryController.jsx b/src/pages/AdminPanel/Telemetry/TelemetryViewer.jsx similarity index 51% rename from src/pages/AdminPanel/TelemetryController.jsx rename to src/pages/AdminPanel/Telemetry/TelemetryViewer.jsx index 716d6e7..2441e82 100644 --- a/src/pages/AdminPanel/TelemetryController.jsx +++ b/src/pages/AdminPanel/Telemetry/TelemetryViewer.jsx @@ -1,39 +1,70 @@ -import { memo, useEffect, useMemo, useState } from 'react' -import { Input } from 'antd' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import { PullRequestOutlined } from '@ant-design/icons' +import { Button, Input } from 'antd' import { defaultPagination, + makeColumn, makeDateSorter, makeNumericColumn, makeNumericRender, makeTextColumn, Table } from '@components/Table' +import Poprompt from '@components/selectors/Poprompt' import { invokeWebApiWrapperAsync } from '@components/factory' import { AdminTelemetryService } from '@api' import { arrayOrDefault } from '@utils' - -const columns = [ - makeNumericColumn('ID', 'id', null, null, makeNumericRender(0)), - makeTextColumn('UID', 'remoteUid'), - makeTextColumn('Назначена на скважину', 'realWell'), - makeTextColumn('Дата начала бурения', 'drillingStartDate', null, makeDateSorter('drillingStartDate')), - makeTextColumn('Часовой пояс', 'timeZoneId'), - makeTextColumn('Скважина', 'well'), - makeTextColumn('Куст', 'cluster'), - makeTextColumn('Месторождение', 'deposit'), - makeTextColumn('Заказчик', 'customer'), - makeTextColumn('Комментарий', 'comment'), - makeTextColumn('Версия HMI', 'hmiVersion'), - makeTextColumn('Версия САУБ', 'saubPlcVersion'), - makeTextColumn('Версия Спин Мастер', 'spinPlcVersion'), -] +import { useHistory } from 'react-router-dom' export const TelemetryController = memo(() => { const [telemetryData, setTelemetryData] = useState([]) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const history = useHistory() + + const toMerger = useCallback((type, id) => () => history.push(`/admin/telemetry/merger/?${type}=${id}`), [history]) + + const mergeRender = useCallback((value, record) => ( + , + size: 'small', + danger: !!value, + }} + footer={( +
+ + +
+ )} + > +

Вы собираетесь использовать данную телеметрию для слияния

+ {record.well && ( +

Внимание! Телеметрии назначена скважина!

+ )} +
+ ), [toMerger]) + + const columns = useMemo(() => [ + makeColumn('', 'hasParent', { render: mergeRender }), + makeNumericColumn('ID', 'id', null, null, makeNumericRender(0)), + makeTextColumn('UID', 'remoteUid'), + makeTextColumn('Назначена на скважину', 'realWell'), + makeTextColumn('Дата начала бурения', 'drillingStartDate', null, makeDateSorter('drillingStartDate')), + makeTextColumn('Часовой пояс', 'timeZoneId'), + makeTextColumn('Скважина', 'well'), + makeTextColumn('Куст', 'cluster'), + makeTextColumn('Месторождение', 'deposit'), + makeTextColumn('Заказчик', 'customer'), + makeTextColumn('Комментарий', 'comment'), + makeTextColumn('Версия HMI', 'hmiVersion'), + makeTextColumn('Версия САУБ', 'saubPlcVersion'), + makeTextColumn('Версия Спин Мастер', 'spinPlcVersion'), + ], [mergeRender]) + const filteredTelemetryData = useMemo(() => telemetryData.filter((telemetry) => telemetry && (!searchValue || [ telemetry.id?.toString() ?? '', telemetry.remoteUid ?? '', diff --git a/src/pages/AdminPanel/Telemetry/index.jsx b/src/pages/AdminPanel/Telemetry/index.jsx new file mode 100644 index 0000000..0db46d6 --- /dev/null +++ b/src/pages/AdminPanel/Telemetry/index.jsx @@ -0,0 +1,42 @@ +import { Layout, Menu } from 'antd' +import { lazy, memo, Suspense } from 'react' +import { Switch, useParams } from 'react-router-dom' + +import { PrivateMenuItem, PrivateRoute, PrivateDefaultRoute } from '@components/Private' + +import { SuspenseFallback } from '@pages/SuspenseFallback' + +const TelemetryViewer = lazy(() => import('./TelemetryViewer')) +const TelemetryMerger = lazy(() => import('./TelemetryMerger')) + +const rootPath = '/admin/telemetry' + +export const Telemetry = memo(() => { + const { tab } = useParams() + + return ( + + + + + + + + + }> + + + + + + + + + + ) +}) + +export default Telemetry diff --git a/src/pages/AdminPanel/index.jsx b/src/pages/AdminPanel/index.jsx index 5a64775..6be3a32 100644 --- a/src/pages/AdminPanel/index.jsx +++ b/src/pages/AdminPanel/index.jsx @@ -1,5 +1,5 @@ import { Layout, Menu } from 'antd' -import { lazy, Suspense } from 'react' +import { lazy, memo, Suspense } from 'react' import { Switch, useParams } from 'react-router-dom' import { PrivateMenuItem, PrivateRoute, PrivateDefaultRoute } from '@components/Private' @@ -14,12 +14,12 @@ const WellController = lazy(() => import( './WellController')) const RoleController = lazy(() => import( './RoleController')) const CompanyTypeController = lazy(() => import('./CompanyTypeController')) const PermissionController = lazy(() => import( './PermissionController')) -const TelemetryController = lazy(() => import( './TelemetryController')) +const TelemetrySection = lazy(() => import( './Telemetry')) const VisitLog = lazy(() => import( './VisitLog')) const rootPath = '/admin' -export const AdminPanel = () => { +export const AdminPanel = memo(() => { const { tab } = useParams() return ( @@ -33,7 +33,7 @@ export const AdminPanel = () => { - + @@ -41,16 +41,16 @@ export const AdminPanel = () => { }> - - - - - - - - - - + + + + + + + + + + { ) -} +}) export default AdminPanel diff --git a/src/utils/permissions.ts b/src/utils/permissions.ts index 8521992..c44a9a7 100644 --- a/src/utils/permissions.ts +++ b/src/utils/permissions.ts @@ -78,7 +78,10 @@ export const requirements: PermissionRecord = { permission: ['AdminPermission.get'], role: ['AdminUserRole.get', 'AdminPermission.get'], visit_log: ['RequerstTracker.get'], - telemetry: ['AdminTelemetry.get'], + telemetry: { + merger: ['AdminTelemetry.get'], + viewer: ['AdminTelemetry.get'], + }, }, deposit: ['Deposit.get', 'Cluster.get'], cluster: {