asb_cloud_front/src/pages/Cluster/ClusterWells.jsx

203 lines
6.6 KiB
React
Raw Normal View History

import { Link, useLocation } from 'react-router-dom'
import { useState, useEffect, memo } from 'react'
2021-10-15 16:03:36 +05:00
import { Tag, Button, Modal } from 'antd'
import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons'
2021-08-27 14:21:48 +05:00
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'
2021-08-27 14:21:48 +05:00
const filtersMinMax = [
{ text: 'min', value: 'min' },
{ text: 'max', value: 'max' },
]
2021-08-27 14:21:48 +05:00
const filtersWellsType = []
const DAY_IN_MS = 86_400_000
const ONLINE_DEADTIME = 600_000
2021-08-27 14:21:48 +05:00
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])
2021-08-27 14:21:48 +05:00
const columns = [
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 }),
2021-08-27 14:21:48 +05:00
]),
makeNumericColumnPlanFact('Продолжительность, сут', 'period', filtersMinMax, makeFilterMinMaxFunction, makeNumericRender(1)),
makeNumericColumnPlanFact('МСП, м/ч', 'rateOfPenetration', filtersMinMax, makeFilterMinMaxFunction, makeNumericRender(1)),
makeNumericColumnPlanFact('Рейсовая скорость, м/ч', 'routeSpeed', filtersMinMax, makeFilterMinMaxFunction, makeNumericRender(1)),
makeNumericColumnPlanFact('НПВ, сут', 'notProductiveTime', filtersMinMax, makeFilterMinMaxFunction, makeNumericRender(1)),
2021-08-27 14:21:48 +05:00
{
title: 'TVD',
key: 'tvd',
render: (value) => <Button onClick={()=> {
setSelectedWellId(value.id)
setIsTVDModalVisible(true)
}}><LineChartOutlined /></Button>,
align: 'center'
2021-08-27 14:21:48 +05:00
},
{
title: 'Операции',
key: 'operations',
render: (value) => <Button onClick={()=> {
setSelectedWellId(value.id)
setIsOpsModalVisible(true)
}}><ProfileOutlined /></Button>,
align: 'center'
2021-08-27 14:21:48 +05:00
},
{
title: 'Участники',
key: 'companies',
dataIndex: 'companies',
render: (item) => item?.map((company) => (
<Tag key={company.caption} color='blue'>
<CompanyView company={company} />
</Tag>
)) ?? '-',
2021-08-27 14:21:48 +05:00
},
]
2021-08-27 14:21:48 +05:00
return (
<>
<Table
columns={columns}
dataSource={tableData}
size={'small'}
bordered
pagination={false}
rowKey={(record) => record.caption}
/>
<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