From 9de6400e7822354339f2d9e6a52cca6a78874bdd Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Mon, 7 Feb 2022 22:20:44 +0500 Subject: [PATCH 01/54] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=20=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BE=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=BC=D1=8B=20=D0=B1=D1=83=D1=80=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/DrillingProgram.jsx | 352 ++++++++++++++++++++-------------- 1 file changed, 210 insertions(+), 142 deletions(-) diff --git a/src/pages/DrillingProgram.jsx b/src/pages/DrillingProgram.jsx index 823bebc..b19a8bf 100644 --- a/src/pages/DrillingProgram.jsx +++ b/src/pages/DrillingProgram.jsx @@ -1,168 +1,236 @@ -import { useEffect, useState } from 'react' -import { FileExcelOutlined } from '@ant-design/icons' -import { Popconfirm, Button, Tooltip, Typography } from 'antd' +import { memo, useState } from 'react' +import { Button, Tooltip, Layout } from 'antd' +import { CommentOutlined, FileWordOutlined, TableOutlined, UploadOutlined } from '@ant-design/icons' import { Flex } from '@components/Grid' +import { UserView } from '@components/views' import LoaderPortal from '@components/LoaderPortal' -import { MarkView, UserView } from '@components/views' -import { invokeWebApiWrapperAsync, download, formatBytes } from '@components/factory' -import { DrillingProgramService, WellService } from '@api' +import { invokeWebApiWrapperAsync } from '@components/factory' +import { arrayOrDefault, formatDate } from '@utils' +import { hasPermission } from '@utils/permissions' +import { DrillingProgramService } from '@api' -import DocumentsTemplate from '@pages/Documents/DocumentsTemplate' +const testCategories = [ + { + caption: 'Задание от геологов', + status: 1, + file: { + name: 'Документ 1.xlsx', + author: { login: 'Человек 9', company: { caption: 'Компания 9' } }, + size: '123 кБ', + uploadDate: '2022-01-01T00:00:00', + }, + lastApprove: '2022-01-01T00:00:00', + lastReject: '2022-01-01T00:00:00', + approved: [{ + user: { login: 'Человек 2', company: { caption: 'Компания 2' }}, + comment: 'Комментарий', + }], + undecided: [{ login: 'Человек 3', company: { caption: 'Компания 1' }}], + rejected: [], + }, { + caption: 'Профиль ствола скважины (ННБ)', + status: 1, + file: { + name: 'Документ 1.xlsx', + author: { login: 'Человек 9', company: { caption: 'Компания 9' }}, + size: '123 кБ', + uploadDate: '2022-01-01T00:00:00', + }, + lastApprove: '2022-01-01T00:00:00', + lastReject: '2022-01-01T00:00:00', + approved: [{ + user: { login: 'Человек 2', company: { caption: 'Компания 2' }}, + comment: 'Комментарий 3', + }], + undecided: [ + { login: 'Человек 3', company: { caption: 'Компания 1' }}, + { login: 'Человек 4', company: { caption: 'Компания 2' }}, + ], + rejected: [{ + user: { login: 'Человек 1', company: { caption: 'Компания 1' }}, + comment: 'Комментарий 2', + }], + }, { + caption: 'Технологические расчёты ННБ', + status: 0, + file: { + name: 'Документ 1.xlsx', + author: { login: 'Человек 9', company: { caption: 'Компания 9' }}, + size: '123 кБ', + uploadDate: '2022-01-01T00:00:00', + }, + lastApprove: '2022-01-01T00:00:00', + lastReject: '2022-01-01T00:00:00', + approved: [], + undecided: [ + { login: 'Человек 2', company: { caption: 'Компания 1' }}, + { login: 'Человек 3', company: { caption: 'Компания 1' }}, + { login: 'Человек 4', company: { caption: 'Компания 2' }}, + ], + rejected: [{ + user: { login: 'Человек 1', company: { caption: 'Компания 1' }}, + comment: 'Комментарий 2', + }], + }, { + caption: 'ГГД', + status: 0, + file: { + name: 'Документ 1.xlsx', + author: { login: 'Человек 9', company: { caption: 'Компания 9' }}, + size: '123 кБ', + uploadDate: '2022-01-01T00:00:00', + }, + lastApprove: '2022-01-01T00:00:00', + lastReject: '2022-01-01T00:00:00', + approved: [], + undecided: [ + { login: 'Человек 2', company: { caption: 'Компания 1' }}, + { login: 'Человек 3', company: { caption: 'Компания 1' }}, + { login: 'Человек 4', company: { caption: 'Компания 2' }}, + { login: 'Человек 2', company: { caption: 'Компания 1' }}, + { login: 'Человек 3', company: { caption: 'Компания 1' }}, + { login: 'Человек 4', company: { caption: 'Компания 2' }}, + ], + rejected: [{ + user: { login: 'Человек 1', company: { caption: 'Компания 1' }}, + comment: 'Комментарий 2', + }], + } +] -const idFileCategoryDrillingProgramItems = 13 -const { Text } = Typography +const testProgram = { + name: 'Документ 1.xlsx', + size: '123 кБ', + uploadDate: '2022-01-01T00:00:00', +} -export const DrillingProgram = ({ idWell }) => { - const [downloadButtonEnabled, selDownloadButtonEnabled] = useState(false) +export const DrillingProgram = memo(({ idWell }) => { const [showLoader, setShowLoader] = useState(false) - const [tooltip, setTooltip] = useState('нет файлов для формирования') - const [wellLabel, setWellLabel] = useState(`${idWell}`) - const [childKey, setChildKey] = useState() - const [lastUpdatedFile, setLastUpdatedFile] = useState() + const [categories, setCategories] = useState(testCategories) + const [program, setProgram] = useState(testProgram) - useEffect(() => invokeWebApiWrapperAsync( + const updateData = async () => await invokeWebApiWrapperAsync( async () => { - const well = await WellService.get(idWell) - setWellLabel(well.caption ?? `${idWell}`) + const categories = arrayOrDefault(await DrillingProgramService.getCategories(idWell)) + const program = await DrillingProgramService.getProgram(idWell) + setCategories(categories) + setProgram(program) }, setShowLoader, - `Не удалось загрузить название скважины "${idWell}"`, - 'Получить название скважины' - ), [idWell]) - - const downloadProgram = () => invokeWebApiWrapperAsync( - async () => await download(`/api/well/${idWell}/drillingProgram`), - setShowLoader, - `Не удалось загрузить программу бурения для скважины "${idWell}"`, - 'Получить программу бурения' + `Не удалось загрузить название скважины "${idWell}"` ) - const openProgramPreview = () => invokeWebApiWrapperAsync( - async() => { - const filWebUrl = await DrillingProgramService.getOrCreateSharedUrl(idWell) - if(filWebUrl && filWebUrl.length > 0) - window.open(filWebUrl, '_blank') - else - throw new Error('Сервер вернул плохую ссылку') + // useEffect(() => updateCategories(), [idWell]) + + const onApprove = (category) => () => invokeWebApiWrapperAsync( + async () => { + await DrillingProgramService.approve(idWell, category) + await updateData() }, setShowLoader, - 'Не удалось создать быстрый просмотр программы', - 'Создать быстрый просмотр программы' + `Не удалось согласовать документ для скважины "${idWell}"!` ) - const filesUpdated = (files) => { - if (!files || files.length === 0) { - setTooltip('Нет файлов для формирования программы') - selDownloadButtonEnabled(false) - return - } - - const isAllFilesAreExcel = files.every(fileInfo => fileInfo?.name.toLowerCase().endsWith('.xlsx')) - const isAnyFileMarked = files.some(file => file?.fileMarks.some(m => m?.idMarkType === 1 && !m?.isDeleted)) - - if (isAllFilesAreExcel && isAnyFileMarked) { - setTooltip('Программа доступна для скачивания') - selDownloadButtonEnabled(true) - } else { - setTooltip('Список файлов содержит недопустимые типы файлов') - } - const last = files.reduce((pre, cur) => pre.uploadDate > cur.uploadDate ? pre : cur) - setLastUpdatedFile(last) - } - - const customColumns = [ - { - title: 'Метки', - key: 'fileMarks', - render: (_, record) => renderMarksColumn(record?.id, record?.fileMarks) + const onReject = (category) => () => invokeWebApiWrapperAsync( + async () => { + await DrillingProgramService.reject(idWell, category) + await updateData() }, - ] - - const renderMarksColumn=(idFile, marks)=>{ - const validMarks = marks?.filter(m => !(m?.isDeleted)) - if(validMarks?.length) - return validMarks.map(mark => deleteMark(mark.id)}/>) - - return ( - addMarkToFile(idFile)}> - - - ) - } - - const addMarkToFile = async (idFile) => { - const mark = { - idFile: idFile, - idMarkType: 1, - isDeleted: false, - comment: '', - } - await DrillingProgramService.createFileMark(idWell, mark) - selDownloadButtonEnabled(true) - setChildKey(Date.now()) - } - - const deleteMark = async (idMark) => { - await DrillingProgramService.deleteFileMark(idWell, idMark) - setChildKey(Date.now()) - } - - const downloadButton = ( -
- Программа бурения - - - - - - - - - - -
+ setShowLoader, + `Не удалось согласовать документ для скважины "${idWell}"!` ) - const lastUpdatedFileView = lastUpdatedFile && - - Последнее изменние: -  '{lastUpdatedFile.name}' -  [{formatBytes(lastUpdatedFile.size)}] -  загружен: {new Date(lastUpdatedFile.uploadDate).toLocaleString()} -  автор: - - return ( - + + {program && ( +
+
Программа бурения
+ + +
Размер: {program.size}
+
Загружен: {formatDate(program.uploadDate)}
+
+
+ )} + + {categories.map((category) => category && ( +
+ +
{category.caption}
+
Согласованты
+
+ + + + +
Автор:
+
Размер: {category.file.size}
+
Загружен: {formatDate(category.file.uploadDate)}
+
+ + + + +
+ +
+ {category.undecided.map((user, i) => ( + + + + ))} +
+ + {category.status === 0 && hasPermission() && ( + + )} + + + Согласовано + {formatDate(category.lastApprove)} + +
+ {category.approved?.map(({ comment, user }, i) => ( +
+ + + + +
+ ))} +
+
+
+ + {category.status === 0 && hasPermission() && ( + + )} + + + Отклонено + {formatDate(category.lastReject)} + +
+ {category.rejected?.map(({ comment, user }, i) => ( +
+ + + + +
+ ))} +
+
+
+
+
+
+ ))} +
) -} +}) export default DrillingProgram From 5ef6279f174d812857d068ab0168f94c40d4711d Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Tue, 8 Feb 2022 19:17:40 +0500 Subject: [PATCH 02/54] =?UTF-8?q?=D0=91=D1=83=D0=BA=D0=B2=D0=B0=20=D0=81?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=B2=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/validationRules.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/validationRules.ts b/src/utils/validationRules.ts index 474968d..9f300a4 100644 --- a/src/utils/validationRules.ts +++ b/src/utils/validationRules.ts @@ -9,7 +9,7 @@ const _min1: Rule = { export const min1: Rule[] = [_min1] export const createLoginRules: Rule[] = [_min1, { - pattern: /^\s*[A-Za-zА-Яа-я][А-Яа-я\w.-]+\s*$/, + pattern: /^\s*[A-zА-яЁё][A-zА-яЁё\w.-]+\s*$/, message: 'Логин должен начинаться с русской или латинской буквы и содержать только символы (А-яA-z0-9_-.)!' }] @@ -19,7 +19,7 @@ export const loginRules: Rule[] = [...createLoginRules, { }] export const nameRules: Rule[] = [_min1, { - pattern: /^[A-zА-я][A-zА-я-]*$/, + pattern: /^[A-zА-яЁё][A-zА-яЁё-]*$/, message: 'Допустимые символы: А-яA-z-', }] From a275bd20c73b703264dffd567bd0b2e87d556687 Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Tue, 8 Feb 2022 19:19:00 +0500 Subject: [PATCH 03/54] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D1=80=D0=B0=D0=B2=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=B8=D0=BC=D0=BF=D0=BE=D1=80=D1=82=D0=B0,=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D1=80=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=B8=20=D0=B0?= =?UTF-8?q?=D0=BD=D0=B0=D0=BB=D0=B8=D1=82=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Measure/MeasureTable.jsx | 15 +++++++++------ src/pages/WellOperations/ImportExportBar.jsx | 3 ++- .../WellCompositeEditor/WellCompositeSections.jsx | 3 ++- .../WellOperations/WellCompositeEditor/index.jsx | 2 ++ 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/pages/Measure/MeasureTable.jsx b/src/pages/Measure/MeasureTable.jsx index 997d456..2cdf50a 100644 --- a/src/pages/Measure/MeasureTable.jsx +++ b/src/pages/Measure/MeasureTable.jsx @@ -18,11 +18,12 @@ import { View } from './View' import '@styles/index.css' import '@styles/measure.css' +import { hasPermission } from '@asb/utils/permissions' const createEditingColumns = (cols, renderDelegate) => cols.map(col => ({ render: renderDelegate, ...col })) -export const MeasureTable = memo(({idWell, group, updateMeasuresFunc, additionalButtons}) => { +export const MeasureTable = memo(({ idWell, group, updateMeasuresFunc, additionalButtons }) => { const [showLoader, setShowLoader] = useState(false) const [displayedValues, setDisplayedValues] = useState({}) const [editingColumns, setEditingColumns] = useState(group.columns) @@ -64,7 +65,9 @@ export const MeasureTable = memo(({idWell, group, updateMeasuresFunc, additional 'Удаление записи для скважины' ) - const isDataDefault = () => !!displayedValues?.isDefaultData + const disabled = !hasPermission('Measure.edit') + const editingDisabled = disabled || !!displayedValues?.isDefaultData + const deleteDisabled = !hasPermission('Measure.delete') || !!displayedValues?.isDefaultData const editTable = (action) => { setEditingActionName(action) @@ -116,14 +119,14 @@ export const MeasureTable = memo(({idWell, group, updateMeasuresFunc, additional ) : ( <> - - - - diff --git a/src/pages/WellOperations/ImportExportBar.jsx b/src/pages/WellOperations/ImportExportBar.jsx index 6dd3481..9e5f846 100644 --- a/src/pages/WellOperations/ImportExportBar.jsx +++ b/src/pages/WellOperations/ImportExportBar.jsx @@ -3,6 +3,7 @@ import { Button, Tooltip, Modal } from 'antd' import { FileOutlined, ImportOutlined, ExportOutlined } from '@ant-design/icons' import { download } from '@components/factory' +import { hasPermission } from '@utils/permissions' import { ImportOperations } from './ImportOperations' @@ -23,7 +24,7 @@ export const ImportExportBar = memo(({ idWell, onImported, disabled }) => { <>