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 { Grid, GridItem } from '@components/Grid'
|
||||
@ -15,9 +15,11 @@ const wellState: Record<number, { enum: WellIconState, label: string }> = {
|
||||
|
||||
export type WellViewProps = TooltipProps & {
|
||||
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={(
|
||||
<Grid style={{ columnGap: '8px' }}>
|
||||
<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>
|
||||
</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'} />
|
||||
</span>
|
||||
{well.caption}
|
||||
<span {...labelProps}>
|
||||
{well.deposit} / {well.cluster} / {well.caption}
|
||||
</span>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Tooltip title={'нет скважины'}>-</Tooltip>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { memo } from 'react'
|
||||
import {
|
||||
FundOutlined,
|
||||
HeatMapOutlined,
|
||||
} from '@ant-design/icons'
|
||||
|
||||
@ -7,6 +8,7 @@ import { makeItem, PrivateMenu } from '@components/PrivateMenu'
|
||||
|
||||
export const menuItems = [
|
||||
makeItem('Карта', 'map', [], <HeatMapOutlined />),
|
||||
makeItem('Наработка АКБ', 'statistics', [], <FundOutlined />),
|
||||
]
|
||||
|
||||
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 FastRunMenu from '@components/FastRunMenu'
|
||||
import { makeMenuBreadcrumbItemsRender } from '@components/MenuBreadcrumb'
|
||||
import { NoAccessComponent, withPermissions } from '@utils'
|
||||
|
||||
import { DepositNavigationMenu, menuItems } from './DepositNavigationMenu'
|
||||
|
||||
const Map = lazy(() => import('./Map'))
|
||||
const DepositNavigationMenu = lazy(() => import('./DepositNavigationMenu'))
|
||||
const GeneralSubsystemStatistics = lazy(() => import('./GeneralSubsystemStatistics'))
|
||||
|
||||
const breadcrumb = makeMenuBreadcrumbItemsRender(menuItems, /^\/deposit\/[^\/#?]+\//)
|
||||
|
||||
const Deposit = memo(() => {
|
||||
const { '*': param } = useParams()
|
||||
@ -17,9 +22,14 @@ const Deposit = memo(() => {
|
||||
const root = useRootPath()
|
||||
const rootPath = useMemo(() => `${root}/deposit`, [root])
|
||||
|
||||
const idDeposit = useMemo(() => {
|
||||
const result = /^([^\/#?]+)/.exec(param)
|
||||
return result && result[1] !== 'null' ? Number(result[1]) : null
|
||||
const [idDeposit, isMap] = useMemo(() => {
|
||||
const result = /^([^\/#?]+)(:?\/([^\/#?]+))?/.exec(param)
|
||||
if (!result) return [null, false]
|
||||
console.log(result)
|
||||
return [
|
||||
result[1] !== 'null' ? Number(result[1]) : null,
|
||||
result[3] === 'map',
|
||||
]
|
||||
}, [param])
|
||||
|
||||
const deposit = useMemo(() => deposits.find((deposit) => deposit.id === idDeposit) || null, [deposits, idDeposit])
|
||||
@ -33,13 +43,14 @@ const Deposit = memo(() => {
|
||||
}
|
||||
|
||||
setLayoutProps({
|
||||
sheet: false,
|
||||
sider: <DepositNavigationMenu disabled={idDeposit === null} variables={{ idDeposit: idDeposit }} />,
|
||||
showSelector: true,
|
||||
breadcrumb: !isMap && breadcrumb,
|
||||
sheet: !isMap,
|
||||
sider: <DepositNavigationMenu variables={{ idDeposit: idDeposit }} />,
|
||||
showSelector: isMap,
|
||||
selectorProps,
|
||||
title: 'Месторождение',
|
||||
})
|
||||
}, [setLayoutProps, idDeposit])
|
||||
}, [setLayoutProps, idDeposit, isMap])
|
||||
|
||||
return (
|
||||
<RootPathContext.Provider value={rootPath}>
|
||||
@ -53,6 +64,7 @@ const Deposit = memo(() => {
|
||||
<Route path={'*'} element={<NoAccessComponent />} />
|
||||
|
||||
<Route path={'map'} element={<Map />} />
|
||||
<Route path={'statistics'} element={<GeneralSubsystemStatistics />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</DepositContext.Provider>
|
||||
|
Loading…
Reference in New Issue
Block a user