forked from ddrilling/asb_cloud_front
Merge branch 'dev' into feature/CF2-72-AdminPanel
This commit is contained in:
commit
df0fe53049
@ -16,10 +16,12 @@ const timePeriodCollection = [
|
|||||||
type PeriodPickerProps = {
|
type PeriodPickerProps = {
|
||||||
defaultValue?: number
|
defaultValue?: number
|
||||||
onChange?: (value: number) => void
|
onChange?: (value: number) => void
|
||||||
|
[other: string]: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PeriodPicker = ({ defaultValue = defaultPeriod, onChange }: PeriodPickerProps) => (
|
export const PeriodPicker = ({ defaultValue = defaultPeriod, onChange, ...other }: PeriodPickerProps) => (
|
||||||
<Select
|
<Select
|
||||||
|
{...other}
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
onChange={(value) => onChange?.(Number(value))}
|
onChange={(value) => onChange?.(Number(value))}
|
||||||
options={timePeriodCollection}
|
options={timePeriodCollection}
|
||||||
|
@ -32,7 +32,7 @@ export const EditableCell = ({
|
|||||||
className={formItemClass}
|
className={formItemClass}
|
||||||
rules={formItemRules ?? [{
|
rules={formItemRules ?? [{
|
||||||
required: isRequired,
|
required: isRequired,
|
||||||
message: `Please Input ${title}!`,
|
message: `Пожалуйста, введите ${title}!`,
|
||||||
}]}
|
}]}
|
||||||
initialValue={initialValue}
|
initialValue={initialValue}
|
||||||
>
|
>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
import { Select, Table as RawTable } from 'antd'
|
import { InputNumber, Select, Table as RawTable } from 'antd'
|
||||||
import { OptionsType } from 'rc-select/lib/interface'
|
import { OptionsType } from 'rc-select/lib/interface'
|
||||||
import { tryAddKeys } from './EditableTable'
|
import { tryAddKeys } from './EditableTable'
|
||||||
import { makeNumericSorter, makeStringSorter} from './sorters'
|
import { makeNumericSorter, makeStringSorter} from './sorters'
|
||||||
@ -143,7 +143,8 @@ export const makeNumericColumn = (
|
|||||||
onFilter: filterDelegate ? filterDelegate(dataIndex) : null,
|
onFilter: filterDelegate ? filterDelegate(dataIndex) : null,
|
||||||
sorter: makeNumericSorter(dataIndex),
|
sorter: makeNumericSorter(dataIndex),
|
||||||
width: width,
|
width: width,
|
||||||
render: renderDelegate??makeNumericRender(),
|
input: <InputNumber style={{ width: '100%' }}/>,
|
||||||
|
render: renderDelegate ?? makeNumericRender(),
|
||||||
align: 'right',
|
align: 'right',
|
||||||
...other
|
...other
|
||||||
})
|
})
|
||||||
|
@ -9,7 +9,7 @@ interface UserViewProps {
|
|||||||
|
|
||||||
export const UserView = ({ user } : UserViewProps) => (user ? (
|
export const UserView = ({ user } : UserViewProps) => (user ? (
|
||||||
<Tooltip title={(
|
<Tooltip title={(
|
||||||
<Grid columnGap='8px'>
|
<Grid style={{ columnGap: '8px' }}>
|
||||||
<GridItem row={1} col={1}>Фамилия:</GridItem>
|
<GridItem row={1} col={1}>Фамилия:</GridItem>
|
||||||
<GridItem row={1} col={2}>{user?.surname}</GridItem>
|
<GridItem row={1} col={2}>{user?.surname}</GridItem>
|
||||||
<GridItem row={2} col={1}>Имя:</GridItem>
|
<GridItem row={2} col={1}>Имя:</GridItem>
|
||||||
|
113
src/pages/TelemetryView/SetpointSender.jsx
Normal file
113
src/pages/TelemetryView/SetpointSender.jsx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
import { Select, Modal, Input, InputNumber } from 'antd'
|
||||||
|
import { SetpointsService } from '../../services/api'
|
||||||
|
import LoaderPortal from '../../components/LoaderPortal'
|
||||||
|
import { invokeWebApiWrapperAsync } from '../../components/factory'
|
||||||
|
import { makeNumericRender, EditableTable, makeNumericInput } from '../../components/Table'
|
||||||
|
import { PeriodPicker, defaultPeriod } from '../../components/PeriodPicker'
|
||||||
|
import { Grid, GridItem } from '../../components/Grid'
|
||||||
|
|
||||||
|
export const SetpointSender = ({ idWell, onClose, visible, setpointNames }) => {
|
||||||
|
const [expirePeriod, setExpirePeriod] = useState(defaultPeriod)
|
||||||
|
const [comment, setComment] = useState('')
|
||||||
|
const [setpoints, setSetpoints] = useState([])
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
|
const addingColumns = [
|
||||||
|
{
|
||||||
|
title: 'Наименование уставки',
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const onAdd = async (sp) => setSetpoints((prevSp) => {
|
||||||
|
sp.key = Date.now()
|
||||||
|
prevSp.push(sp)
|
||||||
|
return prevSp
|
||||||
|
})
|
||||||
|
|
||||||
|
const onEdit = async (sp) => setSetpoints((prevSp) => {
|
||||||
|
const idx = prevSp.findIndex((val) => val.key === sp.key)
|
||||||
|
prevSp[idx] = sp
|
||||||
|
return prevSp
|
||||||
|
})
|
||||||
|
|
||||||
|
const onDelete = async (sp) => setSetpoints((prevSp) => {
|
||||||
|
const idx = prevSp.findIndex((val) => val.key === sp.key)
|
||||||
|
prevSp.splice(idx, 1)
|
||||||
|
return prevSp
|
||||||
|
})
|
||||||
|
|
||||||
|
const onModalOk = () => invokeWebApiWrapperAsync(
|
||||||
|
async () => {
|
||||||
|
const setpointsObject = setpoints.reduce((obj, sp) => (obj[sp.name] = sp.value, obj), {})
|
||||||
|
const request = {
|
||||||
|
uploadDate: new Date(),
|
||||||
|
obsolescenceSec: expirePeriod,
|
||||||
|
setpoints: setpointsObject,
|
||||||
|
comment: comment
|
||||||
|
}
|
||||||
|
await SetpointsService.insert(idWell, request)
|
||||||
|
onClose(true)
|
||||||
|
},
|
||||||
|
setIsLoading,
|
||||||
|
`Не удалось отправить уставки по скважине "${idWell}"`
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
width={800}
|
||||||
|
title={'Рекомендовать уставки'}
|
||||||
|
visible={visible}
|
||||||
|
onCancel={onClose}
|
||||||
|
onOk={onModalOk}
|
||||||
|
okText={'Отправить'}
|
||||||
|
>
|
||||||
|
<LoaderPortal show={isLoading}>
|
||||||
|
<Grid>
|
||||||
|
<GridItem row={1} col={1}>Период актуальности рекомендаций:</GridItem>
|
||||||
|
<GridItem row={1} col={2}>
|
||||||
|
<PeriodPicker style={{ marginLeft: 'auto' }} onChange={setExpirePeriod} width={'100%'}/>
|
||||||
|
</GridItem>
|
||||||
|
|
||||||
|
<GridItem row={2} col={1}>Комментарий:</GridItem>
|
||||||
|
<GridItem row={3} col={1} colSpan={3}>
|
||||||
|
<Input.TextArea
|
||||||
|
rows={4}
|
||||||
|
onChange={(e) => setComment(e.target.value)}
|
||||||
|
value={comment}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</GridItem>
|
||||||
|
|
||||||
|
<GridItem row={4} col={1} colSpan={3}>
|
||||||
|
<EditableTable
|
||||||
|
bordered
|
||||||
|
columns={addingColumns}
|
||||||
|
dataSource={setpoints}
|
||||||
|
onRowAdd={onAdd}
|
||||||
|
onRowEdit={onEdit}
|
||||||
|
onRowDelete={onDelete}
|
||||||
|
pagination={false}
|
||||||
|
style={{ margin: '10px 0' }}
|
||||||
|
/>
|
||||||
|
</GridItem>
|
||||||
|
</Grid>
|
||||||
|
</LoaderPortal>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
77
src/pages/TelemetryView/SetpointViewer.jsx
Normal file
77
src/pages/TelemetryView/SetpointViewer.jsx
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import moment from 'moment'
|
||||||
|
import { memo } from 'react'
|
||||||
|
import { Modal, Input } from 'antd'
|
||||||
|
import { Table } from '../../components/Table'
|
||||||
|
import { UserView } from '../../components/UserView'
|
||||||
|
import { Grid, GridItem } from '../../components/Grid'
|
||||||
|
import { periodToString } from '../../utils/datetime'
|
||||||
|
|
||||||
|
export const setpointStatus = {
|
||||||
|
0: 'Неизвестно',
|
||||||
|
1: 'Ожидает отправки',
|
||||||
|
2: 'Отправлено',
|
||||||
|
3: 'Принято оператором',
|
||||||
|
4: 'Отклонено оператором',
|
||||||
|
5: 'Устарело',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getSetpointStatus = (id) => {
|
||||||
|
if (!id || Object.keys(setpointStatus).every((idx) => Number(idx) !== id))
|
||||||
|
return setpointStatus[0]
|
||||||
|
return setpointStatus[id]
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: 'Название', dataIndex: 'name' },
|
||||||
|
{ title: 'Значение', dataIndex: 'value' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export const SetpointViewer = memo(({ setpoint, visible, onClose, setpointNames }) => {
|
||||||
|
let date = moment(setpoint?.uploadDate).format('DD MMM YYYY, HH:mm:ss')
|
||||||
|
let setpoints = []
|
||||||
|
if (setpoint) {
|
||||||
|
setpoints = Object.keys(setpoint?.setpoints).map((name) => ({
|
||||||
|
name: setpointNames.find(spName => spName.value === name)?.label,
|
||||||
|
value: setpoint.setpoints[name]
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
width={800}
|
||||||
|
title={`Уставка от ${date}`}
|
||||||
|
onCancel={onClose}
|
||||||
|
visible={visible}
|
||||||
|
footer={null}
|
||||||
|
>
|
||||||
|
<Grid>
|
||||||
|
<GridItem row={1} col={1}>Дата рекомендаций:</GridItem>
|
||||||
|
<GridItem row={1} col={2}>{date}</GridItem>
|
||||||
|
|
||||||
|
<GridItem row={2} col={1}>Автор:</GridItem>
|
||||||
|
<GridItem row={2} col={2}><UserView user={setpoint?.author}/></GridItem>
|
||||||
|
|
||||||
|
<GridItem row={3} col={1}>Статус:</GridItem>
|
||||||
|
<GridItem row={3} col={2}>{getSetpointStatus(setpoint?.idState)}</GridItem>
|
||||||
|
|
||||||
|
<GridItem row={4} col={1}>Период актуальности рекомендаций:</GridItem>
|
||||||
|
<GridItem row={4} col={2}>{periodToString(setpoint?.obsolescenceSec)}</GridItem>
|
||||||
|
|
||||||
|
<GridItem row={5} col={1}>Комментарий:</GridItem>
|
||||||
|
<GridItem row={6} col={1} colSpan={3}>
|
||||||
|
<Input.TextArea rows={4} value={setpoint?.comment} readOnly />
|
||||||
|
</GridItem>
|
||||||
|
|
||||||
|
<GridItem row={7} col={1} colSpan={3}>
|
||||||
|
<Table
|
||||||
|
bordered
|
||||||
|
size={'small'}
|
||||||
|
dataSource={setpoints}
|
||||||
|
columns={columns}
|
||||||
|
pagination={false}
|
||||||
|
/>
|
||||||
|
</GridItem>
|
||||||
|
</Grid>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
})
|
@ -1,41 +1,25 @@
|
|||||||
import { Button, Input, Modal, Select } from 'antd'
|
import moment from 'moment'
|
||||||
import { useState } from 'react'
|
import { Button, Modal } from 'antd'
|
||||||
import { invokeWebApiWrapperAsync } from '../../components/factory'
|
import { useState, useEffect } from 'react'
|
||||||
|
import { Table } from '../../components/Table'
|
||||||
|
import { UserView } from '../../components/UserView'
|
||||||
import LoaderPortal from '../../components/LoaderPortal'
|
import LoaderPortal from '../../components/LoaderPortal'
|
||||||
import PeriodPicker, { defaultPeriod } from '../../components/PeriodPicker'
|
import { invokeWebApiWrapperAsync } from '../../components/factory'
|
||||||
import { EditableTable, makeNumericRender } from '../../components/Table'
|
import { makeStringCutter } from '../../utils/string'
|
||||||
import { SetpointsService } from '../../services/api'
|
import { SetpointsService } from '../../services/api'
|
||||||
|
import { SetpointSender } from './SetpointSender'
|
||||||
|
import { SetpointViewer, getSetpointStatus } from './SetpointViewer'
|
||||||
|
|
||||||
export const Setpoints = ({ idWell, ...other }) => {
|
export const Setpoints = ({ idWell, ...other }) => {
|
||||||
const [isModalShown, setIsModalShown] = useState(false)
|
const [isModalVisible, setIsModalVisible] = useState(false)
|
||||||
|
const [isSenderVisible, setIsSenderVisible] = useState(false)
|
||||||
|
const [isViewerVisible, setIsViewerVisible] = useState(false)
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [isUploading, setIsUploading] = useState(false)
|
|
||||||
const [setpointNames, setSetpointNames] = useState([])
|
|
||||||
const [setpoints, setSetpoints] = useState([])
|
const [setpoints, setSetpoints] = useState([])
|
||||||
const [comment, setComment] = useState('')
|
const [selected, setSelected] = useState(null)
|
||||||
const [expirePeriod, setExpirePeriod] = useState(defaultPeriod)
|
const [setpointNames, setSetpointNames] = useState([])
|
||||||
|
|
||||||
const columns = [
|
useEffect(() => invokeWebApiWrapperAsync(
|
||||||
{
|
|
||||||
title: 'Наименование установки',
|
|
||||||
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,
|
|
||||||
render: makeNumericRender(7),
|
|
||||||
align: 'right'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const onOpenClick = () => invokeWebApiWrapperAsync(
|
|
||||||
async () => {
|
async () => {
|
||||||
const names = await SetpointsService.getSetpointsNamesByIdWell(idWell)
|
const names = await SetpointsService.getSetpointsNamesByIdWell(idWell)
|
||||||
if (!names) throw Error('Setpoints not found')
|
if (!names) throw Error('Setpoints not found')
|
||||||
@ -44,84 +28,79 @@ export const Setpoints = ({ idWell, ...other }) => {
|
|||||||
value: spn.name,
|
value: spn.name,
|
||||||
tooltip: spn.comment
|
tooltip: spn.comment
|
||||||
})))
|
})))
|
||||||
setIsModalShown(true)
|
},
|
||||||
|
setIsLoading,
|
||||||
|
`Не удалось загрузить список имёт уставок по скважине "${idWell}"`
|
||||||
|
), [idWell])
|
||||||
|
|
||||||
|
const showMore = (id) => {
|
||||||
|
const selected = setpoints.find((sp) => sp.id === id)
|
||||||
|
setSelected(selected ?? {})
|
||||||
|
setIsViewerVisible(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const historyColumns = [
|
||||||
|
{ title: 'Дата', dataIndex: 'uploadDate', render: item => moment(item).format('DD MMM YYYY, HH:mm:ss') },
|
||||||
|
{ title: 'Автор', dataIndex: 'author', render: (user) => <UserView user={user} /> },
|
||||||
|
{ title: 'Комментарий', dataIndex: 'comment', render: makeStringCutter() },
|
||||||
|
{ title: 'Статус', dataIndex: 'idState', render: (id) => getSetpointStatus(parseInt(id)) },
|
||||||
|
{ dataIndex: 'id', render: (id) => <Button onClick={() => showMore(id)}>Подробнее</Button> },
|
||||||
|
]
|
||||||
|
|
||||||
|
const updateTable = () => invokeWebApiWrapperAsync(
|
||||||
|
async () => {
|
||||||
|
const setpoints = await SetpointsService.getByIdWell(idWell)
|
||||||
|
setSetpoints(setpoints)
|
||||||
},
|
},
|
||||||
setIsLoading,
|
setIsLoading,
|
||||||
`Не удалось загрузить список для скважины "${idWell}"`
|
`Не удалось загрузить список для скважины "${idWell}"`
|
||||||
)
|
)
|
||||||
|
|
||||||
const onModalOk = () => invokeWebApiWrapperAsync(
|
useEffect(updateTable, [idWell])
|
||||||
async () => {
|
|
||||||
// eslint-disable-next-line no-sequences
|
|
||||||
const setpointsObject = setpoints.reduce((obj, sp) => (obj[sp.name] = sp.value, obj), {})
|
|
||||||
const request = {
|
|
||||||
uploadDate: new Date(),
|
|
||||||
obsolescenceSec: expirePeriod,
|
|
||||||
setpoints: setpointsObject,
|
|
||||||
comment: comment
|
|
||||||
}
|
|
||||||
await SetpointsService.insert(idWell, request)
|
|
||||||
setIsModalShown(false)
|
|
||||||
},
|
|
||||||
setIsUploading,
|
|
||||||
`Не удалось отправить рекомендации по скважине "${idWell}"`
|
|
||||||
)
|
|
||||||
|
|
||||||
const onAdd = async (setpoint) => setSetpoints((prevSetpoints) => {
|
const onSenderClose = (pushed) => {
|
||||||
setpoint.key = Date.now()
|
if (pushed) updateTable()
|
||||||
prevSetpoints.push(setpoint)
|
setIsSenderVisible(false)
|
||||||
return prevSetpoints
|
}
|
||||||
})
|
|
||||||
|
|
||||||
const onEdit = async (setpoint) => setSetpoints((prevSetpoints) => {
|
|
||||||
const idx = prevSetpoints.findIndex((val) => val.key === setpoint.key)
|
|
||||||
prevSetpoints[idx] = setpoint
|
|
||||||
return prevSetpoints
|
|
||||||
})
|
|
||||||
|
|
||||||
const onDelete = async (setpoint) => setSetpoints((prevSetpoints) => {
|
|
||||||
const idx = prevSetpoints.findIndex((val) => val.key === setpoint.key)
|
|
||||||
prevSetpoints.splice(idx, 1)
|
|
||||||
return prevSetpoints
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...other}>
|
<div {...other}>
|
||||||
<Button onClick={onOpenClick} loading={isLoading}>
|
<Button onClick={() => setIsModalVisible(true)} loading={isLoading}>
|
||||||
Рекомендовать установки
|
Рекомендованные уставки
|
||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal
|
||||||
width={800}
|
width={1200}
|
||||||
title={'Рекомендация установок'}
|
title={'Рекомендованные уставки'}
|
||||||
visible={isModalShown}
|
visible={isModalVisible}
|
||||||
onCancel={() => setIsModalShown(false)}
|
onCancel={() => setIsModalVisible(false)}
|
||||||
onOk={onModalOk}
|
footer={
|
||||||
okText={'Отправить'}
|
<Button onClick={() => setIsSenderVisible(true)}>
|
||||||
|
Рекомендовать
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<LoaderPortal show={isUploading}>
|
<LoaderPortal show={isLoading}>
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
<Table
|
||||||
Период актуальности рекомендаций:
|
size={'small'}
|
||||||
<PeriodPicker onChange={setExpirePeriod} />
|
|
||||||
</div>
|
|
||||||
<EditableTable
|
|
||||||
bordered
|
bordered
|
||||||
columns={columns}
|
columns={historyColumns}
|
||||||
dataSource={setpoints}
|
dataSource={setpoints}
|
||||||
onRowAdd={onAdd}
|
|
||||||
onRowEdit={onEdit}
|
|
||||||
onRowDelete={onDelete}
|
|
||||||
pagination={false}
|
pagination={false}
|
||||||
style={{ margin: '10px 0' }}
|
|
||||||
/>
|
|
||||||
Комментарий:
|
|
||||||
<Input.TextArea
|
|
||||||
rows={4}
|
|
||||||
onChange={(e) => setComment(e.value)}
|
|
||||||
value={comment}
|
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</LoaderPortal>
|
</LoaderPortal>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<SetpointSender
|
||||||
|
idWell={idWell}
|
||||||
|
setpointNames={setpointNames}
|
||||||
|
visible={isSenderVisible}
|
||||||
|
onClose={onSenderClose}
|
||||||
|
/>
|
||||||
|
<SetpointViewer
|
||||||
|
setpointNames={setpointNames}
|
||||||
|
setpoint={selected}
|
||||||
|
visible={isViewerVisible}
|
||||||
|
onClose={() => setIsViewerVisible(false)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ const blockHeightGroup = [
|
|||||||
color: '#333',
|
color: '#333',
|
||||||
showLabels: true
|
showLabels: true
|
||||||
}, {
|
}, {
|
||||||
label: 'wellDepth',
|
label: 'Глубина скважины',
|
||||||
units: 'м',
|
units: 'м',
|
||||||
xAccessorName: 'wellDepth',
|
xAccessorName: 'wellDepth',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -59,7 +59,7 @@ const blockHeightGroup = [
|
|||||||
showLabels: true,
|
showLabels: true,
|
||||||
showLine: true
|
showLine: true
|
||||||
}, {
|
}, {
|
||||||
label: 'flowLimits',
|
label: 'Предел расхода',
|
||||||
units: 'л/с',
|
units: 'л/с',
|
||||||
xAccessorName: 'flow',
|
xAccessorName: 'flow',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -77,7 +77,7 @@ const blockSpeedGroup = [
|
|||||||
color: '#0a0',
|
color: '#0a0',
|
||||||
showLabels: true,
|
showLabels: true,
|
||||||
}, {
|
}, {
|
||||||
label: 'blockSpeedSp',
|
label: 'Скорость заданная',
|
||||||
units: 'м/ч',
|
units: 'м/ч',
|
||||||
xAccessorName: 'blockSpeedSp',
|
xAccessorName: 'blockSpeedSp',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -96,7 +96,7 @@ const pressureGroup = [
|
|||||||
color: '#c00',
|
color: '#c00',
|
||||||
showLabels: true
|
showLabels: true
|
||||||
}, {
|
}, {
|
||||||
label: 'pressureSp',
|
label: 'Давление заданное',
|
||||||
units: 'атм',
|
units: 'атм',
|
||||||
xAccessorName: 'pressureSp',
|
xAccessorName: 'pressureSp',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -104,7 +104,7 @@ const pressureGroup = [
|
|||||||
footer: 'SP',
|
footer: 'SP',
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'pressureIdle',
|
label: 'Давление ХХ',
|
||||||
units: 'атм',
|
units: 'атм',
|
||||||
xAccessorName: 'pressureIdle',
|
xAccessorName: 'pressureIdle',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -112,7 +112,7 @@ const pressureGroup = [
|
|||||||
footer: 'IDLE',
|
footer: 'IDLE',
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'pressureDeltaLimitMax',
|
label: 'Перепад давления максимальный',
|
||||||
units: 'атм',
|
units: 'атм',
|
||||||
xAccessorName: 'pressureDeltaLimitMax',
|
xAccessorName: 'pressureDeltaLimitMax',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -120,7 +120,7 @@ const pressureGroup = [
|
|||||||
footer: true,
|
footer: true,
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'pressureLimits',
|
label: 'Предел давления заданный',
|
||||||
units: 'атм',
|
units: 'атм',
|
||||||
xAccessorName: 'pressure',
|
xAccessorName: 'pressure',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -138,7 +138,7 @@ const axialLoadGroup = [
|
|||||||
color: '#00a',
|
color: '#00a',
|
||||||
showLabels: true
|
showLabels: true
|
||||||
}, {
|
}, {
|
||||||
label: 'axialLoadSp',
|
label: 'Осевая нагрузка заданная',
|
||||||
units: 'т',
|
units: 'т',
|
||||||
xAccessorName: 'axialLoadSp',
|
xAccessorName: 'axialLoadSp',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -146,7 +146,7 @@ const axialLoadGroup = [
|
|||||||
footer: 'SP',
|
footer: 'SP',
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'axialLoadLimitMax',
|
label: 'Осевая нагрузка максимальная',
|
||||||
units: 'т',
|
units: 'т',
|
||||||
xAccessorName: 'axialLoadLimitMax',
|
xAccessorName: 'axialLoadLimitMax',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -154,7 +154,7 @@ const axialLoadGroup = [
|
|||||||
footer: true,
|
footer: true,
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'axialLoadLimits',
|
label: 'Пределы осевой нагрузки',
|
||||||
units: 'т',
|
units: 'т',
|
||||||
xAccessorName: 'axialLoad',
|
xAccessorName: 'axialLoad',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -172,7 +172,7 @@ const hookWeightGroup = [
|
|||||||
color: '#0aa',
|
color: '#0aa',
|
||||||
showLabels: true
|
showLabels: true
|
||||||
}, {
|
}, {
|
||||||
label: 'hookWeightIdle',
|
label: 'Вес инструмента ХХ',
|
||||||
units: 'т',
|
units: 'т',
|
||||||
xAccessorName: 'hookWeightIdle',
|
xAccessorName: 'hookWeightIdle',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -180,7 +180,7 @@ const hookWeightGroup = [
|
|||||||
footer: 'IDLE',
|
footer: 'IDLE',
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'hookWeightLimitMin',
|
label: 'Вес инструмента минимальный',
|
||||||
units: 'т',
|
units: 'т',
|
||||||
xAccessorName: 'hookWeightLimitMin',
|
xAccessorName: 'hookWeightLimitMin',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -188,7 +188,7 @@ const hookWeightGroup = [
|
|||||||
footer: true,
|
footer: true,
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'hookWeightLimitMax',
|
label: 'Вес инструмента максимальный',
|
||||||
units: 'т',
|
units: 'т',
|
||||||
xAccessorName: 'hookWeightLimitMax',
|
xAccessorName: 'hookWeightLimitMax',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -203,7 +203,7 @@ const hookWeightGroup = [
|
|||||||
color: '#aa0',
|
color: '#aa0',
|
||||||
showLabels: true
|
showLabels: true
|
||||||
}, {
|
}, {
|
||||||
label: 'rotorSpeedLimits',
|
label: 'Скорость вращения ВСП максимальная',
|
||||||
units: 'об/мин',
|
units: 'об/мин',
|
||||||
xAccessorName: 'rotorSpeed',
|
xAccessorName: 'rotorSpeed',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -237,7 +237,7 @@ const rotorTorqueGroup = [
|
|||||||
footer: 'IDLE',
|
footer: 'IDLE',
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'rotorTorqueLimitMax',
|
label: 'Момент максимальный',
|
||||||
units: 'кН·м',
|
units: 'кН·м',
|
||||||
xAccessorName: 'rotorTorqueLimitMax',
|
xAccessorName: 'rotorTorqueLimitMax',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
@ -245,7 +245,7 @@ const rotorTorqueGroup = [
|
|||||||
footer: true,
|
footer: true,
|
||||||
dash
|
dash
|
||||||
}, {
|
}, {
|
||||||
label: 'rotorTorqueLimits',
|
label: 'Ограничения момента',
|
||||||
units: 'кН·м',
|
units: 'кН·м',
|
||||||
xAccessorName: 'rotorTorque',
|
xAccessorName: 'rotorTorque',
|
||||||
yAccessorName: 'date',
|
yAccessorName: 'date',
|
||||||
|
10
src/utils/datetime.ts
Normal file
10
src/utils/datetime.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export const periodToString = (time?: number) => {
|
||||||
|
if (!time) return '00:00:00'
|
||||||
|
const hours = Math.floor(time / 3600)
|
||||||
|
const minutes = Math.floor(time / 60 - hours * 60)
|
||||||
|
const seconds = Math.floor(time - hours * 3600 - minutes * 60)
|
||||||
|
|
||||||
|
const toFixed = (num: number) => `${num}`.padStart(2, '0')
|
||||||
|
|
||||||
|
return `${toFixed(hours)}:${toFixed(minutes)}:${toFixed(seconds)}`
|
||||||
|
}
|
8
src/utils/string.ts
Normal file
8
src/utils/string.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export const makeStringCutter = (maxLength = 100, separator = ' ', suffix = '...') => (comment?: string) => {
|
||||||
|
if (!comment || comment.length < maxLength)
|
||||||
|
return comment
|
||||||
|
let lastSep = comment.lastIndexOf(separator, maxLength)
|
||||||
|
if (lastSep < 0)
|
||||||
|
return comment.substring(0, maxLength - suffix.length) + suffix
|
||||||
|
return comment.substring(0, lastSep)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user