forked from ddrilling/asb_cloud_front
Merge branch 'dev' into feature/documentation
This commit is contained in:
commit
923d469a86
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@ -2,7 +2,15 @@
|
|||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"день",
|
"день",
|
||||||
"спиннера",
|
"спиннера",
|
||||||
"Saub"
|
"Saub",
|
||||||
|
"КНБК",
|
||||||
|
"САУБ",
|
||||||
|
"antd",
|
||||||
|
"Poprompt",
|
||||||
|
"saub",
|
||||||
|
"setpoint",
|
||||||
|
"Setpoints",
|
||||||
|
"usehooks"
|
||||||
],
|
],
|
||||||
"liveServer.settings.port": 5501
|
"liveServer.settings.port": 5501
|
||||||
}
|
}
|
@ -40,6 +40,7 @@ export const makeDateColumn = <T extends unknown>(
|
|||||||
other?: ColumnProps<T>,
|
other?: ColumnProps<T>,
|
||||||
pickerOther?: DatePickerWrapperProps,
|
pickerOther?: DatePickerWrapperProps,
|
||||||
) => makeColumn<T>(title, key, {
|
) => makeColumn<T>(title, key, {
|
||||||
|
editable: true,
|
||||||
...other,
|
...other,
|
||||||
render: (date) => (
|
render: (date) => (
|
||||||
<div className={'text-align-r-container'}>
|
<div className={'text-align-r-container'}>
|
||||||
|
@ -9,7 +9,6 @@ import { OmitExtends } from '@utils/types'
|
|||||||
export * from './date'
|
export * from './date'
|
||||||
export * from './time'
|
export * from './time'
|
||||||
export * from './numeric'
|
export * from './numeric'
|
||||||
export * from './plan_fact'
|
|
||||||
export * from './select'
|
export * from './select'
|
||||||
export * from './tag'
|
export * from './tag'
|
||||||
export * from './text'
|
export * from './text'
|
||||||
@ -45,6 +44,7 @@ export const makeColumn = <T = any>(title: ReactNode, key: Key, other?: ColumnPr
|
|||||||
title: title,
|
title: title,
|
||||||
key: key,
|
key: key,
|
||||||
dataIndex: key,
|
dataIndex: key,
|
||||||
|
render: (value: T) => value,
|
||||||
...other,
|
...other,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { ColumnFilterItem } from 'antd/lib/table/interface'
|
|
||||||
import { InputNumber } from 'antd'
|
import { InputNumber } from 'antd'
|
||||||
import { Key, ReactNode } from 'react'
|
import { Key, ReactNode } from 'react'
|
||||||
|
|
||||||
@ -46,18 +45,17 @@ export const makeNumericColumnOptions = <T extends number>(fixed?: number, sorte
|
|||||||
export const makeNumericColumn = <T extends number>(
|
export const makeNumericColumn = <T extends number>(
|
||||||
title: ReactNode,
|
title: ReactNode,
|
||||||
key: Key,
|
key: Key,
|
||||||
filters?: ColumnFilterItem[],
|
|
||||||
filterDelegate?: FilterGenerator<T>,
|
|
||||||
renderDelegate?: RenderMethod<T>,
|
renderDelegate?: RenderMethod<T>,
|
||||||
|
filterDelegate?: FilterGenerator<T>,
|
||||||
width?: string | number,
|
width?: string | number,
|
||||||
other?: ColumnProps<T>,
|
other?: ColumnProps<T>,
|
||||||
) => makeColumn(title, key, {
|
) => makeColumn(title, key, {
|
||||||
filters,
|
editable: true,
|
||||||
onFilter: filterDelegate ? filterDelegate(key) : undefined,
|
onFilter: filterDelegate ? filterDelegate(key) : undefined,
|
||||||
sorter: makeNumericSorter(key),
|
sorter: makeNumericSorter(key),
|
||||||
width,
|
width,
|
||||||
input: <InputNumber style={{ width: '100%' }}/>,
|
input: <InputNumber style={{ width: '100%' }} defaultValue={0} />,
|
||||||
render: renderDelegate ?? makeNumericRender<T>(2),
|
render: renderDelegate || makeNumericRender<T>(2),
|
||||||
align: 'right',
|
align: 'right',
|
||||||
...other
|
...other
|
||||||
})
|
})
|
||||||
@ -65,54 +63,78 @@ export const makeNumericColumn = <T extends number>(
|
|||||||
export const makeNumericColumnPlanFact = <T extends number>(
|
export const makeNumericColumnPlanFact = <T extends number>(
|
||||||
title: ReactNode,
|
title: ReactNode,
|
||||||
key: Key,
|
key: Key,
|
||||||
filters?: ColumnFilterItem[],
|
|
||||||
filterDelegate?: FilterGenerator<T>,
|
|
||||||
renderDelegate?: RenderMethod<T>,
|
renderDelegate?: RenderMethod<T>,
|
||||||
|
filterDelegate?: FilterGenerator<T>,
|
||||||
|
width?: string | number,
|
||||||
|
other?: ColumnProps<T>,
|
||||||
|
) => {
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
children: [
|
||||||
|
makeNumericColumn<T>('План', `${key}.plan`, renderDelegate, filterDelegate, width, other),
|
||||||
|
makeNumericColumn<T>('Факт', `${key}.fact`, renderDelegate, filterDelegate, width, other),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Для значений типа план/факт появилась модель `PlanFactDto`, использование 2 полей с суффиксами неактуально
|
||||||
|
* @param title Заголовок столбца
|
||||||
|
* @param key Ключ столбца
|
||||||
|
* @param filters Список значений для фильтрации
|
||||||
|
* @param filterDelegate Метод фильтрации
|
||||||
|
* @param renderDelegate Render-метод отображения ячейки
|
||||||
|
* @param width Ширина столбца
|
||||||
|
* @param other Дополнительные опции
|
||||||
|
* @returns Объект-столбец для таблицы
|
||||||
|
*/
|
||||||
|
export const makeNumericColumnPlanFactOld = <T extends number>(
|
||||||
|
title: ReactNode,
|
||||||
|
key: Key,
|
||||||
|
renderDelegate?: RenderMethod<T>,
|
||||||
|
filterDelegate?: FilterGenerator<T>,
|
||||||
width?: string | number,
|
width?: string | number,
|
||||||
other?: ColumnProps<T>,
|
other?: ColumnProps<T>,
|
||||||
) => makeGroupColumn(title, [
|
) => makeGroupColumn(title, [
|
||||||
makeNumericColumn<T>('п', key + 'Plan', filters, filterDelegate, renderDelegate, width, other),
|
makeNumericColumn<T>('План', key + 'Plan', renderDelegate, filterDelegate, width, other),
|
||||||
makeNumericColumn<T>('ф', key + 'Fact', filters, filterDelegate, renderDelegate, width, other),
|
makeNumericColumn<T>('Факт', key + 'Fact', renderDelegate, filterDelegate, width, other),
|
||||||
])
|
])
|
||||||
|
|
||||||
export const makeNumericStartEnd = <T extends number>(
|
export const makeNumericStartEnd = <T extends number>(
|
||||||
title: ReactNode,
|
title: ReactNode,
|
||||||
key: Key,
|
key: Key,
|
||||||
fixed: number,
|
fixed: number,
|
||||||
filters?: ColumnFilterItem[],
|
|
||||||
filterDelegate?: FilterGenerator<T>,
|
|
||||||
renderDelegate?: RenderMethod<T>,
|
renderDelegate?: RenderMethod<T>,
|
||||||
|
filterDelegate?: FilterGenerator<T>,
|
||||||
width?: string | number,
|
width?: string | number,
|
||||||
) => makeGroupColumn(title, [
|
) => makeGroupColumn(title, [
|
||||||
makeNumericColumn<T>('старт', key + 'Start', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, key + 'Start')),
|
makeNumericColumn<T>('старт', key + 'Start', renderDelegate, filterDelegate, width, makeNumericColumnOptions(fixed, key + 'Start')),
|
||||||
makeNumericColumn<T>('конец', key + 'End', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, key + 'End'))
|
makeNumericColumn<T>('конец', key + 'End', renderDelegate, filterDelegate, width, makeNumericColumnOptions(fixed, key + 'End'))
|
||||||
])
|
])
|
||||||
|
|
||||||
export const makeNumericMinMax = <T extends number>(
|
export const makeNumericMinMax = <T extends number>(
|
||||||
title: ReactNode,
|
title: ReactNode,
|
||||||
key: Key,
|
key: Key,
|
||||||
fixed: number,
|
fixed: number,
|
||||||
filters?: ColumnFilterItem[],
|
|
||||||
filterDelegate?: FilterGenerator<T>,
|
|
||||||
renderDelegate?: RenderMethod<T>,
|
renderDelegate?: RenderMethod<T>,
|
||||||
|
filterDelegate?: FilterGenerator<T>,
|
||||||
width?: string | number,
|
width?: string | number,
|
||||||
) => makeGroupColumn(title, [
|
) => makeGroupColumn(title, [
|
||||||
makeNumericColumn<T>('мин', key + 'Min', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, key + 'Min')),
|
makeNumericColumn<T>('мин', key + 'Min', renderDelegate, filterDelegate, width, makeNumericColumnOptions(fixed, key + 'Min')),
|
||||||
makeNumericColumn<T>('макс', key + 'Max', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, key + 'Max')),
|
makeNumericColumn<T>('макс', key + 'Max', renderDelegate, filterDelegate, width, makeNumericColumnOptions(fixed, key + 'Max')),
|
||||||
])
|
])
|
||||||
|
|
||||||
export const makeNumericAvgRange = <T extends number>(
|
export const makeNumericAvgRange = <T extends number>(
|
||||||
title: ReactNode,
|
title: ReactNode,
|
||||||
key: Key,
|
key: Key,
|
||||||
fixed: number,
|
fixed: number,
|
||||||
filters?: ColumnFilterItem[],
|
|
||||||
filterDelegate?: FilterGenerator<T>,
|
|
||||||
renderDelegate?: RenderMethod<T>,
|
renderDelegate?: RenderMethod<T>,
|
||||||
|
filterDelegate?: FilterGenerator<T>,
|
||||||
width?: string | number,
|
width?: string | number,
|
||||||
) => makeGroupColumn(title, [
|
) => makeGroupColumn(title, [
|
||||||
makeNumericColumn<T>('мин', `${key}.min`, filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, `${key}.min`)),
|
makeNumericColumn<T>('мин', `${key}.min`, renderDelegate, filterDelegate, width, makeNumericColumnOptions(fixed, `${key}.min`)),
|
||||||
makeNumericColumn<T>('сред', `${key}.avg`, filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, `${key}.avg`)),
|
makeNumericColumn<T>('сред', `${key}.avg`, renderDelegate, filterDelegate, width, makeNumericColumnOptions(fixed, `${key}.avg`)),
|
||||||
makeNumericColumn<T>('макс', `${key}.max`, filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, `${key}.max`)),
|
makeNumericColumn<T>('макс', `${key}.max`, renderDelegate, filterDelegate, width, makeNumericColumnOptions(fixed, `${key}.max`)),
|
||||||
])
|
])
|
||||||
|
|
||||||
export default makeNumericColumn
|
export default makeNumericColumn
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
import { Key, ReactNode } from 'react'
|
|
||||||
|
|
||||||
import { ColumnProps, makeColumn } from '.'
|
|
||||||
|
|
||||||
export const makeColumnsPlanFact = <T,>(
|
|
||||||
title: string | ReactNode,
|
|
||||||
key: Key | [Key, Key],
|
|
||||||
columsOther?: ColumnProps<T> | [ColumnProps<T>, ColumnProps<T>],
|
|
||||||
) => {
|
|
||||||
const keys = Array.isArray(key) ? key : [`${key}Plan`, `${key}Fact`]
|
|
||||||
const others = Array.isArray(columsOther) ? columsOther : [columsOther, columsOther]
|
|
||||||
|
|
||||||
return {
|
|
||||||
title,
|
|
||||||
children: [
|
|
||||||
makeColumn<T>('план', keys[0], others[0]),
|
|
||||||
makeColumn<T>('факт', keys[1], others[1]),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default makeColumnsPlanFact
|
|
@ -1,9 +1,17 @@
|
|||||||
import { Select, SelectProps } from 'antd'
|
import { Select, SelectProps } from 'antd'
|
||||||
import { DefaultOptionType, SelectValue } from 'antd/lib/select'
|
import { DefaultOptionType, SelectValue } from 'antd/lib/select'
|
||||||
import { Key, ReactNode } from 'react'
|
import { Key, ReactNode, useMemo } from 'react'
|
||||||
|
|
||||||
import { ColumnProps, makeColumn } from '.'
|
import { ColumnProps, makeColumn } from '.'
|
||||||
|
|
||||||
|
const findOption = <T extends DefaultOptionType>(value: any, options: T[] | undefined) =>
|
||||||
|
options?.find((option) => String(option?.value) === String(value))
|
||||||
|
|
||||||
|
const SelectWrapper = ({ value, options, ...other }: SelectProps) => {
|
||||||
|
const selectValue = useMemo(() => findOption(value, options)?.label, [value, options])
|
||||||
|
return <Select value={selectValue} options={options} {...other} />
|
||||||
|
}
|
||||||
|
|
||||||
export const makeSelectColumn = <T extends DefaultOptionType>(
|
export const makeSelectColumn = <T extends DefaultOptionType>(
|
||||||
title: ReactNode,
|
title: ReactNode,
|
||||||
key: Key,
|
key: Key,
|
||||||
@ -12,10 +20,11 @@ export const makeSelectColumn = <T extends DefaultOptionType>(
|
|||||||
other?: ColumnProps<T>,
|
other?: ColumnProps<T>,
|
||||||
selectOther?: SelectProps<SelectValue>
|
selectOther?: SelectProps<SelectValue>
|
||||||
) => makeColumn(title, key, {
|
) => makeColumn(title, key, {
|
||||||
|
editable: true,
|
||||||
...other,
|
...other,
|
||||||
input: <Select options={options} {...selectOther}/>,
|
input: <SelectWrapper options={options} {...selectOther}/>,
|
||||||
render: (value, dataset, index) => {
|
render: (value, dataset, index) => {
|
||||||
const item = options?.find(option => String(option?.value) === String(value))
|
const item = findOption(value, options)
|
||||||
return other?.render?.(item, dataset, index) ?? item?.label ?? defaultValue?.label ?? value?.label ?? '--'
|
return other?.render?.(item, dataset, index) ?? item?.label ?? defaultValue?.label ?? value?.label ?? '--'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -65,6 +65,7 @@ export const makeTagColumn = <T extends DataType>(
|
|||||||
const InputComponent = makeTagInput<T>(value_key, label_key)
|
const InputComponent = makeTagInput<T>(value_key, label_key)
|
||||||
|
|
||||||
return makeColumn(title, dataIndex, {
|
return makeColumn(title, dataIndex, {
|
||||||
|
editable: true,
|
||||||
...other,
|
...other,
|
||||||
render: (item: T[] | undefined, dataset, index) => item?.map((elm: T) => <Tag key={elm[label_key]} color={'blue'}>{other?.render?.(elm, dataset, index) ?? elm[label_key]}</Tag>) ?? '-',
|
render: (item: T[] | undefined, dataset, index) => item?.map((elm: T) => <Tag key={elm[label_key]} color={'blue'}>{other?.render?.(elm, dataset, index) ?? elm[label_key]}</Tag>) ?? '-',
|
||||||
input: <InputComponent {...tagOther} options={options} />,
|
input: <InputComponent {...tagOther} options={options} />,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Tooltip } from 'antd'
|
||||||
import { ColumnFilterItem } from 'antd/lib/table/interface'
|
import { ColumnFilterItem } from 'antd/lib/table/interface'
|
||||||
import { Key, ReactNode } from 'react'
|
import { Key, ReactNode } from 'react'
|
||||||
|
|
||||||
@ -15,6 +16,18 @@ export const makeStringSorter = <T extends string>(key: Key): SorterMethod<T> =>
|
|||||||
return String(vA).localeCompare(String(vB))
|
return String(vA).localeCompare(String(vB))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const makeTextRender = <T extends string>(def = '---', stringCutter?: (text: string) => string) => (value: T) => {
|
||||||
|
if (!value) return def
|
||||||
|
if (stringCutter) {
|
||||||
|
return (
|
||||||
|
<Tooltip title={value}>
|
||||||
|
{stringCutter(value)}
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
export const makeFilterTextMatch = <T extends unknown>(key: keyof DataType<T>) =>
|
export const makeFilterTextMatch = <T extends unknown>(key: keyof DataType<T>) =>
|
||||||
(filterValue: T, dataItem: DataType<T>) => dataItem[key] === filterValue
|
(filterValue: T, dataItem: DataType<T>) => dataItem[key] === filterValue
|
||||||
|
|
||||||
@ -26,10 +39,11 @@ export const makeTextColumn = <T extends unknown = any>(
|
|||||||
render?: RenderMethod<T>,
|
render?: RenderMethod<T>,
|
||||||
other?: ColumnProps
|
other?: ColumnProps
|
||||||
) => makeColumn(title, key, {
|
) => makeColumn(title, key, {
|
||||||
|
editable: true,
|
||||||
filters,
|
filters,
|
||||||
onFilter: filters ? makeFilterTextMatch(key) : undefined,
|
onFilter: filters ? makeFilterTextMatch(key) : undefined,
|
||||||
sorter: sorter ?? makeStringSorter(key),
|
sorter: sorter || makeStringSorter(key),
|
||||||
render: render,
|
render: render || makeTextRender(),
|
||||||
...other
|
...other
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ export const makeTimeColumn = <T extends TimeDto>(
|
|||||||
other?: ColumnProps,
|
other?: ColumnProps,
|
||||||
pickerOther?: TimePickerWrapperProps,
|
pickerOther?: TimePickerWrapperProps,
|
||||||
) => makeColumn<T>(title, key, {
|
) => makeColumn<T>(title, key, {
|
||||||
|
editable: true,
|
||||||
...other,
|
...other,
|
||||||
render: (time) => (
|
render: (time) => (
|
||||||
<div className={'text-align-r-container'}>
|
<div className={'text-align-r-container'}>
|
||||||
|
@ -59,6 +59,7 @@ export const WellSelector = memo(({ value, onChange, treeData, treeLabels, ...ot
|
|||||||
<TreeSelect
|
<TreeSelect
|
||||||
multiple
|
multiple
|
||||||
treeCheckable
|
treeCheckable
|
||||||
|
maxTagCount={'responsive'}
|
||||||
showCheckedStrategy={TreeSelect.SHOW_CHILD}
|
showCheckedStrategy={TreeSelect.SHOW_CHILD}
|
||||||
treeDefaultExpandAll
|
treeDefaultExpandAll
|
||||||
treeData={wellsTree}
|
treeData={wellsTree}
|
||||||
|
@ -3,11 +3,12 @@ import { Input } from 'antd'
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
EditableTable,
|
EditableTable,
|
||||||
makeColumn,
|
|
||||||
makeSelectColumn,
|
makeSelectColumn,
|
||||||
makeStringSorter,
|
makeStringSorter,
|
||||||
defaultPagination,
|
defaultPagination,
|
||||||
makeTimezoneColumn
|
makeTimezoneColumn,
|
||||||
|
makeNumericColumn,
|
||||||
|
makeTextColumn
|
||||||
} from '@components/Table'
|
} from '@components/Table'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { AdminClusterService, AdminDepositService } from '@api'
|
import { AdminClusterService, AdminDepositService } from '@api'
|
||||||
@ -30,17 +31,11 @@ const ClusterController = memo(() => {
|
|||||||
const clusterColumns = useMemo(() => [
|
const clusterColumns = useMemo(() => [
|
||||||
makeSelectColumn('Месторождение', 'idDeposit', deposits, '--', {
|
makeSelectColumn('Месторождение', 'idDeposit', deposits, '--', {
|
||||||
width: 200,
|
width: 200,
|
||||||
editable: true,
|
|
||||||
sorter: makeStringSorter('idDeposit')
|
sorter: makeStringSorter('idDeposit')
|
||||||
}),
|
}),
|
||||||
makeColumn('Название', 'caption', {
|
makeTextColumn('Название', 'caption', undefined, undefined, undefined, { width: 200, formItemRules: min1 }),
|
||||||
width: 200,
|
makeNumericColumn('Широта', 'latitude', coordsFormat, undefined, 150),
|
||||||
editable: true,
|
makeNumericColumn('Долгота', 'longitude', coordsFormat, undefined, 150),
|
||||||
sorter: makeStringSorter('caption'),
|
|
||||||
formItemRules: min1,
|
|
||||||
}),
|
|
||||||
makeColumn('Широта', 'latitude', { width: 150, editable: true, render: coordsFormat }),
|
|
||||||
makeColumn('Долгота', 'longitude', { width: 150, editable: true, render: coordsFormat }),
|
|
||||||
makeTimezoneColumn('Зона', 'timezone', null, true, { width: 150 }),
|
makeTimezoneColumn('Зона', 'timezone', null, true, { width: 150 }),
|
||||||
], [deposits])
|
], [deposits])
|
||||||
|
|
||||||
|
@ -3,10 +3,9 @@ import { Input } from 'antd'
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
EditableTable,
|
EditableTable,
|
||||||
makeColumn,
|
|
||||||
makeStringSorter,
|
|
||||||
makeSelectColumn,
|
makeSelectColumn,
|
||||||
defaultPagination
|
defaultPagination,
|
||||||
|
makeTextColumn
|
||||||
} from '@components/Table'
|
} from '@components/Table'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { AdminCompanyService, AdminCompanyTypeService } from '@api'
|
import { AdminCompanyService, AdminCompanyTypeService } from '@api'
|
||||||
@ -37,16 +36,8 @@ const CompanyController = memo(() => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
setColumns([
|
setColumns([
|
||||||
makeColumn('Название', 'caption', {
|
makeTextColumn('Название', 'caption', undefined, undefined, undefined, { width: 200, formItemRules: min1 }),
|
||||||
width: 200,
|
makeSelectColumn('Тип компании', 'idCompanyType', companyTypes, null, { width: 200 }),
|
||||||
editable: true,
|
|
||||||
sorter: makeStringSorter('caption'),
|
|
||||||
formItemRules: min1,
|
|
||||||
}),
|
|
||||||
makeSelectColumn('Тип компании', 'idCompanyType', companyTypes, null, {
|
|
||||||
width: 200,
|
|
||||||
editable: true
|
|
||||||
}),
|
|
||||||
])
|
])
|
||||||
|
|
||||||
await updateTable()
|
await updateTable()
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { Input } from 'antd'
|
import { Input } from 'antd'
|
||||||
|
|
||||||
import { EditableTable, makeColumn, makeStringSorter, defaultPagination } from '@components/Table'
|
import { EditableTable, defaultPagination, makeTextColumn } from '@components/Table'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { arrayOrDefault, withPermissions } from '@utils'
|
import { arrayOrDefault, withPermissions } from '@utils'
|
||||||
import { min1 } from '@utils/validationRules'
|
import { min1 } from '@utils/validationRules'
|
||||||
import { AdminCompanyTypeService } from '@api'
|
import { AdminCompanyTypeService } from '@api'
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
makeColumn('Название', 'caption', {
|
makeTextColumn('Название', 'caption', undefined, undefined, undefined, { width: 200, formItemRules: min1 }),
|
||||||
width: 200,
|
|
||||||
editable: true,
|
|
||||||
sorter: makeStringSorter('caption'),
|
|
||||||
formItemRules: min1,
|
|
||||||
}),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const CompanyTypeController = memo(() => {
|
const CompanyTypeController = memo(() => {
|
||||||
|
@ -2,15 +2,15 @@ import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
|||||||
import { Input } from 'antd'
|
import { Input } from 'antd'
|
||||||
|
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { EditableTable, makeColumn, defaultPagination, makeTimezoneColumn } from '@components/Table'
|
import { EditableTable, defaultPagination, makeTimezoneColumn, makeTextColumn, makeNumericColumn } from '@components/Table'
|
||||||
import { arrayOrDefault, coordsFormat, withPermissions } from '@utils'
|
import { arrayOrDefault, coordsFormat, withPermissions } from '@utils'
|
||||||
import { min1 } from '@utils/validationRules'
|
import { min1 } from '@utils/validationRules'
|
||||||
import { AdminDepositService } from '@api'
|
import { AdminDepositService } from '@api'
|
||||||
|
|
||||||
const depositColumns = [
|
const depositColumns = [
|
||||||
makeColumn('Название', 'caption', { width: 200, editable: true, formItemRules: min1 }),
|
makeTextColumn('Название', 'caption', undefined, undefined, undefined, { width: 200, formItemRules: min1 }),
|
||||||
makeColumn('Широта', 'latitude', { width: 150, editable: true, render: coordsFormat }),
|
makeNumericColumn('Широта', 'latitude', coordsFormat, undefined, 150),
|
||||||
makeColumn('Долгота', 'longitude', { width: 150, editable: true, render: coordsFormat }),
|
makeNumericColumn('Долгота', 'longitude', coordsFormat, undefined, 150),
|
||||||
makeTimezoneColumn('Зона', 'timezone', null, true, { width: 150 }),
|
makeTimezoneColumn('Зона', 'timezone', null, true, { width: 150 }),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,23 +1,15 @@
|
|||||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { Input } from 'antd'
|
import { Input } from 'antd'
|
||||||
|
|
||||||
import { EditableTable, makeColumn, makeStringSorter } from '@components/Table'
|
import { EditableTable, makeTextColumn } from '@components/Table'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { arrayOrDefault, withPermissions } from '@utils'
|
import { arrayOrDefault, withPermissions } from '@utils'
|
||||||
import { min1 } from '@utils/validationRules'
|
import { min1 } from '@utils/validationRules'
|
||||||
import { AdminPermissionService } from '@api'
|
import { AdminPermissionService } from '@api'
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
makeColumn('Название', 'name', {
|
makeTextColumn('Название', 'name', undefined, undefined, undefined, { isRequired: true, formItemRules: min1 }),
|
||||||
editable: true,
|
makeTextColumn('Описание', 'description'),
|
||||||
sorter: makeStringSorter('name'),
|
|
||||||
isRequired: true,
|
|
||||||
formItemRules: min1,
|
|
||||||
}),
|
|
||||||
makeColumn('Описание', 'description', {
|
|
||||||
editable: true,
|
|
||||||
sorter: makeStringSorter('description'),
|
|
||||||
}),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const PermissionController = memo(() => {
|
const PermissionController = memo(() => {
|
||||||
|
@ -19,15 +19,13 @@ const RoleController = memo(() => {
|
|||||||
)), [roles, searchValue])
|
)), [roles, searchValue])
|
||||||
|
|
||||||
const columns = useMemo(() => [
|
const columns = useMemo(() => [
|
||||||
makeTextColumn('Название', 'caption', null, null, null, { width: 100, editable: true, formItemRules: min1 }),
|
makeTextColumn('Название', 'caption', null, null, null, { width: 100, formItemRules: min1 }),
|
||||||
makeTagColumn('Включённые роли', 'roles', roles, 'id', 'caption', {
|
makeTagColumn('Включённые роли', 'roles', roles, 'id', 'caption', {
|
||||||
width: 400,
|
width: 400,
|
||||||
editable: true,
|
|
||||||
render: (role) => <RoleView role={role} />
|
render: (role) => <RoleView role={role} />
|
||||||
}, { allowClear: true }),
|
}, { allowClear: true }),
|
||||||
makeTagColumn('Разрешения', 'permissions', permissions, 'id', 'name', {
|
makeTagColumn('Разрешения', 'permissions', permissions, 'id', 'name', {
|
||||||
width: 600,
|
width: 600,
|
||||||
editable: true,
|
|
||||||
render: (permission) => <PermissionView info={permission} />,
|
render: (permission) => <PermissionView info={permission} />,
|
||||||
}),
|
}),
|
||||||
], [roles, permissions])
|
], [roles, permissions])
|
||||||
|
@ -50,7 +50,7 @@ const TelemetryController = memo(() => {
|
|||||||
|
|
||||||
const columns = useMemo(() => [
|
const columns = useMemo(() => [
|
||||||
makeColumn('', 'hasParent', { render: mergeRender }),
|
makeColumn('', 'hasParent', { render: mergeRender }),
|
||||||
makeNumericColumn('ID', 'id', null, null, makeNumericRender(0)),
|
makeNumericColumn('ID', 'id', makeNumericRender(0)),
|
||||||
makeTextColumn('UID', 'remoteUid'),
|
makeTextColumn('UID', 'remoteUid'),
|
||||||
makeTextColumn('Назначена на скважину', 'realWell'),
|
makeTextColumn('Назначена на скважину', 'realWell'),
|
||||||
makeDateColumn('Дата начала бурения', 'drillingStartDate'),
|
makeDateColumn('Дата начала бурения', 'drillingStartDate'),
|
||||||
|
@ -115,7 +115,6 @@ const UserController = memo(() => {
|
|||||||
|
|
||||||
setColumns([
|
setColumns([
|
||||||
makeTextColumn('Логин', 'login', null, null, null, {
|
makeTextColumn('Логин', 'login', null, null, null, {
|
||||||
editable: true,
|
|
||||||
formItemRules: [
|
formItemRules: [
|
||||||
{ required: true },
|
{ required: true },
|
||||||
...createLoginRules,
|
...createLoginRules,
|
||||||
@ -130,41 +129,34 @@ const UserController = memo(() => {
|
|||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
makeTextColumn('Фамилия', 'surname', filters.surname, null, null, {
|
makeTextColumn('Фамилия', 'surname', filters.surname, null, null, {
|
||||||
editable: true,
|
|
||||||
formItemRules: [{ required: true }, ...nameRules],
|
formItemRules: [{ required: true }, ...nameRules],
|
||||||
filterSearch: true,
|
filterSearch: true,
|
||||||
onFilter: makeTextOnFilter('surname'),
|
onFilter: makeTextOnFilter('surname'),
|
||||||
}),
|
}),
|
||||||
makeTextColumn('Имя', 'name', filters.name, null, null, {
|
makeTextColumn('Имя', 'name', filters.name, null, null, {
|
||||||
editable: true,
|
|
||||||
formItemRules: nameRules,
|
formItemRules: nameRules,
|
||||||
filterSearch: true,
|
filterSearch: true,
|
||||||
onFilter: makeTextOnFilter('name'),
|
onFilter: makeTextOnFilter('name'),
|
||||||
}),
|
}),
|
||||||
makeTextColumn('Отчество', 'patronymic', filters.partonymic, null, null, {
|
makeTextColumn('Отчество', 'patronymic', filters.partonymic, null, null, {
|
||||||
editable: true,
|
|
||||||
formItemRules: nameRules,
|
formItemRules: nameRules,
|
||||||
filterSearch: true,
|
filterSearch: true,
|
||||||
onFilter: makeTextOnFilter('patronymic'),
|
onFilter: makeTextOnFilter('patronymic'),
|
||||||
}),
|
}),
|
||||||
makeTextColumn('E-mail', 'email', filters.email, null, null, {
|
makeTextColumn('E-mail', 'email', filters.email, null, null, {
|
||||||
editable: true,
|
|
||||||
formItemRules: [{ required: true }, ...emailRules],
|
formItemRules: [{ required: true }, ...emailRules],
|
||||||
filterSearch: true,
|
filterSearch: true,
|
||||||
onFilter: makeTextOnFilter('email'),
|
onFilter: makeTextOnFilter('email'),
|
||||||
}),
|
}),
|
||||||
makeTextColumn('Номер телефона', 'phone', null, null, null, {
|
makeTextColumn('Номер телефона', 'phone', null, null, null, {
|
||||||
editable: true,
|
|
||||||
formItemRules: phoneRules,
|
formItemRules: phoneRules,
|
||||||
}),
|
}),
|
||||||
makeTextColumn('Должность', 'position', null, null, null, { editable: true }),
|
makeTextColumn('Должность', 'position', null, null, null),
|
||||||
makeTextColumn('Роли', 'roleNames', roleFilters, null, rolesRender, {
|
makeTextColumn('Роли', 'roleNames', roleFilters, null, rolesRender, {
|
||||||
editable: true,
|
|
||||||
input: <RoleTag roles={roles} />,
|
input: <RoleTag roles={roles} />,
|
||||||
onFilter: makeArrayOnFilter('roleNames'),
|
onFilter: makeArrayOnFilter('roleNames'),
|
||||||
}),
|
}),
|
||||||
makeSelectColumn('Компания', 'idCompany', companies, '--', {
|
makeSelectColumn('Компания', 'idCompany', companies, '--', {
|
||||||
editable: true,
|
|
||||||
sorter: makeNumericSorter('idCompany'),
|
sorter: makeNumericSorter('idCompany'),
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
@ -12,11 +12,12 @@ import {
|
|||||||
EditableTable,
|
EditableTable,
|
||||||
makeColumn,
|
makeColumn,
|
||||||
makeSelectColumn,
|
makeSelectColumn,
|
||||||
makeStringSorter,
|
|
||||||
makeNumericSorter,
|
makeNumericSorter,
|
||||||
makeTagColumn,
|
makeTagColumn,
|
||||||
defaultPagination,
|
defaultPagination,
|
||||||
makeTimezoneColumn,
|
makeTimezoneColumn,
|
||||||
|
makeTextColumn,
|
||||||
|
makeNumericColumn,
|
||||||
} from '@components/Table'
|
} from '@components/Table'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { TelemetryView, CompanyView } from '@components/views'
|
import { TelemetryView, CompanyView } from '@components/views'
|
||||||
@ -81,23 +82,11 @@ const WellController = memo(() => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
setColumns([
|
setColumns([
|
||||||
makeSelectColumn('Куст', 'idCluster', clusters, '--', {
|
makeSelectColumn('Куст', 'idCluster', clusters, '--', { width: '5rem', sorter: makeNumericSorter('idCluster') }),
|
||||||
width: '5rem',
|
makeTextColumn('Название', 'caption', undefined, undefined, undefined, { width: '5rem' }),
|
||||||
editable: true,
|
makeSelectColumn('Тип', 'idWellType', wellTypes, '--', { width: 150, sorter: makeNumericSorter('idWellType') }),
|
||||||
sorter: makeNumericSorter('idCluster'),
|
makeNumericColumn('Широта', 'latitude', coordsFormat, undefined, 150),
|
||||||
}),
|
makeNumericColumn('Долгота', 'longitude', coordsFormat, undefined, 150),
|
||||||
makeColumn('Название', 'caption', {
|
|
||||||
width: '5rem',
|
|
||||||
editable: true,
|
|
||||||
sorter: makeStringSorter('caption'),
|
|
||||||
}),
|
|
||||||
makeSelectColumn('Тип', 'idWellType', wellTypes, '--', {
|
|
||||||
width: 150,
|
|
||||||
editable: true,
|
|
||||||
sorter: makeNumericSorter('idWellType'),
|
|
||||||
}),
|
|
||||||
makeColumn('Широта', 'latitude', { width: 150, editable: true, render: coordsFormat }),
|
|
||||||
makeColumn('Долгота', 'longitude', { width: 150, editable: true, render: coordsFormat }),
|
|
||||||
makeColumn('Телеметрия', 'telemetry', {
|
makeColumn('Телеметрия', 'telemetry', {
|
||||||
editable: true,
|
editable: true,
|
||||||
render: (telemetry) => <TelemetryView telemetry={telemetry} />,
|
render: (telemetry) => <TelemetryView telemetry={telemetry} />,
|
||||||
@ -105,7 +94,6 @@ const WellController = memo(() => {
|
|||||||
}, ),
|
}, ),
|
||||||
makeTimezoneColumn('Зона', 'timezone', null, true, { width: 170 }),
|
makeTimezoneColumn('Зона', 'timezone', null, true, { width: 170 }),
|
||||||
makeTagColumn('Компании', 'companies', companies, 'id', 'caption', {
|
makeTagColumn('Компании', 'companies', companies, 'id', 'caption', {
|
||||||
editable: true,
|
|
||||||
render: (company) => <CompanyView company={company} />,
|
render: (company) => <CompanyView company={company} />,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
makeTextColumn,
|
makeTextColumn,
|
||||||
makeGroupColumn,
|
makeGroupColumn,
|
||||||
makeColumn,
|
makeColumn,
|
||||||
makeNumericColumnPlanFact,
|
makeNumericColumnPlanFactOld,
|
||||||
Table,
|
Table,
|
||||||
makeNumericRender,
|
makeNumericRender,
|
||||||
makeNumericColumn,
|
makeNumericColumn,
|
||||||
@ -117,7 +117,10 @@ const ClusterWells = memo(({ statsWells }) => {
|
|||||||
const columns = useMemo(() => [
|
const columns = useMemo(() => [
|
||||||
makeTextColumn('скв №', 'caption', null, null,
|
makeTextColumn('скв №', 'caption', null, null,
|
||||||
(_, item) => (
|
(_, item) => (
|
||||||
<Link to={{ pathname: `/well/${item.id}`, state: { from: location.pathname }}} style={{display: 'flex', alignItems: 'center'}}>
|
<Link
|
||||||
|
to={{ pathname: `/well/${item.id}`, state: { from: location.pathname }}}
|
||||||
|
style={{ display: 'flex', alignItems: 'center' }}
|
||||||
|
>
|
||||||
<PointerIcon
|
<PointerIcon
|
||||||
state={item.idState === 1 ? 'active' : 'unknown'}
|
state={item.idState === 1 ? 'active' : 'unknown'}
|
||||||
width={32}
|
width={32}
|
||||||
@ -133,10 +136,10 @@ const ClusterWells = memo(({ statsWells }) => {
|
|||||||
makeDateColumn('начало', 'factStart'),
|
makeDateColumn('начало', 'factStart'),
|
||||||
makeDateColumn('окончание', 'factEnd'),
|
makeDateColumn('окончание', 'factEnd'),
|
||||||
]),
|
]),
|
||||||
makeNumericColumnPlanFact('Продолжительность, сут', 'period', filtersMinMax, makeFilterMinMaxFunction, numericRender),
|
makeNumericColumnPlanFactOld('Продолжительность, сут', 'period', numericRender, makeFilterMinMaxFunction, { filters: filtersMinMax }),
|
||||||
makeNumericColumnPlanFact('МСП, м/ч', 'rateOfPenetration', filtersMinMax, makeFilterMinMaxFunction, numericRender),
|
makeNumericColumnPlanFactOld('МСП, м/ч', 'rateOfPenetration', numericRender, makeFilterMinMaxFunction, { filters: filtersMinMax }),
|
||||||
makeNumericColumnPlanFact('Рейсовая скорость, м/ч', 'routeSpeed', filtersMinMax, makeFilterMinMaxFunction, numericRender),
|
makeNumericColumnPlanFactOld('Рейсовая скорость, м/ч', 'routeSpeed', numericRender, makeFilterMinMaxFunction, { filters: filtersMinMax }),
|
||||||
makeNumericColumn('НПВ, ч', 'notProductiveTimeFact', filtersMinMax, makeFilterMinMaxFunction, numericRender),
|
makeNumericColumn('НПВ, ч', 'notProductiveTimeFact', numericRender, makeFilterMinMaxFunction, { filters: filtersMinMax }),
|
||||||
makeColumn('TVD', 'tvd', { align: 'center', render: (_, value) => (
|
makeColumn('TVD', 'tvd', { align: 'center', render: (_, value) => (
|
||||||
<Button onClick={() => {
|
<Button onClick={() => {
|
||||||
setSelectedWell(value)
|
setSelectedWell(value)
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { memo, useMemo } from 'react'
|
import { memo, useMemo } from 'react'
|
||||||
|
|
||||||
import { Table, makeTextColumn, makeNumericColumnPlanFact } from '@components/Table'
|
import { Table, makeTextColumn, makeNumericColumnPlanFactOld } from '@components/Table'
|
||||||
import { getPrecision } from '@utils/functions'
|
import { getPrecision } from '@utils/functions'
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
makeTextColumn('Конструкция секции', 'sectionType'),
|
makeTextColumn('Конструкция секции', 'sectionType'),
|
||||||
makeTextColumn('Операция', 'operationName'),
|
makeTextColumn('Операция', 'operationName'),
|
||||||
makeNumericColumnPlanFact('Глубина забоя', 'depth', null, null, (number) => getPrecision(number)),
|
makeNumericColumnPlanFactOld('Глубина забоя', 'depth', (number) => getPrecision(number)),
|
||||||
makeNumericColumnPlanFact('Часы', 'durationHours', null, null, (number) => getPrecision(number)),
|
makeNumericColumnPlanFactOld('Часы', 'durationHours', (number) => getPrecision(number)),
|
||||||
makeNumericColumnPlanFact('Комментарий', 'comment', null, null, (text) => text ?? '-')
|
makeNumericColumnPlanFactOld('Комментарий', 'comment', (text) => text ?? '-'),
|
||||||
]
|
]
|
||||||
|
|
||||||
export const WellOperationsTable = memo(({ wellOperations }) => {
|
export const WellOperationsTable = memo(({ wellOperations }) => {
|
||||||
|
@ -18,7 +18,7 @@ const columns = [
|
|||||||
makeNumericColumn('Проходка, м', 'sumDepthInterval'),
|
makeNumericColumn('Проходка, м', 'sumDepthInterval'),
|
||||||
makeNumericColumn('Время работы, ч', 'usedTimeHours'),
|
makeNumericColumn('Время работы, ч', 'usedTimeHours'),
|
||||||
makeNumericColumn('Кол-во запусков', 'operationCount'),
|
makeNumericColumn('Кол-во запусков', 'operationCount'),
|
||||||
makeNumericColumn('Коэф. использования, %', 'kUsage', undefined, undefined, (value) => numericRender(value * 100)),
|
makeNumericColumn('Коэф. использования, %', 'kUsage', (value) => numericRender(value * 100)),
|
||||||
]
|
]
|
||||||
|
|
||||||
const getSubsystemState = (subsystem) => {
|
const getSubsystemState = (subsystem) => {
|
||||||
|
@ -21,13 +21,13 @@ const speedNumericRender = (section) => numericRender(section?.speed)
|
|||||||
|
|
||||||
const makeSectionSorter = (key, name) => (a, b) => (a?.[key]?.[name] ?? 0) - (b?.[key]?.[name] ?? 0)
|
const makeSectionSorter = (key, name) => (a, b) => (a?.[key]?.[name] ?? 0) - (b?.[key]?.[name] ?? 0)
|
||||||
export const makeSectionColumn = (title, key, { speedRender } = {}) => makeGroupColumn(title, [
|
export const makeSectionColumn = (title, key, { speedRender } = {}) => makeGroupColumn(title, [
|
||||||
makeNumericColumn('Проходка', key, null, null, (section => numericRender(section?.depth)), 100, {
|
makeNumericColumn('Проходка', key, (section => numericRender(section?.depth)), undefined, 100, {
|
||||||
sorter: makeSectionSorter(key, 'depth'),
|
sorter: makeSectionSorter(key, 'depth'),
|
||||||
}),
|
}),
|
||||||
makeNumericColumn('Время', key, null, null, (section => numericRender(section?.time)), 100, {
|
makeNumericColumn('Время', key, (section => numericRender(section?.time)), undefined, 100, {
|
||||||
sorter: makeSectionSorter(key, 'time'),
|
sorter: makeSectionSorter(key, 'time'),
|
||||||
}),
|
}),
|
||||||
makeNumericColumn((<>V<sub>рейсовая</sub></>), key, null, null, speedRender ?? speedNumericRender, 100, {
|
makeNumericColumn((<>V<sub>рейсовая</sub></>), key, speedRender ?? speedNumericRender, undefined, 100, {
|
||||||
sorter: makeSectionSorter(key, 'speed'),
|
sorter: makeSectionSorter(key, 'speed'),
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
@ -37,7 +37,7 @@ export const defaultColumns = [
|
|||||||
makeTextColumn('Скважина', 'caption', null, null, null, { fixed: 'left', width: 100 }),
|
makeTextColumn('Скважина', 'caption', null, null, null, { fixed: 'left', width: 100 }),
|
||||||
]
|
]
|
||||||
|
|
||||||
const scrollSettings = { scrollToFirstRowOnChange: true, x: 100, y: 200 }
|
const scrollSettings = { scrollToFirstRowOnChange: true, x: 100, y: '25vh' }
|
||||||
const summaryColSpan = 1 /// TODO: Когда добавится куст изменить на 2
|
const summaryColSpan = 1 /// TODO: Когда добавится куст изменить на 2
|
||||||
|
|
||||||
const getWellData = async (wellsList) => {
|
const getWellData = async (wellsList) => {
|
||||||
|
@ -1,146 +0,0 @@
|
|||||||
import { memo, useCallback, useEffect, useState } from 'react'
|
|
||||||
import { Button, Modal, Popconfirm } from 'antd'
|
|
||||||
|
|
||||||
import { useWell } from '@asb/context'
|
|
||||||
import { makeColumn, makeGroupColumn, makeNumericRender, makeSelectColumn, Table } from '@components/Table'
|
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
|
||||||
import { DrillParamsService, WellOperationService } from '@api'
|
|
||||||
|
|
||||||
const getDeepValue = (data, key) => {
|
|
||||||
if (!key || key.trim() === '') return null
|
|
||||||
const keys = key.split('.')
|
|
||||||
let out = data
|
|
||||||
while (keys.length > 0) {
|
|
||||||
if (!(keys[0] in out)) return null
|
|
||||||
out = out[keys[0]]
|
|
||||||
keys.splice(0, 1)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
const makeNumericSorter = (keys) => (a, b) => getDeepValue(a, keys) - getDeepValue(b, keys)
|
|
||||||
|
|
||||||
const numericRender = makeNumericRender(1)
|
|
||||||
const makeNumericColumn = (title, dataIndex, render, other) => makeColumn(title, dataIndex, {
|
|
||||||
sorter: makeNumericSorter(dataIndex),
|
|
||||||
render: (_, record, index) => {
|
|
||||||
const func = render ?? ((value) => <>{value}</>)
|
|
||||||
const item = getDeepValue(record, dataIndex)
|
|
||||||
return func(item, record, index)
|
|
||||||
},
|
|
||||||
align: 'right',
|
|
||||||
...other,
|
|
||||||
})
|
|
||||||
|
|
||||||
const makeAvgRender = (dataIndex) => (avg, record) => {
|
|
||||||
const max = record[dataIndex]?.max
|
|
||||||
const fillW = (max - avg) / max * 100
|
|
||||||
return (
|
|
||||||
<div className={'avg-column'}>
|
|
||||||
<div className={'avg-fill'} style={{ width: `${fillW}%` }} />
|
|
||||||
<div className={'avg-value'}>
|
|
||||||
{numericRender(avg)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const makeNumericAvgRange = (title, dataIndex, defaultRender = false) => makeGroupColumn(title, [
|
|
||||||
makeNumericColumn('мин', `${dataIndex}.min`),
|
|
||||||
makeNumericColumn('сред', `${dataIndex}.avg`, defaultRender ? undefined : makeAvgRender(dataIndex)),
|
|
||||||
makeNumericColumn('макс', `${dataIndex}.max`),
|
|
||||||
])
|
|
||||||
|
|
||||||
export const getColumns = async (idWell) => {
|
|
||||||
let sectionTypes = await WellOperationService.getSectionTypes(idWell)
|
|
||||||
sectionTypes = Object.entries(sectionTypes).map(([id, value]) => ({
|
|
||||||
label: value,
|
|
||||||
value: id,
|
|
||||||
}))
|
|
||||||
|
|
||||||
return [
|
|
||||||
makeSelectColumn('Конструкция секции','idWellSectionType', sectionTypes, null, {
|
|
||||||
width: 160,
|
|
||||||
sorter: makeNumericSorter('idWellSectionType'),
|
|
||||||
}),
|
|
||||||
makeNumericAvgRange('Нагрузка, т', 'axialLoad'),
|
|
||||||
makeNumericAvgRange('Давление, атм', 'pressure'),
|
|
||||||
makeNumericAvgRange('Момент на ВСП, кН·м', 'rotorTorque', true),
|
|
||||||
makeNumericAvgRange('Обороты на ВСП, об/мин', 'rotorSpeed'),
|
|
||||||
makeNumericAvgRange('Расход, л/с', 'flow'),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const NewParamsTable = memo(({ selectedWellsKeys }) => {
|
|
||||||
const [params, setParams] = useState([])
|
|
||||||
const [paramsColumns, setParamsColumns] = useState([])
|
|
||||||
const [showParamsLoader, setShowParamsLoader] = useState(false)
|
|
||||||
const [isParamsModalVisible, setIsParamsModalVisible] = useState(false)
|
|
||||||
|
|
||||||
const [well] = useWell()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
invokeWebApiWrapperAsync(async () => setParamsColumns(await getColumns(well.id)))
|
|
||||||
}, [well])
|
|
||||||
|
|
||||||
const onParamButtonClick = useCallback(() => invokeWebApiWrapperAsync(
|
|
||||||
async () => {
|
|
||||||
setIsParamsModalVisible(true)
|
|
||||||
const params = await DrillParamsService.getCompositeAll(well.id)
|
|
||||||
setParams(params)
|
|
||||||
},
|
|
||||||
setShowParamsLoader,
|
|
||||||
`Не удалось загрузить список режимов`,
|
|
||||||
{ actionName: 'Получение списка режимов скважины', well }
|
|
||||||
), [well])
|
|
||||||
|
|
||||||
const onParamsAddClick = useCallback(() => invokeWebApiWrapperAsync(
|
|
||||||
async () => {
|
|
||||||
await DrillParamsService.save(well.id, params)
|
|
||||||
setIsParamsModalVisible(false)
|
|
||||||
},
|
|
||||||
setShowParamsLoader,
|
|
||||||
`Не удалось добавить режимы в список`,
|
|
||||||
{ actionName: 'Добавление режима скважины', well }
|
|
||||||
), [well, params])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
size={'large'}
|
|
||||||
disabled={selectedWellsKeys.length <= 0}
|
|
||||||
onClick={onParamButtonClick}
|
|
||||||
>
|
|
||||||
Заполнить режимы текущей скважины
|
|
||||||
</Button>
|
|
||||||
<Modal
|
|
||||||
title={'Заполнить режимы текущей скважины'}
|
|
||||||
centered
|
|
||||||
open={isParamsModalVisible}
|
|
||||||
onCancel={() => setIsParamsModalVisible(false)}
|
|
||||||
width={1700}
|
|
||||||
footer={(
|
|
||||||
<Popconfirm title={'Заменить существующие режимы выбранными?'} onConfirm={onParamsAddClick}>
|
|
||||||
<Button
|
|
||||||
size={'large'}
|
|
||||||
disabled={params.length <= 0}
|
|
||||||
>Сохранить</Button>
|
|
||||||
</Popconfirm>
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<LoaderPortal show={showParamsLoader}>
|
|
||||||
<Table
|
|
||||||
bordered
|
|
||||||
size={'small'}
|
|
||||||
columns={paramsColumns}
|
|
||||||
dataSource={params}
|
|
||||||
pagination={false}
|
|
||||||
/>
|
|
||||||
</LoaderPortal>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
export default NewParamsTable
|
|
@ -1,12 +1,13 @@
|
|||||||
import { Link, useLocation } from 'react-router-dom'
|
import { Link, useLocation } from 'react-router-dom'
|
||||||
import { useState, useEffect, memo, useMemo, lazy, Suspense } from 'react'
|
import { useState, useEffect, memo, useMemo, lazy, Suspense } from 'react'
|
||||||
import { LineChartOutlined, ProfileOutlined, TeamOutlined } from '@ant-design/icons'
|
import { LineChartOutlined, ProfileOutlined, TeamOutlined } from '@ant-design/icons'
|
||||||
import { Button, Badge, Divider, Modal, Row, Col } from 'antd'
|
import { Button, Badge, Divider, Modal } from 'antd'
|
||||||
|
|
||||||
import { useWell } from '@asb/context'
|
import { useWell } from '@asb/context'
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
|
import SuspenseFallback from '@components/SuspenseFallback'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { Table, makeTextColumn, makeNumericColumnPlanFact, makeNumericColumn } from '@components/Table'
|
import { Table, makeTextColumn, makeNumericColumnPlanFactOld, makeNumericColumn } from '@components/Table'
|
||||||
import { WellCompositeService } from '@api'
|
import { WellCompositeService } from '@api'
|
||||||
import {
|
import {
|
||||||
hasPermission,
|
hasPermission,
|
||||||
@ -16,8 +17,6 @@ import {
|
|||||||
getOperations
|
getOperations
|
||||||
} from '@utils'
|
} from '@utils'
|
||||||
|
|
||||||
import NewParamsTable from './NewParamsTable'
|
|
||||||
import SuspenseFallback from '@asb/components/SuspenseFallback'
|
|
||||||
|
|
||||||
const Tvd = lazy(() => import('@pages/Well/WellOperations/Tvd'))
|
const Tvd = lazy(() => import('@pages/Well/WellOperations/Tvd'))
|
||||||
const CompaniesTable = lazy(() => import('@pages/Cluster/CompaniesTable'))
|
const CompaniesTable = lazy(() => import('@pages/Cluster/CompaniesTable'))
|
||||||
@ -146,15 +145,15 @@ const WellCompositeSections = memo(({ statsWells, selectedSections }) => {
|
|||||||
makeTextColumn('скв №', 'caption', null, null,
|
makeTextColumn('скв №', 'caption', null, null,
|
||||||
(text, item) => <Link to={{ pathname: `/well/${item?.id}`, state: { from: location.pathname }}}>{text ?? '-'}</Link>
|
(text, item) => <Link to={{ pathname: `/well/${item?.id}`, state: { from: location.pathname }}}>{text ?? '-'}</Link>
|
||||||
),
|
),
|
||||||
makeTextColumn('Секция', 'sectionType', filtersSectionsType, sortBySectionId, (text) => text ?? '-'),
|
makeTextColumn('Секция', 'sectionType', filtersSectionsType, sortBySectionId, (text) => text ?? '-', { width: 100 }),
|
||||||
makeNumericColumnPlanFact('Глубина, м', 'sectionWellDepth', filtersMinMax, makeFilterMinMaxFunction),
|
makeNumericColumnPlanFactOld('Глубина, м', 'sectionWellDepth', undefined, makeFilterMinMaxFunction, undefined, { filters: filtersMinMax }),
|
||||||
makeNumericColumnPlanFact('Продолжительность, ч', 'sectionBuildDays', filtersMinMax, makeFilterMinMaxFunction),
|
makeNumericColumnPlanFactOld('Продолжительность, ч', 'sectionBuildDays', undefined, makeFilterMinMaxFunction, undefined, { filters: filtersMinMax }),
|
||||||
makeNumericColumnPlanFact('МСП, м/ч', 'sectionRateOfPenetration', filtersMinMax, makeFilterMinMaxFunction),
|
makeNumericColumnPlanFactOld('МСП, м/ч', 'sectionRateOfPenetration', undefined, makeFilterMinMaxFunction, undefined, { filters: filtersMinMax }),
|
||||||
makeNumericColumnPlanFact('Рейсовая скорость, м/ч', 'sectionRouteSpeed', filtersMinMax, makeFilterMinMaxFunction),
|
makeNumericColumnPlanFactOld('Рейсовая скорость, м/ч', 'sectionRouteSpeed', undefined, makeFilterMinMaxFunction, undefined, { filters: filtersMinMax }),
|
||||||
makeNumericColumnPlanFact('Спуск КНБК, м/ч', 'sectionBhaDownSpeed', filtersMinMax, makeFilterMinMaxFunction),
|
makeNumericColumnPlanFactOld('Спуск КНБК, м/ч', 'sectionBhaDownSpeed', undefined, makeFilterMinMaxFunction, undefined, { filters: filtersMinMax }),
|
||||||
makeNumericColumnPlanFact('Подъем КНБК, м/ч', 'sectionBhaUpSpeed', filtersMinMax, makeFilterMinMaxFunction),
|
makeNumericColumnPlanFactOld('Подъем КНБК, м/ч', 'sectionBhaUpSpeed', undefined, makeFilterMinMaxFunction, undefined, { filters: filtersMinMax }),
|
||||||
makeNumericColumnPlanFact('Скорость спуска ОК, м/ч', 'sectionCasingDownSpeed', filtersMinMax, makeFilterMinMaxFunction),
|
makeNumericColumnPlanFactOld('Скорость спуска ОК, м/ч', 'sectionCasingDownSpeed', undefined, makeFilterMinMaxFunction, undefined, { filters: filtersMinMax }),
|
||||||
makeNumericColumn('НПВ, ч', 'nonProductiveHours', filtersMinMax, makeFilterMinMaxFunction, null, '80px'),
|
makeNumericColumn('НПВ, ч', 'nonProductiveHours', undefined, makeFilterMinMaxFunction, '80px', { filters: filtersMinMax }),
|
||||||
{
|
{
|
||||||
title: 'TVD',
|
title: 'TVD',
|
||||||
render: (value) => (
|
render: (value) => (
|
||||||
@ -200,11 +199,11 @@ const WellCompositeSections = memo(({ statsWells, selectedSections }) => {
|
|||||||
dataSource={rows}
|
dataSource={rows}
|
||||||
size={'small'}
|
size={'small'}
|
||||||
bordered
|
bordered
|
||||||
scroll={{ x: true, y: 620 }}
|
scroll={{ x: true, y: '30vh' }}
|
||||||
rowSelection={rowSelection}
|
rowSelection={rowSelection}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
/>
|
/>
|
||||||
<Divider />
|
<Divider style={{ marginTop: 0 }} />
|
||||||
<Badge.Ribbon text={'комбинированная скважина'} color={'gray'}>
|
<Badge.Ribbon text={'комбинированная скважина'} color={'gray'}>
|
||||||
<h3>Выбранные секции</h3>
|
<h3>Выбранные секции</h3>
|
||||||
</Badge.Ribbon>
|
</Badge.Ribbon>
|
||||||
@ -214,12 +213,9 @@ const WellCompositeSections = memo(({ statsWells, selectedSections }) => {
|
|||||||
rowSelection={rowSelection}
|
rowSelection={rowSelection}
|
||||||
size={'small'}
|
size={'small'}
|
||||||
bordered
|
bordered
|
||||||
scroll={{ x: true }}
|
scroll={{ x: true, y: '30vh' }}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
/>
|
/>
|
||||||
<Row justify={'end'} style={{ margin: '1rem 0' }}>
|
|
||||||
<Col><NewParamsTable selectedWellsKeys={selectedWellsKeys} /></Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title={'TVD'}
|
title={'TVD'}
|
||||||
|
@ -40,7 +40,7 @@ export const DocumentsTemplate = ({ idCategory, well: givenWell, mimeTypes, head
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
makeDateColumn('Дата загрузки', 'uploadDate'),
|
makeDateColumn('Дата загрузки', 'uploadDate'),
|
||||||
makeNumericColumn('Размер', 'size', null, null, (value) => formatBytes(value)),
|
makeNumericColumn('Размер', 'size', (value) => formatBytes(value)),
|
||||||
makeColumn('Автор', 'author', { render: item => <UserView user={item}/> }),
|
makeColumn('Автор', 'author', { render: item => <UserView user={item}/> }),
|
||||||
makeColumn('Компания', 'company', { render: (_, record) => <CompanyView company={record?.author?.company}/> }),
|
makeColumn('Компания', 'company', { render: (_, record) => <CompanyView company={record?.author?.company}/> }),
|
||||||
...(customColumns ?? [])
|
...(customColumns ?? [])
|
||||||
|
@ -29,7 +29,7 @@ const categoryDictionary = {
|
|||||||
// Конфигурация таблицы
|
// Конфигурация таблицы
|
||||||
export const makeMessageColumns = (idWell) => [
|
export const makeMessageColumns = (idWell) => [
|
||||||
makeDateColumn('Дата', 'date', undefined, undefined, { width: '120px' }),
|
makeDateColumn('Дата', 'date', undefined, undefined, { width: '120px' }),
|
||||||
makeNumericColumn('Глубина, м', 'wellDepth', null, null, (depth, item) => (
|
makeNumericColumn('Глубина, м', 'wellDepth', (depth, item) => (
|
||||||
<Tooltip title={'Нажмите для перехода в архив'}>
|
<Tooltip title={'Нажмите для перехода в архив'}>
|
||||||
<Link
|
<Link
|
||||||
style={{ color: 'inherit'}}
|
style={{ color: 'inherit'}}
|
||||||
@ -40,7 +40,7 @@ export const makeMessageColumns = (idWell) => [
|
|||||||
{depth.toFixed(2)}
|
{depth.toFixed(2)}
|
||||||
</Link>
|
</Link>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
), '7rem'),
|
), undefined, '7rem'),
|
||||||
makeColumn('Категория', 'categoryId', {
|
makeColumn('Категория', 'categoryId', {
|
||||||
width: '8rem',
|
width: '8rem',
|
||||||
render: (_, item) => categoryDictionary[item.categoryId].title,
|
render: (_, item) => categoryDictionary[item.categoryId].title,
|
||||||
|
@ -26,10 +26,10 @@ const tableColumns = [
|
|||||||
<div className={'table_color'} style={{ backgroundColor }} />
|
<div className={'table_color'} style={{ backgroundColor }} />
|
||||||
)}),
|
)}),
|
||||||
makeTextColumn('Подсистема', 'subsystemName'),
|
makeTextColumn('Подсистема', 'subsystemName'),
|
||||||
makeNumericColumn('Использование, %', 'kUsage', undefined, undefined, val => (+val * 100).toFixed(2), 200),
|
makeNumericColumn('Использование, %', 'kUsage', val => (+val * 100).toFixed(2), undefined, 200),
|
||||||
makeNumericColumn('Проходка, м', 'sumDepthInterval', undefined, undefined, undefined, 200),
|
makeNumericColumn('Проходка, м', 'sumDepthInterval', undefined, undefined, 200),
|
||||||
makeNumericColumn('Время работы, ч', 'usedTimeHours', undefined, undefined, undefined, 200),
|
makeNumericColumn('Время работы, ч', 'usedTimeHours', undefined, undefined, 200),
|
||||||
makeNumericColumn('Кол-во запусков', 'operationCount', undefined, undefined, makeNumericRender(0), 200),
|
makeNumericColumn('Кол-во запусков', 'operationCount', makeNumericRender(0), undefined, 200),
|
||||||
]
|
]
|
||||||
|
|
||||||
// Выбор доступен только до текущей даты
|
// Выбор доступен только до текущей даты
|
||||||
|
@ -5,14 +5,13 @@ import { EditableTable, makeTextColumn } from '@components/Table'
|
|||||||
import { DrillerService } from '@api'
|
import { DrillerService } from '@api'
|
||||||
|
|
||||||
const columnOptions = {
|
const columnOptions = {
|
||||||
editable: true,
|
|
||||||
formItemRules: [{ message: 'Обязательное поле!', required: true }]
|
formItemRules: [{ message: 'Обязательное поле!', required: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
makeTextColumn('Фамилия', 'surname', undefined, undefined, undefined, columnOptions),
|
makeTextColumn('Фамилия', 'surname', undefined, undefined, undefined, columnOptions),
|
||||||
makeTextColumn('Имя', 'name', undefined, undefined, undefined, columnOptions),
|
makeTextColumn('Имя', 'name', undefined, undefined, undefined, columnOptions),
|
||||||
makeTextColumn('Отчество', 'patronymic', undefined, undefined, undefined, { editable: true }),
|
makeTextColumn('Отчество', 'patronymic'),
|
||||||
]
|
]
|
||||||
|
|
||||||
const rowClassName = (record) => record.has ? 'driller_list_active' : ''
|
const rowClassName = (record) => record.has ? 'driller_list_active' : ''
|
||||||
|
@ -14,7 +14,6 @@ import { arrayOrDefault } from '@utils'
|
|||||||
import { ScheduleService } from '@api'
|
import { ScheduleService } from '@api'
|
||||||
|
|
||||||
const columnOptions = {
|
const columnOptions = {
|
||||||
editable: true,
|
|
||||||
formItemRules: [{ message: 'Обязательное поле!', required: true }]
|
formItemRules: [{ message: 'Обязательное поле!', required: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,11 @@ const makeDrillerSorter = (key) => (a, b) => {
|
|||||||
|
|
||||||
export const columns = [
|
export const columns = [
|
||||||
makeTextColumn('Бурильщик', 'driller', null, makeDrillerSorter('driller'), drillerRender, { width: 200 }),
|
makeTextColumn('Бурильщик', 'driller', null, makeDrillerSorter('driller'), drillerRender, { width: 200 }),
|
||||||
makeNumericColumn('Кол-во операций', 'count', null, null, (value) => parseInt(value), 150),
|
makeNumericColumn('Кол-во операций', 'count', (value) => parseInt(value), undefined, 150),
|
||||||
makeNumericColumn('Среднее по ключевому показателю', 'averageValue', null, null, numericRender, 150),
|
makeNumericColumn('Среднее по ключевому показателю', 'averageValue', numericRender, undefined, 150),
|
||||||
makeNumericColumn('Среднее целевого показателя', 'averageTargetValue', null, null, numericRender, 150),
|
makeNumericColumn('Среднее целевого показателя', 'averageTargetValue', numericRender, undefined, 150),
|
||||||
makeNumericColumn('Эффективность (%)', 'efficiency', null, null, numericRender, 150),
|
makeNumericColumn('Эффективность (%)', 'efficiency', numericRender, undefined, 150),
|
||||||
makeNumericColumn('Коэффициент потерь', 'loss', null, null, numericRender, 100),
|
makeNumericColumn('Коэффициент потерь', 'loss', numericRender, undefined, 100),
|
||||||
]
|
]
|
||||||
|
|
||||||
export const OperationsTable = memo(({ data, height, ...other }) => (
|
export const OperationsTable = memo(({ data, height, ...other }) => (
|
||||||
|
@ -8,7 +8,6 @@ import { DetectedOperationService, OperationValueService } from '@api'
|
|||||||
import { arrayOrDefault } from '@utils'
|
import { arrayOrDefault } from '@utils'
|
||||||
|
|
||||||
const columnOptions = {
|
const columnOptions = {
|
||||||
editable: true,
|
|
||||||
formItemRules: [{ message: 'Обязательное поле!', required: true }]
|
formItemRules: [{ message: 'Обязательное поле!', required: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,11 +71,11 @@ export const TargetEditor = memo(({ loading, onChange }) => {
|
|||||||
filterOption: (input, option) =>
|
filterOption: (input, option) =>
|
||||||
String(option?.label ?? '').toLowerCase().indexOf(input.toLowerCase()) >= 0
|
String(option?.label ?? '').toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
}),
|
}),
|
||||||
makeNumericColumn('Цель', 'targetValue', undefined, undefined, numericRender, 150, columnOptions),
|
makeNumericColumn('Цель', 'targetValue', numericRender, undefined, 150, columnOptions),
|
||||||
makeNumericColumn('Норм.', 'standardValue', undefined, undefined, numericRender, 150, columnOptions),
|
makeNumericColumn('Норм.', 'standardValue', numericRender, undefined, 150, columnOptions),
|
||||||
makeGroupColumn('Глубина, м', [
|
makeGroupColumn('Глубина, м', [
|
||||||
makeNumericColumn('Начало', 'depthStart', undefined, undefined, numericRender, 150, columnOptions),
|
makeNumericColumn('Начало', 'depthStart', numericRender, undefined, 150, columnOptions),
|
||||||
makeNumericColumn('Окончание', 'depthEnd', undefined, undefined, numericRender, 150, columnOptions),
|
makeNumericColumn('Окончание', 'depthEnd', numericRender, undefined, 150, columnOptions),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { memo, useCallback, useMemo, useState } from 'react'
|
import { memo, useCallback, useMemo, useState } from 'react'
|
||||||
import { Select, Modal, Input, InputNumber } from 'antd'
|
import { Modal, Input } from 'antd'
|
||||||
|
|
||||||
import { useWell } from '@asb/context'
|
import { useWell } from '@asb/context'
|
||||||
import { Grid, GridItem } from '@components/Grid'
|
import { Grid, GridItem } from '@components/Grid'
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { makeNumericRender, EditableTable } from '@components/Table'
|
import { makeNumericRender, EditableTable, makeSelectColumn, makeNumericColumn } from '@components/Table'
|
||||||
import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
|
import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
|
||||||
import { SetpointsService } from '@api'
|
import { SetpointsService } from '@api'
|
||||||
|
|
||||||
@ -19,24 +19,8 @@ export const SetpointSender = memo(({ onClose, visible, setpointNames }) => {
|
|||||||
const [well] = useWell()
|
const [well] = useWell()
|
||||||
|
|
||||||
const addingColumns = useMemo(() => [
|
const addingColumns = useMemo(() => [
|
||||||
{
|
makeSelectColumn('Наименование уставки', 'name', setpointNames, undefined, { width: 200, isRequired: true }),
|
||||||
title: 'Наименование уставки',
|
makeNumericColumn('Значение', 'value', makeNumericRender(1), undefined, 125, { isRequired: true, align: 'right' }),
|
||||||
dataIndex: 'name',
|
|
||||||
editable: true,
|
|
||||||
isRequired: true,
|
|
||||||
width: 200,
|
|
||||||
input: <Select options={setpointNames} />,
|
|
||||||
render: (val) => setpointNames.find((name) => name.value === val)?.label
|
|
||||||
}, {
|
|
||||||
title: 'Значение',
|
|
||||||
dataIndex: 'value',
|
|
||||||
editable: true,
|
|
||||||
isRequired: true,
|
|
||||||
width: 125,
|
|
||||||
input: <InputNumber style={{ width: '100%' }} formatter={value => `${value}`.replace(',', '.')}/>,
|
|
||||||
render: makeNumericRender(1),
|
|
||||||
align: 'right'
|
|
||||||
}
|
|
||||||
], [setpointNames])
|
], [setpointNames])
|
||||||
|
|
||||||
const onAdd = useCallback(async (sp) => setSetpoints((prevSp) => {
|
const onAdd = useCallback(async (sp) => setSetpoints((prevSp) => {
|
||||||
|
@ -5,9 +5,9 @@ import { Grid, GridItem } from '@components/Grid'
|
|||||||
import { getChartIcon, makeDisplayValue } from '@utils'
|
import { getChartIcon, makeDisplayValue } from '@utils'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
|
||||||
const defaultFormater = makeDisplayValue({ def: '---', fixed: 2 })
|
const defaultFormatter = makeDisplayValue({ def: '---', fixed: 2 })
|
||||||
const defaultValueRender = (v, unit) => (
|
const defaultValueRender = (v, unit) => (
|
||||||
<>{defaultFormater(v)} {unit ?? ''}</>
|
<>{defaultFormatter(v)} {unit ?? ''}</>
|
||||||
)
|
)
|
||||||
|
|
||||||
export const cursorRender = (group, data, flowData) => {
|
export const cursorRender = (group, data, flowData) => {
|
||||||
@ -17,7 +17,7 @@ export const cursorRender = (group, data, flowData) => {
|
|||||||
const firstChart = group.charts[0]
|
const firstChart = group.charts[0]
|
||||||
const y = firstChart.y(d)
|
const y = firstChart.y(d)
|
||||||
const yDate = moment(y)
|
const yDate = moment(y)
|
||||||
const flow = flowData.filter((row) => yDate.isBetween(row.dateStart, row.dateEnd, 's', '[]'))
|
const flow = flowData?.filter((row) => yDate.isBetween(row.dateStart, row.dateEnd, 's', '[]'))
|
||||||
const yValue = firstChart.yAxis.format?.(y) ?? defaultValueRender(y, firstChart.yAxis.unit)
|
const yValue = firstChart.yAxis.format?.(y) ?? defaultValueRender(y, firstChart.yAxis.unit)
|
||||||
const xFormat = (chart) => {
|
const xFormat = (chart) => {
|
||||||
const v = chart.x(d)
|
const v = chart.x(d)
|
||||||
@ -42,13 +42,13 @@ export const cursorRender = (group, data, flowData) => {
|
|||||||
{group.charts.filter((chart) => chart.type === 'rect_area').map((chart, i) => {
|
{group.charts.filter((chart) => chart.type === 'rect_area').map((chart, i) => {
|
||||||
const minX = getByAccessor(chart.minXAccessor)
|
const minX = getByAccessor(chart.minXAccessor)
|
||||||
const maxX = getByAccessor(chart.maxXAccessor)
|
const maxX = getByAccessor(chart.maxXAccessor)
|
||||||
const value = (row) => <span>{defaultFormater(minX(row))} - {defaultFormater(maxX(row))}</span>
|
const value = (row) => <span>{defaultFormatter(minX(row))} - {defaultFormatter(maxX(row))}</span>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={chart.key}>
|
<Fragment key={chart.key}>
|
||||||
<GridItem row={i+2} col={1} style={{ padding: '2px 0' }}>{getChartIcon(chart)}</GridItem>
|
<GridItem row={i+2} col={1} style={{ padding: '2px 0' }}>{getChartIcon(chart)}</GridItem>
|
||||||
<GridItem row={i+2} col={2}>{chart.shortLabel || chart.label}</GridItem>
|
<GridItem row={i+2} col={2}>{chart.shortLabel || chart.label}</GridItem>
|
||||||
{flow.map((row, j) => (
|
{flow?.map((row, j) => (
|
||||||
<GridItem key={`${j}`} row={i+2+(j++)} col={3} style={{ paddingRight: 0, textAlign: 'end' }}>
|
<GridItem key={`${j}`} row={i+2+(j++)} col={3} style={{ paddingRight: 0, textAlign: 'end' }}>
|
||||||
{chart.xAxis.format?.(row) ?? value(row)}
|
{chart.xAxis.format?.(row) ?? value(row)}
|
||||||
</GridItem>
|
</GridItem>
|
||||||
|
@ -13,13 +13,12 @@ import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
|
|||||||
import { formatDate, hasPermission, isRawDate, withPermissions } from '@utils'
|
import { formatDate, hasPermission, isRawDate, withPermissions } from '@utils'
|
||||||
import { Subscribe } from '@services/signalr'
|
import { Subscribe } from '@services/signalr'
|
||||||
import {
|
import {
|
||||||
DrillFlowChartService,
|
|
||||||
OperationStatService,
|
OperationStatService,
|
||||||
TelemetryDataSaubService,
|
TelemetryDataSaubService,
|
||||||
TelemetryDataSpinService
|
TelemetryDataSpinService
|
||||||
} from '@api'
|
} from '@api'
|
||||||
|
|
||||||
import { calcFlowData, makeChartGroups, yAxis } from './dataset'
|
import { makeChartGroups, yAxis } from './dataset'
|
||||||
import { ADDITIVE_PAGES, cutData, DATA_COUNT, getLoadingInterval, makeDateTimeDisabled } from './archive_methods'
|
import { ADDITIVE_PAGES, cutData, DATA_COUNT, getLoadingInterval, makeDateTimeDisabled } from './archive_methods'
|
||||||
import ActiveMessagesOnline from './ActiveMessagesOnline'
|
import ActiveMessagesOnline from './ActiveMessagesOnline'
|
||||||
import TelemetrySummary from './TelemetrySummary'
|
import TelemetrySummary from './TelemetrySummary'
|
||||||
@ -64,12 +63,12 @@ export const normalizeData = (data) => data?.map(item => ({
|
|||||||
const dateSorter = makeDateSorter('date')
|
const dateSorter = makeDateSorter('date')
|
||||||
const defaultDate = () => new Date(Date.now() - defaultPeriod * 1000)
|
const defaultDate = () => new Date(Date.now() - defaultPeriod * 1000)
|
||||||
|
|
||||||
const makeSubjectSubsription = (subject$, handler) => {
|
const makeSubjectSubscription = (subject$, handler) => {
|
||||||
const subscribtion = subject$.pipe(
|
const subscription = subject$.pipe(
|
||||||
buffer(subject$.pipe(throttleTime(700)))
|
buffer(subject$.pipe(throttleTime(700)))
|
||||||
).subscribe((data) => handler(data.flat().filter(Boolean)))
|
).subscribe((data) => handler(data.flat().filter(Boolean)))
|
||||||
|
|
||||||
return () => subscribtion.unsubscribe()
|
return () => subscription.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
const getRowDate = (row) => row && isRawDate(row.date) ? new Date(row.date) : null
|
const getRowDate = (row) => row && isRawDate(row.date) ? new Date(row.date) : null
|
||||||
@ -81,7 +80,6 @@ const TelemetryView = memo(() => {
|
|||||||
const [dataSaub, setDataSaub] = useState([])
|
const [dataSaub, setDataSaub] = useState([])
|
||||||
const [dataSpin, setDataSpin] = useState([])
|
const [dataSpin, setDataSpin] = useState([])
|
||||||
const [showLoader, setShowLoader] = useState(false)
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
const [flowChartData, setFlowChartData] = useState([])
|
|
||||||
const [rop, setRop] = useState(null)
|
const [rop, setRop] = useState(null)
|
||||||
const [chartMethods, setChartMethods] = useState()
|
const [chartMethods, setChartMethods] = useState()
|
||||||
|
|
||||||
@ -147,7 +145,6 @@ const TelemetryView = memo(() => {
|
|||||||
const spinSubject$ = useMemo(() => new BehaviorSubject(), [])
|
const spinSubject$ = useMemo(() => new BehaviorSubject(), [])
|
||||||
|
|
||||||
const filteredData = useMemo(() => cutData(dataSaub, domain.min, domain.max), [dataSaub, domain])
|
const filteredData = useMemo(() => cutData(dataSaub, domain.min, domain.max), [dataSaub, domain])
|
||||||
const flowData = useMemo(() => calcFlowData(dataSaub, flowChartData), [dataSaub, flowChartData])
|
|
||||||
const chartGroups = useMemo(() => makeChartGroups(), [])
|
const chartGroups = useMemo(() => makeChartGroups(), [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -170,8 +167,8 @@ const TelemetryView = memo(() => {
|
|||||||
setSearchParams(params)
|
setSearchParams(params)
|
||||||
}, [archiveMode, endDate, chartInterval])
|
}, [archiveMode, endDate, chartInterval])
|
||||||
|
|
||||||
useEffect(() => makeSubjectSubsription(saubSubject$, handleDataSaub), [saubSubject$, handleDataSaub])
|
useEffect(() => makeSubjectSubscription(saubSubject$, handleDataSaub), [saubSubject$, handleDataSaub])
|
||||||
useEffect(() => makeSubjectSubsription(spinSubject$, handleDataSpin), [spinSubject$, handleDataSpin])
|
useEffect(() => makeSubjectSubscription(spinSubject$, handleDataSpin), [spinSubject$, handleDataSpin])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (archiveMode) return
|
if (archiveMode) return
|
||||||
@ -233,8 +230,6 @@ const TelemetryView = memo(() => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
invokeWebApiWrapperAsync(
|
invokeWebApiWrapperAsync(
|
||||||
async () => {
|
async () => {
|
||||||
const flowChart = await DrillFlowChartService.getByIdWell(well.id)
|
|
||||||
setFlowChartData(flowChart ?? [])
|
|
||||||
const rop = await OperationStatService.getClusterRopStatByIdWell(well.id)
|
const rop = await OperationStatService.getClusterRopStatByIdWell(well.id)
|
||||||
setRop(rop)
|
setRop(rop)
|
||||||
let dates = await TelemetryDataSaubService.getDataDatesRange(well.id)
|
let dates = await TelemetryDataSaubService.getDataDatesRange(well.id)
|
||||||
@ -312,7 +307,6 @@ const TelemetryView = memo(() => {
|
|||||||
{...chartProps}
|
{...chartProps}
|
||||||
yDomain={domain}
|
yDomain={domain}
|
||||||
data={filteredData}
|
data={filteredData}
|
||||||
flowData={flowData}
|
|
||||||
methods={setChartMethods}
|
methods={setChartMethods}
|
||||||
datasetGroups={chartGroups}
|
datasetGroups={chartGroups}
|
||||||
onWheel={onWheel}
|
onWheel={onWheel}
|
||||||
|
@ -40,7 +40,6 @@ export const menuItems = [
|
|||||||
makeItem('План', 'plan', [], <TableOutlined />),
|
makeItem('План', 'plan', [], <TableOutlined />),
|
||||||
makeItem('Факт', 'fact', [], <TableOutlined />),
|
makeItem('Факт', 'fact', [], <TableOutlined />),
|
||||||
makeItem('РТК', 'drillProcessFlow', [], <BarChartOutlined />),
|
makeItem('РТК', 'drillProcessFlow', [], <BarChartOutlined />),
|
||||||
makeItem('Режимы', 'params', [], <ControlOutlined />),
|
|
||||||
]),
|
]),
|
||||||
makeItem('Документы', 'document', [], <FolderOutlined />, [
|
makeItem('Документы', 'document', [], <FolderOutlined />, [
|
||||||
makeItem('Растворный сервис', 'fluidService', [], <FolderOutlined />),
|
makeItem('Растворный сервис', 'fluidService', [], <FolderOutlined />),
|
||||||
|
@ -1,44 +1,83 @@
|
|||||||
import { useState, useEffect, memo, useMemo, useCallback } from 'react'
|
import { useState, useEffect, memo, useMemo, useCallback } from 'react'
|
||||||
|
|
||||||
import { useWell } from '@asb/context'
|
import { useWell } from '@asb/context'
|
||||||
|
import {
|
||||||
|
EditableTable,
|
||||||
|
makeGroupColumn,
|
||||||
|
makeNumericColumn,
|
||||||
|
makeNumericColumnPlanFact,
|
||||||
|
makeNumericRender,
|
||||||
|
makeNumericSorter,
|
||||||
|
makeSelectColumn,
|
||||||
|
} from '@components/Table'
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { EditableTable, makeNumericMinMax, makeNumericStartEnd } from '@components/Table'
|
import { ProcessMapService, WellOperationService } from '@api'
|
||||||
import { DrillFlowChartService } from '@api'
|
|
||||||
import { arrayOrDefault } from '@utils'
|
import { arrayOrDefault } from '@utils'
|
||||||
|
|
||||||
const columns = [
|
const numericRender = makeNumericRender(2)
|
||||||
makeNumericStartEnd('Глубина, м', 'depth'),
|
|
||||||
makeNumericMinMax('Нагрузка, т', 'axialLoad'),
|
export const getColumns = async (idWell) => {
|
||||||
makeNumericMinMax('Перепад давления, атм', 'pressure'),
|
let sectionTypes = await WellOperationService.getSectionTypes(idWell)
|
||||||
makeNumericMinMax('Момент на ВСП, кН·м', 'rotorTorque'),
|
sectionTypes = Object.entries(sectionTypes).map(([id, value]) => ({
|
||||||
makeNumericMinMax('Обороты на ВСП, об/мин', 'rotorSpeed'),
|
label: value,
|
||||||
makeNumericMinMax('Расход, л/с', 'flow')
|
value: id,
|
||||||
|
}))
|
||||||
|
|
||||||
|
return [
|
||||||
|
makeSelectColumn('Конструкция секции','idWellSectionType', sectionTypes, null, {
|
||||||
|
width: 160,
|
||||||
|
sorter: makeNumericSorter('idWellSectionType'),
|
||||||
|
}),
|
||||||
|
makeGroupColumn('Интервал бурения, м', [
|
||||||
|
makeNumericColumn('От', 'depthStart', numericRender),
|
||||||
|
makeNumericColumn('До', 'depthEnd', numericRender),
|
||||||
|
]),
|
||||||
|
makeNumericColumnPlanFact('Перепад давления, атм', 'pressure', numericRender),
|
||||||
|
makeNumericColumnPlanFact('Нагрузка, т', 'axialLoad', numericRender),
|
||||||
|
makeNumericColumnPlanFact('Момент на ВСП, кН·м', 'topDriveTorque', numericRender),
|
||||||
|
makeNumericColumnPlanFact('Обороты на ВСП, об/мин', 'topDriveSpeed', numericRender),
|
||||||
|
makeNumericColumnPlanFact('Расход, л/с', 'flow', numericRender),
|
||||||
|
makeNumericColumn('Плановая механическая скорость, м/ч', 'ropPlan', numericRender),
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
export const DrillProcessFlow = memo(() => {
|
export const DrillProcessFlow = memo(() => {
|
||||||
const [flows, setFlows] = useState([])
|
const [flows, setFlows] = useState([])
|
||||||
const [showLoader, setShowLoader] = useState(false)
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
|
const [columns, setColumns] = useState([])
|
||||||
|
|
||||||
const [well] = useWell()
|
const [well] = useWell()
|
||||||
|
|
||||||
const updateFlows = useCallback(() => invokeWebApiWrapperAsync(
|
const updateFlows = useCallback(() => invokeWebApiWrapperAsync(
|
||||||
async () => {
|
async () => {
|
||||||
const flows = await DrillFlowChartService.getByIdWell(well.id)
|
const flows = await ProcessMapService.getByIdWell(well.id)
|
||||||
setFlows(arrayOrDefault(flows))
|
setFlows(arrayOrDefault(flows))
|
||||||
},
|
},
|
||||||
setShowLoader,
|
setShowLoader,
|
||||||
`Не удалось загрузить режимно-технологическую карту`,
|
`Не удалось загрузить режимно-технологическую карту`,
|
||||||
{ actionName: 'Получение режимно-технологической карты', well }
|
{ actionName: 'Получение режимно-технологической карты', well },
|
||||||
), [well])
|
), [well])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
invokeWebApiWrapperAsync(
|
||||||
|
async () => {
|
||||||
|
const columns = await getColumns(well.id)
|
||||||
|
setColumns(columns)
|
||||||
|
},
|
||||||
|
setShowLoader,
|
||||||
|
`Не удалось загрузить список конструкций секций`,
|
||||||
|
{ actionName: 'Получение списка конструкций секций', well },
|
||||||
|
)
|
||||||
|
}, [well])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateFlows()
|
updateFlows()
|
||||||
}, [well])
|
}, [well])
|
||||||
|
|
||||||
const tableHandlers = useMemo(() => {
|
const tableHandlers = useMemo(() => {
|
||||||
const handlerProps = {
|
const handlerProps = {
|
||||||
service: DrillFlowChartService,
|
service: ProcessMapService,
|
||||||
setLoader: setShowLoader,
|
setLoader: setShowLoader,
|
||||||
onComplete: updateFlows,
|
onComplete: updateFlows,
|
||||||
permission: 'DrillFlowChart.edit',
|
permission: 'DrillFlowChart.edit',
|
||||||
|
@ -31,26 +31,20 @@ const dayWithoutNptRender = (_, row) => dayRender((row.day ?? 0) - (row.nptHours
|
|||||||
const generateColumns = (showNpt = false, categories = [], sectionTypes = []) => [
|
const generateColumns = (showNpt = false, categories = [], sectionTypes = []) => [
|
||||||
makeSelectColumn('Конструкция секции', 'idWellSectionType', sectionTypes, undefined, {
|
makeSelectColumn('Конструкция секции', 'idWellSectionType', sectionTypes, undefined, {
|
||||||
sorter: makeNumericSorter('idWellSectionType'),
|
sorter: makeNumericSorter('idWellSectionType'),
|
||||||
editable: true,
|
|
||||||
width: 160,
|
width: 160,
|
||||||
}),
|
}),
|
||||||
makeSelectColumn('Операция', 'idCategory', categories, undefined, {
|
makeSelectColumn('Операция', 'idCategory', categories, undefined, {
|
||||||
sorter: makeNumericSorter('idCategory'),
|
sorter: makeNumericSorter('idCategory'),
|
||||||
editable: true,
|
|
||||||
width: 200,
|
width: 200,
|
||||||
}),
|
}),
|
||||||
makeTextColumn('Доп. инфо', 'categoryInfo', null, null, null, { editable: true, width: 300, input: <TextArea/> }),
|
makeTextColumn('Доп. инфо', 'categoryInfo', null, null, null, { width: 300, input: <TextArea/> }),
|
||||||
makeColumn('Глубина забоя на начало, м', 'depthStart', makeNumericColumnOptions(2, 'depthStart')),
|
makeNumericColumn('Глубина забоя на начало, м', 'depthStart'),
|
||||||
makeColumn('Глубина забоя при завершении, м', 'depthEnd', makeNumericColumnOptions(2, 'depthEnd')),
|
makeNumericColumn('Глубина забоя при завершении, м', 'depthEnd'),
|
||||||
makeDateColumn('Время начала', 'dateStart', undefined, undefined, {
|
makeDateColumn('Время начала', 'dateStart', undefined, undefined, { width: 170, initialValue: moment().format() }),
|
||||||
editable: true,
|
makeNumericColumn('День', 'day', dayRender, undefined, 80),
|
||||||
width: 170,
|
showNpt && makeNumericColumn('День без НПВ', 'dayWithoutNpt', dayWithoutNptRender, undefined, 80),
|
||||||
initialValue: moment().format(),
|
makeNumericColumn('Часы', 'durationHours', undefined, undefined, 70),
|
||||||
}),
|
makeTextColumn('Комментарий', 'comment', null, null, null, { input: <TextArea /> }),
|
||||||
makeNumericColumn('День', 'day', null, null, dayRender, 80),
|
|
||||||
showNpt && makeNumericColumn('День без НПВ', 'dayWithoutNpt', null, null, dayWithoutNptRender, 80),
|
|
||||||
makeColumn('Часы', 'durationHours', { ...makeNumericColumnOptions(2, 'durationHours'), width: 70 }),
|
|
||||||
makeTextColumn('Комментарий', 'comment', null, null, null, { editable: true, input: <TextArea/> }),
|
|
||||||
].filter(Boolean)
|
].filter(Boolean)
|
||||||
|
|
||||||
export const WellOperationsEditor = memo(({ idType, showNpt, ...other }) => {
|
export const WellOperationsEditor = memo(({ idType, showNpt, ...other }) => {
|
||||||
|
@ -4,15 +4,15 @@ import { FilterOutlined } from '@ant-design/icons'
|
|||||||
|
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { makeDateColumn, makeNumericColumn, makeNumericRender, makeTextColumn, Table } from '@components/Table'
|
import { makeDateColumn, makeNumericColumn, makeTextColumn, Table } from '@components/Table'
|
||||||
|
|
||||||
import '@styles/pages/tvd.less'
|
import '@styles/pages/tvd.less'
|
||||||
|
|
||||||
export const columns = [
|
export const columns = [
|
||||||
makeTextColumn('Конструкция секции', 'wellSectionTypeName', null, null, null, { width: 140 }),
|
makeTextColumn('Конструкция секции', 'wellSectionTypeName', null, null, null, { width: 140 }),
|
||||||
makeNumericColumn('Глубина', 'depth', null, null, null, 80),
|
makeNumericColumn('Глубина', 'depth', undefined, undefined, 80),
|
||||||
makeDateColumn('Дата начала', 'date', false, undefined, { width: 90 }),
|
makeDateColumn('Дата начала', 'date', false, undefined, { width: 90 }),
|
||||||
makeNumericColumn('Длительность (ч)', 'durationHours', null, null, makeNumericRender(2), 120),
|
makeNumericColumn('Длительность (ч)', 'durationHours', undefined, undefined, 120),
|
||||||
makeTextColumn('Доп. инфо', 'categoryInfo', null, null, null),
|
makeTextColumn('Доп. инфо', 'categoryInfo', null, null, null),
|
||||||
makeTextColumn('Комментарий', 'comment'),
|
makeTextColumn('Комментарий', 'comment'),
|
||||||
]
|
]
|
||||||
|
@ -18,9 +18,9 @@ const tableColumns = [
|
|||||||
<div style={{ backgroundColor: d, padding: '5px 0' }} />
|
<div style={{ backgroundColor: d, padding: '5px 0' }} />
|
||||||
) }),
|
) }),
|
||||||
makeTextColumn('Название', 'category', undefined, undefined, undefined, { width: 300 }),
|
makeTextColumn('Название', 'category', undefined, undefined, undefined, { width: 300 }),
|
||||||
makeNumericColumn('Время, мин', 'minutesTotal', undefined, undefined, undefined, 100),
|
makeNumericColumn('Время, мин', 'minutesTotal', undefined, undefined, 100),
|
||||||
makeNumericColumn('Кол-во', 'count', undefined, undefined, (d) => d ? d.toString() : '---', 100),
|
makeNumericColumn('Кол-во', 'count', (d) => d ? d.toString() : '---', undefined, 100),
|
||||||
makeNumericColumn('Процент, %', 'percent', undefined, undefined, (d) => d ? d.toFixed(2) : '---', 100)
|
makeNumericColumn('Процент, %', 'percent', (d) => d ? d.toFixed(2) : '---', undefined, 100),
|
||||||
]
|
]
|
||||||
|
|
||||||
export const TLPie = memo(({ well }) => {
|
export const TLPie = memo(({ well }) => {
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
import { useState, useEffect, useCallback, memo, useMemo } from 'react'
|
|
||||||
|
|
||||||
import { useWell } from '@asb/context'
|
|
||||||
import {
|
|
||||||
EditableTable,
|
|
||||||
makeSelectColumn,
|
|
||||||
makeNumericSorter,
|
|
||||||
makeNumericAvgRange,
|
|
||||||
} from '@components/Table'
|
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
|
||||||
import { DrillParamsService, WellOperationService } from '@api'
|
|
||||||
import { arrayOrDefault } from '@utils'
|
|
||||||
|
|
||||||
export const getColumns = async (idWell) => {
|
|
||||||
let sectionTypes = await WellOperationService.getSectionTypes(idWell)
|
|
||||||
sectionTypes = Object.entries(sectionTypes).map(([id, value]) => ({
|
|
||||||
label: value,
|
|
||||||
value: id,
|
|
||||||
}))
|
|
||||||
|
|
||||||
return [
|
|
||||||
makeSelectColumn('Конструкция секции','idWellSectionType', sectionTypes, null, {
|
|
||||||
editable: true,
|
|
||||||
width: 160,
|
|
||||||
sorter: makeNumericSorter('idWellSectionType'),
|
|
||||||
}),
|
|
||||||
makeNumericAvgRange('Нагрузка, т', 'axialLoad', 1),
|
|
||||||
makeNumericAvgRange('Перепад давления, атм', 'pressure', 1),
|
|
||||||
makeNumericAvgRange('Момент на ВСП, кН·м', 'rotorTorque', 1),
|
|
||||||
makeNumericAvgRange('Обороты на ВСП, об/мин', 'rotorSpeed', 1),
|
|
||||||
makeNumericAvgRange('Расход, л/с', 'flow', 1),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const WellDrillParams = memo(() => {
|
|
||||||
const [params, setParams] = useState([])
|
|
||||||
const [showLoader, setShowLoader] = useState(false)
|
|
||||||
const [columns, setColumns] = useState([])
|
|
||||||
|
|
||||||
const [well] = useWell()
|
|
||||||
|
|
||||||
const updateParams = useCallback(async () => await invokeWebApiWrapperAsync(
|
|
||||||
async () => {
|
|
||||||
const params = arrayOrDefault(await DrillParamsService.getAll(well.id))
|
|
||||||
// Typescript против использования числа в качестве типа значения select
|
|
||||||
params.forEach((param) => param.idWellSectionType = `${param.idWellSectionType}`)
|
|
||||||
setParams(params)
|
|
||||||
},
|
|
||||||
setShowLoader,
|
|
||||||
`Не удалось загрузить список режимов бурения`,
|
|
||||||
{ actionName: 'Получение списка режимов бурения скважины', well }
|
|
||||||
), [well])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
setColumns(await getColumns(well.id))
|
|
||||||
await updateParams()
|
|
||||||
})()
|
|
||||||
}, [well.id, updateParams])
|
|
||||||
|
|
||||||
const recordParser = useCallback((record) => ({ ...record, idWell: well.id }), [well.id])
|
|
||||||
|
|
||||||
const tableHandlers = useMemo(() => {
|
|
||||||
const handlerProps = {
|
|
||||||
service: DrillParamsService,
|
|
||||||
setLoader: setShowLoader,
|
|
||||||
onComplete: updateParams,
|
|
||||||
permission: 'DrillParams.edit',
|
|
||||||
idWell: well.id,
|
|
||||||
idRecord: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
add: { ...handlerProps, action: 'insert', actionName: 'Добавление режима бурения', recordParser },
|
|
||||||
edit: { ...handlerProps, action: 'update', actionName: 'Редактирование режима бурения', recordParser },
|
|
||||||
delete: { ...handlerProps, action: 'delete', actionName: 'Удаление режима бурения', permission: 'DrillParams.delete' },
|
|
||||||
}
|
|
||||||
}, [well.id, updateParams, recordParser])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<LoaderPortal show={showLoader}>
|
|
||||||
<EditableTable
|
|
||||||
bordered
|
|
||||||
size={'small'}
|
|
||||||
columns={columns}
|
|
||||||
dataSource={params}
|
|
||||||
tableName={'well_drill_params'}
|
|
||||||
onRowAdd={tableHandlers.add}
|
|
||||||
onRowEdit={tableHandlers.edit}
|
|
||||||
onRowDelete={tableHandlers.delete}
|
|
||||||
pagination={false}
|
|
||||||
/>
|
|
||||||
</LoaderPortal>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
export default WellDrillParams
|
|
@ -3,22 +3,21 @@ import { useState, useEffect, memo } from 'react'
|
|||||||
import { useWell } from '@asb/context'
|
import { useWell } from '@asb/context'
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { Table, makeColumn, makeColumnsPlanFact, makeNumericRender } from '@components/Table'
|
import { Table, makeColumn, makeNumericRender, makeNumericColumnPlanFactOld } from '@components/Table'
|
||||||
import { calcDuration } from '@utils'
|
import { calcDuration } from '@utils'
|
||||||
import { OperationStatService } from '@api'
|
import { OperationStatService } from '@api'
|
||||||
|
|
||||||
|
|
||||||
const numericRender = makeNumericRender(2)
|
const numericRender = makeNumericRender(2)
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
makeColumn('Тип секции', 'sectionType'),
|
makeColumn('Тип секции', 'sectionType'),
|
||||||
makeColumnsPlanFact('Глубина, м' ,'wellDepth', { render: numericRender }),
|
makeNumericColumnPlanFactOld('Глубина, м', 'wellDepth', numericRender),
|
||||||
makeColumnsPlanFact('Часы' ,'duration', { render: numericRender }),
|
makeNumericColumnPlanFactOld('Часы', 'duration', numericRender),
|
||||||
makeColumnsPlanFact('МСП, м/ч' ,'rop', { render: numericRender }),
|
makeNumericColumnPlanFactOld('МСП, м/ч', 'rop', numericRender),
|
||||||
makeColumnsPlanFact('Рейсовая скорость, м/ч','routeSpeed', { render: numericRender }),
|
makeNumericColumnPlanFactOld('Рейсовая скорость, м/ч', 'routeSpeed', numericRender),
|
||||||
makeColumnsPlanFact('Подъем КНБК, м/ч' ,'bhaUpSpeed', { render: numericRender }),
|
makeNumericColumnPlanFactOld('Подъем КНБК, м/ч', 'bhaUpSpeed', numericRender),
|
||||||
makeColumnsPlanFact('Спуск КНБК, м/ч' ,'bhaDownSpeed', { render: numericRender }),
|
makeNumericColumnPlanFactOld('Спуск КНБК, м/ч', 'bhaDownSpeed', numericRender),
|
||||||
makeColumnsPlanFact('Спуск ОК, м/ч' ,'casingDownSpeed', { render: numericRender }),
|
makeNumericColumnPlanFactOld('Спуск ОК, м/ч', 'casingDownSpeed', numericRender),
|
||||||
]
|
]
|
||||||
|
|
||||||
export const WellSectionsStat = memo(() => {
|
export const WellSectionsStat = memo(() => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { lazy, memo, useCallback, useEffect, useMemo, useState } from 'react'
|
import { lazy, memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { Navigate, Route, Routes, useLocation, useParams } from 'react-router-dom'
|
import { Navigate, Route, Routes, useParams } from 'react-router-dom'
|
||||||
|
|
||||||
import { WellContext, RootPathContext, useRootPath, useLayoutProps, TopRightBlockContext } from '@asb/context'
|
import { WellContext, RootPathContext, useRootPath, useLayoutProps, TopRightBlockContext } from '@asb/context'
|
||||||
import { FastRunMenu } from '@components/FastRunMenu'
|
import { FastRunMenu } from '@components/FastRunMenu'
|
||||||
@ -22,7 +22,6 @@ const WellOperations = lazy(() => import('./WellOperations'))
|
|||||||
const DrillingProgram = lazy(() => import('./DrillingProgram'))
|
const DrillingProgram = lazy(() => import('./DrillingProgram'))
|
||||||
|
|
||||||
const Tvd = lazy(() => import('./WellOperations/Tvd'))
|
const Tvd = lazy(() => import('./WellOperations/Tvd'))
|
||||||
const WellDrillParams = lazy(() => import('./WellOperations/WellDrillParams'))
|
|
||||||
const DrillProcessFlow = lazy(() => import('./WellOperations/DrillProcessFlow'))
|
const DrillProcessFlow = lazy(() => import('./WellOperations/DrillProcessFlow'))
|
||||||
const WellSectionsStat = lazy(() => import('./WellOperations/WellSectionsStat'))
|
const WellSectionsStat = lazy(() => import('./WellOperations/WellSectionsStat'))
|
||||||
const WellOperationsEditorFact = lazy(() => import('./WellOperations/OperationEditor/Fact'))
|
const WellOperationsEditorFact = lazy(() => import('./WellOperations/OperationEditor/Fact'))
|
||||||
@ -45,8 +44,6 @@ const breadcrumb = makeMenuBreadcrumbItemsRender(menuItems, /^\/well\/[^\/#?]+\/
|
|||||||
const Well = memo(() => {
|
const Well = memo(() => {
|
||||||
const { idWell } = useParams()
|
const { idWell } = useParams()
|
||||||
|
|
||||||
const location = useLocation()
|
|
||||||
|
|
||||||
const [well, setWell] = useState({ id: idWell })
|
const [well, setWell] = useState({ id: idWell })
|
||||||
const [topRightBlock, setTopRightBlock] = useState()
|
const [topRightBlock, setTopRightBlock] = useState()
|
||||||
|
|
||||||
@ -130,7 +127,6 @@ const Well = memo(() => {
|
|||||||
<Route path={'plan'} element={<WellOperationsEditorPlan />} />
|
<Route path={'plan'} element={<WellOperationsEditorPlan />} />
|
||||||
<Route path={'fact'} element={<WellOperationsEditorFact />} />
|
<Route path={'fact'} element={<WellOperationsEditorFact />} />
|
||||||
<Route path={'drillProcessFlow'} element={<DrillProcessFlow />} />
|
<Route path={'drillProcessFlow'} element={<DrillProcessFlow />} />
|
||||||
<Route path={'params'} element={<WellDrillParams />} />
|
|
||||||
</Route>
|
</Route>
|
||||||
<Route path={'document/*'} element={<Documents />} />
|
<Route path={'document/*'} element={<Documents />} />
|
||||||
<Route path={'measure/*'} element={<Measure />} />
|
<Route path={'measure/*'} element={<Measure />} />
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.loader-content{
|
.loader-content{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
grid-column-start: 1;
|
grid-column-start: 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user