From a7bd5d961f4b98b2902b84f430b5388b34a18f95 Mon Sep 17 00:00:00 2001 From: "a.chernyshev" Date: Sun, 28 Aug 2022 15:57:58 +0500 Subject: [PATCH] edit drillProcessFlow page --- package-lock.json | 36 +- package.json | 4 +- src/components/Table/Columns/index.ts | 3 +- src/components/Table/Columns/numeric.tsx | 18 +- src/components/Table/Columns/text.tsx | 13 + src/components/Table/index.tsx | 2 + src/pages/WellOperations/DrillProcessFlow.jsx | 389 +++++++++++++++++- src/styles/App.less | 39 +- 8 files changed, 455 insertions(+), 49 deletions(-) diff --git a/package-lock.json b/package-lock.json index 48a8eb2..303c5a9 100755 --- a/package-lock.json +++ b/package-lock.json @@ -54,7 +54,7 @@ "url-loader": "^4.1.1", "webpack": "^5.73.0", "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.1" + "webpack-dev-server": "^4.10.0" } }, "node_modules/@ampproject/remapping": { @@ -4741,9 +4741,9 @@ "dev": true }, "node_modules/connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true, "engines": { "node": ">=0.8" @@ -11743,15 +11743,16 @@ } }, "node_modules/webpack-dev-server": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.1.tgz", - "integrity": "sha512-CTMfu2UMdR/4OOZVHRpdy84pNopOuigVIsRbGX3LVDMWNP8EUgC5mUBMErbwBlHTEX99ejZJpVqrir6EXAEajA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.10.0.tgz", + "integrity": "sha512-7dezwAs+k6yXVFZ+MaL8VnE+APobiO3zvpp3rBHe/HmWQ+avwh0Q3d0xxacOiBybZZ3syTZw9HXzpa3YNbAZDQ==", "dev": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", "@types/express": "^4.17.13", "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", "@types/ws": "^8.5.1", "ansi-html-community": "^0.0.8", @@ -11759,7 +11760,7 @@ "chokidar": "^3.5.3", "colorette": "^2.0.10", "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", + "connect-history-api-fallback": "^2.0.0", "default-gateway": "^6.0.3", "express": "^4.17.3", "graceful-fs": "^4.2.6", @@ -11783,6 +11784,10 @@ "engines": { "node": ">= 12.13.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, "peerDependencies": { "webpack": "^4.37.0 || ^5.0.0" }, @@ -15682,9 +15687,9 @@ "dev": true }, "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true }, "content-disposition": { @@ -20915,15 +20920,16 @@ } }, "webpack-dev-server": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.1.tgz", - "integrity": "sha512-CTMfu2UMdR/4OOZVHRpdy84pNopOuigVIsRbGX3LVDMWNP8EUgC5mUBMErbwBlHTEX99ejZJpVqrir6EXAEajA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.10.0.tgz", + "integrity": "sha512-7dezwAs+k6yXVFZ+MaL8VnE+APobiO3zvpp3rBHe/HmWQ+avwh0Q3d0xxacOiBybZZ3syTZw9HXzpa3YNbAZDQ==", "dev": true, "requires": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", "@types/express": "^4.17.13", "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", "@types/ws": "^8.5.1", "ansi-html-community": "^0.0.8", @@ -20931,7 +20937,7 @@ "chokidar": "^3.5.3", "colorette": "^2.0.10", "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", + "connect-history-api-fallback": "^2.0.0", "default-gateway": "^6.0.3", "express": "^4.17.3", "graceful-fs": "^4.2.6", diff --git a/package.json b/package.json index 39758dd..33f1590 100755 --- a/package.json +++ b/package.json @@ -19,12 +19,12 @@ "start": "webpack-dev-server --mode=development --open --hot", "build": "webpack --mode=production", "test": "jest", - "oul": "npx openapi -i http://127.0.0.1:5000/swagger/v1/swagger.json -o src/services/api", + "oul": "npx openapi -i http://localhost:52123/swagger/v1/swagger.json -o src/services/api", "oud": "npx openapi -i http://192.168.1.70:5000/swagger/v1/swagger.json -o src/services/api", "oug": "npx openapi -i http://46.146.209.148/swagger/v1/swagger.json -o src/services/api", "oug_dev": "npx openapi -i http://46.146.209.148:89/swagger/v1/swagger.json -o src/services/api" }, - "proxy": "http://46.146.209.148:89", + "proxy": "http://localhost:52123", "eslintConfig": { "extends": [ "react-app", diff --git a/src/components/Table/Columns/index.ts b/src/components/Table/Columns/index.ts index de3a044..749d74a 100755 --- a/src/components/Table/Columns/index.ts +++ b/src/components/Table/Columns/index.ts @@ -12,12 +12,13 @@ export { makeNumericColumnPlanFact, makeNumericStartEnd, makeNumericMinMax, + makeNumericDividedColumn, makeNumericAvgRange } from './numeric' export { makeColumnsPlanFact } from './plan_fact' export { makeSelectColumn } from './select' export { makeTagColumn, makeTagInput } from './tag' -export { makeFilterTextMatch, makeTextColumn } from './text' +export { makeFilterTextMatch, makeTextColumn, makeDividedTextColumn } from './text' export { timezoneOptions, TimezoneSelect, diff --git a/src/components/Table/Columns/numeric.tsx b/src/components/Table/Columns/numeric.tsx index 1b2ed3b..99eccb4 100755 --- a/src/components/Table/Columns/numeric.tsx +++ b/src/components/Table/Columns/numeric.tsx @@ -50,12 +50,28 @@ export const makeNumericColumn = ( onFilter: filterDelegate ? filterDelegate(dataIndex) : null, sorter: makeNumericSorter(dataIndex), width: width, - input: , + input: , render: renderDelegate ?? makeNumericRender(), align: 'right', ...other }) +export const makeNumericDividedColumn = ( + title: ReactNode, + dataIndex: string, + filters: object[], + width: string, + other?: columnPropsOther +) => ({ + title: title, + dataIndex: dataIndex, + key: dataIndex, + filters: filters, + width: width, + align: 'right', + ...other +}) + export const makeNumericColumnPlanFact = ( title: ReactNode, dataIndex: string, diff --git a/src/components/Table/Columns/text.tsx b/src/components/Table/Columns/text.tsx index 992b984..bf2a976 100755 --- a/src/components/Table/Columns/text.tsx +++ b/src/components/Table/Columns/text.tsx @@ -24,4 +24,17 @@ export const makeTextColumn = ( ...other }) +export const makeDividedTextColumn = ( + title: ReactNode, + dataIndex: string, + render?: RenderMethod, + other?: columnPropsOther +) => ({ + title: title, + dataIndex: dataIndex, + key: dataIndex, + render: render, + ...other +}) + export default makeTextColumn diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index b03b8de..2241ac3 100755 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -16,6 +16,7 @@ export { makeFilterTextMatch, makeNumericRender, makeNumericColumn, + makeNumericDividedColumn, makeNumericColumnOptions, makeNumericColumnPlanFact, makeNumericStartEnd, @@ -25,6 +26,7 @@ export { makeTagColumn, makeTagInput, makeTextColumn, + makeDividedTextColumn, makeTimezoneColumn, makeTimezoneRenderer, } from './Columns' diff --git a/src/pages/WellOperations/DrillProcessFlow.jsx b/src/pages/WellOperations/DrillProcessFlow.jsx index 86dcb09..44aa24b 100755 --- a/src/pages/WellOperations/DrillProcessFlow.jsx +++ b/src/pages/WellOperations/DrillProcessFlow.jsx @@ -1,29 +1,374 @@ -import { useState, useEffect, memo, useMemo, useCallback } from 'react' +import React, { useState, useEffect, memo, useMemo, useCallback } from 'react' +import { InputNumber, Divider } from 'antd' import { useWell } from '@asb/context' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' -import { EditableTable, makeNumericMinMax, makeNumericStartEnd } from '@components/Table' -import { DrillFlowChartService } from '@api' +import { EditableTable, makeNumericDividedColumn, makeNumericStartEnd, makeGroupColumn, makeSelectColumn, makeDividedTextColumn } from '@components/Table' +import { DrillFlowChartService, WellOperationService } from '@api' import { arrayOrDefault } from '@utils' -const columns = [ - makeNumericStartEnd('Глубина, м', 'depth'), - makeNumericMinMax('Нагрузка, т', 'axialLoad'), - makeNumericMinMax('Давление, атм', 'pressure'), - makeNumericMinMax('Момент на ВСП, кН·м', 'rotorTorque'), - makeNumericMinMax('Обороты на ВСП, об/мин', 'rotorSpeed'), - makeNumericMinMax('Расход, л/с', 'flow') -] - export const DrillProcessFlow = memo(() => { const [flows, setFlows] = useState([]) const [showLoader, setShowLoader] = useState(false) - + const [sectionTypes, setSectionTypes] = useState([]) const [well] = useWell() + const generateColumns = (sectionTypes = []) => [ + makeNumericStartEnd('Глубина по стволу, м', 'depth', 1, null, null, null, '75px'), + makeSelectColumn('Секция', 'idWellSectionType', sectionTypes, null, { + editable: true, + width: '170px' + }), + makeDividedTextColumn('Операция бурения', null, + () => ( +
+ Ротор + + Слайд +
+ ), + { width: '70px' } + ), + makeGroupColumn('АКБ', [ + makeGroupColumn('Давление, атм', [ + makeNumericDividedColumn('мин', 'pressureParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorPressureMin: e, + })} /> + + onChange({ + ...value, + slidePressureMin: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorPressureMin)} + + {formatCellValue(fieldValue?.slidePressureMin)} +
+ ), + editable: true, + width: '107px' + }), + makeNumericDividedColumn('макс', 'pressureParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorPressureMax: e, + })} /> + + onChange({ + ...value, + slidePressureMax: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorPressureMax)} + + {formatCellValue(fieldValue?.slidePressureMax)} +
+ ), + editable: true, + width: '107px', + }), + ]), + makeGroupColumn('Нагрузка, т', [ + makeNumericDividedColumn('мин', 'loadParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorLoadMin: e, + })} /> + + onChange({ + ...value, + slideLoadMin: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorLoadMin)} + + {formatCellValue(fieldValue?.slideLoadMin)} +
+ ), + editable: true, + width: '107px', + }), + makeNumericDividedColumn('макс', 'loadParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorLoadMax: e, + })} /> + + onChange({ + ...value, + slideLoadMax: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorLoadMax)} + + {formatCellValue(fieldValue?.slideLoadMax)} +
+ ), + editable: true, + width: '107px', + }), + ]), + makeGroupColumn('Крутящий момент, кН*м', [ + makeNumericDividedColumn('мин', 'torqueParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorTorqueMin: e, + })} /> + + onChange({ + ...value, + slideTorqueMin: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorTorqueMin)} + + {formatCellValue(fieldValue?.slideTorqueMin)} +
+ ), + editable: true, + width: '107px', + }), + makeNumericDividedColumn('макс', 'torqueParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorTorqueMax: e, + })} /> + + onChange({ + ...value, + slideTorqueMax: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorTorqueMax)} + + {formatCellValue(fieldValue?.slideTorqueMax)} +
+ ), + editable: true, + width: '107px', + }), + ]), + makeGroupColumn('Расход, л/с', [ + makeNumericDividedColumn('мин', 'flowParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorFlowMin: e, + })} /> + + onChange({ + ...value, + slideFlowMin: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorFlowMin)} + + {formatCellValue(fieldValue?.slideFlowMin)} +
+ ), + editable: true, + width: '107px', + }), + makeNumericDividedColumn('макс', 'flowParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorFlowMax: e, + })} /> + + onChange({ + ...value, + slideFlowMax: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorFlowMax)} + + {formatCellValue(fieldValue?.slideFlowMax)} +
+ ), + editable: true, + width: '107px', + }), + ]), + makeNumericDividedColumn('Ограничение скорости, м/ч', 'speedLimitParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorSpeedLimit: e, + })} /> + + onChange({ + ...value, + slideSpeedLimit: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorSpeedLimit)} + + {formatCellValue(fieldValue?.slideSpeedLimit)} +
+ ), + editable: true, + width: '130px', + }), + ]), + makeGroupColumn('Spin Master', [ + makeGroupColumn('Количество оборотов', [ + makeNumericDividedColumn('мин', 'rpmParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorRpmMin: e, + })} /> + + onChange({ + ...value, + slideRpmMin: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorRpmMin)} + + {formatCellValue(fieldValue?.slideRpmMin)} +
+ ), + editable: true, + width: '107px', + }), + makeNumericDividedColumn('макс', 'rpmParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorRpmMax: e, + })} /> + + onChange({ + ...value, + slideRpmMax: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorRpmMax)} + + {formatCellValue(fieldValue?.slideRpmMax)} +
+ ), + editable: true, + width: '107px', + }), + ]), + makeGroupColumn('Скорость вращения, об/мин', [ + makeNumericDividedColumn('мин', 'speedParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorSpeedMin: e, + })} /> + + onChange({ + ...value, + slideSpeedMin: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorSpeedMin)} + + {formatCellValue(fieldValue?.slideSpeedMin)} +
+ ), + editable: true, + width: '107px', + }), + makeNumericDividedColumn('макс', 'speedParams', null, null, { + input: React.createElement(({ value, onChange }) => ( +
+ onChange({ + ...value, + rotorSpeedMax: e, + })} /> + + onChange({ + ...value, + slideSpeedMax: e, + })} /> +
+ )), + render: (fieldValue, item) => ( +
+ {formatCellValue(fieldValue?.rotorSpeedMax)} + + {formatCellValue(fieldValue?.slideSpeedMax)} +
+ ), + editable: true, + width: '107px', + }), + ]), + ]), + ] + const columns = useMemo(() => generateColumns(sectionTypes), [sectionTypes]) + + useEffect(() => { + updateFlows() + }, [well]) + const updateFlows = useCallback(() => invokeWebApiWrapperAsync( async () => { + const sectionTypes = Object.entries(await WellOperationService.getSectionTypes(well.id) ?? {}) + setSectionTypes(sectionTypes.map(([id, label]) => ({ value: parseInt(id), label }))) const flows = await DrillFlowChartService.getByIdWell(well.id) setFlows(arrayOrDefault(flows)) }, @@ -32,10 +377,6 @@ export const DrillProcessFlow = memo(() => { { actionName: 'Получение режимно-технологической карты', well } ), [well]) - useEffect(() => { - updateFlows() - }, [well]) - const tableHandlers = useMemo(() => { const handlerProps = { service: DrillFlowChartService, @@ -47,12 +388,20 @@ export const DrillProcessFlow = memo(() => { const recordParser = (record) => ({ idWell: well.id, ...record }) return { - add: { ...handlerProps, action: 'insert', actionName: 'Добавление месторождения', recordParser }, - edit: { ...handlerProps, action: 'update', actionName: 'Редактирование месторождения', recordParser }, - delete: { ...handlerProps, action: 'delete', actionName: 'Удаление месторождения', permission: 'DrillFlowChart.delete' }, + add: { ...handlerProps, action: 'insert', actionName: 'Добавление параметров для секции РТК', recordParser }, + edit: { ...handlerProps, action: 'update', actionName: 'Редактирование параметров секции РТК', recordParser }, + delete: { ...handlerProps, action: 'delete', actionName: 'Удаление параметров секции РТК', permission: 'DrillFlowChart.delete' }, } }, [updateFlows, well.id]) + const formatCellValue = (value) => { + let res = '-' + if ((value ?? null) !== null && Number.isFinite(+value)) { + res = (+value).toFixed(2) + } + return res + } + return ( .ant-menu { + >.ant-menu { flex: 0; } } @@ -53,7 +54,7 @@ html { background-color: #9d9d9d; } -.shadow{ +.shadow { box-shadow: 1px 1px 4px #00000033; } @@ -71,13 +72,13 @@ html { margin-bottom: 2px; } -.header .title{ +.header .title { flex-grow: 1; color: #fff; padding-left: 450px; } -.header button{ +.header button { color: rgb(255, 255, 255); background-color: rgba(0, 0, 0, 0.1); border: 1px solid rgba(0, 0, 0, 0.2); @@ -116,9 +117,10 @@ html { display: flex; flex-direction: column; align-items: stretch; + overflow: auto; } -.sheet{ +.sheet { padding: 5px 24px; min-height: calc(@layout-min-height - 15px); // 280px; margin: 0 15px 15px 15px; @@ -128,7 +130,7 @@ html { background: #fff; } -.border_small{ +.border_small { border: 1px solid rgba(0, 0, 0, 0.05); } @@ -160,3 +162,20 @@ tr.table_row_size { margin-right: 5px; margin-left: 5px; } + +.cell-divider { + margin: 0px 0px 0px -8px; + width: calc(100% + 16px); +} + +.divided-cell { + height: 64px; + display: flex; + flex-direction: column; + justify-content: space-between; + &__edit { + .cell-divider { + margin: 8px 0px 8px -8px; + } + } +} \ No newline at end of file