feat(web): redesign fleet cards and instance workspace
This commit is contained in:
@@ -78,6 +78,13 @@ export interface InstanceContext {
|
||||
status: 'online' | 'offline' | 'auth-required' | 'degraded' | 'unknown';
|
||||
authentication: 'authenticated' | 'auth-required' | 'unknown';
|
||||
freshness: 'fresh' | 'stale' | 'expired' | 'unknown';
|
||||
resources?: Readonly<{
|
||||
cpuPercent?: number;
|
||||
memoryPercent?: number;
|
||||
maxTemperatureCelsius?: number;
|
||||
phoneNumbers?: readonly string[];
|
||||
}>;
|
||||
resourceSummaryState?: 'loading' | 'ready' | 'unavailable';
|
||||
}
|
||||
export interface AppShellProps {
|
||||
pathname: string;
|
||||
@@ -440,8 +447,13 @@ export function AppShell({
|
||||
setInstanceLoading(false);
|
||||
return;
|
||||
}
|
||||
const controller = new AbortController();
|
||||
let active = true;
|
||||
setInstanceLoading(true);
|
||||
const fleetLoad = (fleetDataSource ?? defaultFleetDataSource).load(controller.signal).then(
|
||||
(fleet) => ({ ok: true as const, fleet }),
|
||||
() => ({ ok: false as const }),
|
||||
);
|
||||
void resolvedInstanceDataSource.get(routeInstanceId).then(
|
||||
(owner) => {
|
||||
if (!active) return;
|
||||
@@ -457,8 +469,50 @@ export function AppShell({
|
||||
status: 'unknown',
|
||||
authentication: 'unknown',
|
||||
freshness: 'unknown',
|
||||
resourceSummaryState: 'loading',
|
||||
});
|
||||
setInstanceLoading(false);
|
||||
|
||||
void fleetLoad.then((result) => {
|
||||
if (!active) return;
|
||||
if (!result.ok) {
|
||||
setLoadedInstance((current) =>
|
||||
current?.id === routeInstanceId
|
||||
? { ...current, resourceSummaryState: 'unavailable' }
|
||||
: current,
|
||||
);
|
||||
return;
|
||||
}
|
||||
const fleet = result.fleet;
|
||||
const fleetOwner = fleet.instances.find((candidate) => candidate.id === routeInstanceId);
|
||||
const status = fleet.statuses.get(routeInstanceId);
|
||||
const routeStatus = !status
|
||||
? 'unknown'
|
||||
: !status.reachable
|
||||
? 'offline'
|
||||
: status.authenticated === false
|
||||
? 'auth-required'
|
||||
: 'online';
|
||||
const freshness = status?.summary?.freshness;
|
||||
setLoadedInstance({
|
||||
id: owner.id,
|
||||
name: owner.name,
|
||||
origin: fleetOwner?.url ?? owner.origin,
|
||||
status: routeStatus,
|
||||
authentication:
|
||||
status?.authenticated === true
|
||||
? 'authenticated'
|
||||
: status?.authenticated === false
|
||||
? 'auth-required'
|
||||
: 'unknown',
|
||||
freshness:
|
||||
freshness === 'fresh' || freshness === 'stale' || freshness === 'expired'
|
||||
? freshness
|
||||
: 'unknown',
|
||||
...(status?.summary?.resources ? { resources: status.summary.resources } : {}),
|
||||
resourceSummaryState: status ? 'ready' : 'unavailable',
|
||||
});
|
||||
});
|
||||
},
|
||||
() => {
|
||||
if (!active) return;
|
||||
@@ -468,8 +522,15 @@ export function AppShell({
|
||||
);
|
||||
return () => {
|
||||
active = false;
|
||||
controller.abort();
|
||||
};
|
||||
}, [instance, resolvedInstanceDataSource, routeInstanceId]);
|
||||
}, [
|
||||
defaultFleetDataSource,
|
||||
fleetDataSource,
|
||||
instance,
|
||||
resolvedInstanceDataSource,
|
||||
routeInstanceId,
|
||||
]);
|
||||
|
||||
const routeInstance = instance?.id === routeInstanceId ? instance : loadedInstance;
|
||||
const refresh = useControlPlaneEvents(
|
||||
|
||||
Reference in New Issue
Block a user