diff --git a/public/favicon.ico b/public/favicon.ico index a11777c..0427b29 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/index.html b/public/index.html index aa069f2..9b38967 100644 --- a/public/index.html +++ b/public/index.html @@ -10,34 +10,11 @@ content="Web site created using create-react-app" /> - - - React App + АСБ Vision
- diff --git a/public/logo192.png b/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/public/logo192.png and /dev/null differ diff --git a/public/logo512.png b/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/public/logo512.png and /dev/null differ diff --git a/src/components/ArchiveColumn.jsx b/src/components/ArchiveColumn.jsx index d2f9b1a..60c5858 100644 --- a/src/components/ArchiveColumn.jsx +++ b/src/components/ArchiveColumn.jsx @@ -1,14 +1,14 @@ import { useState, useEffect } from 'react'; import { Button, Select, Tag, Popover, Row, Tooltip } from 'antd'; import { ChartTimeArchive } from './charts/ChartTimeArchive'; -//import { SlidersOutlined } from '@ant-design/icons'; +import { DeleteOutlined } from '@ant-design/icons'; const { Option } = Select; const linesCollection = [ { label: "Глубина забоя", xAccessorName: "wellDepth", color: '#f00' }, { label: "Положение инструмента", xAccessorName: "bitDepth", color: '#ff0' }, - { label: "Высота талевого блока", xAccessorName: "blockPosition", color: '#f0f' }, + { label: "Положение талевого блока", xAccessorName: "blockPosition", color: '#f0f' }, { label: "Талевый блок. Мин положение", xAccessorName: "blockPositionMin", color: '#0ff' }, { label: "Талевый блок. Макс положение", xAccessorName: "blockPositionMax", color: '#0f0' }, { label: "Скорость талевого блока", xAccessorName: "blockSpeed", color: '#00f' }, @@ -54,7 +54,6 @@ const tagRender = ({ label, value, closable, onClose }) =>{ let color = linesCollection.find(l=>l.xAccessorName === value)?.color return ( {select} - + diff --git a/src/components/WellTreeSelector.jsx b/src/components/WellTreeSelector.jsx index d78c03a..7ff8615 100644 --- a/src/components/WellTreeSelector.jsx +++ b/src/components/WellTreeSelector.jsx @@ -4,6 +4,7 @@ import { WellService } from '../services/api' import Loader from '../components/Loader' import { TreeSelect } from 'antd' import { useHistory } from 'react-router-dom' +import notify from './notify' const groupBy = (table, ...keys) => { let key = keys[0] @@ -49,6 +50,7 @@ export default function WellTreeSelector(props) { setWellsTree(wellsTree) } catch (e) { + notify('Не удалось загрузить список скважин', 'error') console.error(`${e.message}`); } setLoader(false) @@ -65,11 +67,10 @@ export default function WellTreeSelector(props) { return ( <> | any, } -const timeUnitByInterval = (intervalSec:number):String =>{ - if(intervalSec < 24*60*60) +export type TimeParams = { + unit: String + stepSize: number +} + +const linesPerInterval = 32 + +const timeUnitByInterval = (intervalSec:number):String => { + if(intervalSec <= 60) + return 'millisecond' + + if(intervalSec <= 32*60) return 'second' - if(intervalSec < 30*24*60*60) - return 'day' + if(intervalSec <= 32*60*60) + return 'minute' - if(intervalSec < 365*24*60*60) + if(intervalSec <= 32*12*60*60) + return 'hour' + + if(intervalSec <= 32*24*60*60) + return 'day' + + if(intervalSec <= 32*7*24*60*60) return 'week' + + if(intervalSec <= 32*30.4375*24*60*60) + return 'month' + + if(intervalSec <= 32*121.75*24*60*60) + return 'quarter' else return 'year' } +const timeParamsByInterval = (intervalSec:number) :TimeParams => { + let stepSize = intervalSec + let unit = timeUnitByInterval(intervalSec) + + switch(unit){ + case "millisecond": + stepSize *= 1000 + break; + case "second": + //stepSize *= 1 + break; + case "minute": + stepSize /= 60 + break; + case "hour": + stepSize /= 60*60 + break; + case "day": + stepSize /= 24*60*60 + break; + case "week": + stepSize /= 7*24*60*60 + break; + case "month": + stepSize /= 30*24*60*60 + break; + case "quarter": + stepSize /= 91*24*60*60 + break; + case "year": + stepSize /= 365.25*24*60*60 + break; + } + + stepSize = Math.round(stepSize/linesPerInterval) + stepSize = stepSize > 0 ? stepSize : 1; + return {unit, stepSize} +} + export const ChartTimeBase: React.FC = ({options, dataParams}) => { const chartRef = useRef(null) const [chart, setChart] = useState() @@ -130,18 +191,19 @@ export const ChartTimeBase: React.FC = ({options, dataParams chart.data = dataParams.data chart.options.aspectRatio = options?.aspectRatio - if(dataParams.yStart){ let interval = Number(dataParams.yInterval ?? 600) let start = new Date(dataParams.yStart) let end = new Date(dataParams.yStart) - end.setSeconds(end.getSeconds() + interval) + end.setSeconds(end.getSeconds() + interval) + let {unit, stepSize} = timeParamsByInterval(interval) + if(chart.options.scales?.y){ chart.options.scales.y.max = end.getTime() chart.options.scales.y.min = start.getTime() chart.options.scales.y.ticks.display = dataParams.displayLabels ?? true - chart.options.scales.y.time.unit = timeUnitByInterval(interval) - chart.options.scales.y.time.stepSize = Math.round(interval/32) + chart.options.scales.y.time.unit = unit + chart.options.scales.y.time.stepSize = stepSize } } diff --git a/src/components/Notification.jsx b/src/components/notify.js similarity index 86% rename from src/components/Notification.jsx rename to src/components/notify.js index 1608951..e06ae0b 100644 --- a/src/components/Notification.jsx +++ b/src/components/notify.js @@ -11,9 +11,9 @@ const typeDictionary = { * @param body string или ReactNode * @param type для параметра типа. Допустимые значение 'error', 'warning', 'info' */ -export default function Notification(body, type='info'){ +export default function notify(body, type='info'){ - notification.info({ + notification[type]({ description: body, message: typeDictionary[type], type, diff --git a/src/pages/Archive.jsx b/src/pages/Archive.jsx index 036da4b..d3497e3 100644 --- a/src/pages/Archive.jsx +++ b/src/pages/Archive.jsx @@ -12,6 +12,7 @@ import locale from 'antd/lib/locale/ru_RU' import {generateUUID} from '../services/UidGenerator' import { ArchiveColumn } from '../components/ArchiveColumn' import moment from 'moment' +import notify from '../components/notify' const { RangePicker } = DatePicker; @@ -96,7 +97,10 @@ export default function Archive() { DataService.getData(id, startDate, interval, 2048) .then(handleReceiveDataSaub) - .catch(error => console.error(error)) + .catch(error => { + notify(`Не удалось загрузить данные по скважине (${id}) c ${rangeDate[0]} по ${rangeDate[1]}`, 'error') + console.error(error) + }) }, [id, rangeDate]); let charts = null @@ -128,6 +132,7 @@ export default function Archive() { diff --git a/src/pages/Header.jsx b/src/pages/Header.jsx index 34b04e0..ab1de4a 100644 --- a/src/pages/Header.jsx +++ b/src/pages/Header.jsx @@ -6,7 +6,7 @@ import WellTreeSelector from '../components/WellTreeSelector' const { Header } = Layout -export default function PageHeader(props){ +export default function PageHeader({title='Мониторинг', wellsList}){ const login = localStorage['login'] let handleLogout = () => { @@ -14,19 +14,18 @@ export default function PageHeader(props){ localStorage.removeItem('token') } - return( - -
- АСБ - -

Мониторинг

- - - - -
-
- ) - }; \ No newline at end of file + return( + +
+ АСБ + +

{title}

+ + + +
+
+ ) +}; \ No newline at end of file diff --git a/src/pages/LayoutPortal.jsx b/src/pages/LayoutPortal.jsx new file mode 100644 index 0000000..eb3c37e --- /dev/null +++ b/src/pages/LayoutPortal.jsx @@ -0,0 +1,39 @@ +import {Layout} from 'antd' +import PageHeader from './Header' +// import { useState, useEffect, createContext} from 'react' +// import { useParams } from 'react-router-dom' + +const {Content} = Layout + +export default function LayoutPortal({title, children}) { + // const [wells, setWells] = useState([]) + // let { id } = useParams(); + + // let updateWellsList = async () => { + // setLoader(true) + // try { + // let newWells = (await WellService.getWells()).map(w => { return { key: w.id, ...w } }) + // setWells(newWells) + // } + // catch (e) { + // console.error(`${e.message}`); + // } + // setLoader(false) + // } + + // useEffect(() => { + // updateWellsList() + // }, []) + + // const WellsContext = createContext({wells}); + + return ( + + + + + {children} + + + ) +} \ No newline at end of file diff --git a/src/pages/Main.jsx b/src/pages/Main.jsx index 8ca4432..adf515f 100644 --- a/src/pages/Main.jsx +++ b/src/pages/Main.jsx @@ -1,31 +1,25 @@ -import {Layout} from 'antd' import Wells from './Wells' -import PageHeader from './Header' import Well from "../components/Well"; +import LayoutPortal from './LayoutPortal' import {Redirect, Route, Switch} from "react-router-dom"; -const {Content} = Layout - export default function Main() { return ( - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + ) } diff --git a/src/pages/TelemetryView.jsx b/src/pages/TelemetryView.jsx index 6b10633..9bdf2e6 100644 --- a/src/pages/TelemetryView.jsx +++ b/src/pages/TelemetryView.jsx @@ -12,7 +12,7 @@ import moment from 'moment' import {Subscribe} from '../services/signalr' import {DataService, MessageService} from '../services/api' import '../styles/message.css' -import Notification from "../components/Notification"; +import notify from "../components/notify"; const {Option} = Select @@ -207,14 +207,14 @@ export default function TelemetryView(props) { DataService.getData(id) .then(handleReceiveDataSaub) .catch((ex) => { - Notification(`Не удалось загрузить данные по скважине "${id}"`, 'error') + notify(`Не удалось загрузить данные по скважине "${id}"`, 'error') console.log(ex) }) MessageService.getMessage(id) .then(handleReceiveMessages) .catch((ex) => { - Notification(`Не удалось загрузить сообщения по скважине "${id}"`, 'error') + notify(`Не удалось загрузить сообщения по скважине "${id}"`, 'error') console.log(ex) }) diff --git a/src/pages/Wells.jsx b/src/pages/Wells.jsx index 579e5b4..333344d 100644 --- a/src/pages/Wells.jsx +++ b/src/pages/Wells.jsx @@ -3,6 +3,7 @@ import { WellService } from '../services/api' import Loader from '../components/Loader' import { Table } from 'antd' // TreeSelect import { useHistory } from 'react-router-dom' +import notify from '../components/notify' const columns = [ { @@ -36,16 +37,17 @@ export default function Wells(props){ setLoader(true) try{ let newWells = (await WellService.getWells()).map(w =>{return {key:w.id, ...w}}) - console.log(Wells.wellsTree) + console.log(newWells) setWells( newWells ) } catch(e){ - console.error(`${e.message}`); + notify('Не удалось загрузить список скважин', 'error') + console.error(`${e}`); } setLoader(false) } - useEffect(()=>updateWellsList()) + useEffect(()=>updateWellsList(), []) return(<>

Скважины

diff --git a/src/styles/App.less b/src/styles/App.less index cc0c15a..d2ef1e5 100644 --- a/src/styles/App.less +++ b/src/styles/App.less @@ -61,7 +61,7 @@ html { .sheet{ padding: 5px 24px; min-height: 280px; - margin: 0 15px; + margin: 0 15px 15px 15px; } .site-layout-background { @@ -145,3 +145,18 @@ tr.table_row_size { width: 50%; margin-right: 5px; } + +.header-tree-select *{ + color: #fff; + font-size: '1.5rem'; +} + +.header-tree-select{ + border: 1px solid rgba(255, 255, 255, 0.2); + background-color: rgba(0, 0, 0, 0.3); +} + +.header-tree-select:hover{ + border: 1px solid rgba(255, 255, 255, 0.8); + background-color: rgba(0, 0, 0, 0.5); +} \ No newline at end of file diff --git a/src/styles/archive_style.css b/src/styles/archive_style.css deleted file mode 100644 index 0a5d44b..0000000 --- a/src/styles/archive_style.css +++ /dev/null @@ -1,3 +0,0 @@ -.content-sheet { - display: inline-flex; -} \ No newline at end of file