8 changed files with 727 additions and 292 deletions
-
23frontend_reactjs/src/components/ServerData.tsx
-
146frontend_reactjs/src/components/ServerHardware.tsx
-
144frontend_reactjs/src/components/ServerIpsView.tsx
-
143frontend_reactjs/src/components/ServerStorages.tsx
-
191frontend_reactjs/src/components/ServersView.tsx
-
33frontend_reactjs/src/components/TableEditable.tsx
-
36frontend_reactjs/src/hooks/swrHooks.ts
-
303frontend_reactjs/src/pages/Servers.tsx
@ -0,0 +1,146 @@ |
|||||
|
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material' |
||||
|
import React, { Fragment, useEffect, useState } from 'react' |
||||
|
import { IRegion } from '../interfaces/fuel' |
||||
|
import { useHardwares, useRegions, useServerIps, useServers } from '../hooks/swrHooks' |
||||
|
import FullFeaturedCrudGrid from './TableEditable' |
||||
|
import ServerService from '../services/ServersService' |
||||
|
import { GridColDef } from '@mui/x-data-grid' |
||||
|
import { Close } from '@mui/icons-material' |
||||
|
import ServerData from './ServerData' |
||||
|
|
||||
|
export default function ServerHardware() { |
||||
|
const [open, setOpen] = useState(false) |
||||
|
const [options, setOptions] = useState<IRegion[]>([]) |
||||
|
const [search, setSearch] = useState<string | null>("") |
||||
|
const [debouncedSearch, setDebouncedSearch] = useState<string | null>("") |
||||
|
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null) |
||||
|
const { servers, isLoading } = useServers() |
||||
|
|
||||
|
const [serverDataOpen, setServerDataOpen] = useState(false) |
||||
|
const [currentServerData, setCurrentServerData] = useState<any | null>(null) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
const handler = setTimeout(() => { |
||||
|
setDebouncedSearch(search) |
||||
|
}, 500) |
||||
|
|
||||
|
return () => { |
||||
|
clearTimeout(handler) |
||||
|
} |
||||
|
}, [search]) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
if (servers) { |
||||
|
setOptions([...servers]) |
||||
|
} |
||||
|
}, [servers]) |
||||
|
|
||||
|
const handleInputChange = (value: string) => { |
||||
|
setSearch(value) |
||||
|
} |
||||
|
|
||||
|
const handleOptionChange = (value: IRegion | null) => { |
||||
|
setSelectedOption(value) |
||||
|
} |
||||
|
|
||||
|
const { hardwares, isLoading: serversLoading } = useHardwares(selectedOption?.id, 0, 10) |
||||
|
|
||||
|
const hardwareColumns: GridColDef[] = [ |
||||
|
{ field: 'id', headerName: 'ID', type: 'number' }, |
||||
|
{ field: 'name', headerName: 'Название', type: 'string' }, |
||||
|
{ field: 'server_id', headerName: 'Server ID', type: 'number' }, |
||||
|
{ field: 'servername', headerName: 'Название сервера', type: 'string' }, |
||||
|
{ field: 'os_info', headerName: 'ОС', type: 'string' }, |
||||
|
{ field: 'ram', headerName: 'ОЗУ', type: 'string' }, |
||||
|
{ field: 'processor', headerName: 'Проц.', type: 'string' }, |
||||
|
{ field: 'storages_count', headerName: 'Кол-во хранилищ', type: 'number' }, |
||||
|
] |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<Dialog |
||||
|
fullScreen |
||||
|
open={serverDataOpen} |
||||
|
onClose={() => { |
||||
|
setServerDataOpen(false) |
||||
|
}} |
||||
|
aria-labelledby="modal-modal-title" |
||||
|
aria-describedby="modal-modal-description"> |
||||
|
<AppBar sx={{ position: 'sticky' }}> |
||||
|
<Toolbar> |
||||
|
<IconButton |
||||
|
edge="start" |
||||
|
color="inherit" |
||||
|
onClick={() => { |
||||
|
setServerDataOpen(false) |
||||
|
}} |
||||
|
aria-label="close" |
||||
|
> |
||||
|
<Close /> |
||||
|
</IconButton> |
||||
|
</Toolbar> |
||||
|
</AppBar> |
||||
|
|
||||
|
{currentServerData && |
||||
|
<ServerData |
||||
|
id={currentServerData?.id} |
||||
|
region_id={currentServerData?.region_id} |
||||
|
name={currentServerData?.name} |
||||
|
/> |
||||
|
} |
||||
|
</Dialog> |
||||
|
|
||||
|
<Autocomplete |
||||
|
open={open} |
||||
|
onOpen={() => { |
||||
|
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) => ( |
||||
|
<TextField |
||||
|
{...params} |
||||
|
label="Сервер" |
||||
|
InputProps={{ |
||||
|
...params.InputProps, |
||||
|
endAdornment: ( |
||||
|
<Fragment> |
||||
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null} |
||||
|
{params.InputProps.endAdornment} |
||||
|
</Fragment> |
||||
|
) |
||||
|
}} |
||||
|
/> |
||||
|
)} |
||||
|
/> |
||||
|
|
||||
|
{serversLoading ? |
||||
|
<CircularProgress /> |
||||
|
: |
||||
|
servers && |
||||
|
<FullFeaturedCrudGrid |
||||
|
onSave={(id: any) => { |
||||
|
console.log(id) |
||||
|
}} |
||||
|
onDelete={ServerService.removeServer} |
||||
|
initialRows={hardwares} |
||||
|
columns={hardwareColumns} |
||||
|
actions |
||||
|
onRowClick={(params, event, details) => { |
||||
|
setCurrentServerData(params.row) |
||||
|
setServerDataOpen(true) |
||||
|
}} |
||||
|
/> |
||||
|
} |
||||
|
</> |
||||
|
) |
||||
|
} |
@ -0,0 +1,144 @@ |
|||||
|
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material' |
||||
|
import React, { Fragment, useEffect, useState } from 'react' |
||||
|
import { IRegion } from '../interfaces/fuel' |
||||
|
import { useRegions, useServerIps, useServers } from '../hooks/swrHooks' |
||||
|
import FullFeaturedCrudGrid from './TableEditable' |
||||
|
import ServerService from '../services/ServersService' |
||||
|
import { GridColDef } from '@mui/x-data-grid' |
||||
|
import { Close } from '@mui/icons-material' |
||||
|
import ServerData from './ServerData' |
||||
|
|
||||
|
export default function ServerIpsView() { |
||||
|
const [open, setOpen] = useState(false) |
||||
|
const [options, setOptions] = useState<IRegion[]>([]) |
||||
|
const [search, setSearch] = useState<string | null>("") |
||||
|
const [debouncedSearch, setDebouncedSearch] = useState<string | null>("") |
||||
|
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null) |
||||
|
const { servers, isLoading } = useServers() |
||||
|
|
||||
|
const [serverDataOpen, setServerDataOpen] = useState(false) |
||||
|
const [currentServerData, setCurrentServerData] = useState<any | null>(null) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
const handler = setTimeout(() => { |
||||
|
setDebouncedSearch(search) |
||||
|
}, 500) |
||||
|
|
||||
|
return () => { |
||||
|
clearTimeout(handler) |
||||
|
} |
||||
|
}, [search]) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
if (servers) { |
||||
|
setOptions([...servers]) |
||||
|
} |
||||
|
}, [servers]) |
||||
|
|
||||
|
const handleInputChange = (value: string) => { |
||||
|
setSearch(value) |
||||
|
} |
||||
|
|
||||
|
const handleOptionChange = (value: IRegion | null) => { |
||||
|
setSelectedOption(value) |
||||
|
} |
||||
|
|
||||
|
const { serverIps, isLoading: serversLoading } = useServerIps(selectedOption?.id, 0, 10) |
||||
|
|
||||
|
const serverIpsColumns: GridColDef[] = [ |
||||
|
{ field: 'id', headerName: 'ID', type: 'number' }, |
||||
|
{ field: 'server_id', headerName: 'Server ID', type: 'number' }, |
||||
|
{ field: 'name', headerName: 'Название', type: 'string' }, |
||||
|
{ field: 'is_actual', headerName: 'Действителен', type: 'boolean' }, |
||||
|
{ field: 'ip', headerName: 'IP', type: 'string' }, |
||||
|
{ field: 'servername', headerName: 'Название сервера', type: 'string' }, |
||||
|
] |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<Dialog |
||||
|
fullScreen |
||||
|
open={serverDataOpen} |
||||
|
onClose={() => { |
||||
|
setServerDataOpen(false) |
||||
|
}} |
||||
|
aria-labelledby="modal-modal-title" |
||||
|
aria-describedby="modal-modal-description"> |
||||
|
<AppBar sx={{ position: 'sticky' }}> |
||||
|
<Toolbar> |
||||
|
<IconButton |
||||
|
edge="start" |
||||
|
color="inherit" |
||||
|
onClick={() => { |
||||
|
setServerDataOpen(false) |
||||
|
}} |
||||
|
aria-label="close" |
||||
|
> |
||||
|
<Close /> |
||||
|
</IconButton> |
||||
|
</Toolbar> |
||||
|
</AppBar> |
||||
|
|
||||
|
{currentServerData && |
||||
|
<ServerData |
||||
|
id={currentServerData?.id} |
||||
|
region_id={currentServerData?.region_id} |
||||
|
name={currentServerData?.name} |
||||
|
/> |
||||
|
} |
||||
|
</Dialog> |
||||
|
|
||||
|
<Autocomplete |
||||
|
open={open} |
||||
|
onOpen={() => { |
||||
|
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) => ( |
||||
|
<TextField |
||||
|
{...params} |
||||
|
label="Сервер" |
||||
|
InputProps={{ |
||||
|
...params.InputProps, |
||||
|
endAdornment: ( |
||||
|
<Fragment> |
||||
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null} |
||||
|
{params.InputProps.endAdornment} |
||||
|
</Fragment> |
||||
|
) |
||||
|
}} |
||||
|
/> |
||||
|
)} |
||||
|
/> |
||||
|
|
||||
|
{serversLoading ? |
||||
|
<CircularProgress /> |
||||
|
: |
||||
|
servers && |
||||
|
<FullFeaturedCrudGrid |
||||
|
onSave={(id: any) => { |
||||
|
console.log(id) |
||||
|
}} |
||||
|
onDelete={ServerService.removeServer} |
||||
|
initialRows={serverIps} |
||||
|
columns={serverIpsColumns} |
||||
|
actions |
||||
|
onRowClick={(params, event, details) => { |
||||
|
setCurrentServerData(params.row) |
||||
|
setServerDataOpen(true) |
||||
|
}} |
||||
|
/> |
||||
|
} |
||||
|
</> |
||||
|
) |
||||
|
} |
@ -0,0 +1,143 @@ |
|||||
|
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material' |
||||
|
import React, { Fragment, useEffect, useState } from 'react' |
||||
|
import { IRegion } from '../interfaces/fuel' |
||||
|
import { useHardwares, useRegions, useServerIps, useServers, useStorages } from '../hooks/swrHooks' |
||||
|
import FullFeaturedCrudGrid from './TableEditable' |
||||
|
import ServerService from '../services/ServersService' |
||||
|
import { GridColDef } from '@mui/x-data-grid' |
||||
|
import { Close } from '@mui/icons-material' |
||||
|
import ServerData from './ServerData' |
||||
|
|
||||
|
export default function ServerStorage() { |
||||
|
const [open, setOpen] = useState(false) |
||||
|
const [options, setOptions] = useState<IRegion[]>([]) |
||||
|
const [search, setSearch] = useState<string | null>("") |
||||
|
const [debouncedSearch, setDebouncedSearch] = useState<string | null>("") |
||||
|
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null) |
||||
|
const { hardwares, isLoading } = useHardwares() |
||||
|
|
||||
|
const [serverDataOpen, setServerDataOpen] = useState(false) |
||||
|
const [currentServerData, setCurrentServerData] = useState<any | null>(null) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
const handler = setTimeout(() => { |
||||
|
setDebouncedSearch(search) |
||||
|
}, 500) |
||||
|
|
||||
|
return () => { |
||||
|
clearTimeout(handler) |
||||
|
} |
||||
|
}, [search]) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
if (hardwares) { |
||||
|
setOptions([...hardwares]) |
||||
|
} |
||||
|
}, [hardwares]) |
||||
|
|
||||
|
const handleInputChange = (value: string) => { |
||||
|
setSearch(value) |
||||
|
} |
||||
|
|
||||
|
const handleOptionChange = (value: IRegion | null) => { |
||||
|
setSelectedOption(value) |
||||
|
} |
||||
|
|
||||
|
const { storages, isLoading: serversLoading } = useStorages(selectedOption?.id, 0, 10) |
||||
|
|
||||
|
const storageColumns: GridColDef[] = [ |
||||
|
{ field: 'id', headerName: 'ID', type: 'number' }, |
||||
|
{ field: 'hardware_id', headerName: 'Hardware ID', type: 'number' }, |
||||
|
{ field: 'name', headerName: 'Название', type: 'string' }, |
||||
|
{ field: 'size', headerName: 'Размер', type: 'string' }, |
||||
|
{ field: 'storage_type', headerName: 'Тип хранилища', type: 'string' }, |
||||
|
] |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<Dialog |
||||
|
fullScreen |
||||
|
open={serverDataOpen} |
||||
|
onClose={() => { |
||||
|
setServerDataOpen(false) |
||||
|
}} |
||||
|
aria-labelledby="modal-modal-title" |
||||
|
aria-describedby="modal-modal-description"> |
||||
|
<AppBar sx={{ position: 'sticky' }}> |
||||
|
<Toolbar> |
||||
|
<IconButton |
||||
|
edge="start" |
||||
|
color="inherit" |
||||
|
onClick={() => { |
||||
|
setServerDataOpen(false) |
||||
|
}} |
||||
|
aria-label="close" |
||||
|
> |
||||
|
<Close /> |
||||
|
</IconButton> |
||||
|
</Toolbar> |
||||
|
</AppBar> |
||||
|
|
||||
|
{currentServerData && |
||||
|
<ServerData |
||||
|
id={currentServerData?.id} |
||||
|
region_id={currentServerData?.region_id} |
||||
|
name={currentServerData?.name} |
||||
|
/> |
||||
|
} |
||||
|
</Dialog> |
||||
|
|
||||
|
<Autocomplete |
||||
|
open={open} |
||||
|
onOpen={() => { |
||||
|
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) => ( |
||||
|
<TextField |
||||
|
{...params} |
||||
|
label="Hardware" |
||||
|
InputProps={{ |
||||
|
...params.InputProps, |
||||
|
endAdornment: ( |
||||
|
<Fragment> |
||||
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null} |
||||
|
{params.InputProps.endAdornment} |
||||
|
</Fragment> |
||||
|
) |
||||
|
}} |
||||
|
/> |
||||
|
)} |
||||
|
/> |
||||
|
|
||||
|
{serversLoading ? |
||||
|
<CircularProgress /> |
||||
|
: |
||||
|
storages && |
||||
|
<FullFeaturedCrudGrid |
||||
|
onSave={(id: any) => { |
||||
|
console.log(id) |
||||
|
}} |
||||
|
onDelete={ServerService.removeServer} |
||||
|
initialRows={storages} |
||||
|
columns={storageColumns} |
||||
|
actions |
||||
|
onRowClick={(params, event, details) => { |
||||
|
setCurrentServerData(params.row) |
||||
|
setServerDataOpen(true) |
||||
|
}} |
||||
|
/> |
||||
|
} |
||||
|
</> |
||||
|
) |
||||
|
} |
@ -0,0 +1,191 @@ |
|||||
|
import { AppBar, Autocomplete, Box, Chip, CircularProgress, Dialog, Divider, Grid, IconButton, Paper, TextField, Toolbar, Typography } from '@mui/material' |
||||
|
import React, { Fragment, useEffect, useState } from 'react' |
||||
|
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 { Close, Cloud, CloudOff } from '@mui/icons-material' |
||||
|
import ServerData from './ServerData' |
||||
|
import { IServersInfo } from '../interfaces/servers' |
||||
|
|
||||
|
export default function ServersView() { |
||||
|
const [open, setOpen] = useState(false) |
||||
|
const [options, setOptions] = useState<IRegion[]>([]) |
||||
|
const [search, setSearch] = useState<string | null>("") |
||||
|
const [debouncedSearch, setDebouncedSearch] = useState<string | null>("") |
||||
|
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null) |
||||
|
const { regions, isLoading } = useRegions(10, 1, debouncedSearch) |
||||
|
|
||||
|
const { serversInfo } = useServersInfo(selectedOption?.id) |
||||
|
|
||||
|
|
||||
|
const [serverDataOpen, setServerDataOpen] = useState(false) |
||||
|
const [currentServerData, setCurrentServerData] = useState<any | null>(null) |
||||
|
|
||||
|
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 { servers, isLoading: serversLoading } = useServers(selectedOption?.id, 0, 10) |
||||
|
|
||||
|
const serversColumns: GridColDef[] = [ |
||||
|
//{ field: 'id', headerName: 'ID', type: "number" },
|
||||
|
{ field: 'name', headerName: 'Название', type: "string", editable: true }, |
||||
|
] |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<Dialog |
||||
|
fullScreen |
||||
|
open={serverDataOpen} |
||||
|
onClose={() => { |
||||
|
setServerDataOpen(false) |
||||
|
}} |
||||
|
aria-labelledby="modal-modal-title" |
||||
|
aria-describedby="modal-modal-description"> |
||||
|
<AppBar sx={{ position: 'sticky' }}> |
||||
|
<Toolbar> |
||||
|
<IconButton |
||||
|
edge="start" |
||||
|
color="inherit" |
||||
|
onClick={() => { |
||||
|
setServerDataOpen(false) |
||||
|
}} |
||||
|
aria-label="close" |
||||
|
> |
||||
|
<Close /> |
||||
|
</IconButton> |
||||
|
</Toolbar> |
||||
|
</AppBar> |
||||
|
|
||||
|
{currentServerData && |
||||
|
<ServerData |
||||
|
id={currentServerData?.id} |
||||
|
region_id={currentServerData?.region_id} |
||||
|
name={currentServerData?.name} |
||||
|
/> |
||||
|
} |
||||
|
</Dialog> |
||||
|
|
||||
|
<Autocomplete |
||||
|
open={open} |
||||
|
onOpen={() => { |
||||
|
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) => ( |
||||
|
<TextField |
||||
|
{...params} |
||||
|
label="Район" |
||||
|
InputProps={{ |
||||
|
...params.InputProps, |
||||
|
endAdornment: ( |
||||
|
<Fragment> |
||||
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null} |
||||
|
{params.InputProps.endAdornment} |
||||
|
</Fragment> |
||||
|
) |
||||
|
}} |
||||
|
/> |
||||
|
)} |
||||
|
/> |
||||
|
|
||||
|
{servers && |
||||
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', height: '100%' }}> |
||||
|
{serversInfo && |
||||
|
<Grid container spacing={{ xs: 2, md: 3 }} columns={{ xs: 1, sm: 1, md: 2, lg: 3, xl: 4 }}> |
||||
|
{serversInfo.map((serverInfo: IServersInfo) => ( |
||||
|
<Grid key={`si-${serverInfo.id}`} item xs={1} sm={1} md={1}> |
||||
|
<Paper sx={{ display: 'flex', flexDirection: 'column', gap: '16px', p: '16px' }}> |
||||
|
<Typography fontWeight={600}> |
||||
|
{serverInfo.name} |
||||
|
</Typography> |
||||
|
|
||||
|
<Divider /> |
||||
|
|
||||
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> |
||||
|
<Typography> |
||||
|
Количество IP: |
||||
|
</Typography> |
||||
|
|
||||
|
<Typography variant="h6" fontWeight={600}> |
||||
|
{serverInfo.IPs_count} |
||||
|
</Typography> |
||||
|
</Box> |
||||
|
|
||||
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> |
||||
|
<Typography> |
||||
|
Количество серверов: |
||||
|
</Typography> |
||||
|
|
||||
|
<Typography variant="h6" fontWeight={600}> |
||||
|
{serverInfo.servers_count} |
||||
|
</Typography> |
||||
|
</Box> |
||||
|
|
||||
|
<Chip |
||||
|
icon={serverInfo.status === "Online" ? <Cloud /> : serverInfo.status === "Offline" ? <CloudOff /> : <CloudOff />} |
||||
|
variant="outlined" |
||||
|
label={serverInfo.status} |
||||
|
color={serverInfo.status === "Online" ? "success" : serverInfo.status === "Offline" ? "error" : "error"} |
||||
|
/> |
||||
|
</Paper> |
||||
|
</Grid> |
||||
|
))} |
||||
|
</Grid> |
||||
|
} |
||||
|
</Box> |
||||
|
} |
||||
|
|
||||
|
{serversLoading ? |
||||
|
<CircularProgress /> |
||||
|
: |
||||
|
servers && |
||||
|
<FullFeaturedCrudGrid |
||||
|
onSave={(id: any) => { |
||||
|
console.log(id) |
||||
|
}} |
||||
|
onDelete={ServerService.removeServer} |
||||
|
initialRows={servers} |
||||
|
columns={serversColumns} |
||||
|
actions |
||||
|
onRowClick={(params, event, details) => { |
||||
|
setCurrentServerData(params.row) |
||||
|
setServerDataOpen(true) |
||||
|
}} |
||||
|
/> |
||||
|
} |
||||
|
</> |
||||
|
) |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue