diff --git a/frontend_reactjs/src/App.tsx b/frontend_reactjs/src/App.tsx
index 9c4d1b3..ea7f401 100644
--- a/frontend_reactjs/src/App.tsx
+++ b/frontend_reactjs/src/App.tsx
@@ -15,6 +15,90 @@ import Documents from "./pages/Documents"
import Reports from "./pages/Reports"
import Boilers from "./pages/Boilers"
import Servers from "./pages/Servers"
+import { Api, Assignment, Cloud, Factory, Home, Login, People, Shield, Storage } from "@mui/icons-material"
+
+export const pages = [
+ {
+ label: "",
+ path: "/auth/signin",
+ icon: ,
+ component: ,
+ drawer: false,
+ dashboard: false,
+ },
+ {
+ label: "",
+ path: "/auth/signup",
+ icon: ,
+ component: ,
+ drawer: false,
+ dashboard: false,
+ },
+ {
+ label: "Главная",
+ path: "/",
+ icon: ,
+ component: ,
+ drawer: true,
+ dashboard: true
+ },
+ {
+ label: "Пользователи",
+ path: "/user",
+ icon: ,
+ component: ,
+ drawer: true,
+ dashboard: true
+ },
+ {
+ label: "Роли",
+ path: "/role",
+ icon: ,
+ component: ,
+ drawer: true,
+ dashboard: true
+ },
+ {
+ label: "Документы",
+ path: "/documents",
+ icon: ,
+ component: ,
+ drawer: true,
+ dashboard: true
+ },
+ {
+ label: "Отчеты",
+ path: "/reports",
+ icon: ,
+ component: ,
+ drawer: true,
+ dashboard: true
+ },
+ {
+ label: "Серверы",
+ path: "/servers",
+ icon: ,
+ component: ,
+ drawer: true,
+ dashboard: true
+ },
+ {
+ label: "Котельные",
+ path: "/boilers",
+ icon: ,
+ component: ,
+ drawer: true,
+ dashboard: true
+ },
+ {
+ label: "API Test",
+ path: "/api-test",
+ icon: ,
+ component: ,
+ drawer: true,
+ dashboard: true
+ },
+]
function App() {
const auth = useAuthStore()
@@ -44,19 +128,15 @@ function App() {
}>
- } />
- } />
+ {pages.filter((page) => !page.dashboard).map((page, index) => (
+
+ ))}
: }>
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
+ {pages.filter((page) => page.dashboard).map((page, index) => (
+
+ ))}
} />
diff --git a/frontend_reactjs/src/components/CardInfo/CardInfo.tsx b/frontend_reactjs/src/components/CardInfo/CardInfo.tsx
new file mode 100644
index 0000000..49dca84
--- /dev/null
+++ b/frontend_reactjs/src/components/CardInfo/CardInfo.tsx
@@ -0,0 +1,23 @@
+import { Box, Chip, Divider, Paper, Typography } from '@mui/material'
+import React, { PropsWithChildren, ReactElement, ReactNode } from 'react'
+
+interface CardInfoProps extends PropsWithChildren {
+ label: string;
+}
+
+export default function CardInfo({
+ children,
+ label
+}: CardInfoProps) {
+ return (
+
+
+ {label}
+
+
+
+
+ {children}
+
+ )
+}
\ No newline at end of file
diff --git a/frontend_reactjs/src/components/CardInfo/CardInfoChip.tsx b/frontend_reactjs/src/components/CardInfo/CardInfoChip.tsx
new file mode 100644
index 0000000..6c1e00a
--- /dev/null
+++ b/frontend_reactjs/src/components/CardInfo/CardInfoChip.tsx
@@ -0,0 +1,27 @@
+import { Cloud } from '@mui/icons-material';
+import { Chip, SvgIconTypeMap } from '@mui/material'
+import { OverridableComponent } from '@mui/material/OverridableComponent';
+import React, { ReactElement } from 'react'
+
+interface CardInfoChipProps {
+ status: boolean;
+ label: string;
+ iconOn: ReactElement
+ iconOff: ReactElement
+}
+
+export default function CardInfoChip({
+ status,
+ label,
+ iconOn,
+ iconOff
+}: CardInfoChipProps) {
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/frontend_reactjs/src/components/CardInfo/CardInfoLabel.tsx b/frontend_reactjs/src/components/CardInfo/CardInfoLabel.tsx
new file mode 100644
index 0000000..53c0609
--- /dev/null
+++ b/frontend_reactjs/src/components/CardInfo/CardInfoLabel.tsx
@@ -0,0 +1,24 @@
+import { Box, Typography } from '@mui/material'
+import React from 'react'
+
+interface CardInfoLabelProps {
+ label: string;
+ value: string | number;
+}
+
+export default function CardInfoLabel({
+ label,
+ value
+}: CardInfoLabelProps) {
+ return (
+
+
+ {label}
+
+
+
+ {value}
+
+
+ )
+}
\ No newline at end of file
diff --git a/frontend_reactjs/src/components/DataGridCellAutocomplete.tsx b/frontend_reactjs/src/components/DataGridCellAutocomplete.tsx
new file mode 100644
index 0000000..b6c0793
--- /dev/null
+++ b/frontend_reactjs/src/components/DataGridCellAutocomplete.tsx
@@ -0,0 +1,79 @@
+import { Autocomplete, CircularProgress, TextField } from '@mui/material'
+import React, { Fragment, useEffect, useState } from 'react'
+
+interface DataGridCellAutocompleteProps {
+ selectedOption: any;
+ setSelectedOption: any;
+ isLoading: boolean;
+ setDebouncedSearch: any;
+ options: any;
+ setOptions: any;
+}
+
+export default function DataGridCellAutocomplete({
+ selectedOption,
+ setSelectedOption,
+ isLoading,
+ setDebouncedSearch,
+ options,
+ setOptions
+}: DataGridCellAutocompleteProps) {
+ const [open, setOpen] = useState(false)
+ const [search, setSearch] = useState("")
+
+ useEffect(() => {
+ const handler = setTimeout(() => {
+ setDebouncedSearch(search)
+ }, 500)
+
+ return () => {
+ clearTimeout(handler)
+ }
+ }, [search])
+
+ const handleInputChange = (value: string) => {
+ setSearch(value)
+ }
+
+ const handleOptionChange = (value: any | null) => {
+ setSelectedOption(value)
+ }
+
+ return (
+ {
+ setOpen(true)
+ }}
+ onClose={() => {
+ setOpen(false)
+ }}
+ onInputChange={(_, value) => handleInputChange(value)}
+ onChange={(_, value) => handleOptionChange(value)}
+ filterOptions={(x) => x}
+ isOptionEqualToValue={(option: any, value: any) => option.name === value.name}
+ getOptionLabel={(option: any) => option.name ? option.name : ""}
+ options={options}
+ loading={isLoading}
+ value={selectedOption}
+ renderInput={(params) => (
+
+ {isLoading ? : null}
+ {params.InputProps.endAdornment}
+
+ )
+ }}
+ />
+ )}
+ />
+ )
+}
\ No newline at end of file
diff --git a/frontend_reactjs/src/components/ServerHardware.tsx b/frontend_reactjs/src/components/ServerHardware.tsx
index 10c10de..4d257c7 100644
--- a/frontend_reactjs/src/components/ServerHardware.tsx
+++ b/frontend_reactjs/src/components/ServerHardware.tsx
@@ -90,44 +90,46 @@ export default function ServerHardware() {
}
- {
- setOpen(true)
- }}
- onClose={() => {
- setOpen(false)
- }}
- onInputChange={(_, value) => handleInputChange(value)}
- onChange={(_, value) => handleOptionChange(value)}
- filterOptions={(x) => x}
- isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
- getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
- options={options}
- loading={isLoading}
- value={selectedOption}
- renderInput={(params) => (
-
- {isLoading ? : null}
- {params.InputProps.endAdornment}
-
- )
- }}
- />
- )}
- />
-
{serversLoading ?
:
- servers &&
+ hardwares &&
{
+ setOpen(true)
+ }}
+ onClose={() => {
+ setOpen(false)
+ }}
+ onInputChange={(_, value) => handleInputChange(value)}
+ onChange={(_, value) => handleOptionChange(value)}
+ filterOptions={(x) => x}
+ isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
+ getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
+ options={options}
+ loading={isLoading}
+ value={selectedOption}
+ renderInput={(params) => (
+
+ {isLoading ? : null}
+ {params.InputProps.endAdornment}
+
+ )
+ }}
+ />
+ )}
+ />
+ }
onSave={(id: any) => {
console.log(id)
}}
diff --git a/frontend_reactjs/src/components/ServerIpsView.tsx b/frontend_reactjs/src/components/ServerIpsView.tsx
index ff00070..adf6302 100644
--- a/frontend_reactjs/src/components/ServerIpsView.tsx
+++ b/frontend_reactjs/src/components/ServerIpsView.tsx
@@ -88,44 +88,46 @@ export default function ServerIpsView() {
}
- {
- setOpen(true)
- }}
- onClose={() => {
- setOpen(false)
- }}
- onInputChange={(_, value) => handleInputChange(value)}
- onChange={(_, value) => handleOptionChange(value)}
- filterOptions={(x) => x}
- isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
- getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
- options={options}
- loading={isLoading}
- value={selectedOption}
- renderInput={(params) => (
-
- {isLoading ? : null}
- {params.InputProps.endAdornment}
-
- )
- }}
- />
- )}
- />
-
{serversLoading ?
:
- servers &&
+ serverIps &&
{
+ setOpen(true)
+ }}
+ onClose={() => {
+ setOpen(false)
+ }}
+ onInputChange={(_, value) => handleInputChange(value)}
+ onChange={(_, value) => handleOptionChange(value)}
+ filterOptions={(x) => x}
+ isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
+ getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
+ options={options}
+ loading={isLoading}
+ value={selectedOption}
+ renderInput={(params) => (
+
+ {isLoading ? : null}
+ {params.InputProps.endAdornment}
+
+ )
+ }}
+ />
+ )}
+ />
+ }
onSave={(id: any) => {
console.log(id)
}}
diff --git a/frontend_reactjs/src/components/ServerStorages.tsx b/frontend_reactjs/src/components/ServerStorages.tsx
index cab425c..82d84de 100644
--- a/frontend_reactjs/src/components/ServerStorages.tsx
+++ b/frontend_reactjs/src/components/ServerStorages.tsx
@@ -87,44 +87,46 @@ export default function ServerStorage() {
}
- {
- setOpen(true)
- }}
- onClose={() => {
- setOpen(false)
- }}
- onInputChange={(_, value) => handleInputChange(value)}
- onChange={(_, value) => handleOptionChange(value)}
- filterOptions={(x) => x}
- isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
- getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
- options={options}
- loading={isLoading}
- value={selectedOption}
- renderInput={(params) => (
-
- {isLoading ? : null}
- {params.InputProps.endAdornment}
-
- )
- }}
- />
- )}
- />
-
{serversLoading ?
:
storages &&
{
+ setOpen(true)
+ }}
+ onClose={() => {
+ setOpen(false)
+ }}
+ onInputChange={(_, value) => handleInputChange(value)}
+ onChange={(_, value) => handleOptionChange(value)}
+ filterOptions={(x) => x}
+ isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
+ getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
+ options={options}
+ loading={isLoading}
+ value={selectedOption}
+ renderInput={(params) => (
+
+ {isLoading ? : null}
+ {params.InputProps.endAdornment}
+
+ )
+ }}
+ />
+ )}
+ />
+ }
onSave={(id: any) => {
console.log(id)
}}
diff --git a/frontend_reactjs/src/components/ServersView.tsx b/frontend_reactjs/src/components/ServersView.tsx
index b9a880f..d42e7cb 100644
--- a/frontend_reactjs/src/components/ServersView.tsx
+++ b/frontend_reactjs/src/components/ServersView.tsx
@@ -4,13 +4,18 @@ import { IRegion } from '../interfaces/fuel'
import { useRegions, useServers, useServersInfo } from '../hooks/swrHooks'
import FullFeaturedCrudGrid from './TableEditable'
import ServerService from '../services/ServersService'
-import { GridColDef } from '@mui/x-data-grid'
+import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'
import { Close, Cloud, CloudOff } from '@mui/icons-material'
import ServerData from './ServerData'
import { IServersInfo } from '../interfaces/servers'
+import CardInfo from './CardInfo/CardInfo'
+import CardInfoLabel from './CardInfo/CardInfoLabel'
+import CardInfoChip from './CardInfo/CardInfoChip'
+import DataGridCellAutocomplete from './DataGridCellAutocomplete'
export default function ServersView() {
const [open, setOpen] = useState(false)
+ const [editOpen, setEditOpen] = useState(false)
const [options, setOptions] = useState([])
const [search, setSearch] = useState("")
const [debouncedSearch, setDebouncedSearch] = useState("")
@@ -52,6 +57,23 @@ export default function ServersView() {
const serversColumns: GridColDef[] = [
//{ field: 'id', headerName: 'ID', type: "number" },
{ field: 'name', headerName: 'Название', type: "string", editable: true },
+ {
+ field: 'region_id',
+ editable: true,
+ renderEditCell: (params: GridRenderCellParams) => (
+ {
+ params.value = value
+ }}
+ isLoading={isLoading}
+ setDebouncedSearch={setDebouncedSearch}
+ options={options}
+ setOptions={setOptions}
+ />
+ ),
+ width: 200
+ }
]
return (
@@ -88,83 +110,24 @@ export default function ServersView() {
}
- {
- setOpen(true)
- }}
- onClose={() => {
- setOpen(false)
- }}
- onInputChange={(_, value) => handleInputChange(value)}
- onChange={(_, value) => handleOptionChange(value)}
- filterOptions={(x) => x}
- isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
- getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
- options={options}
- loading={isLoading}
- value={selectedOption}
- renderInput={(params) => (
-
- {isLoading ? : null}
- {params.InputProps.endAdornment}
-
- )
- }}
- />
- )}
- />
-
- {servers &&
+ {serversInfo &&
- {serversInfo &&
-
- {serversInfo.map((serverInfo: IServersInfo) => (
-
-
-
- {serverInfo.name}
-
-
-
-
-
-
- Количество IP:
-
-
-
- {serverInfo.IPs_count}
-
-
-
-
-
- Количество серверов:
-
-
-
- {serverInfo.servers_count}
-
-
-
- : serverInfo.status === "Offline" ? : }
- variant="outlined"
- label={serverInfo.status}
- color={serverInfo.status === "Online" ? "success" : serverInfo.status === "Offline" ? "error" : "error"}
- />
-
-
- ))}
-
- }
+
+ {serversInfo.map((serverInfo: IServersInfo) => (
+
+
+
+
+ }
+ iconOff={}
+ />
+
+
+ ))}
+
}
@@ -173,6 +136,41 @@ export default function ServersView() {
:
servers &&
{
+ setOpen(true)
+ }}
+ onClose={() => {
+ setOpen(false)
+ }}
+ onInputChange={(_, value) => handleInputChange(value)}
+ onChange={(_, value) => handleOptionChange(value)}
+ filterOptions={(x) => x}
+ isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
+ getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
+ options={options}
+ loading={isLoading}
+ value={selectedOption}
+ renderInput={(params) => (
+
+ {isLoading ? : null}
+ {params.InputProps.endAdornment}
+
+ )
+ }}
+ />
+ )}
+ />
+ }
onSave={(id: any) => {
console.log(id)
}}
diff --git a/frontend_reactjs/src/components/TableEditable.tsx b/frontend_reactjs/src/components/TableEditable.tsx
index 3c228ed..2df6736 100644
--- a/frontend_reactjs/src/components/TableEditable.tsx
+++ b/frontend_reactjs/src/components/TableEditable.tsx
@@ -24,6 +24,7 @@ import {
useGridApiContext,
} from '@mui/x-data-grid';
import { AxiosResponse } from 'axios';
+import { Autocomplete } from '@mui/material';
interface EditToolbarProps {
setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void;
@@ -31,10 +32,11 @@ interface EditToolbarProps {
newModel: (oldModel: GridRowModesModel) => GridRowModesModel,
) => void;
columns: GridColDef[];
+ autoComplete?: React.ReactElement | null;
}
function EditToolbar(props: EditToolbarProps) {
- const { setRows, setRowModesModel, columns } = props;
+ const { setRows, setRowModesModel, columns, autoComplete } = props;
const handleClick = () => {
const id = Date.now().toString(36)
@@ -50,6 +52,12 @@ function EditToolbar(props: EditToolbarProps) {
} else {
newValues[column.field] = undefined
}
+
+ if (column.field === 'region_id') {
+ // column.valueGetter = (value: any) => {
+ // console.log(value)
+ // }
+ }
})
setRows((oldRows) => [...oldRows, { id, ...newValues, isNew: true }]);
@@ -60,7 +68,13 @@ function EditToolbar(props: EditToolbarProps) {
};
return (
-
+
+ {autoComplete &&
+
+ {autoComplete}
+
+ }
+
} onClick={handleClick}>
Добавить
@@ -75,6 +89,7 @@ interface DataGridProps {
onRowClick: GridEventListener<"rowClick">;
onSave: any;
onDelete: (data: any) => Promise>;
+ autoComplete?: React.ReactElement | null;
}
export default function FullFeaturedCrudGrid({
@@ -83,7 +98,8 @@ export default function FullFeaturedCrudGrid({
actions = false,
onRowClick,
onSave,
- onDelete
+ onDelete,
+ autoComplete
}: DataGridProps) {
const [rows, setRows] = React.useState(initialRows);
const [rowModesModel, setRowModesModel] = React.useState({});
@@ -206,7 +222,7 @@ export default function FullFeaturedCrudGrid({
toolbar: EditToolbar as GridSlots['toolbar'],
}}
slotProps={{
- toolbar: { setRows, setRowModesModel, columns },
+ toolbar: { setRows, setRowModesModel, columns, autoComplete },
}}
/>
diff --git a/frontend_reactjs/src/hooks/swrHooks.ts b/frontend_reactjs/src/hooks/swrHooks.ts
index c9ccbf2..0a168f9 100644
--- a/frontend_reactjs/src/hooks/swrHooks.ts
+++ b/frontend_reactjs/src/hooks/swrHooks.ts
@@ -189,8 +189,7 @@ export function useServers(region_id?: number, offset?: number, limit?: number)
region_id ? `/api/servers?region_id=${region_id}&offset=${offset || 0}&limit=${limit || 10}` : `/api/servers?offset=${offset || 0}&limit=${limit || 10}`,
(url: string) => fetcher(url, BASE_URL.servers),
{
- revalidateOnFocus: false,
- revalidateOnMount: false
+ revalidateOnFocus: false
}
)
@@ -203,11 +202,10 @@ export function useServers(region_id?: number, offset?: number, limit?: number)
export function useServersInfo(region_id?: number, offset?: number, limit?: number) {
const { data, error, isLoading } = useSWR(
- region_id ? `/api/servers_info?region_id=${region_id}&offset=${offset || 0}&limit=${limit || 10}` : null,
- (url) => fetcher(url, BASE_URL.servers),
+ region_id ? `/api/servers_info?region_id=${region_id}&offset=${offset || 0}&limit=${limit || 10}` : `/api/servers_info?offset=${offset || 0}&limit=${limit || 10}`,
+ (url: string) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false,
- revalidateOnMount: false
}
)
@@ -224,7 +222,6 @@ export function useServer(server_id?: number) {
(url) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false,
- revalidateOnMount: false
}
)
@@ -241,7 +238,6 @@ export function useServerIps(server_id?: number | null, offset?: number, limit?:
(url: string) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false,
- revalidateOnMount: false
}
)
@@ -260,7 +256,6 @@ export function useHardwares(server_id?: number, offset?: number, limit?: number
(url: string) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false,
- revalidateOnMount: false
}
)
@@ -296,7 +291,6 @@ export function useStorages(hardware_id?: number, offset?: number, limit?: numbe
(url: string) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false,
- revalidateOnMount: false
}
)
diff --git a/frontend_reactjs/src/layouts/DashboardLayout.tsx b/frontend_reactjs/src/layouts/DashboardLayout.tsx
index 3fb3472..aed23ef 100644
--- a/frontend_reactjs/src/layouts/DashboardLayout.tsx
+++ b/frontend_reactjs/src/layouts/DashboardLayout.tsx
@@ -11,13 +11,14 @@ import Divider from '@mui/material/Divider';
import IconButton from '@mui/material/IconButton';
import Container from '@mui/material/Container';
import MenuIcon from '@mui/icons-material/Menu';
-import { Api, Assignment, Cloud, Factory, Home, People, Shield, Storage, } from '@mui/icons-material';
-import { ListItem, ListItemButton, ListItemIcon, ListItemText, } from '@mui/material';
+import { Api, Assignment, Cloud, Dashboard, Factory, Home, People, Shield, Storage, } from '@mui/icons-material';
+import { colors, ListItem, ListItemButton, ListItemIcon, ListItemText, } from '@mui/material';
import { Outlet, useNavigate } from 'react-router-dom';
import { UserData } from '../interfaces/auth';
import { getUserData, useAuthStore } from '../store/auth';
import { useTheme } from '@emotion/react';
import AccountMenu from '../components/AccountMenu';
+import { pages } from '../App';
const drawerWidth: number = 240;
@@ -69,49 +70,6 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open'
}),
);
-const pages = [
- {
- label: "Главная",
- path: "/",
- icon:
- },
- {
- label: "Пользователи",
- path: "/user",
- icon:
- },
- {
- label: "Роли",
- path: "/role",
- icon:
- },
- {
- label: "Документы",
- path: "/documents",
- icon:
- },
- {
- label: "Отчеты",
- path: "/reports",
- icon:
- },
- {
- label: "Серверы",
- path: "/servers",
- icon:
- },
- {
- label: "Котельные",
- path: "/boilers",
- icon:
- },
- {
- label: "API Test",
- path: "/api-test",
- icon:
- },
-]
-
export default function DashboardLayout() {
const theme = useTheme()
const innerTheme = createTheme(theme)
@@ -186,17 +144,12 @@ export default function DashboardLayout() {
{userData?.login}
- {/*
-
-
-
- */}
-
+
- {pages.map((item, index) => (
+ {pages.filter((page) => page.drawer).map((item, index) => (
@@ -253,10 +207,7 @@ export default function DashboardLayout() {
diff --git a/frontend_reactjs/src/pages/ApiTest.tsx b/frontend_reactjs/src/pages/ApiTest.tsx
index 7d0388c..de42be9 100644
--- a/frontend_reactjs/src/pages/ApiTest.tsx
+++ b/frontend_reactjs/src/pages/ApiTest.tsx
@@ -1,268 +1,10 @@
-import { AppBar, Autocomplete, Box, Chip, CircularProgress, Dialog, Divider, Grid, IconButton, Paper, TextField, Toolbar, Typography, colors } from "@mui/material"
-import { useBoilers, useCities, useRegions, useServers, useServersInfo } from "../hooks/swrHooks"
-import { Fragment, useEffect, useState } from "react"
-import { IBoiler, ICity, IRegion } from "../interfaces/fuel"
-import { DataGrid, GridColDef } from "@mui/x-data-grid"
-import ServerData from "../components/ServerData"
-import { IServer, IServersInfo } from "../interfaces/servers"
-import { Close, Cloud, CloudOff, Storage } from "@mui/icons-material"
+import { Box } from "@mui/material"
+
export default function ApiTest() {
- const [open, setOpen] = useState(false)
- const [options, setOptions] = useState([])
- const [search, setSearch] = useState(null)
- const [debouncedSearch, setDebouncedSearch] = useState("")
- const [selectedOption, setSelectedOption] = useState(null)
- const { regions, isLoading } = useRegions(10, 1, debouncedSearch)
-
- useEffect(() => {
- const handler = setTimeout(() => {
- setDebouncedSearch(search)
- }, 500)
-
- return () => {
- clearTimeout(handler)
- }
- }, [search])
-
- useEffect(() => {
- if (regions) {
- setOptions([...regions])
- }
- }, [regions])
-
- const handleInputChange = (value: string) => {
- setSearch(value)
- }
-
- const handleOptionChange = (value: IRegion | null) => {
- setSelectedOption(value)
- }
-
- const [citiesOpen, setCitiesOpen] = useState(false)
- const [citiesPage, setCitiesPage] = useState(1)
- const [citiesSearch, setCitiesSearch] = useState('')
- const [debouncedCitySearch, setDebouncedCitySearch] = useState('')
- const { cities, isLoading: citiesLoading } = useCities(10, citiesPage, debouncedCitySearch)
- const [citiesOptions, setCitiesOptions] = useState([])
- const [selectedCityOption, setSelectedCityOption] = useState(null)
-
- const handleCityInputChange = (value: string) => {
- setCitiesSearch(value)
- }
-
- const handleCityOptionChange = (value: ICity | null) => {
- setSelectedCityOption(value)
- }
-
- useEffect(() => {
- if (cities) {
- setCitiesOptions([...cities])
- }
- }, [cities])
-
- useEffect(() => {
- const handler = setTimeout(() => {
- setDebouncedCitySearch(citiesSearch)
- }, 500)
-
- return () => {
- clearTimeout(handler)
- }
- }, [citiesSearch])
-
- useEffect(() => {
- setCitiesPage(1)
- setCitiesSearch("")
- }, [])
-
- const { servers, isLoading: serversLoading } = useServers(selectedOption?.id, 0, 10)
-
- const serversColumns: GridColDef[] = [
- { field: 'id', headerName: 'ID', type: "number" },
- { field: 'name', headerName: 'Название', type: "string" },
- ]
-
- const [serverDataOpen, setServerDataOpen] = useState(false)
- const [currentServerData, setCurrentServerData] = useState(null)
-
- const { serversInfo } = useServersInfo(selectedOption?.id)
-
return (
-
-
-
-
-
-
- Servers
-
-
-
-
- {
- setOpen(true)
- }}
- onClose={() => {
- setOpen(false)
- }}
- onInputChange={(_, value) => handleInputChange(value)}
- onChange={(_, value) => handleOptionChange(value)}
- filterOptions={(x) => x}
- isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
- getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
- options={options}
- loading={isLoading}
- value={selectedOption}
- renderInput={(params) => (
-
- {isLoading ? : null}
- {params.InputProps.endAdornment}
-
- )
- }}
- />
- )}
- />
-
- {
- setCitiesOpen(true)
- }}
- onClose={() => {
- setCitiesOpen(false)
- }}
- onInputChange={(_, value) => handleCityInputChange(value)}
- onChange={(_, value) => handleCityOptionChange(value)}
- filterOptions={(x) => x}
- isOptionEqualToValue={(option: ICity, value: ICity) => option.name === value.name}
- getOptionLabel={(option: ICity) => option.name ? option.name : ""}
- options={citiesOptions}
- loading={citiesLoading}
- value={selectedCityOption}
- renderInput={(params) => (
-
- {citiesLoading ? : null}
- {params.InputProps.endAdornment}
-
- )
- }}
- />
- )}
- />
-
- {servers &&
-
-
- Информация
-
-
- {serversInfo &&
-
- {serversInfo.map((serverInfo: IServersInfo) => (
-
-
-
- {serverInfo.name}
-
-
-
-
-
-
- Количество IP:
-
-
-
- {serverInfo.IPs_count}
-
-
-
-
-
- Количество серверов:
-
-
-
- {serverInfo.servers_count}
-
-
-
- : serverInfo.status === "Offline" ? : }
- variant="outlined"
- label={serverInfo.status}
- color={serverInfo.status === "Online" ? "success" : serverInfo.status === "Offline" ? "error" : "error"}
- />
-
-
- ))}
-
- }
-
- }
-
- {serversLoading ?
-
- :
- servers &&
- {
- setCurrentServerData(params.row)
- setServerDataOpen(true)
- }}
- />
- }
-
)
}
\ No newline at end of file