Convert config from maps to lists for ordering

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ian Gulliver
2026-01-24 16:00:26 -08:00
parent 997868949a
commit a6ce2e4696
3 changed files with 65 additions and 62 deletions

View File

@@ -8,12 +8,13 @@ import (
)
type Config struct {
Locations map[string]*Location `yaml:"locations" json:"locations"`
Locations []*Location `yaml:"locations" json:"locations"`
}
type Location struct {
Nodes []string `yaml:"nodes,omitempty" json:"nodes,omitempty"`
Children map[string]*Location `yaml:"children,omitempty" json:"children,omitempty"`
Name string `yaml:"name" json:"name"`
Nodes []string `yaml:"nodes,omitempty" json:"nodes,omitempty"`
Children []*Location `yaml:"children,omitempty" json:"children,omitempty"`
}
func LoadConfig(path string) (*Config, error) {

View File

@@ -1,62 +1,18 @@
locations:
booth:
- name: stage
children:
shared:
nodes:
- satellite-1
qlab:
nodes:
- qlab
- TX-QLAB-1
- TX-QLAB-2
- "SK_PTZEXTREMEV2 [457081]"
- "SK_RACKPRO2 [452514]"
- "d0:11:e5:17:03:0b" # pigeon
audio:
nodes:
- SQ-7
camera-control:
nodes:
- RX-CC-PREVIEW
- RX-CC-M16
video-control:
nodes:
- RX-VC-M4
- RX-VC-M16
control:
nodes:
- "sunset.local"
- RX-CONTROL-1
house-left:
nodes:
- satellite-2
house-right:
nodes:
- satellite-3
stage:
children:
upstage:
- name: upstage
children:
rack-lighting-2:
- name: rack-lighting-2
nodes:
- lighting-2
- "48:59:00:41:00:29" # Pixie Driver 8k Port 1
- "48:59:00:28:00:27" # Pixie Driver 8k Port 2
- "48:59:00:3c:00:3e" # Pixie Driver 8k Port 5
downstage:
- name: downstage
children:
rack-audio:
- name: rack-audio
nodes:
- audio
- "MICS-A"
@@ -70,7 +26,7 @@ locations:
- "MICS-E"
- "00:0e:dd:ac:fc:7d" # MICS-E bridge interface
rack-lighting-1:
- name: rack-lighting-1
nodes:
- lighting-1
- "48:59:00:27:00:27" # Pixie Driver 8k Port 1
@@ -82,7 +38,7 @@ locations:
- "48:59:00:42:00:19" # Pixie Driver 8k Port 7
- "48:59:00:44:00:19" # Pixie Driver 8k Port 8
rack-video:
- name: rack-video
nodes:
- video
- "ATEM 2 M/E Constellation 4K"
@@ -95,3 +51,47 @@ locations:
- TX-M16
- TX-MISC
- TX-PREVIEW
- name: house
children:
- name: house-left
nodes:
- satellite-2
- name: house-right
nodes:
- satellite-3
- name: booth
children:
- name: shared
nodes:
- satellite-1
- name: qlab
nodes:
- qlab
- TX-QLAB-1
- TX-QLAB-2
- "SK_PTZEXTREMEV2 [457081]"
- "SK_RACKPRO2 [452514]"
- "d0:11:e5:17:03:0b" # pigeon
- name: audio
nodes:
- SQ-7
- name: camera-control
nodes:
- RX-CC-PREVIEW
- RX-CC-M16
- name: video-control
nodes:
- RX-VC-M4
- RX-VC-M16
- name: control
nodes:
- "sunset.local"
- RX-CONTROL-1

View File

@@ -54,7 +54,7 @@
let cy;
function getLabel(node) {
if (node.names && node.names.length > 0) return node.names[0];
if (node.names && node.names.length > 0) return node.names.join('\n');
return '??';
}
@@ -75,11 +75,11 @@
return !!(node.poe_budget);
}
function buildLocationIndex(locations, parentId, nodeToLocation, locationMeta) {
function buildLocationIndex(locations, parentId, nodeToLocation, locationMeta, depth, orderBase) {
if (!locations) return;
for (const [name, loc] of Object.entries(locations)) {
const locId = 'loc_' + name.replace(/[^a-zA-Z0-9]/g, '_');
locationMeta.set(locId, { name, parentId });
locations.forEach((loc, idx) => {
const locId = 'loc_' + loc.name.replace(/[^a-zA-Z0-9]/g, '_');
locationMeta.set(locId, { name: loc.name, parentId, depth, order: orderBase + idx });
if (loc.nodes) {
loc.nodes.forEach(nodeRef => {
@@ -88,9 +88,9 @@
}
if (loc.children) {
buildLocationIndex(loc.children, locId, nodeToLocation, locationMeta);
buildLocationIndex(loc.children, locId, nodeToLocation, locationMeta, depth + 1, 0);
}
}
});
}
function getLocationChain(locId, locationMeta) {
@@ -143,7 +143,7 @@
const nodeToLocation = new Map();
const locationMeta = new Map();
buildLocationIndex(config.locations, null, nodeToLocation, locationMeta);
buildLocationIndex(config.locations || [], null, nodeToLocation, locationMeta, 0, 0);
nodes.forEach((n, i) => {
const id = 'n' + i;
@@ -219,6 +219,8 @@
cy = cytoscape({
container: document.getElementById('cy'),
elements: elements,
autoungrabify: true,
autounselectify: true,
style: [
{
selector: 'node',