Удалены старые страницы, использующие TelemetryAnalytics

This commit is contained in:
goodmice 2022-04-29 12:10:42 +05:00
parent f0659f234c
commit 9e8648d33e
12 changed files with 0 additions and 931 deletions

View File

@ -1,163 +0,0 @@
import { Table, Select, DatePicker } from "antd";
import { TelemetryAnalyticsService } from "../src/services/api";
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import notify from "../src/components/notify";
import LoaderPortal from "../src/components/LoaderPortal";
import moment from "moment";
import "../styles/message.css";
const { Option } = Select;
const pageSize = 26;
const { RangePicker } = DatePicker;
const columns = [
{
title: "Название операции",
key: "name",
dataIndex: "name",
},
{
title: "Дата начала операции",
key: "beginDate",
dataIndex: "beginDate",
render: (item) => moment.utc(item).local().format("DD MMM YYYY, HH:mm:ss"),
},
{
title: "Дата окончания операции",
key: "endDate",
dataIndex: "endDate",
render: (item) => moment.utc(item).local().format("DD MMM YYYY, HH:mm:ss"),
},
{
title: "Глубина скважины в начале операции",
key: "beginWellDepth",
dataIndex: "startWellDepth",
},
{
title: "Глубина скважины в конце операции",
key: "endWellDepth",
dataIndex: "endWellDepth",
},
];
const filterOptions = [
{ label: "Невозможно определить операцию", value: 1 },
{ label: "Роторное бурение", value: 2 },
{ label: "Слайдирование", value: 3 },
{ label: "Подъем с проработкой", value: 4 },
{ label: "Спуск с проработкой", value: 5 },
{ label: "Подъем с промывкой", value: 6 },
{ label: "Спуск с промывкой", value: 7 },
{ label: "Спуск в скважину", value: 8 },
{ label: "Спуск с вращением", value: 9 },
{ label: "Подъем из скважины", value: 10 },
{ label: "Подъем с вращением", value: 11 },
{ label: "Промывка в покое", value: 12 },
{ label: "Промывка с вращением", value: 13 },
{ label: "Удержание в клиньях", value: 14 },
{ label: "Неподвижное состояние", value: 15 },
{ label: "Вращение без циркуляции", value: 16 },
{ label: "На поверхности", value: 17 },
];
export default function WellTelemetryAnalysis() {
let { id } = useParams();
const [page, setPage] = useState(1);
const [range, setRange] = useState([]);
const [categories, setCategories] = useState([]);
const [pagination, setPagination] = useState(null);
const [operations, setOperations] = useState([]);
const [loader, setLoader] = useState(false);
const children = filterOptions.map((line) => (
<Option key={line.value}>{line.label}</Option>
));
const onChangeRange = (range) => {
setRange(range);
};
useEffect(() => {
const GetOperations = async () => {
setLoader(true);
try {
let begin = null;
let end = null;
if (range?.length > 1) {
begin = range[0].toISOString();
end = range[1].toISOString();
}
await TelemetryAnalyticsService.getOperationsByWell(
`${id}`,
(page - 1) * pageSize,
pageSize,
categories,
begin,
end
).then((paginatedOperations) => {
setOperations(
paginatedOperations?.items.map((o) => {
return {
key: o.id,
begin: o.date,
...o,
};
})
);
setPagination({
total: paginatedOperations?.count,
current: Math.floor(paginatedOperations?.skip / pageSize),
});
});
} catch (ex) {
notify(`Не удалось загрузить операции по скважине "${id}"`, "error");
console.log(ex);
}
setLoader(false);
};
GetOperations();
}, [id, categories, range, page]);
return (
<>
<div className="filter-group">
<h3 className="filter-group-heading">Фильтр операций</h3>
<Select
mode="multiple"
allowClear
placeholder="Фильтр операций"
className="filter-selector"
value={categories}
onChange={setCategories}
>
{children}
</Select>
<RangePicker
showTime
placeholder={["Дата начала операции", "Дата окончания операции"]}
onChange={onChangeRange}
/>
</div>
<LoaderPortal show={loader}>
<Table
columns={columns}
dataSource={operations}
size={"small"}
pagination={{
pageSize: pageSize,
showSizeChanger: false,
total: pagination?.total,
current: page,
onChange: (page) => setPage(page),
}}
rowKey={(record) => record.id}
/>
</LoaderPortal>
</>
);
}

View File

@ -1,41 +0,0 @@
import moment from 'moment'
import { DatePicker } from 'antd'
import { useState, useEffect } from 'react'
import { useParams } from 'react-router-dom'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { TelemetryAnalyticsService } from '@api'
import { ChartOperationTime } from './charts/ChartOperationTime'
const { RangePicker } = DatePicker
const lines = [{ labelAccessorName: 'processName', pieceAccessorName: 'duration' }]
export const AnalysisOperationTime = () => {
const { id } = useParams()
const [operationTimeData, setOperationTimeData] = useState([])
const [loader, setLoader] = useState(false)
const [range, setRange] = useState([moment().subtract(1,'days'), moment()])
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const begin = range?.length > 1 ? range[0].toISOString() : null
const end = range?.length > 1 ? range[1].toISOString() : null
const summary = await TelemetryAnalyticsService.getOperationsSummary(id, begin, end)
setOperationTimeData(summary)
},
setLoader,
`Не удалось получить данные для анализа Операция-Время по скважине '${id}' за период с ${begin} по ${end}`,
'Получение данных для анализа Операция-Время по скважине'
), [id, range])
return (
<LoaderPortal show={loader}>
<RangePicker showTime onChange={(range) => setRange(range)} />
<ChartOperationTime data={operationTimeData} lines={lines} />
</LoaderPortal>
)
}
export default AnalysisOperationTime

View File

@ -1,68 +0,0 @@
import moment from 'moment'
import { useEffect, useState } from 'react'
import { ChartOpertationTimeBase } from './ChartOperationTimeBase'
export const CreateLabels = () => {
let labels = []
return labels
}
export const CreateData = (lineConfig) => {
let datasets = {
label: lineConfig.label,
data: [],
backgroundColor: [
'#f00', '#ff0', '#f0f', '#0ff', '#00f', '#0f0'
],
}
return datasets
}
export const ChartOperationTime = ({ lines, data, rangeDate }) => {
const [opertationTimeDataParams, setOpertationTimeDataParams] = useState({ data: { labels: [], datasets: [] } })
useEffect(() => {
if ((!lines)
|| (!data))
return
let newLabels = lines.map(lineCfg => {
let labels = CreateLabels(lineCfg)
if (data.length !== 0)
labels = data.map(dataItem => {
return dataItem[lineCfg.labelAccessorName]
})
return labels
})
let newDatasets = lines.map(lineCfg => {
let datasets = CreateData(lineCfg)
if (data.length !== 0)
datasets.data = data.map(dataItem => {
return dataItem[lineCfg.pieceAccessorName]
})
return datasets
})
let interval = rangeDate ? (rangeDate[1] - rangeDate[0]) / 1000 : null
let startDate = rangeDate ? rangeDate[0] : moment()
let newParams = {
xInterval: interval,
xStart: startDate,
data: {
labels: newLabels,
datasets: newDatasets
}
}
setOpertationTimeDataParams(newParams)
console.log(newParams)
}, [data, lines, rangeDate])
return (<>
<ChartOpertationTimeBase dataParams={opertationTimeDataParams} />
</>
)
}

View File

@ -1,177 +0,0 @@
import { useEffect, useRef, useState } from 'react'
import {
Chart,
ArcElement,
TimeScale,
Legend,
PointElement,
ChartData,
ChartTypeRegistry,
ChartOptions,
DoughnutController,
} from 'chart.js'
import 'chartjs-adapter-moment'
import ChartDataLabels from 'chartjs-plugin-datalabels'
Chart.register(TimeScale, DoughnutController, PointElement, ArcElement, Legend, ChartDataLabels)
const defaultOptions = {
responsive: true,
title: {
display: true,
position: 'top',
text: 'Doughnut Chart',
fontSize: 18,
fontColor: '#111'
},
legend: {
display: true,
position: 'bottom',
labels: {
fontColor: '#333',
fontSize: 16
}
}
}
export type ChartTimeData = ChartData<keyof ChartTypeRegistry, {
x: String
label: number
y: number
}[], unknown>
export type ChartTimeDataParams = {
data: ChartTimeData,
xStart?: Date,
xInterval?: number,
displayLabels?: Boolean,
}
export type ChartTimeBaseProps = {
dataParams: ChartTimeDataParams,
// TODO: Create good type for options
options?: ChartOptions<keyof ChartTypeRegistry> | any,
}
export type TimeParams = {
unit: String
stepSize: number
}
const linesPerInterval = 32
export const timeUnitByInterval = (intervalSec: number): String => {
if (intervalSec <= 60)
return 'millisecond'
if (intervalSec <= 32 * 60)
return 'second'
if (intervalSec <= 32 * 60 * 60)
return 'minute'
if (intervalSec <= 32 * 12 * 60 * 60)
return 'hour'
if (intervalSec <= 32 * 24 * 60 * 60)
return 'day'
if (intervalSec <= 32 * 7 * 24 * 60 * 60)
return 'week'
if (intervalSec <= 32 * 30.4375 * 24 * 60 * 60)
return 'month'
if (intervalSec <= 32 * 121.75 * 24 * 60 * 60)
return 'quarter'
else
return 'year'
}
export const timeParamsByInterval = (intervalSec: number): TimeParams => {
let stepSize = intervalSec
let unit = timeUnitByInterval(intervalSec)
switch (unit) {
case 'millisecond':
stepSize *= 1000
break
case 'second':
//stepSize *= 1
break
case 'minute':
stepSize /= 60
break
case 'hour':
stepSize /= 60 * 60
break
case 'day':
stepSize /= 24 * 60 * 60
break
case 'week':
stepSize /= 7 * 24 * 60 * 60
break
case 'month':
stepSize /= 30 * 24 * 60 * 60
break
case 'quarter':
stepSize /= 91 * 24 * 60 * 60
break
case 'year':
stepSize /= 365.25 * 24 * 60 * 60
break
}
stepSize = Math.round(stepSize / linesPerInterval)
stepSize = stepSize > 0 ? stepSize : 1
return { unit, stepSize }
}
export const ChartOpertationTimeBase: React.FC<ChartTimeBaseProps> = ({ options, dataParams }) => {
const chartRef = useRef<HTMLCanvasElement>(null)
const [chart, setChart] = useState<any>()
useEffect(() => {
if ((chartRef.current) && (!chart)) {
let thisOptions = {}
Object.assign(thisOptions, defaultOptions, options)
let newChart = new Chart(chartRef.current, {
type: 'doughnut',
plugins: [ChartDataLabels],
options: thisOptions,
data: dataParams.data
})
setChart(newChart)
return () => chart?.destroy()
}
}, [chart, options, dataParams])
useEffect(() => {
if (!chart)
return
chart.data = dataParams.data
chart.options.aspectRatio = options?.aspectRatio
if (dataParams.xStart) {
let interval = Number(dataParams.xInterval ?? 600)
let start = new Date(dataParams.xStart)
let end = new Date(dataParams.xStart)
end.setSeconds(end.getSeconds() + interval)
let { unit, stepSize } = timeParamsByInterval(interval)
if (chart.options.scales?.x) {
chart.options.scales.x.max = end.getTime()
chart.options.scales.x.min = start.getTime()
chart.options.scales.x.ticks.display = dataParams.displayLabels ?? true
chart.options.scales.x.time.unit = unit
chart.options.scales.x.time.stepSize = stepSize
}
}
chart.update()
}, [chart, dataParams, options])
return (<canvas ref={chartRef} />)
}

View File

@ -1,99 +0,0 @@
import { useEffect, useRef, useState } from 'react'
import {
Chart,
TimeScale,
LinearScale,
Legend,
LineController,
PointElement,
LineElement
} from 'chart.js'
import 'chartjs-adapter-moment'
import ChartDataLabels from 'chartjs-plugin-datalabels'
import zoomPlugin from 'chartjs-plugin-zoom'
Chart.register(TimeScale, LinearScale, LineController, LineElement, PointElement, Legend, ChartDataLabels, zoomPlugin)
const defaultOptions = {
responsive: true,
aspectRatio: 2.45,
scales: {
x: {
type: 'time',
time: {
unit: 'hour',
displayFormats: {
hour: 'MM.DD'
},
tooltipFormat: 'DD T'
},
},
y: {
type: 'linear',
position: 'top',
reverse: true,
// ticks: {
// // forces step size to be 50 units
// stepSize: 50
// }
}
},
parsing: {
xAxisKey: 'date',
yAxisKey: 'depth'
},
elements: {
point: {
radius: 1.7,
hoverRadius: 5,
},
},
plugins: {
datalabels: {
display: false,
},
}
}
const makeDataset = (data, label, color, width = 1.5, dash) => ({
label: label,
data: data,
backgroundColor: color,
borderColor: color,
borderWidth: width,
borderDash: dash,
})
export const ChartTelemetryDepthToDay = ({ depthData, bitPositionData }) => {
const chartRef = useRef(null)
const [chart, setChart] = useState()
useEffect(() => {
const data = {
datasets: [
makeDataset(depthData, 'Глубина', '#0A0'),
makeDataset(bitPositionData, 'Положение долота', 'blue'),
]
}
if(chartRef.current && !chart) {
const thisOptions = {}
Object.assign(thisOptions, defaultOptions)
const newChart = new Chart(chartRef.current, {
type: 'line',
plugins: [ChartDataLabels],
options: thisOptions,
data: data
})
setChart(newChart)
return () => chart?.destroy()
} else {
chart.data = data
chart.update()
}
}, [chart, depthData, bitPositionData])
return(<canvas ref={chartRef} />)
}

View File

@ -1,74 +0,0 @@
import { useEffect, useRef, useState } from 'react'
import { Chart, registerables } from 'chart.js'
Chart.register(...registerables)
const defaultOptions = {
responsive: true,
aspectRatio: 2.6,
scales: {
x: {
title: {
display: true,
text: 'Дата начала интервала'
},
},
y: {
title: {
display: true,
text: 'Коэффициент скорости'
}
}
},
plugins: {
datalabels: {
display: false
}
}
}
export const ChartTelemetryDepthToInterval = ({ depthToIntervalData }) => {
const chartRef = useRef(null)
const [chart, setChart] = useState()
const calculateBarWidth = (dataLength) => {
if (dataLength < 3) return 150
if (dataLength < 16) return 70
return 10
}
useEffect(() => {
const xData = depthToIntervalData.map(el => new Date(el.intervalStartDate).toLocaleString())
const yData = depthToIntervalData.map(el => el.intervalDepthProgress.toFixed(3))
const data = {
labels: xData,
datasets: [{
label: 'Скорость проходки за интервал',
data: yData,
borderColor: '#00b300',
borderWidth: 2,
backgroundColor: '#0A0',
barThickness: calculateBarWidth(xData.length)
}]
}
const thisOptions = {}
Object.assign(thisOptions, defaultOptions)
if (chartRef.current && !chart) {
const newChart = new Chart(chartRef.current, {
type: 'bar',
options: thisOptions,
data: data
})
setChart(newChart)
} else {
chart.data = data
chart.options = thisOptions
chart.update()
}
}, [chart, depthToIntervalData])
return (<canvas ref={chartRef} />)
}

View File

@ -1,89 +0,0 @@
import { useEffect, useRef, useState } from 'react'
import { Chart, registerables } from 'chart.js'
Chart.register(...registerables)
const transformSecondsToHoursString = (seconds) => {
const hours = Math.floor(seconds / 3600)
const minutes = Math.floor((seconds % 3600) / 60)
const s = seconds - (hours * 3600) - (minutes * 60)
return `${hours} ч.${minutes} мин.${s} сек.`
}
const transformSecondsToTimeString = (seconds) => {
if (seconds === 1) // 1 is default state if null returned (1 is to show chart anyway with 0 sec)
return '0 сек.'
else if(seconds < 60)
return seconds + ' сек.'
else if (seconds < 3600)
return Math.floor(seconds / 60) + ' мин. ' + (0.6 * (seconds % 60)).toFixed() + ' сек.'
else
return transformSecondsToHoursString(seconds)
}
const defaultOptions = {
responsive: true,
aspectRatio: 2.8,
plugins: {
datalabels: {
color: '#ffffff',
formatter: transformSecondsToTimeString,
font: {
weight: 'bold'
}
},
tooltip: {
callbacks: {
label: (tooltipItem) => transformSecondsToTimeString(tooltipItem.parsed),
}
}
}
}
const chartPartsColors = [
'#54a60c', '#0ca68a', '#0c8aa6', '#0c57a6', '#0c33a6',
'#6f10d5', '#d510a1', '#f1bc41', '#c5f141', '#41f196',
'#41cbf1', '#4196f1', '#bf41f1', '#41f1c5', '#cbf141',
'#f1ce41', '#f17f41', '#f14141', '#34b40e', '#420eb4'
]
export const ChartTelemetryOperationsSummary = ({ operationsData }) => {
const chartRef = useRef(null)
const [chart, setChart] = useState()
useEffect(() => {
const namesData = operationsData?.map(el => el.operationName) ?? ['Нет операций']
const durationsData = operationsData?.map(el => el.duration) ?? [1]
const data = {
labels: namesData,
datasets: [
{
label: 'Скорость проходки за интервал',
data: durationsData,
borderColor: chartPartsColors,
backgroundColor: chartPartsColors,
}
]
}
const thisOptions = {}
Object.assign(thisOptions, defaultOptions)
if (chartRef.current && !chart) {
const newChart = new Chart(chartRef.current, {
type: 'doughnut',
options: thisOptions,
data: data
})
setChart(newChart)
} else {
chart.data = data
chart.options = thisOptions
chart.update()
}
}, [chart, operationsData])
return (<canvas ref={chartRef} />)
}

View File

@ -1,46 +0,0 @@
import { useState, useEffect, memo, useContext } from 'react'
import { IdWellContext } from '@asb/context'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { ChartTelemetryDepthToDay } from '@components/charts/ChartTelemetryDepthToDay'
import { TelemetryAnalyticsService } from '@api'
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)
const depths = depthToDayData.map(el => ({depth: el.wellDepth, date: el.date}))
.sort((a, b) => new Date(a.date) - new Date(b.date))
setDepthData(depths)
const bitPositions = depthToDayData.map(el => ({depth: el.bitDepth, date: el.date}))
.sort((a, b) => new Date(a.date) - new Date(b.date))
setBitPositionData(bitPositions)
},
setLoader,
`Не удалось получить данные для анализа Глубина-День по скважине "${idWell}"`,
'Получение данных для анализа Глубина-День'
), [idWell])
return (
<LoaderPortal show={loader}>
<div className={'mt-20px'}>
<ChartTelemetryDepthToDay
depthData={depthData}
bitPositionData={bitPositionData}
/>
</div>
</LoaderPortal>
)
})
export default TelemetryAnalysisDepthToDay

View File

@ -1,53 +0,0 @@
import { Select } from 'antd'
import { useState, useEffect, memo, useContext } from 'react'
import { IdWellContext } from '@asb/context'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { ChartTelemetryDepthToInterval } from '@components/charts/ChartTelemetryDepthToInterval'
import { TelemetryAnalyticsService } from '@api'
import { arrayOrDefault } from '@utils'
const timePeriodCollection = [
{ value: '3600', label: '1 час' },
{ value: '21600', label: '6 часов' },
{ value: '43200', label: '12 часов' },
{ value: '86400', label: '24 часа' }
]
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)
setDepthToIntervalData(arrayOrDefault(depthToIntervalData))
},
setLoader,
`Не удалось получить данные для анализа скорость проходки-интервал "${idWell}"`,
'Получение данных для анализа скорость проходки-интервал'
), [idWell, chartInterval])
return (
<LoaderPortal show={loader}>
<div className={'mt-20px'}>
<Select
options={timePeriodCollection}
onChange={setChartInterval}
defaultValue={'86400'}
className={'ml-30px'}
/>
<ChartTelemetryDepthToInterval
depthToIntervalData={depthToIntervalData}
/>
</div>
</LoaderPortal>
)
})
export default TelemetryAnalysisDepthToInterval

View File

@ -1,72 +0,0 @@
import moment from 'moment'
import { Form, DatePicker } from 'antd'
import { useState, useEffect, memo, useContext } from 'react'
import { IdWellContext } from '@asb/context'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { ChartTelemetryOperationsSummary } from '@components/charts/ChartTelemetryOperationsSummary'
import { TelemetryAnalyticsService } from '@api'
const { RangePicker } = DatePicker
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(
async() => {
const datesRange = await TelemetryAnalyticsService.getOperationsDateRange(idWell)
setAviableDatesRange(datesRange)
},
setLoader,
`Не удалось загрузить диапозон дат для скважины "${idWell}"`,
'Получение диапозона дат телеметрии скважины'
), [idWell])
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const operationsSummaryData = await TelemetryAnalyticsService.getOperationsSummary(idWell,
filterDateRange[0].toISOString(), filterDateRange[1].toISOString())
setOperationsData(operationsSummaryData)
},
setLoader,
`Не удалось получить данные для анализа операций по скважине "${idWell}"`,
'Получение данных для анализа операций по скважине'
), [idWell, filterDateRange])
return (
<LoaderPortal show={loader}>
<div className={'w-100 mt-20px'}>
<Form layout={'vertical'} name={'operationsForm'} initialValues={{ remember: true }}>
<div className={'d-flex'}>
<Form.Item
name={'period'}
className={'ml-30px'}
initialValue={filterDateRange}
label={'Диапазон дат графика:'}
>
<RangePicker
showTime
allowClear={false}
disabledDate={disabledDate}
onCalendarChange={(dates) => setFilterDateRange(dates)}
/>
</Form.Item>
</div>
</Form>
</div>
<ChartTelemetryOperationsSummary operationsData={operationsData}/>
</LoaderPortal>
)
})
export default TelemetryAnalysisOperationsSummary

View File

@ -1,5 +0,0 @@
import { memo } from 'react'
export const TelemetryAnalysisOperationsToInterval = memo(() => (<>123</>))
export default TelemetryAnalysisOperationsToInterval

View File

@ -1,44 +0,0 @@
import { useParams } from 'react-router-dom'
import { memo, useContext, useMemo } from 'react'
import { FolderOutlined } from '@ant-design/icons'
import { Layout } from 'antd'
import { RootPathContext } from '@asb/context'
import { PrivateMenu, PrivateSwitch } from '@components/Private'
import TelemetryAnalysisDepthToDay from './TelemetryAnalysisDepthToDay'
import TelemetryAnalysisDepthToInterval from './TelemetryAnalysisDepthToInterval'
import TelemetryAnalysisOperationsSummary from './TelemetryAnalysisOperationsSummary'
import TelemetryAnalysisOperationsToInterval from './TelemetryAnalysisOperationsToInterval'
const { Content } = Layout
export const TelemetryAnalysis = memo(() => {
const { tab } = useParams()
const root = useContext(RootPathContext)
const rootPath = useMemo(() => `${root}/telemetryAnalysis`, [root])
return (
<RootPathContext.Provider value={rootPath}>
<PrivateMenu mode={'horizontal'} selectable={true} className={'well_menu'} selectedKeys={[tab]}>
<PrivateMenu.Link icon={<FolderOutlined />} key={'depthToDay'} title={'Глубина-день'} />
<PrivateMenu.Link icon={<FolderOutlined />} key={'depthToInterval'} title={'Глубина-интервал'} />
<PrivateMenu.Link icon={<FolderOutlined />} key={'operationsSummary'} title={'Все операции'} />
<PrivateMenu.Link icon={<FolderOutlined />} key={'operationsToInterval'} title={'Операции-интервал'} />
</PrivateMenu>
<Layout>
<Content className={'site-layout-background'}>
<PrivateSwitch elseRedirect={['depthToDay', 'depthToInterval', 'operationsSummary', 'operationsToInterval']}>
<TelemetryAnalysisDepthToDay key={'depthToDay'} />
<TelemetryAnalysisDepthToInterval key={'depthToInterval'} />
<TelemetryAnalysisOperationsSummary key={'operationsSummary'} />
<TelemetryAnalysisOperationsToInterval key={'operationsToInterval'} />
</PrivateSwitch>
</Content>
</Layout>
</RootPathContext.Provider>
)
})
export default TelemetryAnalysis