Skip to content

Commit

Permalink
feat: finish the basic version of the admin panel
Browse files Browse the repository at this point in the history
  • Loading branch information
AlasDiablo committed Jul 22, 2024
1 parent 3b5b1f9 commit ab5def4
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 22 deletions.
2 changes: 2 additions & 0 deletions tdm-admin/src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '~/app/App.scss';

import Menu from '~/app/components/Menu';
import Dashboard from '~/app/page/Dashboard';
import Database from '~/app/page/Database';
import File from '~/app/page/File';
import Log from '~/app/page/Log';
Expand Down Expand Up @@ -63,6 +64,7 @@ const App = () => {
</Drawer>

<Container id="container" maxWidth="xl" sx={{ padding: '24px' }}>
{page === 'home' ? <Dashboard /> : null}
{page === 'database' ? <Database /> : null}
{page === 'file' ? <File /> : null}
{page === 'log' ? <Log /> : null}
Expand Down
14 changes: 7 additions & 7 deletions tdm-admin/src/app/components/database/StatusCell.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { DatabaseStatus } from '~/app/util/type';
import { ProcessingStatus } from '~/app/util/type';
import { getDatabaseStatus } from '~/app/util/utils';

import Chip from '@mui/material/Chip';
import { useMemo } from 'react';

type StatusCellProps = {
value: DatabaseStatus;
value: ProcessingStatus;
};

const StatusCell = ({ value }: StatusCellProps) => {
Expand All @@ -14,15 +14,15 @@ const StatusCell = ({ value }: StatusCellProps) => {
}, [value]);

switch (value) {
case DatabaseStatus.UNKNOWN:
case ProcessingStatus.UNKNOWN:
return <Chip label={status} size="small" />;

case DatabaseStatus.WRAPPER_ERROR:
case DatabaseStatus.ENRICHMENT_ERROR:
case DatabaseStatus.FINISHED_ERROR:
case ProcessingStatus.WRAPPER_ERROR:
case ProcessingStatus.ENRICHMENT_ERROR:
case ProcessingStatus.FINISHED_ERROR:
return <Chip label={status} color="warning" size="small" />;

case DatabaseStatus.FINISHED:
case ProcessingStatus.FINISHED:
return <Chip label={status} color="success" size="small" />;

default:
Expand Down
76 changes: 76 additions & 0 deletions tdm-admin/src/app/page/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { dashboard } from '~/app/services/admin/dashboard';
import { getDatabaseStatus } from '~/app/util/utils';

import Alert from '@mui/material/Alert';
import Box from '@mui/material/Box';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import { useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
import {
Area,
AreaChart,
PolarAngleAxis,
PolarGrid,
PolarRadiusAxis,
Radar,
RadarChart,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from 'recharts';

import type { StorageDashboard } from '~/app/util/type';

const Dashboard = () => {
const { data, isFetching, isLoading } = useQuery({
queryKey: ['dashboard'],
queryFn: () => {
return dashboard();
},
});

const statusData = useMemo(() => {
if (!data) {
return [];
}
const output = [];
for (const datum of Object.entries(data.status)) {
output.push({
name: getDatabaseStatus(Number(datum[0])).toLowerCase().replace('_', ' '),
count: datum[1],
});
}
return output;
}, [data]);

if (isFetching || isLoading) {
return <p>Is Loading</p>;
}

if (!data) {
return <Alert color="error">No database found.</Alert>;
}

return (
<Box>
<Paper sx={{ width: '500px', height: '300px', padding: '12px' }}>
<Typography sx={{ textAlign: 'center' }} variant="h5">
Résumé des Status
</Typography>
<ResponsiveContainer width="100%" height="100%">
<RadarChart cx="50%" cy="50%" outerRadius="60%" data={statusData}>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis />
<Tooltip />
<Radar dataKey="count" stroke="#8884d8" fill="#8884d8" fillOpacity={0.6} />
</RadarChart>
</ResponsiveContainer>
</Paper>
</Box>
);
};

export default Dashboard;
2 changes: 1 addition & 1 deletion tdm-admin/src/app/page/Database.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const Database = () => {
}

if (!data) {
return <Alert color="error">No database found.</Alert>;
return <Alert color="error">Nous n&apos;as vont pas peu récupérais les donnée.</Alert>;
}

return (
Expand Down
1 change: 1 addition & 0 deletions tdm-admin/src/app/services/Environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const environment = {
files: '/api/admin/files',
logs: '/api/admin/logs',
database: '/api/admin/database',
dashboard: '/api/admin/dashboard',
},
post: {
config: '/config/set',
Expand Down
15 changes: 15 additions & 0 deletions tdm-admin/src/app/services/admin/dashboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createQuery, environment, getAuthHeader, json } from '~/app/services/Environment';

import type { Dashboard } from '~/app/util/type';

export const dashboard = async (): Promise<Dashboard> => {
const response = await fetch(createQuery(environment.get.dashboard), {
headers: {
Authorization: getAuthHeader(),
},
});
if (response.status !== 200) {
return { status: {}, storage: { download: [], tmp: [], upload: [] } };
}
return await json<Dashboard>(response);
};
22 changes: 20 additions & 2 deletions tdm-admin/src/app/util/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export type Files = {
};

// eslint-disable-next-line no-shadow
export enum DatabaseStatus {
export enum ProcessingStatus {
UNKNOWN,
STARTING,
WRAPPER_RUNNING,
Expand All @@ -60,7 +60,7 @@ export enum DatabaseStatus {

export type Database = {
id: string;
status: DatabaseStatus;
status: ProcessingStatus;
email: string | null;
wrapper: string | null;
wrapperParam: string | null;
Expand All @@ -77,3 +77,21 @@ export type Databases = {
total: number;
results: Database[];
};

export type StorageDashboard = {
date: string;
size: number;
};

export type Dashboard = {
status: Partial<Record<ProcessingStatus, number>>;
storage: {
free: number;
used: number;
files: {
upload: StorageDashboard[];
tmp: StorageDashboard[];
download: StorageDashboard[];
};
};
};
24 changes: 12 additions & 12 deletions tdm-admin/src/app/util/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DatabaseStatus } from '~/app/util/type';
import { ProcessingStatus } from '~/app/util/type';

import type { Page } from '~/app/util/type';

Expand All @@ -19,36 +19,36 @@ export const getPageTitle = (page: Page) => {
}
};

export const getDatabaseStatus = (status: DatabaseStatus) => {
export const getDatabaseStatus = (status: ProcessingStatus) => {
switch (status) {
case DatabaseStatus.UNKNOWN: {
case ProcessingStatus.UNKNOWN: {
return 'UNKNOWN';
}
case DatabaseStatus.STARTING: {
case ProcessingStatus.STARTING: {
return 'STARTING';
}
case DatabaseStatus.WRAPPER_RUNNING: {
case ProcessingStatus.WRAPPER_RUNNING: {
return 'WRAPPER_RUNNING';
}
case DatabaseStatus.WRAPPER_ERROR: {
case ProcessingStatus.WRAPPER_ERROR: {
return 'WRAPPER_ERROR';
}
case DatabaseStatus.ENRICHMENT_RUNNING: {
case ProcessingStatus.ENRICHMENT_RUNNING: {
return 'ENRICHMENT_RUNNING';
}
case DatabaseStatus.ENRICHMENT_ERROR: {
case ProcessingStatus.ENRICHMENT_ERROR: {
return 'ENRICHMENT_ERROR';
}
case DatabaseStatus.WAITING_WEBHOOK: {
case ProcessingStatus.WAITING_WEBHOOK: {
return 'WAITING_WEBHOOK';
}
case DatabaseStatus.PROCESSING_WEBHOOK: {
case ProcessingStatus.PROCESSING_WEBHOOK: {
return 'PROCESSING_WEBHOOK';
}
case DatabaseStatus.FINISHED: {
case ProcessingStatus.FINISHED: {
return 'FINISHED';
}
case DatabaseStatus.FINISHED_ERROR: {
case ProcessingStatus.FINISHED_ERROR: {
return 'FINISHED_ERROR';
}
}
Expand Down
7 changes: 7 additions & 0 deletions tdm-be/src/controller/admin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { filesLocation, logFile, readDir } from '~/lib/files';
import { loggerName } from '~/lib/logger';
import createDashboard from '~/model/Dashboard';
import { findAllProcessing } from '~/model/ProcessingModel';

import express from 'express';
Expand All @@ -8,6 +9,12 @@ import fs from 'node:fs/promises';

const router = express.Router();

router.get('/dashboard', (req, res) => {
createDashboard().then((value) => {
res.json(value);
});
});

router.get('/database', (req, res) => {
let page = 1;
if (req.query.page && Number(req.query.page) > 1) {
Expand Down
62 changes: 62 additions & 0 deletions tdm-be/src/model/Dashboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { filesLocation, readDir } from '~/lib/files';
import { findAllStatus } from '~/model/ProcessingModel';

import { statfs } from 'node:fs/promises';

import type { Stats } from 'node:fs';

const createStorage = async () => {
const files = await Promise.all([
readDir(filesLocation.upload),
readDir(filesLocation.tmp),
readDir(filesLocation.download),
]).then();

let used = 0;
const convertFile = ({ stats }: { file: string; stats: Stats }) => {
used += stats.size;
return {
date: stats.ctime,
size: stats.size,
};
};

const upload = files[0].map(convertFile);
const tmp = files[1].map(convertFile);
const download = files[2].map(convertFile);

const fsStats = await statfs(filesLocation.app);

return {
free: fsStats.bfree * fsStats.bsize,
used,
files: {
upload,
tmp,
download,
},
};
};

const createStatus = () => {
const status: Record<number, number> = {};
for (const datum of findAllStatus()) {
const previousStatus = status[datum.status];
if (previousStatus === undefined) {
status[datum.status] = 1;
continue;
}
status[datum.status] = previousStatus + 1;
}

return status;
};

const createDashboard = async () => {
return {
status: createStatus(),
storage: await createStorage(),
};
};

export default createDashboard;
8 changes: 8 additions & 0 deletions tdm-be/src/model/ProcessingModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ export const countAllProcessing = (): number => {
return 0;
};

export const findAllStatus = (): Array<{ status: number }> => {
const stmt = database.prepare<unknown[], { status: number }>(`
select status from processing;
`);

return stmt.all();
};

export const findAllProcessing = (page: number): { page: number; total: number; results: Processing[] } => {
const stmt = database.prepare<[number], Processing>(`
select id,
Expand Down

0 comments on commit ab5def4

Please sign in to comment.