Добавлен статус ошибки, усилена работа с правами

This commit is contained in:
Александр Сироткин 2022-02-24 17:40:17 +05:00
parent 2951d26b72
commit 60507fba40
3 changed files with 126 additions and 70 deletions

View File

@ -10,6 +10,7 @@ import Poprompt from '@components/Poprompt'
import { UserView } from '@components/views' import { UserView } from '@components/views'
import UploadForm from '@components/UploadForm' import UploadForm from '@components/UploadForm'
import DownloadLink from '@components/DownloadLink' import DownloadLink from '@components/DownloadLink'
import LoaderPortal from '@components/LoaderPortal'
import { formatBytes, invokeWebApiWrapperAsync, notify } from '@components/factory' import { formatBytes, invokeWebApiWrapperAsync, notify } from '@components/factory'
import { DrillingProgramService } from '@api' import { DrillingProgramService } from '@api'
import { formatDate } from '@utils' import { formatDate } from '@utils'
@ -17,7 +18,6 @@ import { formatDate } from '@utils'
import MarksCard from './MarksCard' import MarksCard from './MarksCard'
import '@styles/drilling_program.less' import '@styles/drilling_program.less'
import LoaderPortal from '@asb/components/LoaderPortal'
const CommentPrompt = memo((props) => ( const CommentPrompt = memo((props) => (
<Poprompt <Poprompt
@ -41,12 +41,9 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist
approvers, // Полный список согласовантов approvers, // Полный список согласовантов
permissionToApprove, // Наличие прав на согласование/отклонение документа permissionToApprove, // Наличие прав на согласование/отклонение документа
permissionToUpload, // Наличие прав на загрузку нового файла permissionToUpload, // Наличие прав на загрузку нового файла
// permissionToEdit, // Наличие прав на редактирование/удаление категории
file // Информация о файле file // Информация о файле
} = partData ?? {} } = partData ?? {}
const permissionToEdit = true
const uploadUrl = `/api/well/${idWell}/drillingProgram/part/${idFileCategory}` const uploadUrl = `/api/well/${idWell}/drillingProgram/part/${idFileCategory}`
const [isUploading, setIsUploading] = useState(false) const [isUploading, setIsUploading] = useState(false)
@ -82,7 +79,7 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist
<div className={'drilling_category'} {...other}> <div className={'drilling_category'} {...other}>
<div className={'category_header'}> <div className={'category_header'}>
<h3>{title}</h3> <h3>{title}</h3>
{permissionToEdit && ( {onEdit && (
<div> <div>
<Button icon={<EditOutlined />} onClick={() => onEdit?.(idFileCategory)}>Редактировать</Button> <Button icon={<EditOutlined />} onClick={() => onEdit?.(idFileCategory)}>Редактировать</Button>
<Popconfirm <Popconfirm
@ -109,14 +106,15 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist
)} )}
</div> </div>
<div className={'file_actions'}> <div className={'file_actions'}>
<UploadForm {permissionToUpload && (
url={uploadUrl} <UploadForm
disabled={!permissionToUpload} url={uploadUrl}
style={{ margin: '5px 0 10px 0' }} style={{ margin: '5px 0 10px 0' }}
onUploadStart={() => setIsUploading(true)} onUploadStart={() => setIsUploading(true)}
onUploadComplete={() => onUpdate?.(idFileCategory)} onUploadComplete={() => onUpdate?.(idFileCategory)}
onUploadError={(e) => notify(e?.message ?? 'Ошибка загрузки файла', 'error')} onUploadError={(e) => notify(e?.message ?? 'Ошибка загрузки файла', 'error')}
/> />
)}
<Button <Button
disabled={!file} disabled={!file}
title={'История'} title={'История'}
@ -135,18 +133,22 @@ export const CategoryRender = memo(({ idWell, partData, onUpdate, onEdit, onHist
</span> </span>
))} ))}
</div> </div>
<div className={'approve_list'}> {file && (
{permissionToApprove && file && ( <>
<CommentPrompt text={'Согласовать'} title={'Согласование документа'} onDone={onApprove(true)} /> <div className={'approve_list'}>
)} {permissionToApprove && (
<MarksCard title={'Согласовано'} className={'approve_panel'} marks={file?.fileMarks?.filter((mark) => mark.idMarkType === 1)} /> <CommentPrompt text={'Согласовать'} title={'Согласование документа'} onDone={onApprove(true)} />
</div> )}
<div className={'reject_list'}> <MarksCard title={'Согласовано'} className={'approve_panel'} marks={file?.fileMarks?.filter((mark) => mark.idMarkType === 1)} />
{permissionToApprove && file && ( </div>
<CommentPrompt text={'Отклонить'} title={'Отклонение документа'} onDone={onApprove(false)} /> <div className={'reject_list'}>
)} {permissionToApprove && (
<MarksCard title={'Отклонено'} className={'reject_panel'} marks={file?.fileMarks?.filter((mark) => mark.idMarkType === 0)} /> <CommentPrompt text={'Отклонить'} title={'Отклонение документа'} onDone={onApprove(false)} />
</div> )}
<MarksCard title={'Отклонено'} className={'reject_panel'} marks={file?.fileMarks?.filter((mark) => mark.idMarkType === 0)} />
</div>
</>
)}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,8 +1,13 @@
import { Button, Layout } from 'antd' import { Button, Layout } from 'antd'
import { CloseOutlined, FileWordOutlined, LoadingOutlined } from '@ant-design/icons' import {
CloseOutlined,
FileWordOutlined,
LoadingOutlined,
ReloadOutlined,
WarningOutlined
} from '@ant-design/icons'
import { memo, useCallback, useEffect, useState } from 'react' import { memo, useCallback, useEffect, useState } from 'react'
import { Flex } from '@components/Grid'
import LoaderPortal from '@components/LoaderPortal' import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory' import { invokeWebApiWrapperAsync } from '@components/factory'
import { arrayOrDefault, formatDate } from '@utils' import { arrayOrDefault, formatDate } from '@utils'
@ -15,11 +20,20 @@ import CategoryHistory from './CategoryHistory'
import '@styles/drilling_program.less' import '@styles/drilling_program.less'
const idStateNotInitialized = 0
const idStateApproving = 1
const idStateCreating = 2
const idStateReady = 3
const idStateError = 4
const idStateUnknown = -1
const stateString = { const stateString = {
0: 'Не настроена', [idStateNotInitialized]: { icon: CloseOutlined, text: 'Не настроена' },
1: 'Согласовывается', [idStateApproving]: { icon: LoadingOutlined, text: 'Согласовывается' },
2: 'Формируется', [idStateCreating]: { icon: LoadingOutlined, text: 'Формируется' },
[-1]: 'Неизвестно', [idStateReady]: { icon: null, text: 'Сформирована' },
[idStateError]: { icon: WarningOutlined, text: 'Ошибка формирования' },
[idStateUnknown]: { icon: WarningOutlined, text: 'Неизвестно' },
} }
export const DrillingProgram = memo(({ idWell }) => { export const DrillingProgram = memo(({ idWell }) => {
@ -30,6 +44,20 @@ export const DrillingProgram = memo(({ idWell }) => {
const [categories, setCategories] = useState([]) const [categories, setCategories] = useState([])
const [data, setData] = useState({}) const [data, setData] = useState({})
const {
idState,
permissionToEdit,
parts,
program,
error,
} = data
const stateId = idState ?? idStateUnknown
const state = stateString[stateId]
const StateIcon = state.icon
console.log(parts)
const updateData = useCallback(async () => await invokeWebApiWrapperAsync( const updateData = useCallback(async () => await invokeWebApiWrapperAsync(
async () => { async () => {
const data = await DrillingProgramService.getState(idWell) const data = await DrillingProgramService.getState(idWell)
@ -37,7 +65,7 @@ export const DrillingProgram = memo(({ idWell }) => {
setData(data) setData(data)
setCategories(categories.filter(cat => { setCategories(categories.filter(cat => {
if (cat?.id && (cat.name || cat.shortName)) if (cat?.id && (cat.name || cat.shortName))
if (data?.parts.findIndex((val) => val.idFileCategory === cat.id) < 0) if (parts?.findIndex((val) => val.idFileCategory === cat.id) < 0)
return true return true
return false return false
})) }))
@ -66,55 +94,64 @@ export const DrillingProgram = memo(({ idWell }) => {
return ( return (
<LoaderPortal show={showLoader}> <LoaderPortal show={showLoader}>
<Layout style={{ backgroundColor: 'white' }}> <Layout style={{ backgroundColor: 'white' }}>
{data && ( <div className={'drilling_program'}>
<div className={'drilling_program'}> <div className={'program_header'}>
<div className={'program_header'}> <h3>Программа бурения</h3>
<h3>Программа бурения</h3> {permissionToEdit && (
</div> <div>
<Flex style={{ justifyContent: 'flex-start', alignItems: 'center', backgroundColor: 'white' }}> <Button
{data?.idState === 3 ? ( icon={<ReloadOutlined />}
<> disabled={[idStateNotInitialized, idStateApproving, idStateUnknown].includes(stateId)}
<Button type={'link'} icon={<FileWordOutlined />} style={{ marginLeft: '10px' }}>{data.program.name}</Button> loading={stateId === idStateCreating}
<div style={{ margin: '10px' }}>Размер: {data.program.size}</div> >
<div style={{ margin: '10px' }}>Загружен: {formatDate(data.program.uploadDate)}</div> Сформировать заново
</> </Button>
) : ( </div>
<h3 style={{ margin: '10px'}}> )}
{data?.idState <= 0 ? (
<CloseOutlined style={{ margin: '10px' }} />
) : (
<LoadingOutlined style={{ margin: '10px' }} />
)}
{stateString[data?.idState ?? -1]}
</h3>
)}
</Flex>
</div> </div>
)} <div className={'program_content'}>
{stateId === idStateReady ? (
<>
<Button type={'link'} icon={<FileWordOutlined />} style={{ marginLeft: '10px' }}>{program?.name}</Button>
<div className={'m-10'}>Размер: {program?.size}</div>
<div className={'m-10'}>Загружен: {formatDate(program?.uploadDate)}</div>
</>
) : (
<h3 className={`program_status ${stateId === idStateError ? 'error' : ''}`}>
<StateIcon className={'m-10'} />
{(stateId === idStateError && error?.message) ? error.message : state.text}
</h3>
)}
</div>
</div>
{data?.parts?.map?.((part, idx) => part && ( {parts?.map?.((part, idx) => part && (
<CategoryRender <CategoryRender
key={`${idx}`} key={`${idx}`}
idWell={idWell} idWell={idWell}
partData={part} partData={part}
onEdit={onCategoryEdit} onEdit={permissionToEdit && onCategoryEdit}
onUpdate={updateData} onUpdate={updateData}
onHistory={onCategoryHistory} onHistory={onCategoryHistory}
/> />
))} ))}
<CategoryAdder {permissionToEdit && (
idWell={idWell} <>
categories={categories} <CategoryAdder
onUpdate={updateData} idWell={idWell}
/> categories={categories}
onUpdate={updateData}
/>
<CategoryEditor <CategoryEditor
idWell={idWell} idWell={idWell}
visible={editorVisible} visible={editorVisible}
onClosed={onEditorClosed} onClosed={onEditorClosed}
category={data?.parts?.find((part) => part.idFileCategory === selectedCategory) ?? {}} category={parts?.find((part) => part.idFileCategory === selectedCategory) ?? {}}
/> />
</>
)}
<CategoryHistory <CategoryHistory
idWell={idWell} idWell={idWell}

View File

@ -7,6 +7,7 @@
.ml-15 { margin-left: 15px; } .ml-15 { margin-left: 15px; }
.mv-5 { margin: 5px 0; } .mv-5 { margin: 5px 0; }
.m-10 { margin: 10px; }
.drilling_category { .drilling_category {
margin-top: 10px; margin-top: 10px;
@ -132,9 +133,25 @@
border: @border-style; border: @border-style;
border-top: 0; border-top: 0;
.program_header { > .program_header {
.drilling_category > .category_header(); .drilling_category > .category_header();
} }
> .program_content {
display: flex;
justify-content: flex-start;
align-items: center;
background-color: white;
.program_status {
margin: 10px;
color: black;
}
.program_status.error {
color: red;
}
}
} }
/** Миксин для столбцов сетки (размер, отступы, границы) */ /** Миксин для столбцов сетки (размер, отступы, границы) */