Improve toolbox persistence and goal tree coverage
All checks were successful
Deploy Sokko G / deploy (push) Successful in 15s

This commit is contained in:
Shinuwa 2026-08-24 16:11:22 +02:00
parent 50029b45a2
commit 7348969ac4
10 changed files with 801 additions and 591 deletions

View file

@ -156,6 +156,8 @@ test("toolbox module registry and modules expose expected behavior", async () =>
const taskPlannerItems = await readFile("website/src/features/toolboxes/modules/TaskPlannerItems.jsx", "utf8");
const taskPlannerUtils = await readFile("website/src/features/toolboxes/modules/taskPlannerUtils.js", "utf8");
const goalTreeModule = await readFile("website/src/features/toolboxes/modules/GoalTreeModule.jsx", "utf8");
const goalTreeParts = await readFile("website/src/features/toolboxes/modules/GoalTreeParts.jsx", "utf8");
const goalTreeDisplay = await readFile("website/src/features/toolboxes/modules/goalTreeDisplay.js", "utf8");
const goalTreeUtils = await readFile("website/src/features/toolboxes/modules/goalTreeUtils.js", "utf8");
const equipmentPlannerModule = await readFile("website/src/features/toolboxes/modules/EquipmentPlannerModule.jsx", "utf8");
const equipmentPlannerEditors = await readFile("website/src/features/toolboxes/modules/EquipmentPlannerEditors.jsx", "utf8");
@ -367,14 +369,14 @@ test("toolbox module registry and modules expose expected behavior", async () =>
assert.match(goalTreeModule, /applyGoalTreeDueResets/);
assert.match(goalTreeModule, /TextExchangeActions/);
assert.match(goalTreeModule, /DiagramConnectors/);
assert.match(goalTreeModule, /Tooltip/);
assert.match(goalTreeModule, /GoalTreeIconPicker/);
assert.match(goalTreeModule, /GoalTreeContentEditor/);
assert.match(goalTreeModule, /GoalTreeNodeContentPreview/);
assert.doesNotMatch(goalTreeModule, /\.slice\(0, 3\)/);
assert.match(goalTreeModule, /GoalTreeChecklistInlineControl/);
assert.match(goalTreeModule, /GoalTreeStepLeafControl/);
assert.match(goalTreeModule, /GoalTreePrerequisitePicker/);
assert.match(goalTreeParts, /Tooltip/);
assert.match(goalTreeParts, /export function GoalTreeIconPicker/);
assert.match(goalTreeParts, /export function GoalTreeContentEditor/);
assert.match(goalTreeParts, /function GoalTreeNodeContentPreview/);
assert.doesNotMatch(`${goalTreeModule}\n${goalTreeParts}`, /\.slice\(0, 3\)/);
assert.match(goalTreeParts, /GoalTreeChecklistInlineControl/);
assert.match(goalTreeParts, /GoalTreeStepLeafControl/);
assert.match(goalTreeParts, /export function GoalTreePrerequisitePicker/);
assert.match(goalTreeModule, /function toggleBranch/);
assert.match(goalTreeModule, /function editNode/);
assert.match(goalTreeModule, /function addNodeContentItem/);
@ -387,12 +389,12 @@ test("toolbox module registry and modules expose expected behavior", async () =>
assert.match(goalTreeModule, /module-scroll-button goal-tree-orientation-switch/);
assert.match(goalTreeModule, /Icon name="rotate"/);
assert.match(goalTreeModule, /function toggleLinkedParent/);
assert.match(goalTreeModule, /grouped: false/);
assert.match(goalTreeDisplay, /grouped: false/);
assert.match(goalTreeModule, /getGoalTreeConvergenceKeepOpenIds/);
assert.match(goalTreeModule, /progress\.current/);
assert.match(goalTreeModule, /label: textContent\.itemLabelPlaceholder \|\| "Élément"/);
assert.match(goalTreeDisplay, /progress\.current/);
assert.match(goalTreeDisplay, /label: textContent\.itemLabelPlaceholder \|\| "Élément"/);
assert.doesNotMatch(goalTreeUtils, /"calculator"/);
assert.match(goalTreeModule, /getItemProps\(\{ itemId: node\.id, parentId \}\)/);
assert.match(goalTreeParts, /getItemProps\(\{ itemId: node\.id, parentId \}\)/);
assert.match(goalTreeUtils, /export function calculateGoalTreeFormula/);
assert.match(goalTreeUtils, /export function evaluateGoalTreeNodes/);
assert.match(equipmentPlannerModule, /export function EquipmentPlannerModule/);

View file

@ -4,6 +4,7 @@ import assert from "node:assert/strict";
import { evaluateTableCell } from "../website/src/features/toolboxes/modules/tableFormulaEngine.js";
import { exportModuleText, importModuleText, parseColonImportLines } from "../website/src/features/toolboxes/modules/textImport.js";
import { buildInsertedMixTagValue, normalizeMixTagSpacing, normalizeMixTagText, removeMixTagAtOffset, tokenizeMixTagValue } from "../website/src/utils/mixTagsInputUtils.js";
import { getEffectiveGoalTreeProgressMode, getVisibleGoalTreeEdges } from "../website/src/features/toolboxes/modules/goalTreeDisplay.js";
import { calculateGoalTreeFormula, evaluateGoalTreeNodes } from "../website/src/features/toolboxes/modules/goalTreeUtils.js";
import { getMonthOccurrenceSegments, getWeekGridLayout, getWeekMinutePosition, layoutConcurrentOccurrences } from "../website/src/features/toolboxes/modules/calendarLayout.js";
import { getTimePatternRecurrenceMs, getTimePatternTargetMs } from "../website/src/features/toolboxes/modules/timerUtils.js";
@ -1098,3 +1099,26 @@ test("goal tree parent progress uses base-scaled child bottlenecks", () => {
assert.equal(compact.nodes[4].progressMode, undefined);
assert.equal(compact.nodes[6].progressMode, "auto");
});
test("goal tree display helpers keep collapsed edges and progress modes stable", () => {
const nodes = evaluateGoalTreeNodes(normalizeGoalTreeData({
nodes: [
{ id: "root", title: "Root", kind: "step", qtyTarget: 1, collapsed: true },
{ id: "child", parentId: "root", title: "Child", kind: "step", qtyTarget: 1 },
{ id: "linked", parentId: "", parentIds: ["root"], title: "Linked", kind: "checklist", items: [{ id: "i1", label: "Line", qtyTarget: 1 }] },
{ id: "manualParent", title: "Manual Parent", kind: "step", qtyTarget: 1 },
{ id: "manualChild", parentId: "manualParent", title: "Manual Child", kind: "step", qtyTarget: 1 },
{ id: "autoParent", title: "Auto Parent", kind: "step", qtyTarget: 10 },
{ id: "autoChild", parentId: "autoParent", title: "Auto Child", kind: "step", qtyTarget: 5 }
]
}).nodes);
const edges = getVisibleGoalTreeEdges(nodes);
assert.deepEqual(edges, [
{ from: "manualParent", to: "manualChild" },
{ from: "autoParent", to: "autoChild" }
]);
assert.equal(edges.some((edge) => edge.from === "root" || edge.to === "child" || edge.to === "linked"), false);
assert.equal(getEffectiveGoalTreeProgressMode(nodes.find((node) => node.id === "manualParent"), [nodes.find((node) => node.id === "manualChild")]), "manual");
assert.equal(getEffectiveGoalTreeProgressMode(nodes.find((node) => node.id === "autoParent"), [nodes.find((node) => node.id === "autoChild")]), "auto");
});