Стили вынесены в отдельный файл

This commit is contained in:
Александр Сироткин 2022-12-08 11:48:30 +05:00
parent 65b9ede580
commit 5af996f9e5
2 changed files with 103 additions and 71 deletions

View File

@ -1,19 +1,16 @@
import { CheckOutlined, StopOutlined, QuestionCircleOutlined, WarningOutlined } from '@ant-design/icons'
import { memo, useEffect, useMemo, useState } from 'react'
import {
CheckOutlined,
StopOutlined,
QuestionCircleOutlined,
WarningOutlined,
} from '@ant-design/icons'
import { Card, Empty, Popover } from 'antd'
import { getWellTitle, WellView } from '@components/views'
import LoaderPortal from '@components/LoaderPortal'
import { DateRangeWrapper, makeNumericColumn, makeNumericRender, makeTextColumn, Table } from '@components/Table'
import { getWellTitle, WellView } from '@components/views'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { DateRangeWrapper, makeNumericColumn, makeNumericRender, makeTextColumn, Table } from '@components/Table'
import { arrayOrDefault, withPermissions } from '@utils'
import { SubsystemOperationTimeService } from '@api'
import '@styles/statistics_adw.less'
const numericRender = makeNumericRender(2)
const columns = [
@ -31,15 +28,6 @@ const getSubsystemState = (subsystem) => {
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 />
@ -51,7 +39,7 @@ const getSubsystemIcon = (state) => {
const getCardState = (subsystems) => {
if (subsystems.length <= 0) return null
const states = subsystems.map((ss) => getSubsystemState(ss))
const states = subsystems.map(getSubsystemState)
if (states.some((state) => state === 'error')) return 'error'
if (states.some((state) => state === 'warn')) return 'warn'
return 'ok'
@ -61,33 +49,26 @@ const generateSubsystem = (subsystem) => {
const state = getSubsystemState(subsystem)
return (
<div style={{ display: 'flex', gap: 5, alignItems: 'center', color: getSubsystemColor(state) }}>
<div className={`subsystem-status status-${state}`}>
{getSubsystemIcon(state)}
<span key={subsystem.key}>{subsystem.subsystemName || subsystem.key}</span>
</div>
)
}
const onRow = (record) => {
const state = getSubsystemState(record)
if (state === null) return null
const color = getSubsystemColor(state)
return { style: { backgroundColor: color, color: 'white' } }
}
const onRow = (record) => ({ className: `status-${getSubsystemState(record)}` })
const objectToArray = (obj) => Object.entries(obj).filter(([_, v]) => v).map(([key, v]) => ({ key, ...v }))
const GeneralSubsystemStatistics = memo(() => {
const [data, setData] = useState([])
const [isLoading, setIsLoading] = useState(false)
const [dates, setDates] = useState([null, null])
const [data, setData] = useState([])
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).filter(([_, v]) => v).map(([key, v]) => ({ key, ...v }))
}))
const out = arrayOrDefault(data).map(({ well, ...ss }) => ({ well, subsystems: objectToArray(ss) }))
setData(out)
},
setIsLoading,
@ -96,56 +77,48 @@ const GeneralSubsystemStatistics = memo(() => {
)
}, [dates])
const cards = useMemo(() => {
return data.map((row) => {
const state = getCardState(row.subsystems)
const cards = useMemo(() => data.map((row) => {
const state = getCardState(row.subsystems)
const cardStyle = {
boxShadow: `0 0 5px 2px ${getSubsystemColor(state)}`,
userSelect: 'none',
}
const card = (
<Card className={`subsystem-card status-${state}`} key={row.well.id} title={getWellTitle(row.well)}>
<div className={'subsystem-card-body'}>
{state ? row.subsystems.map((ss) => generateSubsystem(ss)) : <Empty />}
</div>
</Card>
)
const card = (
<Card key={row.well.id} title={getWellTitle(row.well)} style={cardStyle}>
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
{state ? row.subsystems.map((ss) => generateSubsystem(ss)) : <Empty />}
</div>
</Card>
)
if (!state) return card
if (!state) return card
const detailTitle = (
<>
<span style={{ paddingRight: 15 }}>Детальная информация по скважине</span>
<WellView well={row.well} />
</>
)
const detailContent = (
<Table
size={'small'}
pagination={false}
dataSource={row.subsystems}
columns={columns}
onRow={onRow}
/>
)
return <Popover title={detailTitle} content={detailContent}>{card}</Popover>
})
}, [data])
return (
<Popover
title={(
<>
<span style={{ paddingRight: 15 }}>Детальная информация по скважине</span>
<WellView well={row.well} />
</>
)}
content={(
<Table
size={'small'}
pagination={false}
dataSource={row.subsystems}
columns={columns}
onRow={onRow}
/>
)}
>{card}</Popover>
)
}), [data])
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' }}>
<div className={'statistics-adw-page'}>
<div className={'filter-block'}>
<span>Диапазон дат:</span>
<DateRangeWrapper allowClear onChange={setDates} value={dates} />
</div>
<div style={{ padding: 15, display: 'flex', flexWrap: 'wrap', alignItems: 'baseline', gap: 15 }}>
{cards}
</div>
<div className={'well-cards'}>{cards}</div>
</div>
</LoaderPortal>
)

View File

@ -0,0 +1,59 @@
@ok-color: #52c41a;
@warn-color: #faad14;
@error-color: #ff4d4f;
.statistics-adw-page {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 20px;
height: 100%;
& .filter-block {
align-items: center;
padding-left: 15px;
display: flex;
gap: 10px;
}
& .well-cards {
padding: 15px;
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 15px;
& .subsystem-card {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
&.status-ok { box-shadow: 0 0 5px 2px @ok-color; }
&.status-warn { box-shadow: 0 0 5px 2px @warn-color; }
&.status-error { box-shadow: 0 0 5px 2px @error-color; }
& .subsystem-card-body {
display: flex;
flex-direction: column;
gap: 10px;
& .subsystem-status {
display: flex;
gap: 5px;
align-items: center;
&.status-ok { color: @ok-color; }
&.status-warn { color: @warn-color; }
&.status-error { color: @error-color; }
}
}
}
}
}
.ant-table-row {
&.status-ok { background-color: @ok-color; }
&.status-warn { background-color: @warn-color; }
&.status-error { background-color: @error-color; }
}