Add flow validity icons to artmap mappings in flow view
This commit is contained in:
@@ -169,7 +169,7 @@ export function showFlowView(flowSpec) {
|
|||||||
if (path) paths.push({ path, sourceId, destId: clickedNodeId });
|
if (path) paths.push({ path, sourceId, destId: clickedNodeId });
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
error = 'Node is not a source or destination for universe ' + universe;
|
error = 'Node is not a source or destination for universe ' + universeDisplay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -183,7 +183,7 @@ export function showFlowView(flowSpec) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!error && paths.length === 0) error = 'No active flows for universe ' + universe;
|
if (!error && paths.length === 0) error = 'No active flows for universe ' + universeDisplay;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error = 'Unknown protocol: ' + protocol;
|
error = 'Unknown protocol: ' + protocol;
|
||||||
@@ -350,6 +350,21 @@ export function renderFlowPath(pathInfo, nodesByTypeId, flowUniverse, flowProtoc
|
|||||||
relevantMappings.forEach(m => {
|
relevantMappings.forEach(m => {
|
||||||
const mappingEl = document.createElement('div');
|
const mappingEl = document.createElement('div');
|
||||||
mappingEl.className = 'artmap-mapping';
|
mappingEl.className = 'artmap-mapping';
|
||||||
|
const fromMatches = m.from.protocol === flowProtocol && m.from.universe === flowUniverse;
|
||||||
|
const target = fromMatches ? m.to : m.from;
|
||||||
|
const targetValid = hasValidFlow(nodesByTypeId, target.protocol, target.universe);
|
||||||
|
const leftIcon = document.createElement('span');
|
||||||
|
leftIcon.className = 'flow-validity-icon left';
|
||||||
|
const rightIcon = document.createElement('span');
|
||||||
|
rightIcon.className = 'flow-validity-icon right';
|
||||||
|
const activeIcon = fromMatches ? rightIcon : leftIcon;
|
||||||
|
if (targetValid) {
|
||||||
|
activeIcon.textContent = '●';
|
||||||
|
activeIcon.classList.add('valid');
|
||||||
|
} else {
|
||||||
|
activeIcon.textContent = '⊘';
|
||||||
|
activeIcon.classList.add('invalid');
|
||||||
|
}
|
||||||
const fromSpan = document.createElement('span');
|
const fromSpan = document.createElement('span');
|
||||||
fromSpan.className = 'from';
|
fromSpan.className = 'from';
|
||||||
fromSpan.textContent = formatArtmapAddr(m.from);
|
fromSpan.textContent = formatArtmapAddr(m.from);
|
||||||
@@ -358,13 +373,13 @@ export function renderFlowPath(pathInfo, nodesByTypeId, flowUniverse, flowProtoc
|
|||||||
const toSpan = document.createElement('span');
|
const toSpan = document.createElement('span');
|
||||||
toSpan.className = 'to';
|
toSpan.className = 'to';
|
||||||
toSpan.textContent = formatArtmapAddr(m.to);
|
toSpan.textContent = formatArtmapAddr(m.to);
|
||||||
|
mappingEl.appendChild(leftIcon);
|
||||||
mappingEl.appendChild(fromSpan);
|
mappingEl.appendChild(fromSpan);
|
||||||
mappingEl.appendChild(arrowSpan);
|
mappingEl.appendChild(arrowSpan);
|
||||||
mappingEl.appendChild(toSpan);
|
mappingEl.appendChild(toSpan);
|
||||||
|
mappingEl.appendChild(rightIcon);
|
||||||
mappingEl.addEventListener('click', (e) => {
|
mappingEl.addEventListener('click', (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const fromMatches = m.from.protocol === flowProtocol && m.from.universe === flowUniverse;
|
|
||||||
const target = fromMatches ? m.to : m.from;
|
|
||||||
openFlowHash(target.protocol, target.universe, nodeName);
|
openFlowHash(target.protocol, target.universe, nodeName);
|
||||||
});
|
});
|
||||||
mappingsEl.appendChild(mappingEl);
|
mappingsEl.appendChild(mappingEl);
|
||||||
@@ -392,6 +407,24 @@ function getRelevantMappings(mappings, protocol, universe) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasValidFlow(nodesByTypeId, protocol, universe) {
|
||||||
|
let hasSources = false;
|
||||||
|
let hasDests = false;
|
||||||
|
for (const node of nodesByTypeId.values()) {
|
||||||
|
if (protocol === 'sacn') {
|
||||||
|
if ((node.sacn_outputs || []).includes(universe)) hasSources = true;
|
||||||
|
const groups = node.multicast_groups || [];
|
||||||
|
const unicastInputs = node.sacn_unicast_inputs || [];
|
||||||
|
if (groups.some(g => g === 'sacn:' + universe) || unicastInputs.includes(universe)) hasDests = true;
|
||||||
|
} else if (protocol === 'artnet') {
|
||||||
|
if ((node.artnet_inputs || []).includes(universe)) hasSources = true;
|
||||||
|
if ((node.artnet_outputs || []).includes(universe)) hasDests = true;
|
||||||
|
}
|
||||||
|
if (hasSources && hasDests) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
export function closeFlowView() {
|
export function closeFlowView() {
|
||||||
const overlay = document.getElementById('flow-overlay');
|
const overlay = document.getElementById('flow-overlay');
|
||||||
if (overlay) overlay.style.display = 'none';
|
if (overlay) overlay.style.display = 'none';
|
||||||
|
|||||||
@@ -982,7 +982,7 @@ body.sacn-mode .node.sacn-out.sacn-in .sacn-in-hover .sacn-detail-wrapper {
|
|||||||
|
|
||||||
.artmap-mapping {
|
.artmap-mapping {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto 1fr;
|
grid-template-columns: 1em 1fr auto 1fr 1em;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: #aaf;
|
color: #aaf;
|
||||||
@@ -991,6 +991,26 @@ body.sacn-mode .node.sacn-out.sacn-in .sacn-in-hover .sacn-detail-wrapper {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.artmap-mapping .flow-validity-icon {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artmap-mapping .flow-validity-icon.left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artmap-mapping .flow-validity-icon.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artmap-mapping .flow-validity-icon.valid {
|
||||||
|
color: #4c4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artmap-mapping .flow-validity-icon.invalid {
|
||||||
|
color: #e44;
|
||||||
|
}
|
||||||
|
|
||||||
.artmap-mapping .from {
|
.artmap-mapping .from {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
@@ -1004,6 +1024,14 @@ body.sacn-mode .node.sacn-out.sacn-in .sacn-in-hover .sacn-detail-wrapper {
|
|||||||
color: #ccf;
|
color: #ccf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.artmap-mapping:hover .flow-validity-icon.valid {
|
||||||
|
color: #6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artmap-mapping:hover .flow-validity-icon.invalid {
|
||||||
|
color: #f66;
|
||||||
|
}
|
||||||
|
|
||||||
.node.has-error {
|
.node.has-error {
|
||||||
box-shadow: 0 0 0 3px #f66;
|
box-shadow: 0 0 0 3px #f66;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user