Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frontend/src/widgets/graph/atlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const LABEL_DEFAULTS = ["concept", "entity", "note", "todo"];
const PHYSICS_DEFAULTS = { charge: -420, link: 110, collide: 10 };
const TYPE_KEYS = [
"project", "analysis", "concept", "entity", "evidence", "fact",
"figure", "table", "source", "note", "todo-list", "unclassified",
"figure", "table", "source", "note", "todo-list", "procedure",
"execution", "unclassified",
] as const;

export type ViewerMode = "classic" | "atlas";
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/widgets/graph/ce-graph.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
--type-notes: #6f4070;
--type-todo: #9656a2; /* lighter purple */
--type-todo-list: #9656a2;
--type-procedure: #5e4fa2; /* indigo — how-to hubs */
--type-procedures: #5e4fa2;
--type-execution: #c51b8a; /* pink-magenta — dated instances */
--type-executions: #c51b8a;
/* Unclassified is a placeholder for "no type yet" — render with
* a white fill + a thicker black ring so it visually reads as
* "outline only", obviously different from the typed colour
Expand Down Expand Up @@ -426,6 +430,10 @@ body[data-sidebar="collapsed"] #sidebar > * { display: none; }
.dot.dot-notes { background: var(--type-notes); }
.dot.dot-todo { background: var(--type-todo); }
.dot.dot-todo-list { background: var(--type-todo-list); }
.dot.dot-procedure { background: var(--type-procedure); }
.dot.dot-procedures { background: var(--type-procedures); }
.dot.dot-execution { background: var(--type-execution); }
.dot.dot-executions { background: var(--type-executions); }
.dot.dot-project { background: var(--type-project); }
.dot.dot-projects { background: var(--type-projects); }
/* Unclassified gets a white fill + thicker black ring (1.5px) so
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/widgets/graph/curationReplayAnim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const TYPE_COLOR: Record<string, string> = {
source: "#94346e",
note: "#6f4070",
"todo-list": "#9656a2",
procedure: "#5e4fa2",
procedures: "#5e4fa2",
execution: "#c51b8a",
executions: "#c51b8a",
unclassified: "#ffffff",
};
function colorFor(t: string): string {
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/widgets/graph/static/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ window.Graph = (function () {
source: 'source', sources: 'source',
note: 'note', notes: 'note',
todo: 'todo', 'todo-list': 'todo',
procedure: 'procedure', procedures: 'procedure',
execution: 'execution', executions: 'execution',
unclassified: 'unclassified',
};
function canonicalType(t) { return TYPE_CANONICAL[t] || t || 'default'; }
Expand All @@ -101,8 +103,8 @@ window.Graph = (function () {
// via the label-types popover.
const LABEL_TYPE_DEFAULTS = ['concept', 'entity', 'note', 'todo'];
const ALL_LABEL_TYPES = [
'concept', 'entity', 'evidence', 'fact', 'analysis',
'figure', 'table', 'source', 'note', 'todo',
'concept', 'entity', 'procedure', 'execution', 'evidence', 'fact',
'analysis', 'figure', 'table', 'source', 'note', 'todo',
'unclassified',
];
let _labelTypeFilter = (() => {
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/widgets/graph/static/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ window.Sidebar = (function () {
analysis: 'analysis', analyses: 'analysis',
concept: 'concept', concepts: 'concept',
entity: 'entity', entities: 'entity',
procedure: 'procedure', procedures: 'procedure',
execution: 'execution', executions: 'execution',
evidence: 'evidence',
fact: 'fact', facts: 'fact',
figure: 'figure', figures: 'figure',
Expand All @@ -41,16 +43,19 @@ window.Sidebar = (function () {
// → fact → figure → table → source → note → todo-list →
// unclassified).
const TYPE_ORDER = [
'project', 'analysis', 'concept', 'entity', 'evidence', 'fact',
'figure', 'table', 'source', 'note', 'todo-list', 'unclassified',
'project', 'analysis', 'concept', 'entity', 'procedure', 'execution',
'evidence', 'fact', 'figure', 'table', 'source', 'note', 'todo-list',
'unclassified',
];
const TYPE_LABEL = {
project: 'Projects',
analysis: 'Analyses',
concept: 'Concepts',
entity: 'Entities',
procedure: 'Procedures',
execution: 'Executions',
evidence: 'Evidence',
fact: 'Facts',
analysis: 'Analyses',
figure: 'Figures',
table: 'Tables',
source: 'Sources',
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/widgets/graph/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ export const template = /* html */ `
<span class="ctrl-label">edges:</span><span id="edge-mode-state">auto</span>
</button>
<button id="label-types" class="ctrl-btn" title="Which page types show labels" aria-label="Which page types show labels">
<span class="ctrl-label">types:</span><span id="label-types-state">4/11</span>
<span class="ctrl-label">types:</span><span id="label-types-state">4/13</span>
</button>
<div id="label-types-panel" class="label-types-panel hidden" role="dialog" aria-label="Label types">
<div class="label-types-head">Show labels for</div>
<label class="label-types-row" data-type="project"><input type="checkbox"><span class="dot dot-project"></span><span>Projects</span></label>
<label class="label-types-row" data-type="concept"><input type="checkbox"><span class="dot dot-concept"></span><span>Concepts</span></label>
<label class="label-types-row" data-type="entity"><input type="checkbox"><span class="dot dot-entity"></span><span>Entities</span></label>
<label class="label-types-row" data-type="procedure"><input type="checkbox"><span class="dot dot-procedure"></span><span>Procedures</span></label>
<label class="label-types-row" data-type="execution"><input type="checkbox"><span class="dot dot-execution"></span><span>Executions</span></label>
<label class="label-types-row" data-type="evidence"><input type="checkbox"><span class="dot dot-evidence"></span><span>Evidence</span></label>
<label class="label-types-row" data-type="fact"><input type="checkbox"><span class="dot dot-fact"></span><span>Facts</span></label>
<label class="label-types-row" data-type="analysis"><input type="checkbox"><span class="dot dot-analysis"></span><span>Analyses</span></label>
Expand Down
60 changes: 60 additions & 0 deletions tests/unit/test_procedure_execution_palette.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Lock procedure/execution Graph palette hexes + sidebar/template coverage."""

from __future__ import annotations

from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
GRAPH = ROOT / "frontend" / "src" / "widgets" / "graph"

PROC = "#5e4fa2"
EXEC = "#c51b8a"


def test_css_vars_and_sidebar_dots():
css = (GRAPH / "ce-graph.css").read_text()
assert f"--type-procedure: {PROC}" in css or f"--type-procedure: {PROC}" in css or f"--type-procedure:{PROC}" in css.replace(" ", "")
assert PROC in css
assert EXEC in css
assert "--type-procedure" in css
assert "--type-execution" in css
assert ".dot.dot-procedure" in css
assert ".dot.dot-execution" in css


def test_replay_type_color_map():
src = (GRAPH / "curationReplayAnim.ts").read_text()
assert f'procedure: "{PROC}"' in src
assert f'execution: "{EXEC}"' in src


def test_atlas_type_keys_include_procedure_execution():
src = (GRAPH / "atlas.ts").read_text()
assert '"procedure"' in src
assert '"execution"' in src


def test_sidebar_canonical_order_and_labels():
src = (GRAPH / "static" / "sidebar.js").read_text()
assert "procedure:" in src and "procedures:" in src
assert "execution:" in src and "executions:" in src
assert "'procedure'" in src and "'execution'" in src
assert "Procedures" in src
assert "Executions" in src


def test_graph_canonical_and_label_types():
src = (GRAPH / "static" / "graph.js").read_text()
assert "procedure:" in src and "procedures:" in src
assert "execution:" in src and "executions:" in src
assert "'procedure'" in src and "'execution'" in src


def test_template_label_rows_include_procedure_execution():
src = (GRAPH / "template.ts").read_text()
assert 'data-type="procedure"' in src
assert 'data-type="execution"' in src
assert "Procedures" in src
assert "Executions" in src
assert "dot-procedure" in src
assert "dot-execution" in src
Loading