forked from ddrilling/asb_cloud_front
193 lines
6.3 KiB
JavaScript
Executable File
193 lines
6.3 KiB
JavaScript
Executable File
import { Button, Layout } from 'antd'
|
||
import {
|
||
AuditOutlined,
|
||
CheckOutlined,
|
||
CloseOutlined,
|
||
FileWordOutlined,
|
||
LoadingOutlined,
|
||
ReloadOutlined,
|
||
WarningOutlined,
|
||
} from '@ant-design/icons'
|
||
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||
|
||
import { useWell } from '@asb/context'
|
||
import LoaderPortal from '@components/LoaderPortal'
|
||
import { downloadFile, formatBytes, invokeWebApiWrapperAsync } from '@components/factory'
|
||
import { arrayOrDefault, formatDate, wrapPrivateComponent } from '@utils'
|
||
import { DrillingProgramService } from '@api'
|
||
|
||
import CategoryAdder from './CategoryAdder'
|
||
import CategoryRender from './CategoryRender'
|
||
import CategoryEditor from './CategoryEditor'
|
||
import CategoryHistory from './CategoryHistory'
|
||
|
||
import '@styles/drilling_program.less'
|
||
|
||
const ID_STATE = {
|
||
NotInitialized: 0,
|
||
Approving: 1,
|
||
Creating: 2,
|
||
Ready: 3,
|
||
Error: 4,
|
||
Unknown: -1,
|
||
}
|
||
|
||
const STATE_STRING = {
|
||
[ID_STATE.NotInitialized]: { icon: CloseOutlined, text: 'Не настроена' },
|
||
[ID_STATE.Approving]: { icon: AuditOutlined, text: 'Согласовывается' },
|
||
[ID_STATE.Creating]: { icon: LoadingOutlined, text: 'Формируется' },
|
||
[ID_STATE.Ready]: { icon: CheckOutlined, text: 'Сформирована' },
|
||
[ID_STATE.Error]: { icon: WarningOutlined, text: 'Ошибка формирования' },
|
||
[ID_STATE.Unknown]: { icon: WarningOutlined, text: 'Неизвестно' },
|
||
}
|
||
|
||
const DrillingProgram = memo(() => {
|
||
const [selectedCategory, setSelectedCategory] = useState()
|
||
const [historyVisible, setHistoryVisible] = useState(false)
|
||
const [editorVisible, setEditorVisible] = useState(false)
|
||
const [showLoader, setShowLoader] = useState(false)
|
||
const [categories, setCategories] = useState([])
|
||
const [data, setData] = useState({})
|
||
|
||
const [well] = useWell()
|
||
|
||
const {
|
||
idState,
|
||
permissionToEdit,
|
||
parts,
|
||
program,
|
||
error,
|
||
} = useMemo(() => data, [data])
|
||
|
||
const stateId = useMemo(() => idState ?? ID_STATE.Unknown, [idState])
|
||
const state = useMemo(() => STATE_STRING[stateId], [stateId])
|
||
const StateIcon = useMemo(() => state.icon, [state?.icon])
|
||
|
||
const updateData = useCallback(async () => await invokeWebApiWrapperAsync(
|
||
async () => {
|
||
const data = await DrillingProgramService.getState(well.id)
|
||
const categories = arrayOrDefault(await DrillingProgramService.getCategories(well.id))
|
||
setData(data)
|
||
setCategories(categories.filter(cat => {
|
||
if (cat?.id && (cat.name || cat.shortName))
|
||
if (data.parts?.findIndex((val) => val.idFileCategory === cat.id) < 0)
|
||
return true
|
||
return false
|
||
}))
|
||
},
|
||
setShowLoader,
|
||
`Не удалось загрузить категории программы бурения`,
|
||
{ actionName: 'Загрузка категорий программы бурения', well }
|
||
), [well])
|
||
|
||
useEffect(() => {
|
||
updateData()
|
||
}, [updateData])
|
||
|
||
const onCategoryEdit = useCallback((catId) => {
|
||
setSelectedCategory(catId)
|
||
setEditorVisible(!!catId)
|
||
}, [])
|
||
|
||
const onCategoryHistory = useCallback((catId) => {
|
||
setSelectedCategory(catId)
|
||
setHistoryVisible(!!catId)
|
||
}, [])
|
||
|
||
const onEditorClosed = useCallback((needUpdate) => {
|
||
setEditorVisible(false)
|
||
if (needUpdate)
|
||
updateData()
|
||
}, [updateData])
|
||
|
||
const clearError = useCallback(() => invokeWebApiWrapperAsync(
|
||
async () => {
|
||
await DrillingProgramService.clearError(well.id)
|
||
await updateData()
|
||
},
|
||
setShowLoader,
|
||
`Не удалось сбросить ошибку формирования программы бурения`,
|
||
{ actionName: 'Сброс ошибки форматирования программы бурения', well }
|
||
), [well])
|
||
|
||
return (
|
||
<LoaderPortal show={showLoader}>
|
||
<Layout style={{ backgroundColor: 'white' }}>
|
||
<div className={'drilling_program'}>
|
||
<div className={'program_header'}>
|
||
<h3>Программа бурения</h3>
|
||
{permissionToEdit && (
|
||
<div>
|
||
<CategoryAdder categories={categories} onUpdate={updateData} />
|
||
</div>
|
||
)}
|
||
</div>
|
||
<div className={'program_content'}>
|
||
{stateId === ID_STATE.Ready ? (
|
||
<>
|
||
<Button
|
||
type={'link'}
|
||
icon={<FileWordOutlined />}
|
||
style={{ marginLeft: '10px' }}
|
||
onClick={() => downloadFile(program)}
|
||
>
|
||
{program?.name}
|
||
</Button>
|
||
<div className={'m-10'}>Размер: {formatBytes(program?.size)}</div>
|
||
<div className={'m-10'}>Сформирован: {formatDate(program?.uploadDate)}</div>
|
||
</>
|
||
) : stateId === ID_STATE.Error ? (
|
||
<>
|
||
<h3 className={'program_status error'}>
|
||
<StateIcon className={'m-10'} />
|
||
{error?.message ?? state.text}
|
||
</h3>
|
||
<Button onClick={clearError} icon={<ReloadOutlined />}>
|
||
Сбросить статус ошибки
|
||
</Button>
|
||
</>
|
||
) : (
|
||
<h3 className={'program_status'}>
|
||
<StateIcon className={'m-10'} />
|
||
{state.text}
|
||
</h3>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{parts?.map?.((part, idx) => part && (
|
||
<CategoryRender
|
||
key={`${idx}`}
|
||
partData={part}
|
||
onEdit={permissionToEdit && onCategoryEdit}
|
||
onUpdate={updateData}
|
||
onHistory={onCategoryHistory}
|
||
/>
|
||
))}
|
||
|
||
{permissionToEdit && (
|
||
<>
|
||
<CategoryEditor
|
||
visible={editorVisible}
|
||
onClosed={onEditorClosed}
|
||
category={parts?.find((part) => part.idFileCategory === selectedCategory) ?? {}}
|
||
/>
|
||
</>
|
||
)}
|
||
|
||
<CategoryHistory
|
||
idCategory={selectedCategory}
|
||
onClose={() => setHistoryVisible(false)}
|
||
visible={historyVisible}
|
||
/>
|
||
</Layout>
|
||
</LoaderPortal>
|
||
)
|
||
})
|
||
|
||
export default wrapPrivateComponent(DrillingProgram, {
|
||
requirements: [ 'DrillingProgram.get' ],
|
||
title: 'Программа бурения',
|
||
route: 'drillingProgram',
|
||
})
|