Improve calculator progress tracking and responsive layout
All checks were successful
Deploy Sokko G / deploy (push) Successful in 18s

This commit is contained in:
Shinuwa 2026-09-29 11:19:11 +02:00
parent 3f86d863ac
commit 51853245ad
15 changed files with 329 additions and 75 deletions

View file

@ -6,7 +6,7 @@ import { exportModuleText, importModuleText, parseColonImportLines } from "../we
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 { calculateExpression, createStoredFormula, evaluateCalculatorEntries, getEntriesInTreeOrder } from "../website/src/features/toolboxes/modules/calculatorUtils.js";
import { calculateExpression, calculateRemainingValue, createStoredFormula, evaluateCalculatorEntries, getEntriesInTreeOrder, parseCalculatorCurrent } from "../website/src/features/toolboxes/modules/calculatorUtils.js";
import { createDefaultDraft, getDateSpanDays, getDraftSelection, normalizeDraftAlertOffsets, normalizeDraftMonthlyRepeatBy } from "../website/src/features/toolboxes/modules/calendarDraft.js";
import { getMonthOccurrenceSegments, getWeekGridLayout, getWeekMinutePosition, layoutConcurrentOccurrences } from "../website/src/features/toolboxes/modules/calendarLayout.js";
import { appendChecklistItems, moveChecklistItem, moveChecklistItemToCategory, renameChecklistSection } from "../website/src/features/toolboxes/modules/checklistUtils.js";
@ -479,7 +479,7 @@ test("text exchange imports table TSV and calculator hierarchy", () => {
scrollResults: true,
entries: [
{ id: "a", label: "Ore", value: 100, formula: "100" },
{ id: "b", parentId: "a", label: "Shard", value: 500, formula: "base*5" }
{ id: "b", parentId: "a", label: "Shard", value: 480, formula: "base*5", current: 20 }
]
});
const calculatorImport = importModuleText("calculator", exportModuleText("calculator", calculator), context);
@ -487,21 +487,29 @@ test("text exchange imports table TSV and calculator hierarchy", () => {
assert.equal(calculatorImport.data.scrollResults, true);
assert.equal(calculatorImport.data.entries[1].parentId, calculatorImport.data.entries[0].id);
assert.equal(calculatorImport.data.entries[1].formula, "base*5");
assert.equal(calculatorImport.data.entries[1].current, 20);
});
test("calculator helpers evaluate formulas and preserve tree order", () => {
const entries = evaluateCalculatorEntries([
{ id: "root", label: "Root", value: 10, formula: "10" },
{ id: "child", parentId: "root", label: "Child", value: 0, formula: "base*3" },
{ id: "root", label: "Root", value: 8, formula: "10", current: 2 },
{ id: "child", parentId: "root", label: "Child", value: 0, formula: "base*10", current: 20 },
{ id: "sibling", label: "Sibling", value: 2, formula: "1+1" }
]);
assert.equal(calculateExpression("2 + 3 * 4"), 14);
assert.equal(calculateExpression("base / 2", 10), 5);
assert.equal(calculateExpression("window.alert(1)"), null);
assert.equal(calculateRemainingValue("base * 8", "20", 10), 60);
assert.equal(calculateRemainingValue("80", "20,5"), 59.5);
assert.equal(calculateRemainingValue("80", "invalid"), null);
assert.equal(parseCalculatorCurrent(""), 0);
assert.equal(createStoredFormula("+5", 10), "base+5");
assert.equal(createStoredFormula("10*2", 10), "base*2");
assert.deepEqual(entries.map((entry) => [entry.id, entry.value]), [["root", 10], ["child", 30], ["sibling", 2]]);
assert.deepEqual(entries.map((entry) => [entry.id, entry.value]), [["root", 8], ["child", 60], ["sibling", 2]]);
assert.deepEqual(getEntriesInTreeOrder(entries).map((entry) => entry.id), ["root", "child", "sibling"]);
const compact = compactModuleDataForStorage("calculator", normalizeCalculatorData({ entries }));
assert.equal(compact.entries[0].current, 2);
assert.equal(compact.entries[2].current, undefined);
});
test("calendar layout keeps week compaction and overlapping lanes deterministic", () => {