spaces: a timeline and a workload chart, as view layouts - #443
Open
nyblnet wants to merge 1 commit into
Open
Conversation
Two new shapes on the one layout control. `gantt` draws a bar per page from its start date to its due date, with today marked and overdue work outlined; `workload` sums the estimates per assignee into a bar chart drawn by the shared kernel chart engine. Both read the view's existing source, filter, sort and groupBy, so "the workload for this project, open only" needs no key of its own. A chart is a LAYOUT and not a new block type, argued at length in spaces/src/gantt.ts and recorded in docs/DECISIONS.md, because every chart this app grows will inherit the choice. The measurable half: a shell built from the previous release, shown a view block with layout:"gantt", renders a board of the same pages, keeps the key through a save and keeps the new `start` values — verified in a browser against a real origin/main build. A chart block would have fallen to the unknown-type path and drawn one line of text where a schedule was. Adds a `start` date field. Absent `start` is not an edge case but the entire installed base — the tracker shipped with `due` alone — so those draw as a milestone diamond at the due date rather than as a zero-width bar. Wrong data is decided rather than left to arithmetic: a due date before the start is drawn between the two dates that are really in the file and flagged, never silently swapped; a malformed date is an absent date; a negative or non-numeric estimate is excluded from the sum and counted; an oversized view draws a capped, deterministically ordered chart that says what it left out. Dates are integer day numbers computed arithmetically with no Date constructed for any comparison — scripts/test-spaces-gantt.ts (114 checks) runs under five timezones, and a sabotage swapping in a local Date passed under UTC and failed under Pacific/Kiritimati. Both charts print and both survive into the file-manager still: colour and geometry travel as presentation attributes inside the svg rather than in styles.css, which the still's own stylesheet is not. Eighteen new strings in all eight catalogs, packed and confirmed in packed.ts. Shell cost, main and this branch built back to back: +13,304 bytes, of which +6,180 is the shared chart engine.
Build size
Updated: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two new shapes on the view layout control, branched off
origin/mainanddepending on none of the unmerged feature branches.
gantt— one bar per page, from itsstartdate to itsduedate. Todaymarked; overdue work outlined; bar colour from the grouping field's option.
workload— the firstvt:"number"field in the schema, summed perbucket, drawn by
kernel/src/charts.ts(read-only import, the path dashalready uses). The bucket is
groupBy, defaulting to the person field.Both read the view's existing
source,filter,sortandgroupBy, so{"layout":"workload","source":{"under":"<page>"},"filter":{"open":true}}is"the workload for this project, open only" with no new key anywhere.
The chart host: a layout, not a
chartblockArgued in
spaces/src/gantt.tsand recorded indocs/DECISIONS.md, becauseevery chart this app grows inherits it.
source/filter/sort/groupByand nothing else. Achartblock would grow four keys with those same four meanings — twovocabularies for one question, permanently, in every file ever saved.
origin/main, shown{"type":"view","layout":"gantt"}, renders a boardof the same pages, keeps
layout:"gantt"through a save, and keeps the newstartprop blocks — checked in a browser against a real build. Achartblock falls to the unknown-type path and renders its
html: one line of textwhere a schedule was.
dismissed: a workload chart really is an aggregate. It loses on scope — the
aggregation is a property of the output while every input key keeps the
meaning it had. A chart of data that is not pages (a
tableblock'snumbers) should be its own block type, and this is not a precedent against
that.
start, and why absentstartis not an edge caseThe tracker shipped with
dueand nothing else. Every issue in every filealready written therefore has a due date and no start — so those draw as a
milestone diamond at the due date, not a zero-width bar. Symmetric: a start
with no due is a diamond too. Neither date at all: left out, and counted.
Wrong data, decided rather than left to arithmetic
2026-13-99, prose, an object)NaN/Infinityestimate__proto__,toString)Maptally, no prototype chain to fall throughEvery date comparison is an integer day number computed arithmetically
(days-from-civil); no
Dateis constructed for any comparison.Print and the static preview
Colour and geometry travel as presentation attributes inside the SVG, not in
styles.css— which the file-manager still's own stylesheet is not. Measured:disabling the app stylesheet leaves the picture identical in colour and in every
proportion (uniform 1.228× rescale from the container width alone), and both
charts arrive in the serialized
[data-bento-preview]host with their fills,fitting a 300px thumbnail box with no overflow.
Not built, and what is left room for
Dependencies and critical path. Both need a typed page reference, which
exists only on the unverified
spaces-relationsbranch. No field invented, nosecond way to express a page reference. What is left for them at zero format
cost:
GanttModel.barsis a flat list keyed bypageId, each carrying itsresolved
x/won a shared 0..1 axis — an arrow is two lookups and twonumbers, a critical path is a walk over the same list. The edges will live on
the pages, not on the view block, so neither needs this module or the format to
change shape.
Verification
node scripts/test-spaces.mjs— all 9 rigs pass, including the newscripts/test-spaces-gantt.ts(114 behavioural checks, registered in therunner and in
ci.ymlunder a five-timezone matrix). Whole suite also greenunder
TZ=Pacific/KiritimatiandTZ=Pacific/Niue.tsc --noEmitclean;npm run build:single+shell-gate.mjspass.TZ=Pacific/Kiritimati, 10/11 underTZ=UTC. The one that differs is thepoint — replacing the arithmetic day number with
new Date(y, m-1, d)isinvisible from inside UTC and off by a day in UTC+14.
http://127.0.0.1, with abuild-marker check on every probe: bar geometry read with
getBoundingClientRect, SVG<a href="#p/…">routing confirmed by an actualnavigation, the full six-step layout cycle returning the block to a deleted
layoutkey, and the workload Group button readingGroup · Assigneeratherthan
Group · Status.origin/mainand this branch built back to back: +13,304 B(277,769 → 291,073), of which +6,180 B is the shared chart engine, probed
on its own.
test-spaces-size.mjsreports +32,619 B against a driftedreference; that number is not the change.
Format additivity
layout:"gantt"/"workload"are stored words;boardremains the absentkey, so a view cycled all the way round is byte-identical to one nobody touched
(verified in the browser).
startis an ordinary optionalpropblock carryingits own readable
html. Nothing is repurposed and nodocIdis regenerated.Notes for the reviewer
scripts/test-spaces.mjs(one RIGS entry) and.github/workflows/ci.yml(onestep). Registration is not optional — the manifest check fails without both.
scripts/test-spaces-model.tshas two assertions that hardcodednextLayout('gallery') === 'board'; the cycle is six long now and they wereupdated in place.
render.tsstill has the duplicated, unreachabletablebranch tracked on theboard as
spaces-table-unreachable. Left alone — not this change's to fix.that control to a picker. Written down in
fields.tsat the site.