mirror of
https://github.com/litruv/picoGraph.git
synced 2026-07-24 02:36:04 +10:00
109 lines
3.2 KiB
JavaScript
109 lines
3.2 KiB
JavaScript
/**
|
|
* 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);
|
|
});
|
|
}
|
|
}
|