mirror of
https://github.com/litruv/picoGraph.git
synced 2026-07-24 10:46:06 +10:00
Initial commit
moved from private version control
This commit is contained in:
108
scripts/ui/workspace/renderEventList.js
Normal file
108
scripts/ui/workspace/renderEventList.js
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Renders the event summary list.
|
||||
*
|
||||
* @param {object} options Rendering options.
|
||||
* @param {HTMLUListElement | null} options.element Target list element.
|
||||
* @param {import('../../nodes/NodeRegistry.js').NodeRegistry} options.registry Node registry instance.
|
||||
* @param {import('../../core/NodeGraph.js').NodeGraph} options.graph Active node graph.
|
||||
* @param {(nodeId: string) => void} options.focusNode Callback to focus a node.
|
||||
* @param {(message: string) => void} options.renderEmpty Callback to render empty state.
|
||||
* @param {(node: import('../../core/BlueprintNode.js').BlueprintNode, entryTypes: Set<string>) => boolean} options.isEventNode Predicate to determine if node represents an event.
|
||||
*/
|
||||
export function renderEventList({
|
||||
element,
|
||||
registry,
|
||||
graph,
|
||||
focusNode,
|
||||
renderEmpty,
|
||||
isEventNode,
|
||||
}) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
element.innerHTML = "";
|
||||
|
||||
const entryTypes = new Set(registry.getEntryNodeTypes());
|
||||
const events = [...graph.nodes.values()].filter((node) =>
|
||||
isEventNode(node, entryTypes)
|
||||
);
|
||||
const builtInEvents = [];
|
||||
const customEvents = [];
|
||||
|
||||
events.forEach((node) => {
|
||||
if (node.type === "custom_event") {
|
||||
customEvents.push(node);
|
||||
} else {
|
||||
builtInEvents.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
if (!builtInEvents.length && !customEvents.length) {
|
||||
renderEmpty("No events yet");
|
||||
return;
|
||||
}
|
||||
|
||||
const appendHeading = (title) => {
|
||||
const headingItem = document.createElement("li");
|
||||
headingItem.className = "overview-subheading";
|
||||
headingItem.textContent = title;
|
||||
element.appendChild(headingItem);
|
||||
};
|
||||
|
||||
const appendEventItem = (node, displayName) => {
|
||||
const item = document.createElement("li");
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "overview-item";
|
||||
button.dataset.nodeId = node.id;
|
||||
button.addEventListener("click", () => {
|
||||
focusNode(node.id);
|
||||
});
|
||||
|
||||
const label = document.createElement("span");
|
||||
label.className = "overview-item-label";
|
||||
label.textContent = displayName;
|
||||
button.appendChild(label);
|
||||
|
||||
const meta = document.createElement("span");
|
||||
meta.className = "overview-item-meta";
|
||||
meta.textContent = node.id;
|
||||
button.appendChild(meta);
|
||||
|
||||
item.appendChild(button);
|
||||
element.appendChild(item);
|
||||
};
|
||||
|
||||
if (builtInEvents.length) {
|
||||
appendHeading("Events");
|
||||
builtInEvents
|
||||
.slice()
|
||||
.sort((a, b) => a.title.localeCompare(b.title))
|
||||
.forEach((node) => appendEventItem(node, node.title));
|
||||
}
|
||||
|
||||
if (customEvents.length) {
|
||||
appendHeading("Custom Events");
|
||||
customEvents
|
||||
.slice()
|
||||
.sort((a, b) => {
|
||||
const nameA =
|
||||
(typeof a.properties.name === "string"
|
||||
? a.properties.name.trim()
|
||||
: "") || "CustomEvent";
|
||||
const nameB =
|
||||
(typeof b.properties.name === "string"
|
||||
? b.properties.name.trim()
|
||||
: "") || "CustomEvent";
|
||||
return nameA.localeCompare(nameB);
|
||||
})
|
||||
.forEach((node) => {
|
||||
const displayName =
|
||||
(typeof node.properties.name === "string"
|
||||
? node.properties.name.trim()
|
||||
: "") || "CustomEvent";
|
||||
appendEventItem(node, displayName);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user