feat: render scalable Alta site and group hierarchy

This commit is contained in:
2026-08-20 01:15:01 +00:00
parent c65a813e5f
commit 8d256cd4ab
12 changed files with 614 additions and 164 deletions
+3 -2
View File
@@ -13,11 +13,11 @@ function baseFixture() {
return {
sites: [
{ id: 's2', name: 'Zulu' },
{ id: 's1', name: 'Alpha', pendingDeletion: true },
{ id: 's1', name: 'Alpha', pendingDeletionStart: '2026-08-19T12:00:00Z' },
],
groups: [
{ id: 'g2', name: 'Doors', parentId: 's2' },
{ id: 'g1', name: 'Lobby', parentId: 's1', pendingDeletion: true },
{ id: 'g1', name: 'Lobby', parentId: 's1', pendingDeletionStart: '2026-08-19T12:00:00Z' },
],
devices: [
{ id: 'c4', name: 'No Group', siteId: 's1', type: 'camera' },
@@ -36,6 +36,7 @@ test('builds deterministic hierarchy with explicit exceptional buckets and diagn
assert.deepEqual(model.sites.map((site) => site.name), ['Alpha', 'Orphaned cameras', 'Unknown site: missing-s', 'Zulu']);
assert.equal(model.sites[0].pendingDeletion, true);
assert.deepEqual(model.sites[0].groups.map((group) => group.name), ['Doors', 'Lobby', 'Ungrouped', 'Unknown group: missing-g']);
assert.equal(model.sites[0].groups.find((group) => group.id === 'g1').pendingDeletion, true);
assert.deepEqual(model.sites[3].groups[0].cameras.map((camera) => camera.name), ['Inferred']);
const conflict = model.cameraByKey.get('camera:c3');