Servers API

This commit is contained in:
cracklesparkle
2024-07-09 11:58:45 +09:00
parent c74c911eea
commit 6f4aa1903d
26 changed files with 492 additions and 303 deletions

View File

@ -11,6 +11,7 @@
"-": "^0.0.1",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fontsource/open-sans": "^5.0.28",
"@js-preview/docx": "^1.6.2",
"@js-preview/excel": "^1.7.8",
"@js-preview/pdf": "^2.0.2",
@ -2494,6 +2495,11 @@
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
"integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw=="
},
"node_modules/@fontsource/open-sans": {
"version": "5.0.28",
"resolved": "https://registry.npmjs.org/@fontsource/open-sans/-/open-sans-5.0.28.tgz",
"integrity": "sha512-hBvJHY76pJT/JynGUB5EXWhnzjYfLdcMn655J5p1v9lTT9HdQSy+keq2KPVXO2Htlg998BBa3p6u/jlrZ6w0kg=="
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",

View File

@ -13,6 +13,7 @@
"-": "^0.0.1",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fontsource/open-sans": "^5.0.28",
"@js-preview/docx": "^1.6.2",
"@js-preview/excel": "^1.7.8",
"@js-preview/pdf": "^2.0.2",

View File

@ -1,21 +0,0 @@
import { useState, useEffect } from 'react'
interface ICard{
firstname: string
lastname: string
email: string
}
function Card(props:ICard) {
const [curr_card, setCard] = useState<ICard>({firstname:"Иван",lastname:"Петров", email:"email@test.ru"});
useEffect(()=>{setCard(props);},[curr_card])
return (
<div className='block p-6 max-w-sm bg-gray-300
rounded-lg border border-gray-500 align-items: center;'>
<div className='text-4xl text-center'>{curr_card.lastname} {curr_card.firstname}</div>
<div className='text-sm text-center'>{curr_card.email}</div>
</div>
)
}
export default Card

View File

@ -1,35 +0,0 @@
import { DataGrid } from '@mui/x-data-grid';
interface Props {
rows: any,
columns: any,
checkboxSelection?: boolean
}
export default function DataTable(props: Props) {
return (
<DataGrid
autoHeight
style={{ width: "100%" }}
rows={props.rows}
columns={props.columns}
initialState={{
pagination: {
paginationModel: { page: 0, pageSize: 10 },
},
}}
pageSizeOptions={[10, 20, 50, 100]}
checkboxSelection={props.checkboxSelection}
disableRowSelectionOnClick
processRowUpdate={(updatedRow, originalRow) => {
console.log(updatedRow)
return updatedRow
}}
onProcessRowUpdateError={(error)=>{
console.log(error)
}}
/>
);
}

View File

@ -1,4 +1,4 @@
import { useDocuments, useFolders } from '../hooks/swrHooks'
import { useDocuments, useDownload, useFolders } from '../hooks/swrHooks'
import { IDocument, IDocumentFolder } from '../interfaces/documents'
import { Box, Breadcrumbs, Button, Card, CardActionArea, CircularProgress, Divider, IconButton, Input, InputLabel, LinearProgress, Link, List, ListItem, ListItemButton, SxProps } from '@mui/material'
import { Cancel, Close, Download, Folder, InsertDriveFile, Upload, UploadFile } from '@mui/icons-material'
@ -45,7 +45,29 @@ function ItemFolder({ folder, index, handleFolderClick, ...props }: FolderProps)
)
}
const handleSave = async (file: Blob, filename: string) => {
const link = document.createElement('a')
link.href = window.URL.createObjectURL(file)
link.download = filename
link.click()
link.remove()
window.URL.revokeObjectURL(link.href)
}
function ItemDocument({ doc, index, handleDocumentClick, ...props }: DocumentProps) {
const [shouldFetch, setShouldFetch] = useState(false)
const { file, isLoading } = useDownload(shouldFetch ? doc?.document_folder_id : null, shouldFetch ? doc?.id : null)
useEffect(() => {
if (shouldFetch) {
if (file) {
handleSave(file, doc.name)
setShouldFetch(false)
}
}
}, [shouldFetch, file])
return (
<ListItemButton>
<Box
@ -59,11 +81,17 @@ function ItemDocument({ doc, index, handleDocumentClick, ...props }: DocumentPro
<Box>
<IconButton
onClick={() => {
console.log("TODO: save")
if (!isLoading) {
setShouldFetch(true)
}
}}
sx={{ ml: 'auto' }}
>
<Download />
{isLoading ?
<CircularProgress size={24} variant='indeterminate' />
:
<Download />
}
</IconButton>
</Box>
</ListItemButton>

View File

@ -1,57 +0,0 @@
export interface Props {
showModal: boolean;
}
export default function Modal(props:Props){
return(<>
{props.showModal &&
<div id="crud-modal" tabIndex={-1} className="bg-black opacity-75 overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full" onClick={()=> console.log("click")}>
<div className="relative p-4 w-full max-w-md max-h-full" >
<div className="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div className="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
Create New Product
</h3>
<button type="button" className="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-toggle="crud-modal">
<svg className="w-3 h-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span className="sr-only">Close modal</span>
</button>
</div>
<form className="p-4 md:p-5">
<div className="grid gap-4 mb-4 grid-cols-2">
<div className="col-span-2">
<label className="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Name</label>
<input type="text" name="name" id="name" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="Type product name" />
</div>
<div className="col-span-2 sm:col-span-1">
<label className="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Price</label>
<input type="number" name="price" id="price" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="$2999" />
</div>
<div className="col-span-2 sm:col-span-1">
<label className="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Category</label>
<select id="category" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500">
<option >Select category</option>
<option value="TV">TV/Monitors</option>
<option value="PC">PC</option>
<option value="GA">Gaming/Console</option>
<option value="PH">Phones</option>
</select>
</div>
<div className="col-span-2">
<label className="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Product Description</label>
<textarea id="description" rows={4} className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Write product description here"></textarea>
</div>
</div>
<button type="submit" className="text-white inline-flex items-center bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
<svg className="me-1 -ms-1 w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fillRule="evenodd" d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z" clipRule="evenodd"></path></svg>
Add new product
</button>
</form>
</div>
</div>
</div> }
</>)
}

View File

@ -1,19 +0,0 @@
import { useState, useEffect } from 'react'
interface IRoleCard{
id: number
name: string
}
function RoleCard(props:IRoleCard) {
const [curr_card, setCard] = useState<IRoleCard>({id: 1, name: "Тест"});
useEffect(()=>{setCard(props);},[curr_card])
return (
<div className='block p-6 max-w-sm bg-gray-300
rounded-lg border border-gray-500 align-items: center;'>
<div className='text-4xl text-center'>{curr_card.name}</div>
</div>
)
}
export default RoleCard

View File

@ -68,7 +68,7 @@ function DocxViewer({
jsPreviewDocx.init(previewContainerRef.current, {
breakPages: true,
inWrapper: true,
ignoreHeight: true
ignoreHeight: true,
})
.preview(url)
}

View File

@ -1,4 +1,11 @@
export const USER_DATA_KEY = 'userData';
export const TOKEN_AUTH_KEY = 'authToken'
export const TOKEN_ISSUED_DATE_KEY = 'tokenIssuedDate';
export const TOKEN_EXPIRY_DURATION = 7 * 24 * 60 * 60 * 1000;
export const TOKEN_EXPIRY_DURATION = 7 * 24 * 60 * 60 * 1000;
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
}

View File

@ -1,8 +1,9 @@
import useSWR from "swr";
import RoleService from "../services/RoleService";
import UserService from "../services/UserService";
import { blobFetcher, fetcher } from "../http/axiosInstance";
import { fetcher } from "../http/axiosInstance";
import { fileTypeFromBlob } from "file-type/core";
import { BASE_URL } from "../constants";
export function useRoles() {
const { data, error, isLoading } = useSWR(`/auth/roles`, RoleService.getRoles)
@ -66,10 +67,10 @@ export function useDocuments(folder_id?: number) {
}
}
export function useDownload(folder_id?: number, id?: number) {
export function useDownload(folder_id?: number | null, id?: number | null) {
const { data, error, isLoading } = useSWR(
folder_id && id ? `/info/document/${folder_id}&${id}` : null,
folder_id && id ? blobFetcher : null,
folder_id && id ? (url) => fetcher(url, BASE_URL.info, "blob") : null,
{
revalidateOnFocus: false
}
@ -98,7 +99,7 @@ export function useFileType(fileName?: string, file?: Blob) {
}
}
export function useReport(city_id: number) {
export function useReport(city_id?: number) {
const { data, error, isLoading } = useSWR(
city_id ? `/info/reports/${city_id}?to_export=false` : null,
fetcher,
@ -112,4 +113,174 @@ export function useReport(city_id: number) {
isLoading,
isError: error
}
}
// API general
export function useAddress(limit?: number, page?: number) {
const { data, error, isLoading } = useSWR(
`/general/address?limit=${limit || 10}&page=${page || 1}`,
(url) => fetcher(url, import.meta.env.VITE_API_FUEL_URL),
{
revalidateOnFocus: false
}
)
return {
address: data,
isLoading,
isError: error
}
}
export function useBoilers(limit?: number, page?: number, search?: string) {
const { data, error, isLoading } = useSWR(
`/general/boilers?limit=${limit || 10}&page=${page || 1}&search=${search || ""}`,
(url) => fetcher(url, BASE_URL.fuel),
{
revalidateOnFocus: false
}
)
return {
boilers: data,
isLoading,
isError: error
}
}
// Servers
export function useServers(region_id?: number, offset?: number, limit?: number) {
const { data, error, isLoading } = useSWR(
region_id ? `/api/servers?region_id=${region_id}&offset=${offset || 0}&limit=${limit || 10}` : null,
(url) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false
}
)
return {
servers: data,
isLoading,
isError: error
}
}
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),
{
revalidateOnFocus: false
}
)
return {
serversInfo: data,
isLoading,
isError: error
}
}
export function useServer(server_id?: number) {
const { data, error, isLoading } = useSWR(
server_id ? `/api/server/${server_id}` : null,
(url) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false
}
)
return {
server: data,
isLoading,
isError: error
}
}
export function useServerIps(server_id?: number, offset?: number, limit?: number) {
const { data, error, isLoading } = useSWR(
server_id ? `/api/servers?server_id=${server_id}&offset=${offset || 0}&limit=${limit || 10}` : null,
(url) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false
}
)
return {
serverIps: data,
isLoading,
isError: error
}
}
// Hardware
export function useHardwares(server_id?: number, offset?: number, limit?: number) {
const { data, error, isLoading } = useSWR(
server_id ? `/api/hardwares?server_id=${server_id}&offset=${offset || 0}&limit=${limit || 10}` : null,
(url) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false
}
)
return {
hardwares: data,
isLoading,
isError: error
}
}
export function useHardware(hardware_id?: number) {
const { data, error, isLoading } = useSWR(
hardware_id ? `/api/hardware/${hardware_id}` : null,
(url) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false
}
)
return {
hardware: data,
isLoading,
isError: error
}
}
// Storage
export function useStorages(hardware_id?: number, offset?: number, limit?: number) {
const { data, error, isLoading } = useSWR(
hardware_id ? `/api/storages?hardware_id=${hardware_id}&offset=${offset || 0}&limit=${limit || 10}` : null,
(url) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false
}
)
return {
storages: data,
isLoading,
isError: error
}
}
export function useStorage(storage_id?: number) {
const { data, error, isLoading } = useSWR(
storage_id ? `/api/storage/${storage_id}` : null,
(url) => fetcher(url, BASE_URL.servers),
{
revalidateOnFocus: false
}
)
return {
storage: data,
isLoading,
isError: error
}
}

View File

@ -1,27 +1,10 @@
import axios from 'axios';
import axios, { ResponseType } from 'axios';
import { useAuthStore } from '../store/auth';
export const axiosInstanceAuth = axios.create({
baseURL: `${import.meta.env.VITE_API_AUTH_URL}`,
});
const axiosInstance = axios.create({
baseURL: `${import.meta.env.VITE_API_CORE_URL}`,
baseURL: import.meta.env.VITE_API_INFO_URL,
});
axiosInstanceAuth.interceptors.request.use(
(config) => {
const token = useAuthStore.getState().token;
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
axiosInstance.interceptors.request.use(
(config) => {
const token = useAuthStore.getState().token;
@ -35,13 +18,12 @@ axiosInstance.interceptors.request.use(
}
);
export const fetcher = (url: string) => axiosInstance.get(url, {
export const fetcher = (url: string, baseURL?: string, responseType?: ResponseType) => axiosInstance.get(url, {
baseURL: baseURL || import.meta.env.VITE_API_INFO_URL,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(res => res.data)
export const blobFetcher = (url: string) => axiosInstance.get(url, {
responseType: "blob"
},
responseType: responseType ? responseType : "json"
}).then(res => res.data)
export default axiosInstance;

View File

@ -0,0 +1,27 @@
export interface IServer {
id: number;
name: string;
region_id: number;
}
export interface IServerIP {
name: string;
is_actual: boolean;
ip: string;
server_id: number;
}
export interface IHardware {
name: string;
os_info: string;
ram: string;
processor: string;
server_id: number;
}
export interface IStorage {
name: string;
size: string;
storage_type: string;
hardware_id: number;
}

View File

@ -65,7 +65,7 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open'
}),
width: theme.spacing(7),
[theme.breakpoints.up('sm')]: {
width: theme.spacing(9),
//width: theme.spacing(9),
},
}),
},

View File

@ -1,3 +1,4 @@
import "@fontsource/open-sans";
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
@ -9,6 +10,23 @@ import { ruRU } from '@mui/material/locale'
const theme = createTheme(
{
typography: {
fontFamily: [
'Open Sans'
].join(',')
},
components: {
MuiButtonBase: {
defaultProps: {
//disableRipple: true,
}
},
MuiButtonGroup: {
defaultProps: {
//disableRipple: true,
}
}
},
palette: {
primary: { main: '#1976d2' },
},

View File

@ -1,101 +1,20 @@
import { useEffect, useState } from "react"
import { Button, Typography } from "@mui/material"
import axiosInstance from "../http/axiosInstance"
import DataTable from "../components/DataTable"
import { GridColDef } from "@mui/x-data-grid"
import { useServers } from "../hooks/swrHooks"
export default function ApiTest() {
const [state, setState] = useState<any>(null)
const [exportData, setExportData] = useState<any>(null)
const fetch = async () => {
await axiosInstance.get(`/info/reports/0?to_export=true`, {
responseType: 'blob'
}).then(response => {
setExportData(response.data)
console.log(response.data)
const url = window.URL.createObjectURL(response.data)
const link = document.createElement('a')
link.href = url
link.setAttribute('download', 'report.xlsx')
document.body.appendChild(link);
link.click();
link.remove();
})
}
const fetchBlob = async () => {
// await axiosInstance.get(`/info/document/1&2`, {
// responseType: 'blob'
// }).then(response => {
// setState(response)
// })
await axiosInstance.get(`/info/reports/0`).then(response => {
setState(JSON.parse(response.data))
})
}
const columns: GridColDef[] =
[
{ field: 'id', headerName: "№", type: "number", width: 90 },
{ field: 'region', headerName: 'Регион', type: "string", width: 90, },
{ field: 'city', headerName: 'Город', type: "string", width: 130 },
{ field: 'name_type', headerName: 'Вид объекта', type: "string", width: 90, },
{ field: 'name', headerName: 'Наименование', type: "string", width: 90, },
// { field: 'code', headerName: 'Код', type: "string", width: 130 },
// { field: 'code_city', headerName: '', type: "string", width: 90, },
// { field: 'code_fuel', headerName: '', type: "string", width: 90, },
// { field: 'code_master', headerName: '', type: "string", width: 90, },
// { field: 'code_region', headerName: '', type: "string", width: 90, },
// { field: 'code_type', headerName: '', type: "string", width: 90, },
{ field: 'num', headerName: 'Инвентарный код', type: "string", width: 90, },
{ field: 'fuel_type', headerName: 'Тип топлива', type: "string", width: 90, },
{ field: 'fuel', headerName: 'Топливо', type: "string", width: 90, },
{ field: 'zone', headerName: 'Мертвая зона', type: "string", width: 90, },
{ field: 'active', headerName: 'Активность', type: "boolean", width: 70 },
// { field: 'full_name', headerName: 'Полное наименование', type: "string", width: 90, },
];
const { servers } = useServers(32, 0, 10)
return (
<>
<Typography>
<Button onClick={() => {
fetchBlob()
}}>
Получить таблицу
{servers && JSON.stringify(servers)}
</Button>
<Button onClick={() => {
fetch()
}}>
Экспорт
</Button>
{state &&
<DataTable
checkboxSelection={false}
columns={
[
{ field: 'id', headerName: '№', width: 70 },
...Object.keys(state).map(key => ({
field: key,
headerName: key.charAt(0).toUpperCase() + key.slice(1),
width: 150
}))
]
}
rows={
[...new Set(Object.keys(state).flatMap(key => Object.keys(state[key])))].map(id => {
const row: any = { id: Number(id) };
Object.keys(state).forEach(key => {
row[key] = state[key][id];
});
return row;
})
} />
}
</Typography>
</>
)

View File

@ -1,7 +1,15 @@
import { Box, Card, Typography } from "@mui/material";
export default function Main() {
return (
<>
Главная
</>
<Box>
<Typography variant='h6' fontWeight='700'>
Последние файлы
</Typography>
<Card>
</Card>
</Box>
)
}

View File

@ -1,7 +1,7 @@
import { useEffect, useState } from "react"
import { Box, Button, Typography } from "@mui/material"
import axiosInstance from "../http/axiosInstance"
import DataTable from "../components/DataTable"
import { DataGrid } from "@mui/x-data-grid"
export default function Reports() {
const [state, setState] = useState<any>(null)
@ -43,27 +43,42 @@ export default function Reports() {
</Box>
{state &&
<DataTable
<DataGrid
autoHeight
style={{ width: "100%" }}
rows={[...new Set(Object.keys(state).flatMap(key => Object.keys(state[key])))].map(id => {
const row: any = { id: Number(id) };
Object.keys(state).forEach(key => {
row[key] = state[key][id];
});
return row;
})}
columns={[
{ field: 'id', headerName: '№', width: 70 },
...Object.keys(state).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}
columns={
[
{ field: 'id', headerName: '№', width: 70 },
...Object.keys(state).map(key => ({
field: key,
headerName: key.charAt(0).toUpperCase() + key.slice(1),
width: 150
}))
]
}
rows={
[...new Set(Object.keys(state).flatMap(key => Object.keys(state[key])))].map(id => {
const row: any = { id: Number(id) };
Object.keys(state).forEach(key => {
row[key] = state[key][id];
});
return row;
})
} />
disableRowSelectionOnClick
processRowUpdate={(updatedRow, originalRow) => {
console.log(updatedRow)
return updatedRow
}}
onProcessRowUpdateError={(error) => {
console.log(error)
}}
/>
}
</Box>
</>

View File

@ -1,7 +1,6 @@
import { useState } from 'react'
import { Box, Button, CircularProgress } from '@mui/material'
import DataTable from '../components/DataTable'
import { GridColDef } from '@mui/x-data-grid'
import { DataGrid, GridColDef } from '@mui/x-data-grid'
import { useRoles } from '../hooks/swrHooks'
import CreateRoleModal from '../components/modals/CreateRoleModal'
@ -36,7 +35,28 @@ export default function Roles() {
setOpen={setOpen}
/>
<DataTable rows={roles} columns={columns} />
<DataGrid
autoHeight
style={{ width: "100%" }}
rows={roles}
columns={columns}
initialState={{
pagination: {
paginationModel: { page: 0, pageSize: 10 },
},
}}
pageSizeOptions={[10, 20, 50, 100]}
disableRowSelectionOnClick
processRowUpdate={(updatedRow, originalRow) => {
console.log(updatedRow)
return updatedRow
}}
onProcessRowUpdateError={(error) => {
console.log(error)
}}
/>
</Box>
)
}

View File

@ -1,6 +1,5 @@
import { Box, Button, CircularProgress } from "@mui/material"
import DataTable from "../components/DataTable"
import { GridColDef } from "@mui/x-data-grid"
import { DataGrid, GridColDef } from "@mui/x-data-grid"
import { useRoles, useUsers } from "../hooks/swrHooks"
import { IRole } from "../interfaces/role"
import { useState } from "react"
@ -56,7 +55,29 @@ export default function Settings() {
setOpen={setOpen}
/>
<DataTable rows={users} columns={columns} />
<DataGrid
autoHeight
style={{ width: "100%" }}
rows={users}
columns={columns}
initialState={{
pagination: {
paginationModel: { page: 0, pageSize: 10 },
},
}}
pageSizeOptions={[10, 20, 50, 100]}
checkboxSelection
disableRowSelectionOnClick
processRowUpdate={(updatedRow, originalRow) => {
console.log(updatedRow)
return updatedRow
}}
onProcessRowUpdateError={(error) => {
console.log(error)
}}
/>
</Box>
)
}

View File

@ -1,6 +1,5 @@
import { Box, Button, CircularProgress } from "@mui/material"
import DataTable from "../components/DataTable"
import { GridColDef } from "@mui/x-data-grid"
import { DataGrid, GridColDef } from "@mui/x-data-grid"
import { useRoles, useUsers } from "../hooks/swrHooks"
import { IRole } from "../interfaces/role"
import { useState } from "react"
@ -51,7 +50,29 @@ export default function Users() {
setOpen={setOpen}
/>
<DataTable rows={users} columns={columns} />
<DataGrid
autoHeight
style={{ width: "100%" }}
rows={users}
columns={columns}
initialState={{
pagination: {
paginationModel: { page: 0, pageSize: 10 },
},
}}
pageSizeOptions={[10, 20, 50, 100]}
checkboxSelection
disableRowSelectionOnClick
processRowUpdate={(updatedRow, originalRow) => {
console.log(updatedRow)
return updatedRow
}}
onProcessRowUpdateError={(error) => {
console.log(error)
}}
/>
</Box>
)
}

View File

@ -1,19 +1,24 @@
import axiosInstance, { axiosInstanceAuth } from "../http/axiosInstance";
import { AxiosRequestConfig } from "axios";
import { BASE_URL } from "../constants";
import axiosInstance from "../http/axiosInstance";
const config: AxiosRequestConfig = {
baseURL: BASE_URL.auth,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
export default class AuthService {
static async login(data: any) {
return await axiosInstanceAuth.post(`/auth/login`, data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
return await axiosInstance.post(`/auth/login`, data, config)
}
static async refreshToken(token: string) {
return await axiosInstanceAuth.post(`/auth/refresh_token/${token}`)
return await axiosInstance.post(`/auth/refresh_token/${token}`, null, config)
}
static async getCurrentUser(token: string) {
return await axiosInstanceAuth.get(`/auth/get_current_user/${token}`)
return await axiosInstance.get(`/auth/get_current_user/${token}`, config)
}
}

View File

@ -0,0 +1,13 @@
import { AxiosRequestConfig } from "axios";
import axiosInstance from "../http/axiosInstance";
import { BASE_URL } from "../constants";
const config: AxiosRequestConfig = {
baseURL: BASE_URL.fuel
}
export default class FuelService {
static async getAddress(limit?: number, page?: number) {
return await axiosInstance.get(`/general/address?limit=${limit || 10}&page=${page || 1}`, config)
}
}

View File

@ -1,18 +1,24 @@
import axiosInstance, { axiosInstanceAuth } from "../http/axiosInstance";
import { AxiosRequestConfig } from "axios";
import axiosInstance from "../http/axiosInstance";
import { IRoleCreate } from "../interfaces/role";
import { BASE_URL } from "../constants";
const config: AxiosRequestConfig = {
baseURL: BASE_URL.auth
}
export default class RoleService {
static async getRoles() {
return await axiosInstanceAuth.get(`/auth/roles`)
return await axiosInstance.get(`/auth/roles`, config)
}
static async createRole(data: IRoleCreate) {
return await axiosInstanceAuth.post(`/auth/roles/`, data)
return await axiosInstance.post(`/auth/roles/`, data, config)
}
static async getRoleById(id: number) {
return await axiosInstanceAuth.get(`/auth/roles/${id}`)
return await axiosInstance.get(`/auth/roles/${id}`, config)
}
// static async deleteRole(id: number) {

View File

@ -0,0 +1,42 @@
import axios, { AxiosRequestConfig } from "axios";
import axiosInstance from "../http/axiosInstance";
import { IHardware, IServer, IServerIP, IStorage } from "../interfaces/servers";
import { BASE_URL } from "../constants";
const config: AxiosRequestConfig = {
baseURL: BASE_URL.servers
}
export default class ServerService {
static async removeServer(server_id: number) {
return await axiosInstance.delete(`/api/server/${server_id}`, config)
}
static async addServer(data: IServer) {
return await axiosInstance.post(`/api/server/`, data, config)
}
static async removeHardware(hardware_id: number) {
return await axiosInstance.delete(`/api/hardware/${hardware_id}`, config)
}
static async addHardware(data: IHardware) {
return await axiosInstance.post(`/api/hardware`, data, config)
}
static async removeStorage(storage_id: number) {
return await axiosInstance.delete(`/api/storage/${storage_id}`, config)
}
static async addStorage(data: IStorage) {
return await axiosInstance.post(`/api/storage`, data, config)
}
static async addServerIp(data: IServerIP) {
return await axiosInstance.post(`/api/server_ip`, data, config)
}
static async removeServerIp(ip_id: number) {
return await axiosInstance.delete(`/api/server_ip/${ip_id}`, config)
}
}

View File

@ -1,17 +1,23 @@
import axiosInstance, { axiosInstanceAuth } from "../http/axiosInstance";
import { AxiosRequestConfig } from "axios";
import axiosInstance from "../http/axiosInstance";
import { UserCreds, UserData } from "../interfaces/auth";
import { BASE_URL } from "../constants";
const config: AxiosRequestConfig = {
baseURL: BASE_URL.auth
}
export default class UserService {
static async createUser(data: any) {
return await axiosInstanceAuth.post(`/auth/user`, data)
return await axiosInstance.post(`/auth/user`, data, config)
}
static async getCurrentUser(token: string) {
return await axiosInstanceAuth.get(`/auth/get_current_user/${token}`)
return await axiosInstance.get(`/auth/get_current_user/${token}`, config)
}
static async getUsers() {
return await axiosInstanceAuth.get(`/auth/user`)
return await axiosInstance.get(`/auth/user`, config)
}
// static async deleteUser(id: number) {
@ -19,14 +25,14 @@ export default class UserService {
// }
static async getUser(id: number) {
return await axiosInstanceAuth.get(`/auth/user/${id}`)
return await axiosInstance.get(`/auth/user/${id}`, config)
}
static async updatePassword(data: UserCreds) {
return await axiosInstanceAuth.put(`/auth/user/password_change`, data)
return await axiosInstance.put(`/auth/user/password_change`, data, config)
}
static async updateUser(data: UserData) {
return await axiosInstanceAuth.put(`/auth/user`, data)
return await axiosInstance.put(`/auth/user`, data, config)
}
}

View File

@ -1148,6 +1148,11 @@
resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz"
integrity sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==
"@fontsource/open-sans@^5.0.28":
version "5.0.28"
resolved "https://registry.npmjs.org/@fontsource/open-sans/-/open-sans-5.0.28.tgz"
integrity sha512-hBvJHY76pJT/JynGUB5EXWhnzjYfLdcMn655J5p1v9lTT9HdQSy+keq2KPVXO2Htlg998BBa3p6u/jlrZ6w0kg==
"@humanwhocodes/config-array@^0.11.14":
version "0.11.14"
resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz"