feat(gantt): declare viewMode on ObjectGanttSchema and wire both renderer branches - #5825
Merged
Merged
Conversation
…erer branches (#5074) Executes the 2026-08-19 maintainer-confirmed ruling (declare-and-wire; the spec half landed upstream first): - ObjectGanttSchema declares viewMode in the TS interface and the zod mirror, DERIVED from the pinned @objectstack/spec GanttConfigSchema member by reference so the list cannot drift. Deliberately no default: absence keeps letting a persisted layout seed the granularity before the renderer's 'day' fallback. - getGanttConfig picks viewMode into GanttConfigEx, so both the flattened object-gantt style and the spec gantt config block carry it. - The timeline branch (GanttView) now receives the authored viewMode; previously only the ResourceWorkload branch honoured it. The (schema as any).viewMode cast is retired. - Tests: wiring pins for both branches and both authoring styles (ObjectGantt.viewmode.test.tsx), plus contract pins for derivation by reference, declared-key validation, and no-default absence semantics (gantt-view-mode-declared.test.ts). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EuPCi56cnGyykygi3z9w4m
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
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.
Fixes #5074
Executes the maintainer-confirmed ruling of 2026-08-19 (issue comment 5339681862): declare
viewModeand wire BOTH branches. The triage seat's "remove" recommendation was rejected there and is not re-opened here.Precondition re-verified in
node_modulesCounter-probed the installed
@objectstack/spec(the repo's pinned release) before writing anything, same probe shape as the unlock scan:GanttConfigSchema.viewMode(via@objectstack/spec/ui)z.enum(['day','week','month','quarter','year']).optional(), no defaultresourceView(known-present control)zzNotAKey(known-absent control)What changed
packages/types/src/objectql.ts—ObjectGanttSchemadeclaresviewMode?: SpecGanttConfig['viewMode'], DERIVED from the spec type so the member list cannot drift. Doc comment pins the absence semantics (no default; persisted layout may seed granularity).packages/types/src/zod/objectql.zod.ts— the zod mirror declaresviewMode: SpecGanttConfigSchema.shape.viewMode.describe(...)— the spec's own optional enum by reference (.describe()wraps; the inner enum object stays reference-identical, pinned by test).packages/plugin-gantt/src/ObjectGantt.tsx—getGanttConfigpicksviewModeintoGanttConfigExon the flattened path, so both the flattenedobject-ganttstyle and the specganttconfig block carry it;viewMode={ganttConfig?.viewMode}toGanttView— deliberately without|| 'day', so an omitted key keeps letting the persisted layout (persistLayoutKey) seed the granularity before GanttView's own'day'fallback (a guard comment marks this as load-bearing);ResourceWorkloadbranch readsganttConfig?.viewMode || 'day'— the(schema as any).viewModecast is retired (zero remainingas any).viewModereads in the repo); the now-unusedGanttViewModetype import is dropped.viewModeis now a DECLARED key, so an off-enum value (e.g.'hour') fails the zod parse where it previously passed through.passthrough()unvalidated. Values on the published spec enum are unaffected. Repo sweep found no fixture, example, or app authoringviewModeon a gantt schema (only the unrelatedpreviewModeand gantt demo i18n labels), so nothing in-repo is re-judged by the narrowing..changeset/gantt-viewmode-declared-both-branches-5074.md(minorfor@object-ui/types+@object-ui/plugin-gantt; no bare version literals).Out of scope, untouched
The other nine undeclared
as anyreads (readOnly,markers,holidays,skipWeekends,criticalPath,showBaselines,mobileReadOnly,navigation,persistLayout) stay with the #5043 family track. #5057 and #5126 chain behind this card and remain open — nothing here closes them. The staleGanttViewModeJSDoc card (#5132) andcontent/docs/plugins/plugin-gantt.mdxare untouched.Tests
New suites:
packages/plugin-gantt/src/ObjectGantt.viewmode.test.tsx— wiring pins (GanttView/ResourceWorkload mocked to thin shells, the file's established convention): timeline honours an authoredviewModein both authoring styles; timeline receives exactlyundefinedwhen omitted (the pin that stops someone "simplifying"|| 'day'back in); ResourceWorkload still honours the key and keeps its'day'fallback.packages/types/src/__tests__/gantt-view-mode-declared.test.ts— contract pins: key declared; inner enum reference-identical to the spec's (anti-fork); every spec member accepted; off-enum value refused with aninvalid_valueissue on theviewModepath; omitted key stays absent after parse (no default materialised); TS member mutually assignable with the spec type +@ts-expect-errornon-member pin (compiled bytsconfig.test.json, so it is real enforcement).Reverse verification on a real commit (
git checkout HEAD~1 -- <3 source files>, tests kept; then restored,git diff HEAD --statempty, re-run green 11/11):|| 'day'regression, not the pre-fix state); both ResourceWorkload legs (that branch already honoured the key); "accepts every member" (passthrough accepted the undeclared key pre-fix); "no default materialised" (absent either way at runtime — its compile-time half red-shifts only undertsc -p tsconfig.test.jsonagainst the reverted interface); the TS mutual-assignability leg (runtime-erased).Verification union at
c4a12f52e(the PR head), all through the container's shared verify lock, verdict lines read from the gate's own output:pnpm exec vitest run packages/plugin-gantt/ packages/types/(repo root, per AGENTS.md) — Test Files 92 passed (92), Tests 912 passed (912)pnpm --filter @object-ui/types type-checkandpnpm --filter @object-ui/plugin-gantt type-check(dependency closure built first) — both clean, script names echoedpnpm lint(turbo run lint, full farm — not narrowed) — 47/47 tasks successfulnode scripts/check-changeset-presence.mjs✅ ·check-changeset-no-major.mjs✅ ·check-control-bytes.mjs✅ ·check-spec-symbol-derivation.mjs✅CI is expected to run the same farm; per dispatch protocol this PR is reported at draft time without waiting for CI convergence.
Generated by Claude Code
Generated by Claude Code