forked from VinokurovVE/tests
Disabled signup; Map test
This commit is contained in:
@ -31,6 +31,7 @@ export const pages = [
|
||||
component: <SignIn />,
|
||||
drawer: false,
|
||||
dashboard: false,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "",
|
||||
@ -39,6 +40,7 @@ export const pages = [
|
||||
component: <SignUp />,
|
||||
drawer: false,
|
||||
dashboard: false,
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
label: "",
|
||||
@ -47,6 +49,7 @@ export const pages = [
|
||||
component: <PasswordReset />,
|
||||
drawer: false,
|
||||
dashboard: false,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "Настройки",
|
||||
@ -55,6 +58,7 @@ export const pages = [
|
||||
component: <Settings />,
|
||||
drawer: false,
|
||||
dashboard: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "Главная",
|
||||
@ -62,7 +66,8 @@ export const pages = [
|
||||
icon: <Home />,
|
||||
component: <Main />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "Пользователи",
|
||||
@ -70,7 +75,8 @@ export const pages = [
|
||||
icon: <People />,
|
||||
component: <Users />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "Роли",
|
||||
@ -78,7 +84,8 @@ export const pages = [
|
||||
icon: <Shield />,
|
||||
component: <Roles />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "Документы",
|
||||
@ -86,7 +93,8 @@ export const pages = [
|
||||
icon: <Storage />,
|
||||
component: <Documents />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "Отчеты",
|
||||
@ -94,7 +102,8 @@ export const pages = [
|
||||
icon: <Assignment />,
|
||||
component: <Reports />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "Серверы",
|
||||
@ -102,7 +111,8 @@ export const pages = [
|
||||
icon: <Cloud />,
|
||||
component: <Servers />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "Котельные",
|
||||
@ -110,7 +120,8 @@ export const pages = [
|
||||
icon: <Factory />,
|
||||
component: <Boilers />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
label: "API Test",
|
||||
@ -118,15 +129,17 @@ export const pages = [
|
||||
icon: <Api />,
|
||||
component: <ApiTest />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
label: "Карта",
|
||||
label: "ИКС",
|
||||
path: "/map-test",
|
||||
icon: <Map />,
|
||||
component: <MapTest />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
label: "Chunk test",
|
||||
@ -134,7 +147,8 @@ export const pages = [
|
||||
icon: <Warning />,
|
||||
component: <ChunkedUpload />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
label: "Монитор",
|
||||
@ -142,7 +156,8 @@ export const pages = [
|
||||
icon: <MonitorHeart />,
|
||||
component: <MonitorPage />,
|
||||
drawer: true,
|
||||
dashboard: true
|
||||
dashboard: true,
|
||||
enabled: false,
|
||||
},
|
||||
]
|
||||
|
||||
@ -174,13 +189,13 @@ function App() {
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route element={<MainLayout />}>
|
||||
{pages.filter((page) => !page.dashboard).map((page, index) => (
|
||||
{pages.filter((page) => !page.dashboard).filter((page) => page.enabled).map((page, index) => (
|
||||
<Route key={`ml-${index}`} path={page.path} element={page.component} />
|
||||
))}
|
||||
</Route>
|
||||
|
||||
<Route element={auth.isAuthenticated ? <DashboardLayout /> : <Navigate to={"/auth/signin"} />}>
|
||||
{pages.filter((page) => page.dashboard).map((page, index) => (
|
||||
{pages.filter((page) => page.dashboard).filter((page) => page.enabled).map((page, index) => (
|
||||
<Route key={`dl-${index}`} path={page.path} element={page.component} />
|
||||
))}
|
||||
<Route path="*" element={<NotFound />} />
|
||||
|
@ -184,7 +184,8 @@ export default function FolderViewer() {
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '16px'
|
||||
gap: '16px',
|
||||
p: '16px'
|
||||
}}>
|
||||
<FileViewer
|
||||
open={fileViewerModal}
|
||||
|
@ -4,18 +4,18 @@ import 'ol/ol.css'
|
||||
import Map from 'ol/Map'
|
||||
import View from 'ol/View'
|
||||
import { Draw, Modify, Select, Snap, Translate } from 'ol/interaction'
|
||||
import { ImageStatic, OSM, TileDebug, Vector as VectorSource, XYZ } from 'ol/source'
|
||||
import { ImageStatic, OSM, Vector as VectorSource, XYZ } from 'ol/source'
|
||||
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
|
||||
import { Divider, IconButton, Slider, Stack, Select as MUISelect, MenuItem, Box, Typography } from '@mui/material'
|
||||
import { Add, Adjust, Api, CircleOutlined, OpenWith, RectangleOutlined, Straighten, Timeline, Undo, Upload, Warning } from '@mui/icons-material'
|
||||
import { Type } from 'ol/geom/Geometry'
|
||||
import { Divider, IconButton, Slider, Stack, Select as MUISelect, MenuItem, Box, Typography, Drawer, Button, Modal, Accordion, AccordionSummary, AccordionDetails, SxProps, Theme } from '@mui/material'
|
||||
import { Add, Adjust, Api, CircleOutlined, ExpandMore, OpenWith, RectangleOutlined, Straighten, Timeline, Undo, Upload, Warning } from '@mui/icons-material'
|
||||
import Geometry, { Type } from 'ol/geom/Geometry'
|
||||
import { click, never, noModifierKeys, platformModifierKeyOnly, primaryAction, shiftKeyOnly } from 'ol/events/condition'
|
||||
import Feature from 'ol/Feature'
|
||||
import { SatelliteMapsProvider } from '../../interfaces/map'
|
||||
import { containsExtent, Extent, getCenter, getHeight, getWidth } from 'ol/extent'
|
||||
import { drawingLayerStyle, regionsLayerStyle, selectStyle } from './MapStyles'
|
||||
import { googleMapsSatelliteSource, regionsLayerSource, yandexMapsSatelliteSource } from './MapSources'
|
||||
import { mapCenter, mapExtent } from './MapConstants'
|
||||
import { mapCenter } from './MapConstants'
|
||||
import ImageLayer from 'ol/layer/Image'
|
||||
import VectorImageLayer from 'ol/layer/VectorImage'
|
||||
import { LineString, MultiPoint, Point, Polygon, SimpleGeometry } from 'ol/geom'
|
||||
@ -25,17 +25,28 @@ import { Coordinate } from 'ol/coordinate'
|
||||
import { Stroke, Fill, Circle as CircleStyle, Style } from 'ol/style'
|
||||
import { calculateExtent, calculateRotationAngle, rotateProjection } from './mapUtils'
|
||||
import MapBrowserEvent from 'ol/MapBrowserEvent'
|
||||
import { get } from 'ol/proj'
|
||||
import axios from 'axios'
|
||||
import { fromLonLat, get } from 'ol/proj'
|
||||
import { useCities } from '../../hooks/swrHooks'
|
||||
import useSWR from 'swr'
|
||||
import { fetcher } from '../../http/axiosInstance'
|
||||
import { BASE_URL } from '../../constants'
|
||||
|
||||
const MapComponent = () => {
|
||||
const { cities } = useCities(100, 1)
|
||||
|
||||
useEffect(() => {
|
||||
if (cities) {
|
||||
cities.map((city: any) => {
|
||||
citiesLayer.current?.getSource()?.addFeature(new Feature(new Point(fromLonLat([city.longitude, city.width]))))
|
||||
})
|
||||
}
|
||||
}, [cities])
|
||||
|
||||
const [currentCoordinate, setCurrentCoordinate] = useState<Coordinate | null>(null)
|
||||
const [currentZ, setCurrentZ] = useState<number | undefined>(undefined)
|
||||
const [currentX, setCurrentX] = useState<number | undefined>(undefined)
|
||||
const [currentY, setCurrentY] = useState<number | undefined>(undefined)
|
||||
|
||||
const [testExtent, setTestExtent] = useState<Extent | null>(null)
|
||||
|
||||
const [file, setFile] = useState(null)
|
||||
const [polygonExtent, setPolygonExtent] = useState<Extent | undefined>(undefined)
|
||||
const [bottomLeft, setBottomLeft] = useState<Coordinate | undefined>(undefined)
|
||||
@ -72,12 +83,19 @@ const MapComponent = () => {
|
||||
},
|
||||
}))
|
||||
|
||||
const nodeLayer = useRef<VectorLayer | null>(null)
|
||||
const nodeLayerSource = useRef<VectorSource>(new VectorSource())
|
||||
|
||||
const overlayLayer = useRef<VectorLayer | null>(null)
|
||||
const overlayLayerSource = useRef<VectorSource>(new VectorSource())
|
||||
|
||||
const drawingLayer = useRef<VectorLayer | null>(null)
|
||||
const drawingLayerSource = useRef<VectorSource>(new VectorSource())
|
||||
|
||||
const citiesLayer = useRef<VectorLayer>(new VectorLayer({
|
||||
source: new VectorSource()
|
||||
}))
|
||||
|
||||
const regionsLayer = useRef<VectorImageLayer>(new VectorImageLayer({
|
||||
source: regionsLayerSource,
|
||||
style: regionsLayerStyle
|
||||
@ -98,6 +116,21 @@ const MapComponent = () => {
|
||||
type: currentTool,
|
||||
condition: noModifierKeys
|
||||
})
|
||||
|
||||
draw.current.on('drawend', function (s) {
|
||||
console.log(s.feature.getGeometry()?.getType())
|
||||
let type = 'POLYGON'
|
||||
|
||||
switch (s.feature.getGeometry()?.getType()) {
|
||||
case 'LineString':
|
||||
type = 'LINE'
|
||||
case 'Polygon':
|
||||
type = 'POLYGON'
|
||||
}
|
||||
const coordinates = (s.feature.getGeometry() as SimpleGeometry).getCoordinates()
|
||||
uploadCoordinates(coordinates, type)
|
||||
})
|
||||
|
||||
map?.current?.addInteraction(draw.current)
|
||||
snap.current = new Snap({ source: drawingLayerSource.current })
|
||||
map?.current?.addInteraction(snap.current)
|
||||
@ -595,14 +628,18 @@ const MapComponent = () => {
|
||||
},
|
||||
})
|
||||
|
||||
nodeLayer.current = new VectorLayer({
|
||||
source: nodeLayerSource.current,
|
||||
style: drawingLayerStyle
|
||||
})
|
||||
|
||||
map.current = new Map({
|
||||
layers: [baseLayer.current, new TileLayer({
|
||||
source: new TileDebug(),
|
||||
}), satLayer.current, regionsLayer.current, drawingLayer.current, imageLayer.current, overlayLayer.current],
|
||||
controls: [],
|
||||
layers: [baseLayer.current, satLayer.current, regionsLayer.current, citiesLayer.current, drawingLayer.current, imageLayer.current, overlayLayer.current, nodeLayer.current],
|
||||
target: mapElement.current as HTMLDivElement,
|
||||
view: new View({
|
||||
center: mapCenter,
|
||||
zoom: 2,
|
||||
center: mapCenter,//center: fromLonLat([130.401113, 67.797368]),
|
||||
zoom: 16,
|
||||
maxZoom: 21,
|
||||
//extent: mapExtent,
|
||||
}),
|
||||
@ -665,6 +702,27 @@ const MapComponent = () => {
|
||||
}
|
||||
}, [currentTool])
|
||||
|
||||
const uploadCoordinates = async (coordinates: any, type: any) => {
|
||||
try {
|
||||
const response = await fetch(`${import.meta.env.VITE_API_EMS_URL}/nodes`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ coordinates, object_id: 1, type: type }) // Replace with actual object_id
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
console.log('Node created:', data);
|
||||
} else {
|
||||
console.error('Failed to upload coordinates');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const [satelliteOpacity, setSatelliteOpacity] = useState<number>(0)
|
||||
|
||||
const [statusText, setStatusText] = useState('')
|
||||
@ -712,52 +770,48 @@ const MapComponent = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const mapControlsStyle: SxProps<Theme> = {
|
||||
borderRadius: '4px',
|
||||
position: 'absolute',
|
||||
zIndex: '1',
|
||||
backgroundColor: (theme) =>
|
||||
theme.palette.mode === 'light'
|
||||
? '#FFFFFFAA'
|
||||
: '#000000AA',
|
||||
backdropFilter: 'blur(8px)'
|
||||
}
|
||||
|
||||
const { data: nodes } = useSWR('/nodes/all', () => fetcher('/nodes/all', BASE_URL.ems), { revalidateOnFocus: false })
|
||||
|
||||
useEffect(() => {
|
||||
// Draw features based on database data
|
||||
if (Array.isArray(nodes)) {
|
||||
nodes.map(node => {
|
||||
if (node.shape_type === 'LINE') {
|
||||
let coordinates: Coordinate[] = []
|
||||
if (Array.isArray(node.shape)) {
|
||||
node.shape.map((point: any) => {
|
||||
const coordinate = [point.x as number, point.y as number] as Coordinate
|
||||
coordinates.push(coordinate)
|
||||
})
|
||||
}
|
||||
//console.log(coordinates)
|
||||
nodeLayerSource.current.addFeature(new Feature({ geometry: new LineString(coordinates) }))
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [nodes])
|
||||
|
||||
return (
|
||||
<Stack flex={1} flexDirection='column'>
|
||||
<Stack my={1} spacing={1} direction='row' divider={<Divider orientation='vertical' flexItem />}>
|
||||
<IconButton title='Добавить подложку'>
|
||||
<Add />
|
||||
</IconButton>
|
||||
|
||||
<Stack>
|
||||
<Typography>
|
||||
x: {currentCoordinate?.[0]}
|
||||
</Typography>
|
||||
<Typography>
|
||||
y: {currentCoordinate?.[1]}
|
||||
</Typography>
|
||||
</Stack>
|
||||
|
||||
<Typography>
|
||||
Z={currentZ}
|
||||
X={currentX}
|
||||
Y={currentY}
|
||||
</Typography>
|
||||
|
||||
<IconButton onClick={() => submitOverlay()}>
|
||||
<Upload />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
<Stack my={1} spacing={1} direction='row' divider={<Divider orientation='vertical' flexItem />}>
|
||||
|
||||
<Stack flex={1} alignItems='center' justifyContent='center'>
|
||||
<Slider aria-label="Opacity" min={0} max={1} step={0.001} defaultValue={satelliteOpacity} value={satelliteOpacity} onChange={(_, value) => setSatelliteOpacity(Array.isArray(value) ? value[0] : value)} />
|
||||
</Stack>
|
||||
|
||||
<MUISelect
|
||||
variant='standard'
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
value={satMapsProvider}
|
||||
label="Satellite Provider"
|
||||
onChange={(e) => setSatMapsProvider(e.target.value as SatelliteMapsProvider)}
|
||||
>
|
||||
<MenuItem value={'google'}>Google</MenuItem>
|
||||
<MenuItem value={'yandex'}>Яндекс</MenuItem>
|
||||
<MenuItem value={'custom'}>Custom</MenuItem>
|
||||
</MUISelect>
|
||||
|
||||
|
||||
<Box height={'calc(100% - 64px)'} maxHeight={'100%'} flex={'1'} flexGrow={'1'} position={'relative'}>
|
||||
<Stack
|
||||
direction={'column'}
|
||||
sx={{
|
||||
...mapControlsStyle,
|
||||
top: '8px',
|
||||
right: '8px',
|
||||
}}
|
||||
divider={<Divider orientation='horizontal' flexItem />}>
|
||||
<IconButton onClick={() => {
|
||||
fetch(`${import.meta.env.VITE_API_EMS_URL}/hello`, { method: 'GET' }).then(res => console.log(res))
|
||||
}}>
|
||||
@ -812,14 +866,113 @@ const MapComponent = () => {
|
||||
</IconButton>
|
||||
</Stack>
|
||||
|
||||
<Box>
|
||||
<div id="map-container" ref={mapElement} style={{ width: '100%', height: '600px', maxHeight: '100%', position: 'relative', flexGrow: 1 }}></div>
|
||||
</Box>
|
||||
<Stack
|
||||
direction={'column'}
|
||||
sx={{
|
||||
...mapControlsStyle,
|
||||
maxWidth: '300px',
|
||||
width: '100%',
|
||||
top: '8px',
|
||||
left: '8px',
|
||||
}} divider={<Divider orientation='horizontal' flexItem />}
|
||||
>
|
||||
<Stack direction={'row'}>
|
||||
<IconButton onClick={() => submitOverlay()}>
|
||||
<Upload />
|
||||
</IconButton>
|
||||
|
||||
<IconButton title='Добавить подложку'>
|
||||
<Add />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
|
||||
|
||||
<Stack direction={'row'} padding={'8px'} spacing={4}>
|
||||
<Slider size='small' aria-label="Opacity" min={0} max={1} step={0.001} defaultValue={satelliteOpacity} value={satelliteOpacity} onChange={(_, value) => setSatelliteOpacity(Array.isArray(value) ? value[0] : value)} />
|
||||
|
||||
<MUISelect
|
||||
variant='standard'
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
value={satMapsProvider}
|
||||
label="Satellite Provider"
|
||||
onChange={(e) => setSatMapsProvider(e.target.value as SatelliteMapsProvider)}
|
||||
>
|
||||
<MenuItem value={'google'}>Google</MenuItem>
|
||||
<MenuItem value={'yandex'}>Яндекс</MenuItem>
|
||||
<MenuItem value={'custom'}>Custom</MenuItem>
|
||||
</MUISelect>
|
||||
</Stack>
|
||||
|
||||
<Accordion disableGutters sx={{ backgroundColor: 'transparent' }} defaultExpanded>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMore />}
|
||||
aria-controls="panel1-content"
|
||||
id="panel1-header"
|
||||
>
|
||||
<Typography>Объекты</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Typography>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
|
||||
malesuada lacus ex, sit amet blandit leo lobortis eget.
|
||||
</Typography>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
|
||||
<Stack>
|
||||
{statusText}
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Stack direction={'row'}
|
||||
sx={{
|
||||
...mapControlsStyle,
|
||||
bottom: '8px',
|
||||
left: '8px',
|
||||
}}
|
||||
|
||||
divider={<Divider orientation='vertical' flexItem />}
|
||||
>
|
||||
<Stack>
|
||||
<Typography>
|
||||
x: {currentCoordinate?.[0]}
|
||||
</Typography>
|
||||
<Typography>
|
||||
y: {currentCoordinate?.[1]}
|
||||
</Typography>
|
||||
</Stack>
|
||||
|
||||
<Typography>
|
||||
Z={currentZ}
|
||||
X={currentX}
|
||||
Y={currentY}
|
||||
</Typography>
|
||||
</Stack>
|
||||
|
||||
<Stack direction={'row'}
|
||||
sx={{
|
||||
...mapControlsStyle,
|
||||
bottom: '8px',
|
||||
right: '8px',
|
||||
}}
|
||||
|
||||
divider={<Divider orientation='vertical' flexItem />}>
|
||||
<Stack>
|
||||
{statusText}
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<div
|
||||
id="map-container"
|
||||
ref={mapElement}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
maxHeight: '100%',
|
||||
position: 'fixed',
|
||||
flexGrow: 1
|
||||
}}
|
||||
>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,8 @@ import Style from "ol/style/Style";
|
||||
|
||||
const drawingLayerStyle: FlatStyleLike = {
|
||||
'fill-color': 'rgba(255, 255, 255, 0.2)',
|
||||
'stroke-color': '#ffcc33',
|
||||
//'stroke-color': '#ffcc33',
|
||||
'stroke-color': '#000000',
|
||||
'stroke-width': 2,
|
||||
'circle-radius': 7,
|
||||
'circle-fill-color': '#ffcc33',
|
||||
|
@ -7,5 +7,6 @@ export const BASE_URL = {
|
||||
auth: import.meta.env.VITE_API_AUTH_URL,
|
||||
info: import.meta.env.VITE_API_INFO_URL,
|
||||
fuel: import.meta.env.VITE_API_FUEL_URL,
|
||||
servers: import.meta.env.VITE_API_SERVERS_URL
|
||||
servers: import.meta.env.VITE_API_SERVERS_URL,
|
||||
ems: import.meta.env.VITE_API_EMS_URL,
|
||||
}
|
@ -166,7 +166,7 @@ export default function DashboardLayout() {
|
||||
<Divider />
|
||||
|
||||
<List component="nav">
|
||||
{pages.filter((page) => page.drawer).map((item, index) => (
|
||||
{pages.filter((page) => page.drawer).filter((page) => page.enabled).map((item, index) => (
|
||||
<ListItem
|
||||
key={index}
|
||||
disablePadding
|
||||
@ -204,12 +204,7 @@ export default function DashboardLayout() {
|
||||
}}
|
||||
>
|
||||
<Toolbar />
|
||||
<Container
|
||||
maxWidth={false}
|
||||
sx={{ mt: 4, mb: 4 }}
|
||||
>
|
||||
<Outlet />
|
||||
</Container>
|
||||
<Outlet />
|
||||
</Box>
|
||||
</Box>
|
||||
</ThemeProvider>
|
||||
|
@ -16,6 +16,13 @@ const mainTheme = createTheme(
|
||||
].join(',')
|
||||
},
|
||||
components: {
|
||||
MuiAppBar: {
|
||||
// styleOverrides: {
|
||||
// colorPrimary: {
|
||||
// backgroundColor: 'gray'
|
||||
// }
|
||||
// }
|
||||
},
|
||||
MuiListItemButton: {
|
||||
defaultProps: {
|
||||
//disableRipple: true
|
||||
@ -38,6 +45,7 @@ const mainTheme = createTheme(
|
||||
},
|
||||
MuiIconButton: {
|
||||
defaultProps: {
|
||||
|
||||
}
|
||||
},
|
||||
MuiIcon: {
|
||||
|
@ -2,8 +2,6 @@ import FolderViewer from '../components/FolderViewer'
|
||||
|
||||
export default function Documents() {
|
||||
return (
|
||||
<div>
|
||||
<FolderViewer />
|
||||
</div>
|
||||
<FolderViewer />
|
||||
)
|
||||
}
|
@ -2,13 +2,13 @@ import { Box, Card, Typography } from "@mui/material";
|
||||
|
||||
export default function Main() {
|
||||
return (
|
||||
<Box>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', p: '16px' }}>
|
||||
<Typography variant='h6' fontWeight='700'>
|
||||
Последние файлы
|
||||
</Typography>
|
||||
|
||||
<Card>
|
||||
|
||||
|
||||
</Card>
|
||||
</Box>
|
||||
)
|
||||
|
@ -2,9 +2,7 @@ import MapComponent from '../components/map/MapComponent'
|
||||
|
||||
function MapTest() {
|
||||
return (
|
||||
<div>
|
||||
<MapComponent />
|
||||
</div>
|
||||
<MapComponent />
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -41,86 +41,84 @@ export default function Reports() {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
||||
<Box sx={{ display: 'flex', gap: '16px' }}>
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
onInputChange={(_, value) => setSearch(value)}
|
||||
onChange={(_, value) => setSelectedOption(value)}
|
||||
isOptionEqualToValue={(option: ICity, value: ICity) => option.id === value.id}
|
||||
getOptionLabel={(option: ICity) => option.name ? option.name : ""}
|
||||
options={cities || []}
|
||||
loading={isLoading}
|
||||
value={selectedOption}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
size='small'
|
||||
label="Населенный пункт"
|
||||
InputProps={{
|
||||
...params.InputProps,
|
||||
endAdornment: (
|
||||
<Fragment>
|
||||
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
||||
{params.InputProps.endAdornment}
|
||||
</Fragment>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<IconButton onClick={() => refreshReport()}>
|
||||
<Update />
|
||||
</IconButton>
|
||||
|
||||
<Button onClick={() => exportReport()}>
|
||||
Экспорт
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<DataGrid
|
||||
autoHeight
|
||||
style={{ width: "100%" }}
|
||||
loading={reportLoading}
|
||||
rows={
|
||||
report ?
|
||||
[...new Set(Object.keys(report).flatMap(key => Object.keys(report[key])))].map(id => {
|
||||
const row: any = { id: Number(id) };
|
||||
Object.keys(report).forEach(key => {
|
||||
row[key] = report[key][id];
|
||||
});
|
||||
return row;
|
||||
})
|
||||
:
|
||||
[]
|
||||
}
|
||||
columns={[
|
||||
{ field: 'id', headerName: '№', width: 70 },
|
||||
...Object.keys(report).map(key => ({
|
||||
field: key,
|
||||
headerName: key.charAt(0).toUpperCase() + key.slice(1),
|
||||
width: 150
|
||||
}))
|
||||
]}
|
||||
initialState={{
|
||||
pagination: {
|
||||
paginationModel: { page: 0, pageSize: 10 },
|
||||
},
|
||||
}}
|
||||
pageSizeOptions={[10, 20, 50, 100]}
|
||||
checkboxSelection={false}
|
||||
disableRowSelectionOnClick
|
||||
|
||||
processRowUpdate={(updatedRow) => {
|
||||
return updatedRow
|
||||
}}
|
||||
|
||||
onProcessRowUpdateError={() => {
|
||||
}}
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', p: '16px' }}>
|
||||
<Box sx={{ display: 'flex', gap: '16px' }}>
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
onInputChange={(_, value) => setSearch(value)}
|
||||
onChange={(_, value) => setSelectedOption(value)}
|
||||
isOptionEqualToValue={(option: ICity, value: ICity) => option.id === value.id}
|
||||
getOptionLabel={(option: ICity) => option.name ? option.name : ""}
|
||||
options={cities || []}
|
||||
loading={isLoading}
|
||||
value={selectedOption}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
size='small'
|
||||
label="Населенный пункт"
|
||||
InputProps={{
|
||||
...params.InputProps,
|
||||
endAdornment: (
|
||||
<Fragment>
|
||||
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
||||
{params.InputProps.endAdornment}
|
||||
</Fragment>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<IconButton onClick={() => refreshReport()}>
|
||||
<Update />
|
||||
</IconButton>
|
||||
|
||||
<Button onClick={() => exportReport()}>
|
||||
Экспорт
|
||||
</Button>
|
||||
</Box>
|
||||
</>
|
||||
|
||||
<DataGrid
|
||||
autoHeight
|
||||
style={{ width: "100%" }}
|
||||
loading={reportLoading}
|
||||
rows={
|
||||
report ?
|
||||
[...new Set(Object.keys(report).flatMap(key => Object.keys(report[key])))].map(id => {
|
||||
const row: any = { id: Number(id) };
|
||||
Object.keys(report).forEach(key => {
|
||||
row[key] = report[key][id];
|
||||
});
|
||||
return row;
|
||||
})
|
||||
:
|
||||
[]
|
||||
}
|
||||
columns={[
|
||||
{ field: 'id', headerName: '№', width: 70 },
|
||||
...Object.keys(report).map(key => ({
|
||||
field: key,
|
||||
headerName: key.charAt(0).toUpperCase() + key.slice(1),
|
||||
width: 150
|
||||
}))
|
||||
]}
|
||||
initialState={{
|
||||
pagination: {
|
||||
paginationModel: { page: 0, pageSize: 10 },
|
||||
},
|
||||
}}
|
||||
pageSizeOptions={[10, 20, 50, 100]}
|
||||
checkboxSelection={false}
|
||||
disableRowSelectionOnClick
|
||||
|
||||
processRowUpdate={(updatedRow) => {
|
||||
return updatedRow
|
||||
}}
|
||||
|
||||
onProcessRowUpdateError={() => {
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
}
|
@ -31,7 +31,8 @@ export default function Roles() {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start',
|
||||
gap: '16px',
|
||||
flexGrow: 1
|
||||
flexGrow: 1,
|
||||
p: '16px'
|
||||
}}>
|
||||
<Button onClick={() => setOpen(true)}>
|
||||
Добавить роль
|
||||
|
@ -36,42 +36,40 @@ export default function Servers() {
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', height: '100%' }}>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', height: '100%', p: '16px' }}>
|
||||
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||
<Tabs value={currentTab} onChange={(_, value) =>
|
||||
handleTabChange(value)
|
||||
} aria-label="basic tabs example">
|
||||
<Tab label="Серверы" />
|
||||
<Tab label="IP-адреса" />
|
||||
<Tab label="Hardware" />
|
||||
<Tab label="Storages" />
|
||||
</Tabs>
|
||||
</Box>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', height: '100%', p: '16px' }}>
|
||||
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||
<Tabs value={currentTab} onChange={(_, value) =>
|
||||
handleTabChange(value)
|
||||
} aria-label="basic tabs example">
|
||||
<Tab label="Серверы" />
|
||||
<Tab label="IP-адреса" />
|
||||
<Tab label="Hardware" />
|
||||
<Tab label="Storages" />
|
||||
</Tabs>
|
||||
</Box>
|
||||
|
||||
<CustomTabPanel value={currentTab} index={0}>
|
||||
<ServersView />
|
||||
</CustomTabPanel>
|
||||
<CustomTabPanel value={currentTab} index={0}>
|
||||
<ServersView />
|
||||
</CustomTabPanel>
|
||||
|
||||
<CustomTabPanel value={currentTab} index={1}>
|
||||
<ServerIpsView />
|
||||
</CustomTabPanel>
|
||||
<CustomTabPanel value={currentTab} index={1}>
|
||||
<ServerIpsView />
|
||||
</CustomTabPanel>
|
||||
|
||||
<CustomTabPanel value={currentTab} index={2}>
|
||||
<ServerHardware />
|
||||
</CustomTabPanel>
|
||||
<CustomTabPanel value={currentTab} index={2}>
|
||||
<ServerHardware />
|
||||
</CustomTabPanel>
|
||||
|
||||
<CustomTabPanel value={currentTab} index={3}>
|
||||
<ServerStorage />
|
||||
</CustomTabPanel>
|
||||
<CustomTabPanel value={currentTab} index={3}>
|
||||
<ServerStorage />
|
||||
</CustomTabPanel>
|
||||
|
||||
<BarChart
|
||||
{/* <BarChart
|
||||
xAxis={[{ scaleType: 'band', data: ['group A', 'group B', 'group C'] }]}
|
||||
series={[{ data: [4, 3, 5] }, { data: [1, 6, 3] }, { data: [2, 5, 6] }]}
|
||||
width={500}
|
||||
height={300}
|
||||
/>
|
||||
</Box>
|
||||
/> */}
|
||||
</Box>
|
||||
)
|
||||
}
|
@ -50,6 +50,7 @@ export default function Users() {
|
||||
flexDirection: "column",
|
||||
alignItems: "flex-start",
|
||||
gap: "16px",
|
||||
p: '16px'
|
||||
}}
|
||||
>
|
||||
<Button onClick={() => setOpen(true)}>
|
||||
|
@ -87,13 +87,11 @@ const SignIn = () => {
|
||||
{isSubmitting ? <CircularProgress size={16} /> : 'Вход'}
|
||||
</Button>
|
||||
|
||||
<Button fullWidth href="/auth/signup" type="button" variant="text" color="primary">
|
||||
{/* <Button fullWidth href="/auth/signup" type="button" variant="text" color="primary">
|
||||
Регистрация
|
||||
</Button>
|
||||
</Button> */}
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
|
||||
</form>
|
||||
</Box>
|
||||
</Container>
|
||||
|
Reference in New Issue
Block a user