forked from ddrilling/asb_cloud_front
Добавлена базовая версия страницы
This commit is contained in:
parent
043f73fde3
commit
4b20a44d88
@ -1,4 +1,4 @@
|
|||||||
import { memo } from 'react'
|
import { DetailedHTMLProps, HTMLAttributes, memo } from 'react'
|
||||||
import { Tooltip, TooltipProps } from 'antd'
|
import { Tooltip, TooltipProps } from 'antd'
|
||||||
|
|
||||||
import { Grid, GridItem } from '@components/Grid'
|
import { Grid, GridItem } from '@components/Grid'
|
||||||
@ -15,9 +15,11 @@ const wellState: Record<number, { enum: WellIconState, label: string }> = {
|
|||||||
|
|
||||||
export type WellViewProps = TooltipProps & {
|
export type WellViewProps = TooltipProps & {
|
||||||
well?: WellDto
|
well?: WellDto
|
||||||
|
iconProps?: DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
|
||||||
|
labelProps?: DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WellView = memo<WellViewProps>(({ well, ...other }) => well ? (
|
export const WellView = memo<WellViewProps>(({ well, iconProps, labelProps, ...other }) => well ? (
|
||||||
<Tooltip {...other} title={(
|
<Tooltip {...other} title={(
|
||||||
<Grid style={{ columnGap: '8px' }}>
|
<Grid style={{ columnGap: '8px' }}>
|
||||||
<GridItem row={1} col={1}>Название:</GridItem>
|
<GridItem row={1} col={1}>Название:</GridItem>
|
||||||
@ -47,10 +49,12 @@ export const WellView = memo<WellViewProps>(({ well, ...other }) => well ? (
|
|||||||
<GridItem row={8} col={2}>{well.id ?? '---'}</GridItem>
|
<GridItem row={8} col={2}>{well.id ?? '---'}</GridItem>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}>
|
)}>
|
||||||
<span role={'img'} style={{ marginRight: 8, lineHeight: 0, verticalAlign: '-0.25em' }}>
|
<span role={'img'} style={{ marginRight: 8, lineHeight: 0, verticalAlign: '-0.25em' }} {...iconProps}>
|
||||||
<WellIcon state={wellState[well.idState || 0].enum} width={'1em'} height={'1em'} />
|
<WellIcon state={wellState[well.idState || 0].enum} width={'1em'} height={'1em'} />
|
||||||
</span>
|
</span>
|
||||||
{well.caption}
|
<span {...labelProps}>
|
||||||
|
{well.deposit} / {well.cluster} / {well.caption}
|
||||||
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : (
|
) : (
|
||||||
<Tooltip title={'нет скважины'}>-</Tooltip>
|
<Tooltip title={'нет скважины'}>-</Tooltip>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import {
|
import {
|
||||||
|
FundOutlined,
|
||||||
HeatMapOutlined,
|
HeatMapOutlined,
|
||||||
} from '@ant-design/icons'
|
} from '@ant-design/icons'
|
||||||
|
|
||||||
@ -7,6 +8,7 @@ import { makeItem, PrivateMenu } from '@components/PrivateMenu'
|
|||||||
|
|
||||||
export const menuItems = [
|
export const menuItems = [
|
||||||
makeItem('Карта', 'map', [], <HeatMapOutlined />),
|
makeItem('Карта', 'map', [], <HeatMapOutlined />),
|
||||||
|
makeItem('Наработка АКБ', 'statistics', [], <FundOutlined />),
|
||||||
]
|
]
|
||||||
|
|
||||||
export const DepositNavigationMenu = memo((props) => (
|
export const DepositNavigationMenu = memo((props) => (
|
||||||
|
104
src/pages/Deposit/GeneralSubsystemStatistics.jsx
Normal file
104
src/pages/Deposit/GeneralSubsystemStatistics.jsx
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { memo, useCallback, useEffect, useState } from 'react'
|
||||||
|
import { QuestionCircleOutlined } from '@ant-design/icons'
|
||||||
|
import { Card } from 'antd'
|
||||||
|
|
||||||
|
import { WellView } from '@components/views'
|
||||||
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
|
import { DateRangeWrapper, makeNumericColumn, makeNumericRender, makeTextColumn, Table } from '@components/Table'
|
||||||
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
|
import { arrayOrDefault, withPermissions } from '@utils'
|
||||||
|
import { SubsystemOperationTimeService } from '@api'
|
||||||
|
|
||||||
|
const numericRender = makeNumericRender(2)
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
makeTextColumn('Подсистема', 'subsystemName', undefined, undefined, (value, row) => value || row.key),
|
||||||
|
makeNumericColumn('Проходка, м', 'sumDepthInterval'),
|
||||||
|
makeNumericColumn('Время работы, ч', 'usedTimeHours'),
|
||||||
|
makeNumericColumn('Кол-во запусков', 'operationCount'),
|
||||||
|
makeNumericColumn('Коэф. использования, %', 'kUsage', undefined, undefined, (value) => numericRender(value * 100)),
|
||||||
|
]
|
||||||
|
|
||||||
|
const getSubsystemIcon = (subsystem) => {
|
||||||
|
return <QuestionCircleOutlined />
|
||||||
|
}
|
||||||
|
|
||||||
|
const GeneralSubsystemStatistics = memo(() => {
|
||||||
|
const [data, setData] = useState([])
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
const [selected, setSelected] = useState(null)
|
||||||
|
const [dates, setDates] = useState([null, null])
|
||||||
|
|
||||||
|
const onRow = useCallback((record) => {
|
||||||
|
|
||||||
|
}, [selected])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
invokeWebApiWrapperAsync(
|
||||||
|
async () => {
|
||||||
|
const data = await SubsystemOperationTimeService.getStatByWell(dates?.[0]?.toISOString(), dates?.[1]?.toISOString())
|
||||||
|
const out = arrayOrDefault(data).map(({ well, ...subsystems }) => ({
|
||||||
|
well,
|
||||||
|
subsystems: Object.entries(subsystems).map(([key, value]) => ({ key, ...value })),
|
||||||
|
}))
|
||||||
|
setData(out)
|
||||||
|
},
|
||||||
|
setIsLoading,
|
||||||
|
'Не удалось загрузить статистику наработки подсистем',
|
||||||
|
{ actionName: 'Загрузка статистики наработки подсистем' },
|
||||||
|
)
|
||||||
|
}, [dates])
|
||||||
|
|
||||||
|
const makeOnCardClick = useCallback((row) => () => {
|
||||||
|
setSelected((prev) => (prev?.well.id === row.well.id) ? null : row)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LoaderPortal show={isLoading} style={{ flex: 1 }}>
|
||||||
|
<div className={'general-statistics'} style={{ display: 'flex', flexDirection: 'column', alignItems: 'stretch', gap: 20, height: '100%' }}>
|
||||||
|
<div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
|
||||||
|
<span>Диапазон дат:</span>
|
||||||
|
<DateRangeWrapper allowClear onChange={setDates} value={dates} />
|
||||||
|
</div>
|
||||||
|
<div style={{ padding: 15, flex: 1, display: 'flex', flexWrap: 'wrap', alignItems: 'baseline', gap: 15, overflowY: 'auto' }}>
|
||||||
|
{data.map((row) => {
|
||||||
|
const cardStyle = {
|
||||||
|
boxShadow: row.well.id === selected?.well.id ? '0 0 5px 2px gray' : null,
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card key={row.well.id} title={<WellView well={row.well} />} onClick={makeOnCardClick(row)} style={cardStyle}>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
|
||||||
|
{row.subsystems.map((ss) => (
|
||||||
|
<div style={{ display: 'flex', gap: 5, alignItems: 'center' }}>
|
||||||
|
{getSubsystemIcon(ss)}
|
||||||
|
<span key={ss.key}>{ss.subsystemName || ss.key}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
{selected && (
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
|
||||||
|
<div style={{ display: 'flex', gap: 15, alignItems: 'center', justifyContent: 'center', fontSize: '1.25em', fontWeight: 600 }}>
|
||||||
|
<span>Детальная информация по скважине</span>
|
||||||
|
<WellView well={selected.well} />
|
||||||
|
</div>
|
||||||
|
<Table
|
||||||
|
bordered
|
||||||
|
size={'small'}
|
||||||
|
pagination={false}
|
||||||
|
dataSource={selected.subsystems}
|
||||||
|
columns={columns}
|
||||||
|
onRow={onRow}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</LoaderPortal>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default withPermissions(GeneralSubsystemStatistics, [])
|
@ -3,10 +3,15 @@ import { lazy, memo, useEffect, useMemo } from 'react'
|
|||||||
|
|
||||||
import { DepositContext, RootPathContext, useDepositList, useLayoutProps, useRootPath } from '@asb/context'
|
import { DepositContext, RootPathContext, useDepositList, useLayoutProps, useRootPath } from '@asb/context'
|
||||||
import FastRunMenu from '@components/FastRunMenu'
|
import FastRunMenu from '@components/FastRunMenu'
|
||||||
|
import { makeMenuBreadcrumbItemsRender } from '@components/MenuBreadcrumb'
|
||||||
import { NoAccessComponent, withPermissions } from '@utils'
|
import { NoAccessComponent, withPermissions } from '@utils'
|
||||||
|
|
||||||
|
import { DepositNavigationMenu, menuItems } from './DepositNavigationMenu'
|
||||||
|
|
||||||
const Map = lazy(() => import('./Map'))
|
const Map = lazy(() => import('./Map'))
|
||||||
const DepositNavigationMenu = lazy(() => import('./DepositNavigationMenu'))
|
const GeneralSubsystemStatistics = lazy(() => import('./GeneralSubsystemStatistics'))
|
||||||
|
|
||||||
|
const breadcrumb = makeMenuBreadcrumbItemsRender(menuItems, /^\/deposit\/[^\/#?]+\//)
|
||||||
|
|
||||||
const Deposit = memo(() => {
|
const Deposit = memo(() => {
|
||||||
const { '*': param } = useParams()
|
const { '*': param } = useParams()
|
||||||
@ -17,9 +22,14 @@ const Deposit = memo(() => {
|
|||||||
const root = useRootPath()
|
const root = useRootPath()
|
||||||
const rootPath = useMemo(() => `${root}/deposit`, [root])
|
const rootPath = useMemo(() => `${root}/deposit`, [root])
|
||||||
|
|
||||||
const idDeposit = useMemo(() => {
|
const [idDeposit, isMap] = useMemo(() => {
|
||||||
const result = /^([^\/#?]+)/.exec(param)
|
const result = /^([^\/#?]+)(:?\/([^\/#?]+))?/.exec(param)
|
||||||
return result && result[1] !== 'null' ? Number(result[1]) : null
|
if (!result) return [null, false]
|
||||||
|
console.log(result)
|
||||||
|
return [
|
||||||
|
result[1] !== 'null' ? Number(result[1]) : null,
|
||||||
|
result[3] === 'map',
|
||||||
|
]
|
||||||
}, [param])
|
}, [param])
|
||||||
|
|
||||||
const deposit = useMemo(() => deposits.find((deposit) => deposit.id === idDeposit) || null, [deposits, idDeposit])
|
const deposit = useMemo(() => deposits.find((deposit) => deposit.id === idDeposit) || null, [deposits, idDeposit])
|
||||||
@ -33,13 +43,14 @@ const Deposit = memo(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setLayoutProps({
|
setLayoutProps({
|
||||||
sheet: false,
|
breadcrumb: !isMap && breadcrumb,
|
||||||
sider: <DepositNavigationMenu disabled={idDeposit === null} variables={{ idDeposit: idDeposit }} />,
|
sheet: !isMap,
|
||||||
showSelector: true,
|
sider: <DepositNavigationMenu variables={{ idDeposit: idDeposit }} />,
|
||||||
|
showSelector: isMap,
|
||||||
selectorProps,
|
selectorProps,
|
||||||
title: 'Месторождение',
|
title: 'Месторождение',
|
||||||
})
|
})
|
||||||
}, [setLayoutProps, idDeposit])
|
}, [setLayoutProps, idDeposit, isMap])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RootPathContext.Provider value={rootPath}>
|
<RootPathContext.Provider value={rootPath}>
|
||||||
@ -53,6 +64,7 @@ const Deposit = memo(() => {
|
|||||||
<Route path={'*'} element={<NoAccessComponent />} />
|
<Route path={'*'} element={<NoAccessComponent />} />
|
||||||
|
|
||||||
<Route path={'map'} element={<Map />} />
|
<Route path={'map'} element={<Map />} />
|
||||||
|
<Route path={'statistics'} element={<GeneralSubsystemStatistics />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</DepositContext.Provider>
|
</DepositContext.Provider>
|
||||||
|
Loading…
Reference in New Issue
Block a user