diff --git a/src/components/ActiveMessagesOnline.jsx b/src/components/ActiveMessagesOnline.jsx new file mode 100644 index 0000000..6b33a61 --- /dev/null +++ b/src/components/ActiveMessagesOnline.jsx @@ -0,0 +1,84 @@ +import {useState, useEffect} from 'react' +import {MessageService} from '../services/api' +import {Subscribe} from '../services/signalr' +import moment from 'moment' +import notify from "../components/notify" +import '../styles/message.css' +import {Table} from "antd"; +import LoaderPortal from "./LoaderPortal" + +// Словарь категорий для строк таблицы +const categoryDictionary = { + 1: {title: 'Важное'}, + 2: {title: 'Предупреждение'}, + 3: {title: 'Информация'}, +} + +// Конфигурация таблицы +const columns = [ + { + title: 'Дата', + dataIndex: 'date', + render: (item) => moment(item).format('DD MMM YYYY, HH:MM:ss'), + sorter: (a, b) => new Date(b.date) - new Date(a.date), + sortDirections: ['descend', 'ascend'], + }, + { + title: 'Категория', + dataIndex: 'categoryId', + render: (_, item) => categoryDictionary[item.categoryId].title, + style: (_, item) => categoryDictionary[item.categoryId].style, + sorter: (a, b) => a.categoryId - b.categoryId, + sortDirections: ['descend', 'ascend'], + }, + { + title: 'Сообщение', + dataIndex: 'message', + onFilter: (value, record) => record.name.indexOf(value) === 0, + }, + { + title: 'Пользователь', + dataIndex: 'user', + }, +]; + +export default function ActiveMessagesOnline({idWell}) { + const [messages, setMessages] = useState([]) + const [loader, setLoader] = useState(false) + + const handleReceiveMessages = (messages) => { + if (messages) { + setMessages(messages.items.splice(0, 4)) + } + } + + useEffect(() => { + const update = async () => { + setLoader(true) + try { + const messages = await MessageService.getMessage(idWell) + handleReceiveMessages(messages) + } + catch (ex) { + notify(`Не удалось загрузить сообщения по скважине "${idWell}"`, 'error') + console.log(ex) + } + setLoader(false) + return Subscribe('hubs/telemetry','ReceiveMessages', `well_${idWell}`, handleReceiveMessages) + } + update() + }, [idWell]) + + return ( + `event_message_${record.categoryId} event_message`} + className={'message_table'} + size={'small'} + pagination={false} + rowKey={(record) => record.id} + /> + ) +} \ No newline at end of file diff --git a/src/components/Column.jsx b/src/components/Column.jsx new file mode 100644 index 0000000..19e5af3 --- /dev/null +++ b/src/components/Column.jsx @@ -0,0 +1,45 @@ +import {Display} from "./Display"; +import {ChartTimeOnline} from "./charts/ChartTimeOnline"; +import {ChartTimeOnlineFooter} from "./ChartTimeOnlineFooter"; + +export const Column = ({lineGroup, data, interval, showBorder}) => { + let lines = [lineGroup.linePv] + + if (lineGroup.lineSp) + lines.push(lineGroup.lineSp) + + if (lineGroup.lineOther) + lines.push(lineGroup.lineOther) + + if (lineGroup.lineAvg) + lines.push(lineGroup.lineAvg) + + if (lineGroup.lineMax) + lines.push(lineGroup.lineMax) + + let dataLast = null + let pv = null + if (data?.length > 0) { + dataLast = data[data.length - 1]; + if (lineGroup.linePv) + pv = dataLast[lineGroup.linePv?.xAccessorName] + } + + return ( + <> +
+ +
+ + + ) +} \ No newline at end of file diff --git a/src/components/factory.ts b/src/components/factory.ts new file mode 100644 index 0000000..e53dbaa --- /dev/null +++ b/src/components/factory.ts @@ -0,0 +1,26 @@ +export const makeColumn = (title:string, key:string, other?:any) => ({ + title: title, + key: key, + dataIndex: key, + ...other, +}) + +export const makeColumnsPlanFact = (title:string, keyPlan:string, keyFact?:string, groupOther?:any) => +{ + let keyPlanLocal = keyPlan + let keyFactLocal = keyFact ?? '' + + if(!keyFact){ + keyPlanLocal = keyPlan + 'Plan' + keyFactLocal = keyPlan + 'Fact' + } + + return { + title: title, + ...groupOther, + children: [ + makeColumn('план', keyPlanLocal), + makeColumn('факт', keyFactLocal), + ] + } +} \ No newline at end of file diff --git a/src/pages/Deposit.jsx b/src/pages/Deposit.jsx index 26818fb..d79b3e2 100644 --- a/src/pages/Deposit.jsx +++ b/src/pages/Deposit.jsx @@ -31,7 +31,7 @@ export default function Deposit() { const [showLoader, setShowLoader] = useState(false) useEffect(()=>{ - const updateClusters = async()=>{ + const update = async()=>{ setShowLoader(true) try{ const data = await ClusterService.getClusters() @@ -43,7 +43,7 @@ export default function Deposit() { } setShowLoader(false) } - updateClusters() + update() }, []) const viewParams = calcViewParams(clustersData) diff --git a/src/pages/TelemetryView.jsx b/src/pages/TelemetryView.jsx index e53d613..0492c36 100644 --- a/src/pages/TelemetryView.jsx +++ b/src/pages/TelemetryView.jsx @@ -1,18 +1,16 @@ import {useState, useEffect} from 'react' import {useParams} from 'react-router-dom' -import {Row, Col, Select, Table} from 'antd' -import {ChartTimeOnline} from '../components/charts/ChartTimeOnline' +import {Row, Col, Select} from 'antd' import LoaderPortal from '../components/LoaderPortal' -import {ChartTimeOnlineFooter} from '../components/ChartTimeOnlineFooter' +import {Column} from '../components/Column' import {CustomColumn} from '../components/CustomColumn' import {UserOfWells} from '../components/UserOfWells' -import {ModeDisplay} from '../components/ModeDisplay' -import {Display} from '../components/Display' -import moment from 'moment' import {Subscribe} from '../services/signalr' -import {DataService, MessageService} from '../services/api' +import {DataService} from '../services/api' import '../styles/message.css' import notify from "../components/notify" +import {ModeDisplay} from "../components/ModeDisplay" +import ActiveMessagesOnline from '../components/ActiveMessagesOnline' const {Option} = Select @@ -21,8 +19,16 @@ const dash = [7, 3] const blockHeightGroup = { label: "Высота блока", yDisplay: false, - linePv: { label: "blockPosition", units: 'м', xAccessorName: "blockPosition", yAccessorName: "date", color: '#333' }, - lineOther: { label: "wellDepth", units: 'м', xAccessorName: "wellDepth", yAccessorName: "date", color: '#333', showLine: false, xConstValue:30 }, + linePv: {label: "blockPosition", units: 'м', xAccessorName: "blockPosition", yAccessorName: "date", color: '#333'}, + lineOther: { + label: "wellDepth", + units: 'м', + xAccessorName: "wellDepth", + yAccessorName: "date", + color: '#333', + showLine: false, + xConstValue: 30 + }, } const blockSpeedGroup = { @@ -114,83 +120,6 @@ const rotorTorqueGroup = { const paramsGroups = [blockHeightGroup, blockSpeedGroup, pressureGroup, axialLoadGroup, hookWeightGroup, rotorTorqueGroup] -export const Column = ({lineGroup, data, interval, showBorder}) => { - let lines = [lineGroup.linePv] - - if (lineGroup.lineSp) - lines.push(lineGroup.lineSp) - - if (lineGroup.lineOther) - lines.push(lineGroup.lineOther) - - if (lineGroup.lineAvg) - lines.push(lineGroup.lineAvg) - - if (lineGroup.lineMax) - lines.push(lineGroup.lineMax) - - let dataLast = null - let pv = null - if (data?.length > 0) { - dataLast = data[data.length - 1]; - if (lineGroup.linePv) - pv = dataLast[lineGroup.linePv?.xAccessorName] - } - - return ( - <> -
- -
- - - ) -} - -// Словарь категорий для строк таблицы -const categoryDictionary = { - 1: {title: 'Важное'}, - 2: {title: 'Предупреждение'}, - 3: {title: 'Информация'}, -} - -// Конфигурация таблицы -const columns = [ - { - title: 'Дата', - dataIndex: 'date', - render: (item) => moment(item).format('DD MMM YYYY, HH:MM:ss'), - sorter: (a, b) => new Date(b.date) - new Date(a.date), - sortDirections: ['descend', 'ascend'], - }, - { - title: 'Категория', - dataIndex: 'categoryId', - render: (_, item) => categoryDictionary[item.categoryId].title, - style: (_, item) => categoryDictionary[item.categoryId].style, - sorter: (a, b) => a.categoryId - b.categoryId, - sortDirections: ['descend', 'ascend'], - }, - { - title: 'Сообщение', - dataIndex: 'message', - onFilter: (value, record) => record.name.indexOf(value) === 0, - }, - { - title: 'Пользователь', - dataIndex: 'user', - }, -]; - const timePeriodCollection = [ {value: '60', label: '1 минута'}, {value: '300', label: '5 минут'}, @@ -208,7 +137,6 @@ export default function TelemetryView(props) { let {id} = useParams() const [saubData, setSaubData] = useState([]) const [chartInterval, setChartInterval] = useState(defaultChartInterval) - const [messages, setMessages] = useState([]) const [loader, setLoader] = useState(false) @@ -220,45 +148,29 @@ export default function TelemetryView(props) { } } - const handleReceiveMessages = (messages) => { - if (messages) { - setMessages(messages.items.splice(0, 4)) - } - } - useEffect(() => { - setLoader(true) - let promiseData = DataService.getData(id) - .then(handleReceiveDataSaub) - .catch((ex) => { - notify(`Не удалось загрузить данные по скважине "${id}"`, 'error') + const update = async () => { + setLoader(true) + try { + const data = await DataService.getData(id) + handleReceiveDataSaub(data) + } catch (ex) { + notify(`Не удалось получить данные по скважине "${id}"`, 'error') console.log(ex) - }) - - let promiseMessages = MessageService.getMessage(id) - .then(handleReceiveMessages) - .catch((ex) => { - notify(`Не удалось загрузить сообщения по скважине "${id}"`, 'error') - console.log(ex) - }) - - Promise.all([promiseData, promiseMessages]).then(()=>setLoader(false)) - - let unSubscribeDataSaubHub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub) - let unSubscribeMessagesHub = Subscribe('hubs/telemetry','ReceiveMessages', `well_${id}`, handleReceiveMessages) - return () => { - unSubscribeDataSaubHub() - unSubscribeMessagesHub() + } + setLoader(false) + return Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub) } - }, [id]); + update() + }, [id]) useEffect(() => { setLoader(true) DataService.getData(id, null, chartInterval) .then(handleReceiveDataSaub) .catch(error => console.error(error)) - .finally(()=>setLoader(false)) - }, [id, chartInterval]); + .finally(() => setLoader(false)) + }, [id, chartInterval]) const colSpan = 24 / (paramsGroups.length) @@ -287,20 +199,12 @@ export default function TelemetryView(props) { {paramsGroups.map((group, index) =>
- + )} -
`event_message_${record.categoryId} event_message`} - className={'message_table'} - size={'small'} - pagination={false} - rowKey={(record) => record.id} - /> + ) } \ No newline at end of file diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index f8ac02b..9ec271b 100644 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -9,6 +9,7 @@ import WellAnalysis from "../pages/WellAnalysis"; import TelemetryView from "../pages/TelemetryView"; import MenuDocuments from "../components/MenuDocuments"; import WellStat from "./WellStat"; +import MenuDocuments from "../components/MenuDocuments"; const { Content } = Layout