forked from ddrilling/asb_cloud_front
Улучшено отображение на маленьких экранах
This commit is contained in:
parent
cc1c6a0661
commit
b2d241a8e7
63
src/App.tsx
63
src/App.tsx
@ -1,14 +1,10 @@
|
||||
import { BrowserRouter as Router, Navigate, Route, Routes } from 'react-router-dom'
|
||||
import { lazy, memo, Suspense } from 'react'
|
||||
import locale from 'antd/lib/locale/ru_RU'
|
||||
import { ConfigProvider } from 'antd'
|
||||
|
||||
import { RootPathContext } from '@asb/context'
|
||||
import SuspenseFallback from '@components/SuspenseFallback'
|
||||
import { getUser, NoAccessComponent } from '@utils'
|
||||
import { OpenAPI } from '@api'
|
||||
import { NoAccessComponent } from '@utils'
|
||||
|
||||
import '@styles/include/antd_theme.less'
|
||||
import '@styles/App.less'
|
||||
|
||||
const UserOutlet = lazy(() => import('@components/outlets/UserOutlet'))
|
||||
@ -24,45 +20,38 @@ const Deposit = lazy(() => import('@pages/Deposit'))
|
||||
const Cluster = lazy(() => import('@pages/Cluster'))
|
||||
const Well = lazy(() => import('@pages/Well'))
|
||||
|
||||
// OpenAPI.BASE = 'http://localhost:3000'
|
||||
// TODO: Удалить взятие из 'token' в следующем релизе, вставлено для совместимости
|
||||
OpenAPI.TOKEN = async () => getUser().token || localStorage.getItem('token') || ''
|
||||
OpenAPI.HEADERS = { 'Content-Type': 'application/json' }
|
||||
|
||||
export const App = memo(() => (
|
||||
<ConfigProvider locale={locale}>
|
||||
<RootPathContext.Provider value={''}>
|
||||
<Suspense fallback={<SuspenseFallback style={{ minHeight: '100vh' }} />}>
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route index element={<Navigate to={'deposit'} replace />} />
|
||||
<Route path={'*'} element={<NoAccessComponent />} />
|
||||
<RootPathContext.Provider value={''}>
|
||||
<Suspense fallback={<SuspenseFallback style={{ minHeight: '100vh' }} />}>
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route index element={<Navigate to={'deposit'} replace />} />
|
||||
<Route path={'*'} element={<NoAccessComponent />} />
|
||||
|
||||
{/* Public pages */}
|
||||
<Route path={'/login'} element={<Login />} />
|
||||
<Route path={'/register'} element={<Register />} />
|
||||
{/* Public pages */}
|
||||
<Route path={'/login'} element={<Login />} />
|
||||
<Route path={'/register'} element={<Register />} />
|
||||
|
||||
{/* User pages */}
|
||||
<Route element={<UserOutlet />}>
|
||||
<Route path={'/file_download/:idFile/*'} element={<FileDownload />} />
|
||||
{/* User pages */}
|
||||
<Route element={<UserOutlet />}>
|
||||
<Route path={'/file_download/:idFile/*'} element={<FileDownload />} />
|
||||
|
||||
<Route element={<DepositsOutlet />}>
|
||||
<Route element={<LayoutPortal />}>
|
||||
{/* Admin pages */}
|
||||
<Route path={'/admin/*'} element={<AdminPanel />} />
|
||||
<Route element={<DepositsOutlet />}>
|
||||
<Route element={<LayoutPortal />}>
|
||||
{/* Admin pages */}
|
||||
<Route path={'/admin/*'} element={<AdminPanel />} />
|
||||
|
||||
{/* Client pages */}
|
||||
<Route path={'/deposit/*'} element={<Deposit />} />
|
||||
<Route path={'/cluster/:idCluster'} element={<Cluster />} />
|
||||
<Route path={'/well/:idWell/*'} element={<Well />} />
|
||||
</Route>
|
||||
{/* Client pages */}
|
||||
<Route path={'/deposit/*'} element={<Deposit />} />
|
||||
<Route path={'/cluster/:idCluster'} element={<Cluster />} />
|
||||
<Route path={'/well/:idWell/*'} element={<Well />} />
|
||||
</Route>
|
||||
</Route>
|
||||
</Routes>
|
||||
</Router>
|
||||
</Suspense>
|
||||
</RootPathContext.Provider>
|
||||
</ConfigProvider>
|
||||
</Route>
|
||||
</Routes>
|
||||
</Router>
|
||||
</Suspense>
|
||||
</RootPathContext.Provider>
|
||||
))
|
||||
|
||||
export default App
|
||||
|
@ -6,11 +6,12 @@ type LoaderPortalProps = HTMLAttributes<HTMLDivElement> & {
|
||||
show?: boolean,
|
||||
fade?: boolean,
|
||||
spinnerProps?: HTMLAttributes<HTMLDivElement>,
|
||||
fillContent?: boolean
|
||||
}
|
||||
|
||||
export const LoaderPortal: React.FC<LoaderPortalProps> = ({ className = '', show, fade = true, children, spinnerProps, ...other }) => (
|
||||
export const LoaderPortal: React.FC<LoaderPortalProps> = ({ className = '', show, fade = true, children, spinnerProps, fillContent, ...other }) => (
|
||||
<div className={`loader-container ${className}`} {...other}>
|
||||
<div className={'loader-content'}>{children}</div>
|
||||
<div className={`loader-content${fillContent ? ' loader-content-fill' : ''}`}>{children}</div>
|
||||
{show && fade && <div className={'loader-fade'}/>}
|
||||
{show && <div className={'loader-overlay'}><Loader {...spinnerProps} /></div>}
|
||||
</div>
|
||||
|
@ -221,9 +221,7 @@ export const EditableTable = memo(({
|
||||
|
||||
const mergedColumns = useMemo(() => [...columns.map(handleColumn), operationColumn], [columns, handleColumn, operationColumn])
|
||||
|
||||
useEffect(() => {
|
||||
setData(tryAddKeys(dataSource))
|
||||
}, [dataSource])
|
||||
useEffect(() => setData(tryAddKeys(dataSource)), [dataSource])
|
||||
|
||||
return (
|
||||
<Form form={form}>
|
||||
|
@ -193,6 +193,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
|
||||
methods,
|
||||
|
||||
className = '',
|
||||
style,
|
||||
...other
|
||||
}: D3MonitoringChartsProps<DataType>) => {
|
||||
const [datasets, setDatasets, resetDatasets] = useUserSettings(chartName, datasetGroups)
|
||||
@ -513,6 +514,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
|
||||
style={{
|
||||
width: givenWidth,
|
||||
height: givenHeight,
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
|
@ -1,15 +1,28 @@
|
||||
import React from 'react'
|
||||
import locale from 'antd/lib/locale/ru_RU'
|
||||
import { ConfigProvider } from 'antd'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import React from 'react'
|
||||
|
||||
import { getUser } from '@utils'
|
||||
import { OpenAPI } from '@api'
|
||||
|
||||
import App from './App'
|
||||
|
||||
import '@styles/include/antd_theme.less'
|
||||
import '@styles/index.css'
|
||||
|
||||
// OpenAPI.BASE = 'http://localhost:3000'
|
||||
// TODO: Удалить взятие из 'token' в следующем релизе, вставлено для совместимости
|
||||
OpenAPI.TOKEN = async () => getUser().token || localStorage.getItem('token') || ''
|
||||
OpenAPI.HEADERS = { 'Content-Type': 'application/json' }
|
||||
|
||||
const container = document.getElementById('root') ?? document.body
|
||||
const root = createRoot(container)
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
<ConfigProvider locale={locale}>
|
||||
<App />
|
||||
</ConfigProvider>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
@ -7,11 +7,11 @@ import {
|
||||
makeTextColumn,
|
||||
makeGroupColumn,
|
||||
makeColumn,
|
||||
makeDateSorter,
|
||||
makeNumericColumnPlanFact,
|
||||
Table,
|
||||
makeNumericRender,
|
||||
makeNumericColumn,
|
||||
makeDateColumn,
|
||||
} from '@components/Table'
|
||||
import LoaderPortal from '@components/LoaderPortal'
|
||||
import PointerIcon from '@components/icons/PointerIcon'
|
||||
@ -39,7 +39,6 @@ const filtersWellsType = []
|
||||
const DAY_IN_MS = 86_400_000
|
||||
const ONLINE_DEADTIME = 600_000
|
||||
|
||||
const getDate = (str) => isRawDate(str) ? new Date(str).toLocaleString() : '-'
|
||||
const numericRender = makeNumericRender(1)
|
||||
|
||||
const ClusterWells = memo(({ statsWells }) => {
|
||||
@ -131,8 +130,8 @@ const ClusterWells = memo(({ statsWells }) => {
|
||||
),
|
||||
makeTextColumn('Тип скв.', 'wellType', filtersWellsType, null, (text) => text ?? '-'),
|
||||
makeGroupColumn('Фактические сроки', [
|
||||
makeColumn('начало', 'factStart', { sorter: makeDateSorter('factStart'), render: getDate }),
|
||||
makeColumn('окончание', 'factEnd', { sorter: makeDateSorter('factEnd'), render: getDate }),
|
||||
makeDateColumn('начало', 'factStart'),
|
||||
makeDateColumn('окончание', 'factEnd'),
|
||||
]),
|
||||
makeNumericColumnPlanFact('Продолжительность, сут', 'period', filtersMinMax, makeFilterMinMaxFunction, numericRender),
|
||||
makeNumericColumnPlanFact('МСП, м/ч', 'rateOfPenetration', filtersMinMax, makeFilterMinMaxFunction, numericRender),
|
||||
|
@ -223,7 +223,7 @@ const Archive = memo(() => {
|
||||
const chartData = useMemo(() => cutData(dataSaub, domain.min, domain.max), [dataSaub, domain])
|
||||
|
||||
return (
|
||||
<LoaderPortal show={showLoader}>
|
||||
<LoaderPortal show={showLoader} style={{ flexGrow: 1 }}>
|
||||
<Flex style={{margin: '8px 8px 0'}}>
|
||||
<div>
|
||||
Начальная дата:
|
||||
@ -259,6 +259,7 @@ const Archive = memo(() => {
|
||||
render: cursorRender,
|
||||
}
|
||||
}}
|
||||
style={{ flexGrow: 1 }}
|
||||
height={'76vh'}
|
||||
onWheel={onGraphWheel}
|
||||
/>
|
||||
|
@ -28,7 +28,7 @@ const categoryDictionary = {
|
||||
|
||||
// Конфигурация таблицы
|
||||
export const makeMessageColumns = (idWell) => [
|
||||
makeDateColumn('Дата', 'date', undefined, undefined, { width: '10rem' }),
|
||||
makeDateColumn('Дата', 'date', undefined, undefined, { width: '120px' }),
|
||||
makeNumericColumn('Глубина, м', 'wellDepth', null, null, (depth, item) => (
|
||||
<Tooltip title={'Нажмите для перехода в архив'}>
|
||||
<Link
|
||||
@ -50,7 +50,7 @@ export const makeMessageColumns = (idWell) => [
|
||||
ellipsis: true,
|
||||
}),
|
||||
makeColumn('Сообщение', 'message', { onFilter: (value, record) => record.name.indexOf(value) === 0 }),
|
||||
makeTextColumn('Пользователь', 'user', null, null, null, { width: '10rem' }),
|
||||
makeTextColumn('Пользователь', 'user', null, null, null, { width: '120px' }),
|
||||
]
|
||||
|
||||
const filterOptions = [
|
||||
|
@ -32,7 +32,7 @@ import MomentStabPicDisabled from '@images/DempherOff.png'
|
||||
import SpinPicEnabled from '@images/SpinEnabled.png'
|
||||
import SpinPicDisabled from '@images/SpinDisabled.png'
|
||||
|
||||
import '@styles/monitoring.less'
|
||||
import '@styles/telemetry_view.less'
|
||||
import '@styles/message.less'
|
||||
|
||||
const { Option } = Select
|
||||
@ -186,7 +186,7 @@ const TelemetryView = memo(() => {
|
||||
|
||||
return (
|
||||
<LoaderPortal show={showLoader}>
|
||||
<Grid style={{ gridTemplateColumns: 'auto repeat(6, 1fr)' }}>
|
||||
<Grid className={'telemetry-view-page'} style={{ gridTemplateColumns: 'auto repeat(6, 1fr)' }}>
|
||||
<GridItem col={'1'} row={'1'} colSpan={'8'} style={{ marginBottom: '0.5rem' }}>
|
||||
<div className={'page-top'}>
|
||||
<ModeDisplay data={dataSaub} />
|
||||
|
@ -7,8 +7,5 @@
|
||||
// Переменные для темы тут:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less
|
||||
|
||||
//@primary-color: rgba(124, 124, 124, 0.3);
|
||||
@primary-color: rgb(195, 40,40);
|
||||
//@primary-color:rgb(65, 63, 61);
|
||||
//@layout-header-background: rgb(195, 40,40);
|
||||
@layout-header-background: rgb(65, 63, 61);
|
||||
@primary-color: #C32828; // rgb(195, 40, 40)
|
||||
@layout-header-background:#413F3D; // rgb(65, 63, 61)
|
||||
|
@ -19,6 +19,10 @@
|
||||
}
|
||||
|
||||
.page-layout {
|
||||
--sheet-padding: 15px;
|
||||
|
||||
@sheet-padding: var(--sheet-padding);
|
||||
|
||||
height: 100vh;
|
||||
|
||||
& .menu-sider {
|
||||
@ -88,8 +92,9 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
padding: 0 15px 15px 15px;
|
||||
gap: @sheet-padding;
|
||||
padding: @sheet-padding;
|
||||
padding-top: 0;
|
||||
|
||||
& .ant-breadcrumb-link, .ant-breadcrumb-separator {
|
||||
.no-select;
|
||||
@ -99,7 +104,7 @@
|
||||
}
|
||||
|
||||
& .sheet{
|
||||
padding: 15px;
|
||||
padding: @sheet-padding;
|
||||
// min-height: calc(@layout-min-height - 30px); // 280px;
|
||||
overflow: visible;
|
||||
// margin: 15px;
|
||||
@ -126,3 +131,15 @@
|
||||
.site-layout-background {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1280px) {
|
||||
.page-layout {
|
||||
--sheet-padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.page-layout {
|
||||
--sheet-padding: 5px;
|
||||
}
|
||||
}
|
||||
|
@ -39,11 +39,18 @@
|
||||
}
|
||||
|
||||
.loader-content{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-column-start: 1;
|
||||
grid-column-end: span 3;
|
||||
grid-row-start: 1;
|
||||
}
|
||||
|
||||
.loader-content.loader-content-fill {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.loader-overlay{
|
||||
grid-column-start: 1;
|
||||
grid-column-end: span 3;
|
||||
|
@ -1,17 +0,0 @@
|
||||
.page-top {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: -5px;
|
||||
|
||||
& > * {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
& > .icons {
|
||||
display: flex;
|
||||
|
||||
& > * {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
66
src/styles/telemetry_view.less
Normal file
66
src/styles/telemetry_view.less
Normal file
@ -0,0 +1,66 @@
|
||||
.telemetry-view-page {
|
||||
--page-gap: 10px;
|
||||
|
||||
@page-gap: var(--page-gap);
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: space-between;
|
||||
gap: @page-gap;
|
||||
}
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
.flex-container;
|
||||
|
||||
& .page-top {
|
||||
.flex-container;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
|
||||
& .icons {
|
||||
display: flex;
|
||||
|
||||
& > * {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& .page-main {
|
||||
flex-grow: 1;
|
||||
.flex-container;
|
||||
|
||||
& .page-left {
|
||||
.flex-container;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
& .modes, & .current-values {
|
||||
.flex-container;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& .page-right {
|
||||
flex-grow: 1;
|
||||
.flex-container;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1280px) {
|
||||
.telemetry-view-page {
|
||||
--page-gap: 7.5px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.telemetry-view-page {
|
||||
--page-gap: 5px;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user