asb_cloud_front/src/pages/Cluster/ClusterWells.jsx

204 lines
6.7 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Link, useLocation } from 'react-router-dom'
import { useState, useEffect, memo, useMemo } from 'react'
import { Tag, Button, Modal } from 'antd'
import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons'
import {
makeTextColumn,
makeGroupColumn,
makeColumn,
makeDateSorter,
makeNumericColumnPlanFact,
Table,
makeNumericRender,
} from '@components/Table'
import { CompanyView } from '@components/views'
import LoaderPortal from '@components/LoaderPortal'
import PointerIcon from '@components/icons/PointerIcon'
import { invokeWebApiWrapperAsync } from '@components/factory'
import {
getOperations,
calcAndUpdateStatsBySections,
makeFilterMinMaxFunction
} from '@utils/functions'
import { isRawDate } from '@utils'
import { Tvd } from '@pages/WellOperations/Tvd'
import WellOperationsTable from './WellOperationsTable'
const filtersMinMax = [
{ text: 'min', value: 'min' },
{ text: 'max', value: 'max' },
]
const filtersWellsType = []
const DAY_IN_MS = 86_400_000
const ONLINE_DEADTIME = 600_000
const getDate = (str) => isRawDate(str) ? new Date(str).toLocaleString() : '-'
export const ClusterWells = memo(({ statsWells }) => {
const [selectedWellId, setSelectedWellId] = useState(0)
const [isTVDModalVisible, setIsTVDModalVisible] = useState(false)
const [isOpsModalVisible, setIsOpsModalVisible] = useState(false)
const [wellOperations, setWellOperations] = useState([])
const [tableData, setTableData] = useState([])
const [showLoader, setShowLoader] = useState(false)
const location = useLocation()
useEffect(() => {
if (!isOpsModalVisible || selectedWellId <= 0) {
setWellOperations([])
return
}
invokeWebApiWrapperAsync(
async () => {
const operations = await getOperations(selectedWellId)
setWellOperations(operations.operations)
},
setShowLoader,
`Не удалось загрузить операции по скважине "${selectedWellId}"`,
'Получение операций по скважине'
)
}, [selectedWellId, isOpsModalVisible])
useEffect(() => {
let data = statsWells?.map((well) => {
if (!filtersWellsType.some((el) => el.text === well.wellType))
filtersWellsType.push({ text: well.wellType, value: well.wellType })
const dateOrM = (a, b) => a && b ? (new Date(b) - new Date(a)) / DAY_IN_MS : '-'
const periodPlanValue = dateOrM(well.total?.plan?.start, well.total?.plan?.end)
const periodFactValue = dateOrM(well.total?.fact?.start, well.total?.fact?.end)
return {
key: well.caption,
id: well.id,
caption: well.caption,
wellType: well.wellType,
factStart: well.total?.fact?.start,
factEnd: well.total?.fact?.end,
periodPlan: periodPlanValue,
periodFact: periodFactValue,
rateOfPenetrationPlan: well.total?.plan?.rop,
rateOfPenetrationFact: well.total?.fact?.rop,
routeSpeedPlan: well.total?.plan?.routeSpeed,
routeSpeedFact: well.total?.fact?.routeSpeed,
notProductiveTimePlan: well.total?.plan?.nonProductiveHours,
notProductiveTimeFact: well.total?.fact?.nonProductiveHours,
companies: well.companies,
lastTelemetryDate: well.lastTelemetryDate,
idState: well.idState
}
})
calcAndUpdateStatsBySections(data ?? [], [
'factStart',
'factEnd',
'periodPlan',
'periodFact',
'rateOfPenetrationPlan',
'rateOfPenetrationFact',
'routeSpeedPlan',
'routeSpeedFact',
'notProductiveTime',
])
setTableData(data)
}, [statsWells])
const columns = useMemo(() => [
makeTextColumn('скв №', 'caption', null, null,
(_, item) => (
<Link to={{ pathname: `/well/${item.id}`, state: { from: location.pathname }}} style={{display: 'flex', alignItems: 'center'}}>
<PointerIcon
state={item.idState === 1 ? 'active' : 'unknown'}
width={32}
height={38}
online={item.lastTelemetryDate && (Date.now() - Date.parse(item.lastTelemetryDate) < ONLINE_DEADTIME)}
/>
{item.caption ?? '-'}
</Link>
)
),
makeTextColumn('Тип скв.', 'wellType', filtersWellsType, null, (text) => text ?? '-'),
makeGroupColumn('Фактические сроки', [
makeColumn('начало', 'factStart', { sorter: makeDateSorter('factStart'), render: getDate }),
makeColumn('окончание', 'factEnd', { sorter: makeDateSorter('factEnd'), render: getDate }),
]),
makeNumericColumnPlanFact('Продолжительность, сут', 'period', filtersMinMax, makeFilterMinMaxFunction, makeNumericRender(1)),
makeNumericColumnPlanFact('МСП, м/ч', 'rateOfPenetration', filtersMinMax, makeFilterMinMaxFunction, makeNumericRender(1)),
makeNumericColumnPlanFact('Рейсовая скорость, м/ч', 'routeSpeed', filtersMinMax, makeFilterMinMaxFunction, makeNumericRender(1)),
makeNumericColumnPlanFact('НПВ, сут', 'notProductiveTime', filtersMinMax, makeFilterMinMaxFunction, makeNumericRender(1)),
{
title: 'TVD',
key: 'tvd',
render: (value) => <Button onClick={()=> {
setSelectedWellId(value.id)
setIsTVDModalVisible(true)
}}><LineChartOutlined /></Button>,
align: 'center'
},
{
title: 'Операции',
key: 'operations',
render: (value) => <Button onClick={()=> {
setSelectedWellId(value.id)
setIsOpsModalVisible(true)
}}><ProfileOutlined /></Button>,
align: 'center'
},
{
title: 'Участники',
key: 'companies',
dataIndex: 'companies',
render: (item) => item?.map((company) => (
<Tag key={company.caption} color='blue'>
<CompanyView company={company} />
</Tag>
)) ?? '-',
},
], [location.pathname])
return (
<>
<Table
columns={columns}
dataSource={tableData}
size={'small'}
bordered
pagination={false}
rowKey={(record) => record.caption}
tableName={'cluster'}
/>
<Modal
title={'TVD'}
centered
visible={isTVDModalVisible}
onCancel={() => setIsTVDModalVisible(false)}
width={1500}
footer={null}
>
<Tvd idWell={selectedWellId} />
</Modal>
<Modal
title={'Операции'}
centered
visible={isOpsModalVisible}
onCancel={() => setIsOpsModalVisible(false)}
width={1500}
footer={null}
>
<LoaderPortal show={showLoader}>
<WellOperationsTable wellOperations={wellOperations} />
</LoaderPortal>
</Modal>
</>
)
})
export default ClusterWells