UI polishing
This commit is contained in:
@@ -75,6 +75,20 @@ function DetailsModal({ open, client, groupIdToName, onClose }: DetailsModalProp
|
|||||||
? 'IP-Adresse'
|
? 'IP-Adresse'
|
||||||
: key === 'registration_time'
|
: key === 'registration_time'
|
||||||
? 'Registriert am'
|
? 'Registriert am'
|
||||||
|
: key === 'description'
|
||||||
|
? 'Beschreibung'
|
||||||
|
: key === 'last_alive'
|
||||||
|
? 'Letzter Kontakt'
|
||||||
|
: key === 'model'
|
||||||
|
? 'Modell'
|
||||||
|
: key === 'uuid'
|
||||||
|
? 'Client-Code'
|
||||||
|
: key === "os_version"
|
||||||
|
? 'Betriebssystem'
|
||||||
|
: key === 'software_version'
|
||||||
|
? 'Clientsoftware'
|
||||||
|
: key === 'macs'
|
||||||
|
? 'MAC-Adressen'
|
||||||
: key.charAt(0).toUpperCase() + key.slice(1)}
|
: key.charAt(0).toUpperCase() + key.slice(1)}
|
||||||
:
|
:
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useState, useRef } from 'react';
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
import { fetchGroupsWithClients, restartClient } from './apiClients';
|
import { fetchGroupsWithClients, restartClient } from './apiClients';
|
||||||
import type { Group } from './apiClients';
|
import type { Group, Client } from './apiClients';
|
||||||
import {
|
import {
|
||||||
GridComponent,
|
GridComponent,
|
||||||
ColumnsDirective,
|
ColumnsDirective,
|
||||||
@@ -13,25 +13,35 @@ import {
|
|||||||
|
|
||||||
const REFRESH_INTERVAL = 15000; // 15 Sekunden
|
const REFRESH_INTERVAL = 15000; // 15 Sekunden
|
||||||
|
|
||||||
|
// Typ für Collapse-Event
|
||||||
|
// type DetailRowCollapseArgs = {
|
||||||
|
// data?: { id?: string | number };
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Typ für DataBound-Event
|
||||||
|
type DetailRowDataBoundArgs = {
|
||||||
|
data?: { id?: string | number };
|
||||||
|
};
|
||||||
|
|
||||||
const Dashboard: React.FC = () => {
|
const Dashboard: React.FC = () => {
|
||||||
const [groups, setGroups] = useState<Group[]>([]);
|
const [groups, setGroups] = useState<Group[]>([]);
|
||||||
const [expandedGroupIds, setExpandedGroupIds] = useState<string[]>([]);
|
const [expandedGroupIds, setExpandedGroupIds] = useState<string[]>([]);
|
||||||
const gridRef = useRef<any>(null);
|
const gridRef = useRef<GridComponent | null>(null);
|
||||||
|
|
||||||
// Funktion für das Schließen einer Gruppe (Collapse)
|
// Funktion für das Schließen einer Gruppe (Collapse)
|
||||||
const onDetailCollapse = (args: any) => {
|
// const onDetailCollapse = (args: DetailRowCollapseArgs) => {
|
||||||
if (args && args.data && args.data.id) {
|
// if (args && args.data && args.data.id) {
|
||||||
const groupId = String(args.data.id);
|
// const groupId = String(args.data.id);
|
||||||
setExpandedGroupIds(prev => prev.filter(id => String(id) !== groupId));
|
// setExpandedGroupIds(prev => prev.filter(id => String(id) !== groupId));
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
// Registriere das Event nach dem Mount am Grid
|
// // Registriere das Event nach dem Mount am Grid
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (gridRef.current) {
|
// if (gridRef.current) {
|
||||||
gridRef.current.detailCollapse = onDetailCollapse;
|
// gridRef.current.detailCollapse = onDetailCollapse;
|
||||||
}
|
// }
|
||||||
}, []);
|
// }, []);
|
||||||
|
|
||||||
// Optimiertes Update: Nur bei echten Datenänderungen wird das Grid aktualisiert
|
// Optimiertes Update: Nur bei echten Datenänderungen wird das Grid aktualisiert
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -77,7 +87,7 @@ const Dashboard: React.FC = () => {
|
|||||||
// Health-Badge
|
// Health-Badge
|
||||||
const getHealthBadge = (group: Group) => {
|
const getHealthBadge = (group: Group) => {
|
||||||
const total = group.clients.length;
|
const total = group.clients.length;
|
||||||
const alive = group.clients.filter((c: any) => c.is_alive).length;
|
const alive = group.clients.filter((c: Client) => c.is_alive).length;
|
||||||
const ratio = total === 0 ? 0 : alive / total;
|
const ratio = total === 0 ? 0 : alive / total;
|
||||||
let color = 'danger';
|
let color = 'danger';
|
||||||
let text = `${alive} / ${total} offline`;
|
let text = `${alive} / ${total} offline`;
|
||||||
@@ -98,7 +108,7 @@ const Dashboard: React.FC = () => {
|
|||||||
<ColumnsDirective>
|
<ColumnsDirective>
|
||||||
<ColumnDirective field="description" headerText="Beschreibung" width="150" />
|
<ColumnDirective field="description" headerText="Beschreibung" width="150" />
|
||||||
<ColumnDirective field="ip" headerText="IP" width="120" />
|
<ColumnDirective field="ip" headerText="IP" width="120" />
|
||||||
<ColumnDirective
|
{/* <ColumnDirective
|
||||||
field="last_alive"
|
field="last_alive"
|
||||||
headerText="Letztes Lebenszeichen"
|
headerText="Letztes Lebenszeichen"
|
||||||
width="180"
|
width="180"
|
||||||
@@ -110,7 +120,7 @@ const Dashboard: React.FC = () => {
|
|||||||
const date = new Date(dateStr);
|
const date = new Date(dateStr);
|
||||||
return isNaN(date.getTime()) ? props.last_alive : date.toLocaleString();
|
return isNaN(date.getTime()) ? props.last_alive : date.toLocaleString();
|
||||||
}}
|
}}
|
||||||
/>
|
/> */}
|
||||||
<ColumnDirective
|
<ColumnDirective
|
||||||
field="is_alive"
|
field="is_alive"
|
||||||
headerText="Alive"
|
headerText="Alive"
|
||||||
@@ -142,15 +152,19 @@ const Dashboard: React.FC = () => {
|
|||||||
try {
|
try {
|
||||||
const result = await restartClient(uuid);
|
const result = await restartClient(uuid);
|
||||||
alert(`Neustart erfolgreich: ${result.message}`);
|
alert(`Neustart erfolgreich: ${result.message}`);
|
||||||
} catch (error: any) {
|
} catch (error: unknown) {
|
||||||
alert(`Fehler beim Neustart: ${error.message}`);
|
if (error && typeof error === 'object' && 'message' in error) {
|
||||||
|
alert(`Fehler beim Neustart: ${(error as { message: string }).message}`);
|
||||||
|
} else {
|
||||||
|
alert('Unbekannter Fehler beim Neustart');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// SyncFusion Grid liefert im Event die Zeile/Gruppe
|
// SyncFusion Grid liefert im Event die Zeile/Gruppe
|
||||||
const onDetailDataBound = (args: any) => {
|
const onDetailDataBound = (args: DetailRowDataBoundArgs) => {
|
||||||
if (args && args.data && args.data.id) {
|
if (args && args.data && args.data.id) {
|
||||||
const groupId = args.data.id;
|
const groupId = String(args.data.id);
|
||||||
setExpandedGroupIds(prev => (prev.includes(groupId) ? prev : [...prev, groupId]));
|
setExpandedGroupIds(prev => (prev.includes(groupId) ? prev : [...prev, groupId]));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -176,7 +190,7 @@ const Dashboard: React.FC = () => {
|
|||||||
<ColumnDirective
|
<ColumnDirective
|
||||||
headerText="Health"
|
headerText="Health"
|
||||||
width="160"
|
width="160"
|
||||||
template={(props: any) => getHealthBadge(props)}
|
template={(props: Group) => getHealthBadge(props)}
|
||||||
/>
|
/>
|
||||||
</ColumnsDirective>
|
</ColumnsDirective>
|
||||||
</GridComponent>
|
</GridComponent>
|
||||||
|
|||||||
Reference in New Issue
Block a user