forked from ddrilling/asb_cloud_front
Доработка страницы Наработки АКБ
* Добавлены цвета * Добавлены иконки для подсистем * Добавлена фильтрация на null
This commit is contained in:
parent
8f98cc066c
commit
28a0962793
@ -1,6 +1,11 @@
|
|||||||
import { memo, useCallback, useEffect, useState } from 'react'
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { QuestionCircleOutlined } from '@ant-design/icons'
|
import {
|
||||||
import { Card } from 'antd'
|
CheckOutlined,
|
||||||
|
StopOutlined,
|
||||||
|
QuestionCircleOutlined,
|
||||||
|
WarningOutlined,
|
||||||
|
} from '@ant-design/icons'
|
||||||
|
import { Card, Empty } from 'antd'
|
||||||
|
|
||||||
import { WellView } from '@components/views'
|
import { WellView } from '@components/views'
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
@ -19,8 +24,48 @@ const columns = [
|
|||||||
makeNumericColumn('Коэф. использования, %', 'kUsage', undefined, undefined, (value) => numericRender(value * 100)),
|
makeNumericColumn('Коэф. использования, %', 'kUsage', undefined, undefined, (value) => numericRender(value * 100)),
|
||||||
]
|
]
|
||||||
|
|
||||||
const getSubsystemIcon = (subsystem) => {
|
const getSubsystemState = (subsystem) => {
|
||||||
return <QuestionCircleOutlined />
|
if (!subsystem || typeof subsystem.kUsage !== 'number') return null
|
||||||
|
if (subsystem.kUsage <= 0.2) return 'error'
|
||||||
|
if (subsystem.kUsage <= 0.7) return 'warn'
|
||||||
|
return 'ok'
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSubsystemColor = (state) => {
|
||||||
|
switch (state) {
|
||||||
|
case 'ok': return '#52c41a'
|
||||||
|
case 'warn': return '#faad14'
|
||||||
|
case 'error': return '#ff4d4f'
|
||||||
|
default: return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSubsystemIcon = (state) => {
|
||||||
|
switch (state) {
|
||||||
|
case 'ok': return <CheckOutlined />
|
||||||
|
case 'warn': return <WarningOutlined />
|
||||||
|
case 'error': return <StopOutlined />
|
||||||
|
default: return <QuestionCircleOutlined />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCardState = (subsystems) => {
|
||||||
|
if (subsystems.length <= 0) return null
|
||||||
|
const states = subsystems.map((ss) => getSubsystemState(ss))
|
||||||
|
if (states.some((state) => state === 'error')) return 'error'
|
||||||
|
if (states.some((state) => state === 'warn')) return 'warn'
|
||||||
|
return 'ok'
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateSubsystem = (subsystem) => {
|
||||||
|
const state = getSubsystemState(subsystem)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', gap: 5, alignItems: 'center', color: getSubsystemColor(state) }}>
|
||||||
|
{getSubsystemIcon(state)}
|
||||||
|
<span key={subsystem.key}>{subsystem.subsystemName || subsystem.key}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const GeneralSubsystemStatistics = memo(() => {
|
const GeneralSubsystemStatistics = memo(() => {
|
||||||
@ -30,7 +75,10 @@ const GeneralSubsystemStatistics = memo(() => {
|
|||||||
const [dates, setDates] = useState([null, null])
|
const [dates, setDates] = useState([null, null])
|
||||||
|
|
||||||
const onRow = useCallback((record) => {
|
const onRow = useCallback((record) => {
|
||||||
|
const state = getSubsystemState(record)
|
||||||
|
if (state === null) return null
|
||||||
|
const color = getSubsystemColor(state)
|
||||||
|
return { style: { backgroundColor: color } }
|
||||||
}, [selected])
|
}, [selected])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -39,7 +87,7 @@ const GeneralSubsystemStatistics = memo(() => {
|
|||||||
const data = await SubsystemOperationTimeService.getStatByWell(dates?.[0]?.toISOString(), dates?.[1]?.toISOString())
|
const data = await SubsystemOperationTimeService.getStatByWell(dates?.[0]?.toISOString(), dates?.[1]?.toISOString())
|
||||||
const out = arrayOrDefault(data).map(({ well, ...subsystems }) => ({
|
const out = arrayOrDefault(data).map(({ well, ...subsystems }) => ({
|
||||||
well,
|
well,
|
||||||
subsystems: Object.entries(subsystems).map(([key, value]) => ({ key, ...value })),
|
subsystems: Object.entries(subsystems).filter(([_, v]) => v).map(([key, v]) => ({ key, ...v }))
|
||||||
}))
|
}))
|
||||||
setData(out)
|
setData(out)
|
||||||
},
|
},
|
||||||
@ -53,32 +101,37 @@ const GeneralSubsystemStatistics = memo(() => {
|
|||||||
setSelected((prev) => (prev?.well.id === row.well.id) ? null : row)
|
setSelected((prev) => (prev?.well.id === row.well.id) ? null : row)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
const cards = useMemo(() => {
|
||||||
<LoaderPortal show={isLoading} style={{ flex: 1 }}>
|
return data.map((row) => {
|
||||||
<div className={'general-statistics'} style={{ display: 'flex', flexDirection: 'column', alignItems: 'stretch', gap: 20, height: '100%' }}>
|
const state = getCardState(row.subsystems)
|
||||||
<div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
|
const isSelected = row.well.id === selected?.well.id
|
||||||
<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 = {
|
const cardStyle = {
|
||||||
boxShadow: row.well.id === selected?.well.id ? '0 0 5px 2px gray' : null,
|
boxShadow: `0 0 5px 2px ${isSelected ? 'gray' : getSubsystemColor(state)}`,
|
||||||
|
userSelect: 'none',
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card key={row.well.id} title={<WellView well={row.well} />} onClick={makeOnCardClick(row)} style={cardStyle}>
|
<Card key={row.well.id} title={<WellView well={row.well} />} onClick={state ? makeOnCardClick(row) : null} style={cardStyle}>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
|
||||||
{row.subsystems.map((ss) => (
|
{state ? row.subsystems.map((ss) => generateSubsystem(ss)) : <Empty />}
|
||||||
<div style={{ display: 'flex', gap: 5, alignItems: 'center' }}>
|
|
||||||
{getSubsystemIcon(ss)}
|
|
||||||
<span key={ss.key}>{ss.subsystemName || ss.key}</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
})}
|
})
|
||||||
|
}, [data, selected])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LoaderPortal show={isLoading} style={{ flex: 1 }}>
|
||||||
|
<div className={'general-statistics'} style={{ display: 'flex', flexDirection: 'column', alignItems: 'stretch', gap: 20, height: '100%' }}>
|
||||||
|
<div style={{ paddingLeft: 15, display: 'flex', gap: 10, alignItems: 'center' }}>
|
||||||
|
<span>Диапазон дат:</span>
|
||||||
|
<DateRangeWrapper allowClear onChange={setDates} value={dates} />
|
||||||
|
</div>
|
||||||
|
<div style={{ flex: 1, overflowY: 'scroll' }}>
|
||||||
|
<div style={{ padding: 15, display: 'flex', flexWrap: 'wrap', alignItems: 'baseline', gap: 15 }}>
|
||||||
|
{cards}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{selected && (
|
{selected && (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
|
||||||
@ -87,7 +140,6 @@ const GeneralSubsystemStatistics = memo(() => {
|
|||||||
<WellView well={selected.well} />
|
<WellView well={selected.well} />
|
||||||
</div>
|
</div>
|
||||||
<Table
|
<Table
|
||||||
bordered
|
|
||||||
size={'small'}
|
size={'small'}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
dataSource={selected.subsystems}
|
dataSource={selected.subsystems}
|
||||||
|
Loading…
Reference in New Issue
Block a user