summaryrefslogtreecommitdiffhomepage
path: root/src/features/plugins/logic/highlight.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-09-03 18:05:29 +0900
committerAdam Malczewski <[email protected]>2026-09-03 18:05:29 +0900
commit3a4922a05930b0dc22740bf5621910803e8f275e (patch)
treed5f831c3d3838cfff346e378f5370a9c58bc2ed3 /src/features/plugins/logic/highlight.ts
parent33c7245f18346553f660434bc3ac589cff3e80c2 (diff)
downloaddispatch-web-3a4922a05930b0dc22740bf5621910803e8f275e.tar.gz
dispatch-web-3a4922a05930b0dc22740bf5621910803e8f275e.zip
feat(plugin-system): plan 07 frontend plugin manager ui
Diffstat (limited to 'src/features/plugins/logic/highlight.ts')
-rw-r--r--src/features/plugins/logic/highlight.ts37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/features/plugins/logic/highlight.ts b/src/features/plugins/logic/highlight.ts
new file mode 100644
index 0000000..1bcfaad
--- /dev/null
+++ b/src/features/plugins/logic/highlight.ts
@@ -0,0 +1,37 @@
+import type { PluginNode } from "./types";
+
+/** The two highlight sets for the §8 bidirectional dependency hover. */
+export interface HighlightSets {
+ /** The hovered row's DIRECT dependencies (highlighted when hovering an item). */
+ readonly deps: ReadonlySet<string>;
+ /** The loaded/unloaded rows that DIRECTLY depend on the hovered row
+ * (highlighted when hovering a dependency). */
+ readonly dependents: ReadonlySet<string>;
+}
+
+const EMPTY: HighlightSets = { deps: new Set(), dependents: new Set() };
+
+/**
+ * Bidirectional hover highlighting (§8): hover any item → its DIRECT
+ * dependencies highlight; hover a dependency → its dependents highlight.
+ * One hop in each direction (the plan's grammar is "its dependencies" /
+ * "its dependents" — the visual neighborhood, not the transitive closure;
+ * the transitive closures live in `computeCascade` / `autoCheckBackendPrereqs`).
+ *
+ * Works across BOTH manager tables (a loaded row can highlight an unloaded
+ * dependency row and vice versa) — the node list spans the whole catalog.
+ * Pure input → output; `hoveredId` null (no hover) → both sets empty.
+ */
+export function dependencyHighlightSets(
+ hoveredId: string | null,
+ nodes: readonly PluginNode[],
+): HighlightSets {
+ if (hoveredId === null) return EMPTY;
+ const hovered = nodes.find((n) => n.id === hoveredId);
+ if (hovered === undefined) return EMPTY;
+ const deps = new Set(hovered.dependsOn);
+ const dependents = new Set(
+ nodes.filter((n) => n.id !== hoveredId && n.dependsOn.includes(hoveredId)).map((n) => n.id),
+ );
+ return { deps, dependents };
+}