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