feat(web): complete fleet and instance management slices

This commit is contained in:
chick
2026-07-17 17:12:35 +08:00
parent 4093634e13
commit 6e817f380a
15 changed files with 1737 additions and 203 deletions
+23 -3
View File
@@ -2,7 +2,27 @@ import type { FleetDataSource, FleetSnapshot } from './fleet-page.js';
import type { FleetInstance } from './fleet-table-view-model.js';
interface InstancePage {
readonly data?: readonly FleetInstance[];
readonly items?: readonly unknown[];
readonly page?: {
readonly page?: unknown;
readonly pageSize?: unknown;
readonly total?: unknown;
};
}
function parseInstance(value: unknown): FleetInstance {
if (value === null || typeof value !== 'object' || Array.isArray(value))
throw new Error('Fleet response is invalid.');
const item = value as Record<string, unknown>;
if (
typeof item.id !== 'string' ||
typeof item.name !== 'string' ||
typeof item.origin !== 'string' ||
!Array.isArray(item.tags) ||
!item.tags.every((tag) => typeof tag === 'string')
)
throw new Error('Fleet response is invalid.');
return { id: item.id, name: item.name, url: item.origin, tags: item.tags };
}
export function createFleetApiDataSource(fetcher: typeof fetch = fetch): FleetDataSource {
@@ -15,8 +35,8 @@ export function createFleetApiDataSource(fetcher: typeof fetch = fetch): FleetDa
});
if (!response.ok) throw new Error(`Fleet request failed (${response.status}).`);
const body = (await response.json()) as InstancePage;
if (!Array.isArray(body.data)) throw new Error('Fleet response is invalid.');
return { instances: body.data, statuses: new Map() };
if (!Array.isArray(body.items)) throw new Error('Fleet response is invalid.');
return { instances: body.items.map(parseInstance), statuses: new Map() };
},
};
}