From 79452f06dbb651da162fc2045c09e777bb14f452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Fri, 30 Jul 2021 15:13:15 +0500 Subject: [PATCH 1/5] components factory update --- src/components/factory.ts | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/components/factory.ts b/src/components/factory.ts index e53dbaa..95f9e28 100644 --- a/src/components/factory.ts +++ b/src/components/factory.ts @@ -5,22 +5,31 @@ export const makeColumn = (title:string, key:string, other?:any) => ({ ...other, }) -export const makeColumnsPlanFact = (title:string, keyPlan:string, keyFact?:string, groupOther?:any) => +export const makeColumnsPlanFact = (title:string, key:string|string[], gruopOther?:any, columsOther?:any|any[]) => { - let keyPlanLocal = keyPlan - let keyFactLocal = keyFact ?? '' + let keyPlanLocal = key + let keyFactLocal = key - if(!keyFact){ - keyPlanLocal = keyPlan + 'Plan' - keyFactLocal = keyPlan + 'Fact' + if(key instanceof Array){ + keyPlanLocal = key[0] + keyFactLocal = key[1] + }else{ + keyPlanLocal = key + 'Plan' + keyFactLocal = key + 'Fact' } + let columsOtherLoacl :any[2] + if(columsOther instanceof Array) + columsOtherLoacl = [columsOther[0], columsOther[1]] + else + columsOtherLoacl = [columsOther, columsOther] + return { title: title, - ...groupOther, - children: [ - makeColumn('план', keyPlanLocal), - makeColumn('факт', keyFactLocal), + ...gruopOther, + children: [ + makeColumn('план', keyPlanLocal, columsOtherLoacl[0]), + makeColumn('факт', keyFactLocal, columsOtherLoacl[1]), ] } } \ No newline at end of file From a6ddfa39c54ee7868034291563fd5e533ab1f27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Fri, 30 Jul 2021 16:13:26 +0500 Subject: [PATCH 2/5] doc, Add RegExpIsFloat --- src/components/factory.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/factory.ts b/src/components/factory.ts index 95f9e28..5cb0ffb 100644 --- a/src/components/factory.ts +++ b/src/components/factory.ts @@ -1,3 +1,15 @@ +export const RegExpIsFloat = /^[-+]?\d+\.?\d?$/ + +/* + other - объект с дополнительными свойствами колонки + поддерживаются все базовые свойства из описания https://ant.design/components/table/#Column + плю дополнительные для колонок EditableTable: + editable - редактируемая колонка, bool + input - react компонента редактора (, , ...) + isRequired - значение может быть пустым, + formItemClass - css класс для , если требуется + formItemRules - массив правил валидации значений https://ant.design/components/form/#Rule, + */ export const makeColumn = (title:string, key:string, other?:any) => ({ title: title, key: key, @@ -5,7 +17,7 @@ export const makeColumn = (title:string, key:string, other?:any) => ({ ...other, }) -export const makeColumnsPlanFact = (title:string, key:string|string[], gruopOther?:any, columsOther?:any|any[]) => +export const makeColumnsPlanFact = (title:string, key:string|string[], columsOther?:any|any[], gruopOther?:any) => { let keyPlanLocal = key let keyFactLocal = key From f0e30a32f8aa3e5e9d52d9dda305f7ff5a4bf270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Fri, 30 Jul 2021 16:14:07 +0500 Subject: [PATCH 3/5] Add EditableTable --- src/components/EditableTable.jsx | 140 +++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/components/EditableTable.jsx diff --git a/src/components/EditableTable.jsx b/src/components/EditableTable.jsx new file mode 100644 index 0000000..24b2ace --- /dev/null +++ b/src/components/EditableTable.jsx @@ -0,0 +1,140 @@ +import { Form, Input, Popconfirm, Typography, Table } from "antd" +import { useState } from "react"; + +const EditableCell = ({ + editing, + record, + dataIndex, + input, + isRequired, + title, + formItemClass, + formItemRules, + children, +}) => { + + const inputNode = input ?? + const rules = formItemRules ?? [{ + required: isRequired, + message: `Please Input ${title}!`, + }] + + const editor = + {inputNode} + + + return ( + {editing ? editor: children} + ) +} + +export const EditableTable = ({columns, dataSource, onUpdateData: onChange, ...otherTableProps}) => { + const [form] = Form.useForm() + const [editingKey, setEditingKey] = useState('') + + const isEditing = (record) => record.key === editingKey + + const edit = (record) => { + form.setFieldsValue({...record}) + setEditingKey(record.key) + } + + const cancel = () => { + setEditingKey('') + } + + const save = async (key) => { + try { + const row = await form.validateFields() + const newData = [...dataSource] + const index = newData.findIndex((item) => key === item.key) + + if (index > -1) { + const item = newData[index] + newData.splice(index, 1, { ...item, ...row }) + } else { + newData.push(row) + } + + setEditingKey('') + if(onChange) + onChange(newData) + else + console.error(`EditableTable.onChange doesn't connected`) + } catch (errInfo) { + console.log('Validate Failed:', errInfo) + } + } + + const operationColumn = { + title: '', + dataIndex: 'operation', + render: (_, record) => { + const editable = isEditing(record) + return editable ? ( + + save(record.key)} + style={{ + marginRight: 8, + }} + > + Save + + + Cancel + + + ) : ( + edit(record)}> + Edit + + ) + }, + } + + const handleColumn = (col) => { + if (col.children) + col.children = col.children.map(handleColumn) + + if (!col.editable) + return col + + return { + ...col, + onCell: (record) => ({ + editing: isEditing(record), + record, + dataIndex: col.dataIndex ?? col.key, + input: col.input, + isRequired: col.isRequired, + title: col.title, + dataType: col.dataType, + formItemClass: col.formItemClass, + formItemRules: col.formItemRules, + }), + } + } + + const mergedColumns = [...columns.map(handleColumn), operationColumn] + + return ( +
+ + + ) +} \ No newline at end of file From 5d18d73d28c902cc92fd435da25b3d623d2a717a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Fri, 30 Jul 2021 16:14:56 +0500 Subject: [PATCH 4/5] =?UTF-8?q?WellStat=20=D1=80=D0=B5=D0=B4=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D1=83=D0=B5=D0=BC=D0=BE=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Well.jsx | 4 +- src/pages/WellStat.jsx | 86 +++++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index f8ac02b..ead68d1 100644 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -8,7 +8,7 @@ import Analysis from "../pages/Analysis"; import WellAnalysis from "../pages/WellAnalysis"; import TelemetryView from "../pages/TelemetryView"; import MenuDocuments from "../components/MenuDocuments"; -import WellStat from "./WellStat"; +import WellStat from "./WellStat" const { Content } = Layout @@ -83,7 +83,7 @@ export default function Well() { - + diff --git a/src/pages/WellStat.jsx b/src/pages/WellStat.jsx index 5372b1a..97c3901 100644 --- a/src/pages/WellStat.jsx +++ b/src/pages/WellStat.jsx @@ -1,44 +1,28 @@ -//import {useParams} from "react-router-dom"; -//import {Link} from "react-router-dom"; import LoaderPortal from '../components/LoaderPortal' import { useState, useEffect } from "react"; -// import {ClusterService} from '../services/api' -// import notify from '../components/notify' -import {Table, Tag, Button} from 'antd'; - -const makeColumn = (title, key) => ({title: title, key: key, dataIndex: key,}) - -const makePlanFactColumns = (title, keyPlan, keyFact) => -{ - let keyPlanLocal = keyPlan - let keyFactLocal = keyFact - - if(!keyFact){ - keyPlanLocal = keyPlan + 'Plan' - keyFactLocal = keyPlan + 'Fact' - } - - return { - title: title, - children: [ - makeColumn('план', keyPlanLocal), - makeColumn('факт', keyFactLocal), - ] - } -} +import {makeColumn, makeColumnsPlanFact, RegExpIsFloat} from '../components/factory' +import {WellService} from '../services/api' +import notify from '../components/notify' +import { EditableTable } from '../components/EditableTable'; const columns = [ - makeColumn('Конструкция секции', 'sectionType'), - makePlanFactColumns('Глубина, м', 'wellDepth'), - makePlanFactColumns('Период, д', 'buildDays'), - makePlanFactColumns('Механическая скорость проходки, м/час', 'rateOfPenetration'), - makePlanFactColumns('Рейсовая скорость, м/час', 'routeSpeed'), - makePlanFactColumns('Скорость подъема КНБК', 'bhaUpSpeed'), - makePlanFactColumns('Скорость спуска КНБК', 'bhaDownSpeed'), - makePlanFactColumns('Скорость спуска обсадной колонны', 'casingDownSpeed'), + makeColumn('Конструкция секции', 'sectionType', {editable:true}), + makeColumnsPlanFact('Глубина, м', 'wellDepth', {editable:true, formItemRules:[ + { + required: true, + message: `Введите число`, + pattern: RegExpIsFloat + }]}), + makeColumnsPlanFact('Период, д', 'buildDays', {editable:true}), + makeColumnsPlanFact('Механическая скорость проходки, м/час', 'rateOfPenetration', {editable:true}), + makeColumnsPlanFact('Рейсовая скорость, м/час', 'routeSpeed', {editable:true}), + makeColumnsPlanFact('Скорость подъема КНБК', 'bhaUpSpeed', {editable:true}), + makeColumnsPlanFact('Скорость спуска КНБК', 'bhaDownSpeed', {editable:true}), + makeColumnsPlanFact('Скорость спуска обсадной колонны', 'casingDownSpeed', {editable:true}), ] // const data = [{ +// key:1, // sectionType: 'загагулина', // wellDepthPlan: 1, // wellDepthFact: 1, @@ -56,17 +40,33 @@ const columns = [ // casingDownSpeedFact: 1, // }] -export default function WellStat({data}){ +export default function WellStat({idWell}){ const [showLoader, setShowLoader] = useState(false) + const [data, setData] = useState(null) + + useEffect(()=>{ + const update = async()=>{ + setShowLoader(true) + try{ + const data = await WellService.getSections(idWell) + setData(data); + } catch (ex) { + console.log(ex) + notify(`Не удалось загрузить секции по скважине "${idWell}"`, 'error') + } + setShowLoader(false) + } + update(); + } ,[idWell]) + return( -
record.sectionType} - /> + ) } \ No newline at end of file From 618edda299373887b987fdd2535a66c857923796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Mon, 2 Aug 2021 11:09:55 +0500 Subject: [PATCH 5/5] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=82=D0=B8=D1=80?= =?UTF-8?q?=D1=83=D0=B5=D0=BC=D0=BE=D0=B9=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8?= =?UTF-8?q?=D1=86=D1=8B.=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D1=8B=D0=B5=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5,=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5,=20=D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=82=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/EditableTable.jsx | 119 ++++++++++++++++++++++--------- src/pages/WellStat.jsx | 8 +++ 2 files changed, 92 insertions(+), 35 deletions(-) diff --git a/src/components/EditableTable.jsx b/src/components/EditableTable.jsx index 24b2ace..f0fee09 100644 --- a/src/components/EditableTable.jsx +++ b/src/components/EditableTable.jsx @@ -1,6 +1,9 @@ -import { Form, Input, Popconfirm, Typography, Table } from "antd" +import { Form, Input, Table, Button, Popconfirm } from "antd" +import { EditOutlined, SaveOutlined, PlusOutlined, CloseCircleOutlined, DeleteOutlined } from '@ant-design/icons' import { useState } from "react"; +const newRowKeyValue = 'newRow' + const EditableCell = ({ editing, record, @@ -32,8 +35,17 @@ const EditableCell = ({ ) } -export const EditableTable = ({columns, dataSource, onUpdateData: onChange, ...otherTableProps}) => { +export const EditableTable = ({ + columns, + dataSource, + onChange, // Метод вызывается со всем dataSource с измененными элементами после любого действия + onRowAdd, // Метод вызывается с новой добавленной записью. Если метод не поределен, то кнопка добавления строки не показывается + onRowEdit,// Метод вызывается с новой отредактированной записью. Если метод не поределен, то кнопка редактирования строки не показывается + onRowDelete,// Метод вызывается с удаленной записью. Если метод не поределен, то кнопка удаления строки не показывается + ...otherTableProps}) => { + const [form] = Form.useForm() + const [data, setData] = useState(dataSource?? []) const [editingKey, setEditingKey] = useState('') const isEditing = (record) => record.key === editingKey @@ -44,57 +56,94 @@ export const EditableTable = ({columns, dataSource, onUpdateData: onChange, ...o } const cancel = () => { + if(editingKey == newRowKeyValue) + { + const newData = [...data] + const index = newData.findIndex((item) => newRowKeyValue === item.key) + newData.splice(index, 1) + setData(newData) + } setEditingKey('') } - const save = async (key) => { + const addNewRow = () => { + let newRow = { + key:newRowKeyValue + } + const newData = [...data, newRow] + setData(newData) + edit(newRow) + } + + const save = async (record) => { try { const row = await form.validateFields() - const newData = [...dataSource] - const index = newData.findIndex((item) => key === item.key) + const newData = [...data] + const index = newData.findIndex((item) => record.key === item.key) + let item = newData[index] - if (index > -1) { - const item = newData[index] - newData.splice(index, 1, { ...item, ...row }) - } else { - newData.push(row) - } + newData.splice(index, 1, { ...item, ...row }) + if(item.key === newRowKeyValue) + item.key = newRowKeyValue + newData.length + setEditingKey('') + setData(newData) + + if (editingKey === newRowKeyValue) + onRowAdd(item) + else + onRowEdit(item) + if(onChange) onChange(newData) - else - console.error(`EditableTable.onChange doesn't connected`) + } catch (errInfo) { console.log('Validate Failed:', errInfo) } } + const deleteRow = (record) =>{ + const newData = [...data] + const index = newData.findIndex((item) => record.key === item.key) + + newData.splice(index, 1) + setData(newData) + + onRowDelete(record) + + if(onChange) + onChange(newData) + } + const operationColumn = { - title: '', + title: (!!onRowAdd) &&