forked from VinokurovVE/tests
Update
This commit is contained in:
13
frontend_reactjs/package-lock.json
generated
13
frontend_reactjs/package-lock.json
generated
@ -20,6 +20,7 @@
|
|||||||
"@mui/material": "^5.15.20",
|
"@mui/material": "^5.15.20",
|
||||||
"@mui/x-charts": "^7.8.0",
|
"@mui/x-charts": "^7.8.0",
|
||||||
"@mui/x-data-grid": "^7.7.1",
|
"@mui/x-data-grid": "^7.7.1",
|
||||||
|
"@uidotdev/usehooks": "^2.4.1",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"file-type": "^19.0.0",
|
"file-type": "^19.0.0",
|
||||||
@ -3897,6 +3898,18 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@uidotdev/usehooks": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@uidotdev/usehooks/-/usehooks-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18.0.0",
|
||||||
|
"react-dom": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@ungap/structured-clone": {
|
"node_modules/@ungap/structured-clone": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
"@mui/material": "^5.15.20",
|
"@mui/material": "^5.15.20",
|
||||||
"@mui/x-charts": "^7.8.0",
|
"@mui/x-charts": "^7.8.0",
|
||||||
"@mui/x-data-grid": "^7.7.1",
|
"@mui/x-data-grid": "^7.7.1",
|
||||||
|
"@uidotdev/usehooks": "^2.4.1",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"file-type": "^19.0.0",
|
"file-type": "^19.0.0",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Box, Chip, Divider, Paper, Typography } from '@mui/material'
|
import { Divider, Paper, Typography } from '@mui/material'
|
||||||
import React, { PropsWithChildren, ReactElement, ReactNode } from 'react'
|
import { PropsWithChildren } from 'react'
|
||||||
|
|
||||||
interface CardInfoProps extends PropsWithChildren {
|
interface CardInfoProps extends PropsWithChildren {
|
||||||
label: string;
|
label: string;
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { Cloud } from '@mui/icons-material';
|
import { Chip } from '@mui/material'
|
||||||
import { Chip, SvgIconTypeMap } from '@mui/material'
|
import { ReactElement } from 'react'
|
||||||
import { OverridableComponent } from '@mui/material/OverridableComponent';
|
|
||||||
import React, { ReactElement } from 'react'
|
|
||||||
|
|
||||||
interface CardInfoChipProps {
|
interface CardInfoChipProps {
|
||||||
status: boolean;
|
status: boolean;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { Box, Typography } from '@mui/material'
|
import { Box, Typography } from '@mui/material'
|
||||||
import React from 'react'
|
|
||||||
|
|
||||||
interface CardInfoLabelProps {
|
interface CardInfoLabelProps {
|
||||||
label: string;
|
label: string;
|
||||||
value: string | number;
|
value: string | number;
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
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<string | null>("")
|
|
||||||
|
|
||||||
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 (
|
|
||||||
<Autocomplete
|
|
||||||
sx={{ flexGrow: '1' }}
|
|
||||||
open={open}
|
|
||||||
onOpen={() => {
|
|
||||||
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) => (
|
|
||||||
<TextField
|
|
||||||
{...params}
|
|
||||||
size='small'
|
|
||||||
label="Район"
|
|
||||||
variant='standard'
|
|
||||||
InputProps={{
|
|
||||||
...params.InputProps,
|
|
||||||
endAdornment: (
|
|
||||||
<Fragment>
|
|
||||||
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
|
||||||
{params.InputProps.endAdornment}
|
|
||||||
</Fragment>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
@ -3,8 +3,9 @@ import { IServer } from '../interfaces/servers'
|
|||||||
import { useServerIps } from '../hooks/swrHooks'
|
import { useServerIps } from '../hooks/swrHooks'
|
||||||
import FullFeaturedCrudGrid from './TableEditable'
|
import FullFeaturedCrudGrid from './TableEditable'
|
||||||
import { GridColDef } from '@mui/x-data-grid'
|
import { GridColDef } from '@mui/x-data-grid'
|
||||||
|
import { AxiosResponse } from 'axios'
|
||||||
|
|
||||||
function ServerData({ id, name, region_id }: IServer) {
|
function ServerData({ id }: IServer) {
|
||||||
const { serverIps } = useServerIps(id, 0, 10)
|
const { serverIps } = useServerIps(id, 0, 10)
|
||||||
|
|
||||||
const serverIpsColumns: GridColDef[] = [
|
const serverIpsColumns: GridColDef[] = [
|
||||||
@ -24,9 +25,16 @@ function ServerData({ id, name, region_id }: IServer) {
|
|||||||
columns={serverIpsColumns}
|
columns={serverIpsColumns}
|
||||||
actions
|
actions
|
||||||
onRowClick={(params, event, details) => {
|
onRowClick={(params, event, details) => {
|
||||||
|
console.log(params.id, event, details)
|
||||||
//setCurrentServerData(params.row)
|
//setCurrentServerData(params.row)
|
||||||
//setServerDataOpen(true)
|
//setServerDataOpen(true)
|
||||||
}}
|
}}
|
||||||
|
onSave={undefined}
|
||||||
|
onDelete={function (data: any): Promise<AxiosResponse<any, any>> {
|
||||||
|
console.log(data)
|
||||||
|
throw new Error('Function not implemented.')
|
||||||
|
}}
|
||||||
|
loading={false}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material'
|
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material'
|
||||||
import React, { Fragment, useEffect, useState } from 'react'
|
import { Fragment, useEffect, useState } from 'react'
|
||||||
import { IRegion } from '../interfaces/fuel'
|
import { IRegion } from '../interfaces/fuel'
|
||||||
import { useHardwares, useRegions, useServerIps, useServers } from '../hooks/swrHooks'
|
import { useHardwares, useServers } from '../hooks/swrHooks'
|
||||||
import FullFeaturedCrudGrid from './TableEditable'
|
import FullFeaturedCrudGrid from './TableEditable'
|
||||||
import ServerService from '../services/ServersService'
|
import ServerService from '../services/ServersService'
|
||||||
import { GridColDef } from '@mui/x-data-grid'
|
import { GridColDef } from '@mui/x-data-grid'
|
||||||
@ -95,41 +95,37 @@ export default function ServerHardware() {
|
|||||||
:
|
:
|
||||||
hardwares &&
|
hardwares &&
|
||||||
<FullFeaturedCrudGrid
|
<FullFeaturedCrudGrid
|
||||||
autoComplete={
|
autoComplete={<Autocomplete
|
||||||
<Autocomplete
|
open={open}
|
||||||
open={open}
|
onOpen={() => {
|
||||||
onOpen={() => {
|
setOpen(true)
|
||||||
setOpen(true)
|
}}
|
||||||
}}
|
onClose={() => {
|
||||||
onClose={() => {
|
setOpen(false)
|
||||||
setOpen(false)
|
}}
|
||||||
}}
|
onInputChange={(_, value) => handleInputChange(value)}
|
||||||
onInputChange={(_, value) => handleInputChange(value)}
|
onChange={(_, value) => handleOptionChange(value)}
|
||||||
onChange={(_, value) => handleOptionChange(value)}
|
filterOptions={(x) => x}
|
||||||
filterOptions={(x) => x}
|
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
|
||||||
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
|
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
||||||
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
options={options}
|
||||||
options={options}
|
loading={isLoading}
|
||||||
loading={isLoading}
|
value={selectedOption}
|
||||||
value={selectedOption}
|
renderInput={(params) => (
|
||||||
renderInput={(params) => (
|
<TextField
|
||||||
<TextField
|
{...params}
|
||||||
{...params}
|
label="Сервер"
|
||||||
label="Сервер"
|
size='small'
|
||||||
size='small'
|
InputProps={{
|
||||||
InputProps={{
|
...params.InputProps,
|
||||||
...params.InputProps,
|
endAdornment: (
|
||||||
endAdornment: (
|
<Fragment>
|
||||||
<Fragment>
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
||||||
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
{params.InputProps.endAdornment}
|
||||||
{params.InputProps.endAdornment}
|
</Fragment>
|
||||||
</Fragment>
|
)
|
||||||
)
|
}} />
|
||||||
}}
|
)} />}
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onSave={(id: any) => {
|
onSave={(id: any) => {
|
||||||
console.log(id)
|
console.log(id)
|
||||||
}}
|
}}
|
||||||
@ -140,8 +136,7 @@ export default function ServerHardware() {
|
|||||||
onRowClick={(params, event, details) => {
|
onRowClick={(params, event, details) => {
|
||||||
setCurrentServerData(params.row)
|
setCurrentServerData(params.row)
|
||||||
setServerDataOpen(true)
|
setServerDataOpen(true)
|
||||||
}}
|
}} loading={false} />
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material'
|
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material'
|
||||||
import React, { Fragment, useEffect, useState } from 'react'
|
import { Fragment, useEffect, useState } from 'react'
|
||||||
import { IRegion } from '../interfaces/fuel'
|
import { IRegion } from '../interfaces/fuel'
|
||||||
import { useRegions, useServerIps, useServers } from '../hooks/swrHooks'
|
import { useServerIps, useServers } from '../hooks/swrHooks'
|
||||||
import FullFeaturedCrudGrid from './TableEditable'
|
import FullFeaturedCrudGrid from './TableEditable'
|
||||||
import ServerService from '../services/ServersService'
|
import ServerService from '../services/ServersService'
|
||||||
import { GridColDef } from '@mui/x-data-grid'
|
import { GridColDef } from '@mui/x-data-grid'
|
||||||
@ -93,41 +93,37 @@ export default function ServerIpsView() {
|
|||||||
:
|
:
|
||||||
serverIps &&
|
serverIps &&
|
||||||
<FullFeaturedCrudGrid
|
<FullFeaturedCrudGrid
|
||||||
autoComplete={
|
autoComplete={<Autocomplete
|
||||||
<Autocomplete
|
open={open}
|
||||||
open={open}
|
onOpen={() => {
|
||||||
onOpen={() => {
|
setOpen(true)
|
||||||
setOpen(true)
|
}}
|
||||||
}}
|
onClose={() => {
|
||||||
onClose={() => {
|
setOpen(false)
|
||||||
setOpen(false)
|
}}
|
||||||
}}
|
onInputChange={(_, value) => handleInputChange(value)}
|
||||||
onInputChange={(_, value) => handleInputChange(value)}
|
onChange={(_, value) => handleOptionChange(value)}
|
||||||
onChange={(_, value) => handleOptionChange(value)}
|
filterOptions={(x) => x}
|
||||||
filterOptions={(x) => x}
|
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
|
||||||
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
|
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
||||||
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
options={options}
|
||||||
options={options}
|
loading={isLoading}
|
||||||
loading={isLoading}
|
value={selectedOption}
|
||||||
value={selectedOption}
|
renderInput={(params) => (
|
||||||
renderInput={(params) => (
|
<TextField
|
||||||
<TextField
|
{...params}
|
||||||
{...params}
|
size='small'
|
||||||
size='small'
|
label="Сервер"
|
||||||
label="Сервер"
|
InputProps={{
|
||||||
InputProps={{
|
...params.InputProps,
|
||||||
...params.InputProps,
|
endAdornment: (
|
||||||
endAdornment: (
|
<Fragment>
|
||||||
<Fragment>
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
||||||
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
{params.InputProps.endAdornment}
|
||||||
{params.InputProps.endAdornment}
|
</Fragment>
|
||||||
</Fragment>
|
)
|
||||||
)
|
}} />
|
||||||
}}
|
)} />}
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onSave={(id: any) => {
|
onSave={(id: any) => {
|
||||||
console.log(id)
|
console.log(id)
|
||||||
}}
|
}}
|
||||||
@ -138,8 +134,7 @@ export default function ServerIpsView() {
|
|||||||
onRowClick={(params, event, details) => {
|
onRowClick={(params, event, details) => {
|
||||||
setCurrentServerData(params.row)
|
setCurrentServerData(params.row)
|
||||||
setServerDataOpen(true)
|
setServerDataOpen(true)
|
||||||
}}
|
}} loading={false} />
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -1,34 +1,26 @@
|
|||||||
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material'
|
import { AppBar, Autocomplete, CircularProgress, Dialog, IconButton, TextField, Toolbar } from '@mui/material'
|
||||||
import React, { Fragment, useEffect, useState } from 'react'
|
import { Fragment, useEffect, useState } from 'react'
|
||||||
import { IRegion } from '../interfaces/fuel'
|
import { IRegion } from '../interfaces/fuel'
|
||||||
import { useHardwares, useRegions, useServerIps, useServers, useStorages } from '../hooks/swrHooks'
|
import { useHardwares, useStorages } from '../hooks/swrHooks'
|
||||||
import FullFeaturedCrudGrid from './TableEditable'
|
import FullFeaturedCrudGrid from './TableEditable'
|
||||||
import ServerService from '../services/ServersService'
|
import ServerService from '../services/ServersService'
|
||||||
import { GridColDef } from '@mui/x-data-grid'
|
import { GridColDef } from '@mui/x-data-grid'
|
||||||
import { Close } from '@mui/icons-material'
|
import { Close } from '@mui/icons-material'
|
||||||
import ServerData from './ServerData'
|
import ServerData from './ServerData'
|
||||||
|
import { useDebounce } from '@uidotdev/usehooks'
|
||||||
|
|
||||||
export default function ServerStorage() {
|
export default function ServerStorage() {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [options, setOptions] = useState<IRegion[]>([])
|
const [options, setOptions] = useState<IRegion[]>([])
|
||||||
const [search, setSearch] = useState<string | null>("")
|
const [search, setSearch] = useState<string | null>("")
|
||||||
const [debouncedSearch, setDebouncedSearch] = useState<string | null>("")
|
|
||||||
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null)
|
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null)
|
||||||
const { hardwares, isLoading } = useHardwares()
|
const { hardwares, isLoading } = useHardwares()
|
||||||
|
|
||||||
|
const debouncedSearch = useDebounce(search, 500)
|
||||||
|
|
||||||
const [serverDataOpen, setServerDataOpen] = useState(false)
|
const [serverDataOpen, setServerDataOpen] = useState(false)
|
||||||
const [currentServerData, setCurrentServerData] = useState<any | null>(null)
|
const [currentServerData, setCurrentServerData] = useState<any | null>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const handler = setTimeout(() => {
|
|
||||||
setDebouncedSearch(search)
|
|
||||||
}, 500)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearTimeout(handler)
|
|
||||||
}
|
|
||||||
}, [search])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hardwares) {
|
if (hardwares) {
|
||||||
setOptions([...hardwares])
|
setOptions([...hardwares])
|
||||||
@ -92,41 +84,37 @@ export default function ServerStorage() {
|
|||||||
:
|
:
|
||||||
storages &&
|
storages &&
|
||||||
<FullFeaturedCrudGrid
|
<FullFeaturedCrudGrid
|
||||||
autoComplete={
|
autoComplete={<Autocomplete
|
||||||
<Autocomplete
|
open={open}
|
||||||
open={open}
|
onOpen={() => {
|
||||||
onOpen={() => {
|
setOpen(true)
|
||||||
setOpen(true)
|
}}
|
||||||
}}
|
onClose={() => {
|
||||||
onClose={() => {
|
setOpen(false)
|
||||||
setOpen(false)
|
}}
|
||||||
}}
|
onInputChange={(_, value) => handleInputChange(value)}
|
||||||
onInputChange={(_, value) => handleInputChange(value)}
|
onChange={(_, value) => handleOptionChange(value)}
|
||||||
onChange={(_, value) => handleOptionChange(value)}
|
filterOptions={(x) => x}
|
||||||
filterOptions={(x) => x}
|
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
|
||||||
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
|
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
||||||
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
options={options}
|
||||||
options={options}
|
loading={isLoading}
|
||||||
loading={isLoading}
|
value={selectedOption}
|
||||||
value={selectedOption}
|
renderInput={(params) => (
|
||||||
renderInput={(params) => (
|
<TextField
|
||||||
<TextField
|
{...params}
|
||||||
{...params}
|
size='small'
|
||||||
size='small'
|
label="Hardware"
|
||||||
label="Hardware"
|
InputProps={{
|
||||||
InputProps={{
|
...params.InputProps,
|
||||||
...params.InputProps,
|
endAdornment: (
|
||||||
endAdornment: (
|
<Fragment>
|
||||||
<Fragment>
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
||||||
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
{params.InputProps.endAdornment}
|
||||||
{params.InputProps.endAdornment}
|
</Fragment>
|
||||||
</Fragment>
|
)
|
||||||
)
|
}} />
|
||||||
}}
|
)} />}
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onSave={(id: any) => {
|
onSave={(id: any) => {
|
||||||
console.log(id)
|
console.log(id)
|
||||||
}}
|
}}
|
||||||
@ -138,6 +126,7 @@ export default function ServerStorage() {
|
|||||||
setCurrentServerData(params.row)
|
setCurrentServerData(params.row)
|
||||||
setServerDataOpen(true)
|
setServerDataOpen(true)
|
||||||
}}
|
}}
|
||||||
|
loading={false}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AppBar, Autocomplete, Box, Chip, CircularProgress, Dialog, Divider, Grid, IconButton, Paper, TextField, Toolbar, Typography } from '@mui/material'
|
import { AppBar, Autocomplete, Box, CircularProgress, Dialog, Grid, IconButton, TextField, Toolbar } from '@mui/material'
|
||||||
import React, { Fragment, useEffect, useState } from 'react'
|
import { Fragment, useEffect, useState } from 'react'
|
||||||
import { IRegion } from '../interfaces/fuel'
|
import { IRegion } from '../interfaces/fuel'
|
||||||
import { useRegions, useServers, useServersInfo } from '../hooks/swrHooks'
|
import { useRegions, useServers, useServersInfo } from '../hooks/swrHooks'
|
||||||
import FullFeaturedCrudGrid from './TableEditable'
|
import FullFeaturedCrudGrid from './TableEditable'
|
||||||
@ -11,47 +11,30 @@ import { IServersInfo } from '../interfaces/servers'
|
|||||||
import CardInfo from './CardInfo/CardInfo'
|
import CardInfo from './CardInfo/CardInfo'
|
||||||
import CardInfoLabel from './CardInfo/CardInfoLabel'
|
import CardInfoLabel from './CardInfo/CardInfoLabel'
|
||||||
import CardInfoChip from './CardInfo/CardInfoChip'
|
import CardInfoChip from './CardInfo/CardInfoChip'
|
||||||
import DataGridCellAutocomplete from './DataGridCellAutocomplete'
|
import { useDebounce } from '@uidotdev/usehooks'
|
||||||
|
|
||||||
export default function ServersView() {
|
export default function ServersView() {
|
||||||
const [open, setOpen] = useState(false)
|
|
||||||
const [editOpen, setEditOpen] = useState(false)
|
|
||||||
const [options, setOptions] = useState<IRegion[]>([])
|
const [options, setOptions] = useState<IRegion[]>([])
|
||||||
const [search, setSearch] = useState<string | null>("")
|
const [search, setSearch] = useState<string | null>("")
|
||||||
const [debouncedSearch, setDebouncedSearch] = useState<string | null>("")
|
//const [debouncedSearch, setDebouncedSearch] = useState<string | null>("")
|
||||||
|
|
||||||
|
const debouncedSearch = useDebounce(search, 500)
|
||||||
|
|
||||||
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null)
|
const [selectedOption, setSelectedOption] = useState<IRegion | null>(null)
|
||||||
|
|
||||||
const { regions, isLoading } = useRegions(10, 1, debouncedSearch)
|
const { regions, isLoading } = useRegions(10, 1, debouncedSearch)
|
||||||
|
|
||||||
const { serversInfo } = useServersInfo(selectedOption?.id)
|
const { serversInfo } = useServersInfo(selectedOption?.id)
|
||||||
|
|
||||||
|
|
||||||
const [serverDataOpen, setServerDataOpen] = useState(false)
|
const [serverDataOpen, setServerDataOpen] = useState(false)
|
||||||
const [currentServerData, setCurrentServerData] = useState<any | null>(null)
|
const [currentServerData, setCurrentServerData] = useState<any | null>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const handler = setTimeout(() => {
|
|
||||||
setDebouncedSearch(search)
|
|
||||||
}, 500)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearTimeout(handler)
|
|
||||||
}
|
|
||||||
}, [search])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (regions) {
|
if (regions) {
|
||||||
setOptions([...regions])
|
setOptions([...regions])
|
||||||
}
|
}
|
||||||
}, [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 { servers, isLoading: serversLoading } = useServers(selectedOption?.id, 0, 10)
|
||||||
|
|
||||||
const serversColumns: GridColDef[] = [
|
const serversColumns: GridColDef[] = [
|
||||||
@ -60,16 +43,40 @@ export default function ServersView() {
|
|||||||
{
|
{
|
||||||
field: 'region_id',
|
field: 'region_id',
|
||||||
editable: true,
|
editable: true,
|
||||||
|
renderCell: (params) => (
|
||||||
|
<div>
|
||||||
|
{params.value}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
renderEditCell: (params: GridRenderCellParams) => (
|
renderEditCell: (params: GridRenderCellParams) => (
|
||||||
<DataGridCellAutocomplete
|
<Autocomplete
|
||||||
selectedOption={params.value}
|
sx={{ display: 'flex', flexGrow: '1' }}
|
||||||
setSelectedOption={(value: any) => {
|
onInputChange={(_, value) => setSearch(value)}
|
||||||
|
onChange={(_, value) => {
|
||||||
params.value = value
|
params.value = value
|
||||||
}}
|
}}
|
||||||
isLoading={isLoading}
|
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
|
||||||
setDebouncedSearch={setDebouncedSearch}
|
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
||||||
options={options}
|
options={options}
|
||||||
setOptions={setOptions}
|
loading={isLoading}
|
||||||
|
value={params.value}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
size='small'
|
||||||
|
variant='standard'
|
||||||
|
label="Район"
|
||||||
|
InputProps={{
|
||||||
|
...params.InputProps,
|
||||||
|
endAdornment: (
|
||||||
|
<Fragment>
|
||||||
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
||||||
|
{params.InputProps.endAdornment}
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
width: 200
|
width: 200
|
||||||
@ -131,59 +138,47 @@ export default function ServersView() {
|
|||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
|
|
||||||
{serversLoading ?
|
<FullFeaturedCrudGrid
|
||||||
<CircularProgress />
|
loading={serversLoading}
|
||||||
:
|
autoComplete={
|
||||||
servers &&
|
<Autocomplete
|
||||||
<FullFeaturedCrudGrid
|
onInputChange={(_, value) => setSearch(value)}
|
||||||
autoComplete={
|
onChange={(_, value) => setSelectedOption(value)}
|
||||||
<Autocomplete
|
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.id === value.id}
|
||||||
open={open}
|
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
||||||
onOpen={() => {
|
options={options}
|
||||||
setOpen(true)
|
loading={isLoading}
|
||||||
}}
|
value={selectedOption}
|
||||||
onClose={() => {
|
renderInput={(params) => (
|
||||||
setOpen(false)
|
<TextField
|
||||||
}}
|
{...params}
|
||||||
onInputChange={(_, value) => handleInputChange(value)}
|
size='small'
|
||||||
onChange={(_, value) => handleOptionChange(value)}
|
label="Район"
|
||||||
filterOptions={(x) => x}
|
InputProps={{
|
||||||
isOptionEqualToValue={(option: IRegion, value: IRegion) => option.name === value.name}
|
...params.InputProps,
|
||||||
getOptionLabel={(option: IRegion) => option.name ? option.name : ""}
|
endAdornment: (
|
||||||
options={options}
|
<Fragment>
|
||||||
loading={isLoading}
|
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
||||||
value={selectedOption}
|
{params.InputProps.endAdornment}
|
||||||
renderInput={(params) => (
|
</Fragment>
|
||||||
<TextField
|
)
|
||||||
{...params}
|
}}
|
||||||
size='small'
|
/>
|
||||||
label="Район"
|
)}
|
||||||
InputProps={{
|
/>
|
||||||
...params.InputProps,
|
}
|
||||||
endAdornment: (
|
onSave={(id: any) => {
|
||||||
<Fragment>
|
console.log(id)
|
||||||
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
}}
|
||||||
{params.InputProps.endAdornment}
|
onDelete={ServerService.removeServer}
|
||||||
</Fragment>
|
initialRows={servers}
|
||||||
)
|
columns={serversColumns}
|
||||||
}}
|
actions
|
||||||
/>
|
onRowClick={(params, event, details) => {
|
||||||
)}
|
setCurrentServerData(params.row)
|
||||||
/>
|
setServerDataOpen(true)
|
||||||
}
|
}}
|
||||||
onSave={(id: any) => {
|
/>
|
||||||
console.log(id)
|
|
||||||
}}
|
|
||||||
onDelete={ServerService.removeServer}
|
|
||||||
initialRows={servers}
|
|
||||||
columns={serversColumns}
|
|
||||||
actions
|
|
||||||
onRowClick={(params, event, details) => {
|
|
||||||
setCurrentServerData(params.row)
|
|
||||||
setServerDataOpen(true)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import * as React from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
@ -19,12 +19,8 @@ import {
|
|||||||
GridRowModel,
|
GridRowModel,
|
||||||
GridRowEditStopReasons,
|
GridRowEditStopReasons,
|
||||||
GridSlots,
|
GridSlots,
|
||||||
GridRowProps,
|
|
||||||
GridRow,
|
|
||||||
useGridApiContext,
|
|
||||||
} from '@mui/x-data-grid';
|
} from '@mui/x-data-grid';
|
||||||
import { AxiosResponse } from 'axios';
|
import { AxiosResponse } from 'axios';
|
||||||
import { Autocomplete } from '@mui/material';
|
|
||||||
|
|
||||||
interface EditToolbarProps {
|
interface EditToolbarProps {
|
||||||
setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void;
|
setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void;
|
||||||
@ -90,6 +86,7 @@ interface DataGridProps {
|
|||||||
onSave: any;
|
onSave: any;
|
||||||
onDelete: (data: any) => Promise<AxiosResponse<any, any>>;
|
onDelete: (data: any) => Promise<AxiosResponse<any, any>>;
|
||||||
autoComplete?: React.ReactElement | null;
|
autoComplete?: React.ReactElement | null;
|
||||||
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function FullFeaturedCrudGrid({
|
export default function FullFeaturedCrudGrid({
|
||||||
@ -99,10 +96,11 @@ export default function FullFeaturedCrudGrid({
|
|||||||
onRowClick,
|
onRowClick,
|
||||||
onSave,
|
onSave,
|
||||||
onDelete,
|
onDelete,
|
||||||
autoComplete
|
autoComplete,
|
||||||
|
loading
|
||||||
}: DataGridProps) {
|
}: DataGridProps) {
|
||||||
const [rows, setRows] = React.useState(initialRows);
|
const [rows, setRows] = useState(initialRows);
|
||||||
const [rowModesModel, setRowModesModel] = React.useState<GridRowModesModel>({});
|
const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
|
||||||
|
|
||||||
const handleRowEditStop: GridEventListener<'rowEditStop'> = (params, event) => {
|
const handleRowEditStop: GridEventListener<'rowEditStop'> = (params, event) => {
|
||||||
if (params.reason === GridRowEditStopReasons.rowFocusOut) {
|
if (params.reason === GridRowEditStopReasons.rowFocusOut) {
|
||||||
@ -147,6 +145,12 @@ export default function FullFeaturedCrudGrid({
|
|||||||
setRowModesModel(newRowModesModel);
|
setRowModesModel(newRowModesModel);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (initialRows) {
|
||||||
|
setRows(initialRows)
|
||||||
|
}
|
||||||
|
}, [initialRows])
|
||||||
|
|
||||||
const actionColumns: GridColDef[] = [
|
const actionColumns: GridColDef[] = [
|
||||||
{
|
{
|
||||||
field: 'actions',
|
field: 'actions',
|
||||||
@ -210,7 +214,8 @@ export default function FullFeaturedCrudGrid({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DataGrid
|
<DataGrid
|
||||||
rows={rows}
|
loading={loading}
|
||||||
|
rows={rows || []}
|
||||||
columns={actions ? [...columns, ...actionColumns] : columns}
|
columns={actions ? [...columns, ...actionColumns] : columns}
|
||||||
editMode="row"
|
editMode="row"
|
||||||
rowModesModel={rowModesModel}
|
rowModesModel={rowModesModel}
|
||||||
|
@ -184,12 +184,12 @@ export function useBoilers(limit?: number, page?: number, search?: string) {
|
|||||||
|
|
||||||
// Servers
|
// Servers
|
||||||
|
|
||||||
export function useServers(region_id?: number, offset?: number, limit?: number) {
|
export function useServers(region_id?: number | null, offset?: number, limit?: number) {
|
||||||
const { data, error, isLoading } = useSWR(
|
const { data, error, isLoading } = useSWR(
|
||||||
region_id ? `/api/servers?region_id=${region_id}&offset=${offset || 0}&limit=${limit || 10}` : `/api/servers?offset=${offset || 0}&limit=${limit || 10}`,
|
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),
|
(url: string) => fetcher(url, BASE_URL.servers),
|
||||||
{
|
{
|
||||||
revalidateOnFocus: false
|
revalidateOnFocus: false,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import Divider from '@mui/material/Divider';
|
|||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import Container from '@mui/material/Container';
|
import Container from '@mui/material/Container';
|
||||||
import MenuIcon from '@mui/icons-material/Menu';
|
import MenuIcon from '@mui/icons-material/Menu';
|
||||||
import { Api, Assignment, Cloud, Dashboard, Factory, Home, People, Shield, Storage, } from '@mui/icons-material';
|
|
||||||
import { colors, ListItem, ListItemButton, ListItemIcon, ListItemText, } from '@mui/material';
|
import { colors, ListItem, ListItemButton, ListItemIcon, ListItemText, } from '@mui/material';
|
||||||
import { Outlet, useNavigate } from 'react-router-dom';
|
import { Outlet, useNavigate } from 'react-router-dom';
|
||||||
import { UserData } from '../interfaces/auth';
|
import { UserData } from '../interfaces/auth';
|
||||||
|
@ -9,7 +9,7 @@ import { createTheme } from '@mui/material'
|
|||||||
import { ruRU } from '@mui/material/locale'
|
import { ruRU } from '@mui/material/locale'
|
||||||
import { getDarkMode, usePrefStore } from "./store/preferences.ts";
|
import { getDarkMode, usePrefStore } from "./store/preferences.ts";
|
||||||
|
|
||||||
const darkTheme = createTheme(
|
const mainTheme = createTheme(
|
||||||
{
|
{
|
||||||
typography: {
|
typography: {
|
||||||
fontFamily: [
|
fontFamily: [
|
||||||
@ -28,6 +28,11 @@ const darkTheme = createTheme(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const darkTheme = createTheme(
|
||||||
|
{
|
||||||
palette: {
|
palette: {
|
||||||
mode: "dark",
|
mode: "dark",
|
||||||
primary: { main: '#1976d2' },
|
primary: { main: '#1976d2' },
|
||||||
@ -38,23 +43,6 @@ const darkTheme = createTheme(
|
|||||||
|
|
||||||
const lightTheme = createTheme(
|
const lightTheme = createTheme(
|
||||||
{
|
{
|
||||||
typography: {
|
|
||||||
fontFamily: [
|
|
||||||
'Inter'
|
|
||||||
].join(',')
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
MuiButtonBase: {
|
|
||||||
defaultProps: {
|
|
||||||
//disableRipple: true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MuiButtonGroup: {
|
|
||||||
defaultProps: {
|
|
||||||
//disableRipple: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
palette: {
|
palette: {
|
||||||
mode: "light",
|
mode: "light",
|
||||||
primary: { main: '#1976d2' },
|
primary: { main: '#1976d2' },
|
||||||
@ -82,7 +70,7 @@ function ThemedApp() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={prefStore.darkMode ? darkTheme : lightTheme}>
|
<ThemeProvider theme={prefStore.darkMode ? { ...mainTheme, ...darkTheme } : { ...mainTheme, ...lightTheme }}>
|
||||||
<App />
|
<App />
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Box, Typography } from '@mui/material'
|
import { Box, Typography } from '@mui/material'
|
||||||
import { DataGrid, GridColDef } from '@mui/x-data-grid'
|
import { DataGrid, GridColDef } from '@mui/x-data-grid'
|
||||||
import React, { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { IBoiler } from '../interfaces/fuel'
|
import { IBoiler } from '../interfaces/fuel'
|
||||||
import { useBoilers } from '../hooks/swrHooks'
|
import { useBoilers } from '../hooks/swrHooks'
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ export default function Servers() {
|
|||||||
const [currentTab, setCurrentTab] = useState(0)
|
const [currentTab, setCurrentTab] = useState(0)
|
||||||
|
|
||||||
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
|
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
|
||||||
|
console.log(event)
|
||||||
setCurrentTab(newValue);
|
setCurrentTab(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ const config: AxiosRequestConfig = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class AuthService {
|
export default class AuthService {
|
||||||
static async login(data: FormData) {
|
static async login(data: URLSearchParams) {
|
||||||
return await axiosInstance.post(`/auth/login`, data, config)
|
return await axiosInstance.post(`/auth/login`, data, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,13 @@
|
|||||||
],
|
],
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
"lib": [
|
||||||
|
"ES2020",
|
||||||
|
"DOM",
|
||||||
|
"DOM.Iterable"
|
||||||
|
],
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|
||||||
/* Bundler mode */
|
/* Bundler mode */
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
@ -16,13 +19,18 @@
|
|||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
/* Linting */
|
/* Linting */
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noFallthroughCasesInSwitch": true
|
"noFallthroughCasesInSwitch": true
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": [
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
"src"
|
||||||
}
|
],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1706,6 +1706,11 @@
|
|||||||
"@typescript-eslint/types" "7.13.0"
|
"@typescript-eslint/types" "7.13.0"
|
||||||
eslint-visitor-keys "^3.4.3"
|
eslint-visitor-keys "^3.4.3"
|
||||||
|
|
||||||
|
"@uidotdev/usehooks@^2.4.1":
|
||||||
|
version "2.4.1"
|
||||||
|
resolved "https://registry.npmjs.org/@uidotdev/usehooks/-/usehooks-2.4.1.tgz"
|
||||||
|
integrity sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg==
|
||||||
|
|
||||||
"@ungap/structured-clone@^1.2.0":
|
"@ungap/structured-clone@^1.2.0":
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz"
|
resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz"
|
||||||
@ -4167,7 +4172,7 @@ randomfill@^1.0.3:
|
|||||||
randombytes "^2.0.5"
|
randombytes "^2.0.5"
|
||||||
safe-buffer "^5.1.0"
|
safe-buffer "^5.1.0"
|
||||||
|
|
||||||
"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0", react-dom@^18.2.0, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.0:
|
"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0", react-dom@^18.2.0, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.0, react-dom@>=18.0.0:
|
||||||
version "18.3.1"
|
version "18.3.1"
|
||||||
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
|
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
|
||||||
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
|
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
|
||||||
@ -4220,7 +4225,7 @@ react-transition-group@^4.4.5:
|
|||||||
loose-envify "^1.4.0"
|
loose-envify "^1.4.0"
|
||||||
prop-types "^15.6.2"
|
prop-types "^15.6.2"
|
||||||
|
|
||||||
"react@^16.11.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^17.0.0 || ^18.0.0", react@^18.2.0, react@^18.3.1, react@>=16.6.0, react@>=16.8, react@>=16.8.0:
|
"react@^16.11.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^17.0.0 || ^18.0.0", react@^18.2.0, react@^18.3.1, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=18.0.0:
|
||||||
version "18.3.1"
|
version "18.3.1"
|
||||||
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
|
||||||
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
|
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
|
||||||
|
Reference in New Issue
Block a user