diff --git a/src/pages/Measure/InclinometryTable.jsx b/src/pages/Measure/InclinometryTable.jsx
new file mode 100644
index 0000000..fe04957
--- /dev/null
+++ b/src/pages/Measure/InclinometryTable.jsx
@@ -0,0 +1,50 @@
+import React, { useEffect, useState } from 'react'
+import { Modal } from 'antd'
+import { Table } from '../../components/Table'
+import { formatDate } from './MeasureTable'
+import { v } from './columnsCommon'
+
+export const InclinometryTable = React.memo(({ group, visible, onClose }) => {
+ const [tableColumns, setTableColumns] = useState([])
+ const [tableData, setTableData] = useState([])
+
+ useEffect(() => {
+ setTableColumns([{
+ title: 'Дата',
+ key: 'date',
+ dataIndex: 'date',
+ render: (item) => formatDate(item),
+ fixed: 'left',
+ width: '8rem',
+ },
+ ...(group?.columns?.map((column) => ({...column, title: v(column.title)})) ?? [])
+ ])
+ }, [group?.columns])
+
+ useEffect(() => {
+ setTableData(group?.values?.map(row => ({ date: row.timestamp, ...row.data })))
+ }, [group?.values])
+
+ return !group?.columns ? null : (
+
+
+
+ )
+})
+
+export default InclinometryTable
diff --git a/src/pages/Measure/MeasureTable.jsx b/src/pages/Measure/MeasureTable.jsx
index 4831ec6..04fbff9 100644
--- a/src/pages/Measure/MeasureTable.jsx
+++ b/src/pages/Measure/MeasureTable.jsx
@@ -1,198 +1,161 @@
import { useState, useEffect } from 'react'
import { Button, Form, Input, Popconfirm, Timeline } from 'antd'
import moment from 'moment'
-import { CheckSquareOutlined,
- EditOutlined,
- SaveOutlined,
- PlusOutlined,
- CloseCircleOutlined,
- DeleteOutlined } from '@ant-design/icons'
+import {
+ CheckSquareOutlined,
+ EditOutlined,
+ SaveOutlined,
+ PlusOutlined,
+ CloseCircleOutlined,
+ DeleteOutlined
+} from '@ant-design/icons'
import { View } from './View'
import LoaderPortal from '../../components/LoaderPortal'
import { MeasureService } from '../../services/api'
import '../../styles/index.css'
import '../../styles/measure.css'
+import { invokeWebApiWrapperAsync } from '../../components/factory'
-const format='YYYY.MM.DD HH:mm'
+const dateFormat = 'YYYY.MM.DD HH:mm'
+export const formatDate = (date) => date ? moment.utc(date).local().format(dateFormat) : 'Нет данных'
-export const MeasureTable = ({idWell, idCategory, title, columns, values, updateMeasuresFunc}) => {
+export const MeasureTable = ({idWell, group, updateMeasuresFunc, additionalButtons}) => {
+ const [showLoader, setShowLoader] = useState(false)
+ const [displayedValues, setDisplayedValues] = useState({})
+ const [editingColumns, setEditingColumns] = useState(group.columns)
+ const [isTableEditing, setIsTableEditing] = useState(false)
+ const [editingActionName, setEditingActionName] = useState('')
+ const [data, setData] = useState([])
- const [showLoader, setShowLoader] = useState(false);
- const [displayedValues, setDisplayedValues] = useState({});
- const [editingColumns, setEditingColumns] = useState(columns);
- const [isTableEditing, setIsTableEditing] = useState(false);
- const [editingActionName, setEditingActionName] = useState('');
-
- const [measuresForm] = Form.useForm();
+ const [measuresForm] = Form.useForm()
const createEditingColumns = (cols, renderDelegate) =>
- cols.map(col =>
- ({ render: renderDelegate,
- ...col
- })
- )
+ cols.map(col => ({ render: renderDelegate, ...col }))
useEffect(() => {
- const defaultValuesToDisplay = values[values.length-1]
-
- setDisplayedValues(defaultValuesToDisplay)
- }, [values])
+ const data = [group.defaultValue].concat(group.values ?? [])
+ setData(data)
+ setDisplayedValues(data.at(-1))
+ }, [group.defaultValue, group.values])
useEffect(() => {
- let switchableColumns = []
-
- isTableEditing
- ? switchableColumns = createEditingColumns(columns, () => )
- : switchableColumns = createEditingColumns(columns, null)
+ const switchableColumns = createEditingColumns(
+ group.columns,
+ isTableEditing ? () => : null
+ )
if(editingActionName === 'edit')
- measuresForm.setFieldsValue(displayedValues?.data);
+ measuresForm.setFieldsValue(displayedValues?.data)
else if(editingActionName === 'add')
measuresForm.resetFields()
setEditingColumns(switchableColumns)
- }, [isTableEditing, columns, editingActionName, displayedValues?.data, measuresForm])
+ }, [isTableEditing, group.columns, editingActionName, displayedValues?.data, measuresForm])
- const markMeasuresAsDeleted = async () => {
- setShowLoader(true)
- await MeasureService.markAsDelete(idWell, displayedValues.id)
- updateMeasuresFunc()
- setShowLoader(false)
+ const markMeasuresAsDeleted = async () => await invokeWebApiWrapperAsync(
+ async () => {
+ await MeasureService.markAsDelete(idWell, displayedValues.id)
+ updateMeasuresFunc()
+ },
+ setShowLoader,
+ `Не удалось удалить запись ${displayedValues.id} для скважины "${idWell}"`
+ )
+
+ const isDataDefault = () => !!displayedValues?.isDefaultData
+
+ const editTable = (action) => {
+ setEditingActionName(action)
+ setIsTableEditing(true)
}
- const checkIsDataDefault = () =>
- displayedValues?.isDefaultData ? true : false
+ const handleSubmitMeasuresForm = async (formData) => await invokeWebApiWrapperAsync(
+ async () => {
+ measuresForm.validateFields()
- const crudButtons =
-
-
-
-
markMeasuresAsDeleted()}
- disabled={checkIsDataDefault()}
- >
-
-
-
+ const measureParams = {
+ idWell: idWell,
+ idCategory: group.idCategory,
+ timestamp: new Date().toISOString(),
+ data: formData
+ }
- const confirmButtons =
-
-
-
-
-
-
-
- let handleSubmitMeasuresForm = async (formData) => {
- measuresForm.validateFields()
+ if(editingActionName === 'add') {
+ await MeasureService.insert(idWell, measureParams)
+ } else if (editingActionName === 'edit') {
+ measureParams.id = displayedValues.id
+ measureParams.timestamp = displayedValues.timestamp
+ await MeasureService.update(idWell, measureParams)
+ }
- const measureParams = {
- idWell: idWell,
- idCategory: idCategory,
- timestamp: new Date().toISOString(),
- data: formData
- }
+ setIsTableEditing(false)
+ updateMeasuresFunc()
+ },
+ setShowLoader,
+ `Не удалось добавить/изменить запись для скаважины "${idWell}"`
+ )
- setShowLoader(true)
+ return (
+ <>
+ {group.title}
+
+
+
+
+ { isTableEditing ? (
+ <>
+
+
+ >
+ ) : (
+ <>
+
+
+
+
+
+ >
+ )}
+ {additionalButtons?.(isTableEditing)}
+
+
- if(editingActionName === 'add') {
- await MeasureService.insert(idWell, measureParams)
- } else if (editingActionName === 'edit') {
- measureParams.id = displayedValues.id
- measureParams.timestamp = displayedValues.timestamp
- await MeasureService.update(idWell, measureParams)
- }
-
- setIsTableEditing(false)
- updateMeasuresFunc()
- setShowLoader(false)
- }
-
- return <>
-
-
{title}
-
-
-
-
- {isTableEditing
- ? confirmButtons
- : crudButtons
- }
+
+
+ {data.map((item, index) =>
+ setDisplayedValues(item)}
+ dot={item?.id !== displayedValues?.id ? null :
+
+ }
+ >
+
+ {formatDate(item.timestamp)}
+
+
+ )}
+
+
-
-
-
- {values.map((item, index) =>
- setDisplayedValues(item)}
- dot={item?.id === displayedValues?.id
- ?
- : null}
- >
-
- {item.timestamp ? moment.utc(item.timestamp).local().format(format) : 'Нет данных'}
-
-
- )}
-
+
+
+
+
-
-
-
-
-
-
- >
-}
\ No newline at end of file
+ >
+ )
+}
diff --git a/src/pages/Measure/View.jsx b/src/pages/Measure/View.jsx
index e097f4c..a42cbbe 100644
--- a/src/pages/Measure/View.jsx
+++ b/src/pages/Measure/View.jsx
@@ -1,62 +1,61 @@
-import { Empty, Form } from 'antd';
-import {Grid, GridItem} from '../../components/Grid'
+import React from 'react'
+import { Empty, Form } from 'antd'
+import { Grid, GridItem } from '../../components/Grid'
import '../../styles/index.css'
-const renderSwitchableColumn = (column, itm) => {
- if(column.render) {
- return (
-
- {column.render(itm[column.dataIndex])}
-
- )
- }
+const colsCount = 3
- return
{itm[column.dataIndex]}
+const headerCellStyle = {
+ border:'1px solid lightgrey'
}
-export const View = ({columns, item}) => {
+const valueCellStyle = {
+ border:'1px solid lightgrey',
+ justifyContent:'right',
+ marginRight:'16px',
+ fontWeight:'bold',
+ textAlign:'right',
+ padding: 0
+}
+
+export const View = React.memo(({columns, item}) => {
if (!item || !columns?.length)
return
- const colsCount = 3
- const viewItems = columns.map( (column, i) => {
- const row = Math.floor(i / colsCount) + 1
- const colb = i % colsCount
-
- return <>
-
- {column.title}
-
-
-
- {renderSwitchableColumn(column, item)}
-
- >
- })
-
- return <>
+ return (
- {viewItems}
+ {columns.map((column, i) => (
+ <>
+
+ {column.title}
+
+
+
+ {column.render ? (
+
+ {column.render(item[column.dataIndex])}
+
+ ) : (
+ {item[column.dataIndex]}
+ )}
+
+ >
+ ))}
- >
-}
\ No newline at end of file
+ )
+})
\ No newline at end of file
diff --git a/src/pages/Measure/index.jsx b/src/pages/Measure/index.jsx
index e4b6dd9..bdc6d5d 100644
--- a/src/pages/Measure/index.jsx
+++ b/src/pages/Measure/index.jsx
@@ -1,64 +1,99 @@
import { useState, useEffect } from 'react'
-import { columnsMudDiagram} from './mudDiagramData'
-import { mudDiagramDefaultData} from './mudDiagramData'
-import { columnsDrillingFluid} from './drillingFluidData'
-import { drillingFluidDefaultData} from './drillingFluidData'
-import { columnsNnb } from './nnbData'
-import { nnbDefaultData } from './nnbData'
+import { columnsNnb, nnbDefaultData } from './nnbData'
+import { columnsMudDiagram, mudDiagramDefaultData } from './mudDiagramData'
+import { columnsDrillingFluid, drillingFluidDefaultData } from './drillingFluidData'
import { invokeWebApiWrapperAsync } from '../../components/factory'
import { MeasureService } from '../../services/api'
import LoaderPortal from '../../components/LoaderPortal'
import { MeasureTable } from './MeasureTable'
+import InclinometryTable from './InclinometryTable'
+import { Button } from 'antd'
+import { TableOutlined } from '@ant-design/icons'
+
+const defaultData = [
+ {
+ idCategory: 1,
+ title: 'Замер бурового раствора',
+ columns: columnsDrillingFluid,
+ values: [drillingFluidDefaultData],
+ defaultValue: drillingFluidDefaultData,
+ },
+ {
+ idCategory: 2,
+ title: 'Шламограмма',
+ columns: columnsMudDiagram,
+ values: [mudDiagramDefaultData],
+ defaultValue: mudDiagramDefaultData,
+ },
+ {
+ idCategory: 3,
+ title: 'ННБ',
+ columns: columnsNnb,
+ values: [nnbDefaultData],
+ defaultValue: nnbDefaultData,
+ }
+]
export default function Measure({idWell}){
const [showLoader, setShowLoader] = useState(false)
- const [fluidValues, setFluidValues] = useState([])
- const [mudValues, setMudValues] = useState([])
- const [nnbValues, setNnbValues] = useState([])
const [isMeasuresUpdating, setIsMeasuresUpdating] = useState(false)
+ const [data, setData] = useState(defaultData)
+ const [tableIdx, setTableIdx] = useState(-1)
- const updateCurrentValues = () => invokeWebApiWrapperAsync(async()=>{
- const measures = await MeasureService.getHisory(idWell)
- setIsMeasuresUpdating(false)
+ const updateCurrentValues = () => invokeWebApiWrapperAsync(
+ async () => {
+ const measures = await MeasureService.getHisory(idWell)
+ setIsMeasuresUpdating(false)
- const fluids = measures.filter(el => el.idCategory === 1)
- setFluidValues(fluids.length ? fluids : [drillingFluidDefaultData])
- const muds = measures.filter(el => el.idCategory === 2)
- setMudValues(muds.length ? muds : [mudDiagramDefaultData])
- const nnbs = measures.filter(el => el.idCategory === 3)
- setNnbValues(nnbs.length ? nnbs : [nnbDefaultData])
- }
- ,setShowLoader
- ,`Не удалось загрузить последние данные по скважине ${idWell}`)
+ setData(prevData => {
+ prevData.forEach(el => el.values = [])
+ measures.forEach(el => {
+ const idx = prevData.findIndex(group => el.idCategory === group.idCategory)
+ if (idx >= 0)
+ prevData[idx].values.push(el)
+ })
+ return prevData
+ })
+ },
+ setShowLoader,
+ `Не удалось загрузить последние данные по скважине ${idWell}`
+ )
+
+ useEffect(() => {
+ setData(prevData => {
+ data[2].additionalButtons = (group, idx) => (isEditing) => isEditing ? null : (
+
+ )
+
+ return prevData
+ })
+ }, [])
useEffect(updateCurrentValues, [idWell, isMeasuresUpdating])
- return <>
+ return <>
- setIsMeasuresUpdating(true)}
- />
- setIsMeasuresUpdating(true)}
- />
- setIsMeasuresUpdating(true)}
+ {data.map((group, idx) => (
+ setIsMeasuresUpdating(true)}
+ additionalButtons={group.additionalButtons?.(group, idx)}
+ />
+ ))}
+ = 0}
+ onClose={() => setTableIdx(-1)}
+ group={data[tableIdx]}
/>
>
-}
\ No newline at end of file
+}
diff --git a/src/styles/index.css b/src/styles/index.css
index 39aef5a..4103d37 100644
--- a/src/styles/index.css
+++ b/src/styles/index.css
@@ -23,6 +23,10 @@ body {
display: none;
}
+.flex-1 {
+ flex: 1;
+}
+
.w-15 {
width: 15%
}