feat(tracker): Gantt — #10 bar coloring + overlays + sub-issue progress#10873
Draft
MichaelUray wants to merge 389 commits into
Draft
feat(tracker): Gantt — #10 bar coloring + overlays + sub-issue progress#10873MichaelUray wants to merge 389 commits into
MichaelUray wants to merge 389 commits into
Conversation
|
Connected to Huly®: UBERF-16463 |
This was referenced May 21, 2026
…view comments
The dependency-add cycle check in the issue-editor panel used only
incoming + outgoing slices of the current issue:
wouldCreateCycle(sourceId, targetId, [...incoming, ...outgoing])
That catches direct A→A and direct duplicates but misses transitive
cycles. Example: with C→B and B→A already in place, adding A→C from
A's panel passes the check because C→B is not in A's local slice —
the DFS never sees the back-edge B→A→C from the C side, so the new
edge silently closes the loop. The Gantt view already does a
project-wide check; the issue panel must match.
Add a third live-query bound to { space: issue.space } that loads all
relations in the project, and pass the full list to wouldCreateCycle
on add. The visible Predecessors/Successors lists keep using the
existing incoming/outgoing slices.
gantt + dependency code. The substance of each note is preserved but
rephrased so the comments document the technical reason, not the
review thread that surfaced it.
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
The optional-chained `getAttribute('content-type')?.includes(...)` yields
`boolean | undefined`; guard the nullish case explicitly with `?? false`
to satisfy @typescript-eslint/strict-boolean-expressions without changing
behaviour (absent/non-JSON content-type still marks recording unavailable).
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…cade tier
Apply the reviewer-approved fix patterns to the pre-existing eslint errors
surfaced by the CI formatting job in the PR3b feature code:
- no-confusing-void-expression: block-body arrows for void event handlers
(GanttCanvas/GanttSidebar/ConfirmCascadePopup/GanttHelpPopup dblclick/click/
cleanup handlers).
- no-misused-promises: single stable void-wrapper (onWindowPointerUp) shared by
attach/detach so the listener reference stays paired.
- prefer-optional-chain: nested {#if} guards preserving TS narrowing
(GanttCanvas connector overlay, GanttDependencyLayer) and loose == null form.
- no-invalid-void-type: dispatcher payload void -> undefined (matches the
codebase convention).
- strict-boolean-expressions: explicit zero / nullish handling in
dependency-router and exporter.
- test files: drop non-null assertions in favour of optional chaining, remove
unused imports/vars, rename snake_case locals to camelCase.
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…ter develop merge Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…useup wrapper
The cascade merge + eslint import consolidation left three type errors
svelte-check flags in the PR3b GanttView:
- the './lib/types' import got merged into an `import type { ... }` with
redundant inner `type` modifiers (invalid syntax) — flatten to plain names;
- `getEventPositionElement` was dropped from the @hcengineering/ui import —
restore it (used by openGanttMenu);
- an onWindowMouseUp wrapper carried over from the PR3a edit tier referenced
handleCanvasMouseUp, which PR3b renamed to handleCanvasPointerUp (wrapped as
onWindowPointerUp) — remove the now-dead, dangling wrapper.
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Der Add-Sub-Issue-Button oeffnet seit bc2414a (unified hierarchy add chooser) nicht mehr direkt das CreateIssue-Formular, sondern zuerst den HierarchyAddPopup mit den Optionen 'Create new sub-issue' / 'Link existing as sub-issue'. Die Playwright-page-objects clicken den Zwischenschritt jetzt mit, bevor das Formular gefuellt wird: - IssuesPage.clickOnSubIssues (subissues.spec 'create sub-issue') - IssuesDetailsPage.clickButtonAddSubIssue (subissues.spec 'Edit a sub-issue' / 'Delete a sub-issue') Keine Assertion abgeschwaecht, kein Timeout erhoeht — nur der neue UI-Pfad wird durchlaufen (analog zur milestone-page-object-Anpassung in Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com> hcengineering#10851).
…ional The Gantt schema PR (ControlPanel) adds several unconditional rows between Assignee and Estimation in the issue side panel (Start date, Due date, Deadline, Scheduling mode). The prior positional locator (//span[text()="Estimation"]/../div/button)[N] had to be re-indexed each time a row was added and had drifted to [5], which no longer resolves to the Estimation editor button — so editIssue's estimation step could never open the EditBoxPopup and 'div.selectPopup input' never appeared, failing issues.spec:49 'Edit an issue' and subissues.spec:52 'Edit a sub-issue'. Switch buttonEstimation to the same following-sibling path already used by textEstimation, which targets the Estimation label's own editor button regardless of how many rows precede it. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Restore the ru.json dependency/cascade i18n keys and the final Gantt component sources that were carried into this branch via a merge commit. Linearizing the branch onto the new develop dropped that merge, so this commit re-materializes the exact intended tip content (develop does not touch these files). Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…tics The Alt-bypass violation count was still computing FS with the old 'predDue + lag' (no +1-day) formula. Aligning it with the new fsAnchor helpers keeps Alt-bypass agreeing with cascade decisions and the CP overlay in both legacy and working-days modes. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…heduler/CP GanttView now subscribes to the current Project document and reads its optional workingDaysConfig. The config is forwarded to: - computeCriticalPath via the new third argument (cfg) - simulateCascade via options.workingDays Reactive: a project-config change retriggers the debounced CP recompute exactly as issue/relation mutations already do. Spaces without a Project (or with no config set) keep legacy calendar-day behaviour. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…ix FS +1d off-by-one simulateCascade now accepts an optional WorkingDaysConfig via `options.workingDays`. Forward and backward FS/SS/FF/SF anchor math routes through the new working-days helpers, which fall back to legacy calendar-day arithmetic when no config is given. The legacy branch also implements the +1-day FS rule that critical-path already obeys. Previously scheduler.ts computed FS successor anchor as `predDue + lag * DAY_MS`, while critical-path.ts used `predDue + DAY_MS + lag * DAY_MS`. This silent disagreement meant cascade and CPM could disagree about whether a successor was satisfying the FS constraint by exactly one day. The spec (§Datums-Semantik) makes the +1-day rule verbindlich; this commit aligns scheduler.ts with that convention. BREAKING CHANGE: three pre-existing test expectations encode the bug and were recalibrated: - Test 5 (pull-predecessor): A.newDue = May 1 (was May 2), newStart = Apr 27 (was Apr 28). - Test 6 (FS lag=2): B.newStart = May 8 (was May 7). - Test 7 (FS lag=-1): B.newStart = May 12 (was May 11). New tests cover the working-days mode (Mo-Fr, holidays, pull-predecessor across a weekend) plus the legacy +1-day FS rule. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Adds a new background layer in GanttCanvas that fills every weekend or holiday day with a low-alpha theme-divider colour. The layer renders between the SVG root and the gridlines so it sits under all bars and overlays — pointer-events are disabled. - viewport.ts: new pure helper nonWorkingDaysInRange(from, to, cfg, max) returning UTC-midnight timestamps of non-working days in the viewport. Returns [] in legacy mode so the canvas pays zero cost when the project has no working-days config. - GanttCanvas.svelte: new workingDaysConfig prop + reactive nonWorkingDays array, threaded into a dedicated <g class='non-working-days'> group. - GanttView.svelte: forwards the project's cfg to the canvas. - 5 new viewport tests covering legacy mode, weekend listing, the maxDays cap, inverted ranges, and explicit holidays. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
- TProject gains an optional workingDaysConfig property stored as a JSON
Record (TypeRecord). Optional + additive: every existing Project keeps
workingDaysConfig=undefined, preserving legacy calendar-day behaviour.
- Migration registers the new state 'gantt-add-working-days-config' as a
no-op upgrade entry so the tracker schema-version tracker advances.
- 14 new IntlString keys (WorkingDaysConfig, WorkingDaysTitle, ..., per-
weekday short labels Mon..Sun) registered in plugins/tracker/src/index.ts.
- EN + DE translations added in plugins/tracker-assets/lang/{en,de}.json
for all 14 new keys.
This commit only persists the type and surfaces the labels; the
project-settings UI to edit the config is intentionally deferred to a
follow-up so this PR stays focused on scheduler correctness.
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
computeCriticalPath now accepts an optional WorkingDaysConfig and routes forward/backward anchor math through the shared working-days helpers. Slack stays in milliseconds (LS - ES) to keep the result shape stable for existing UI consumers; conversion to a working-day count for display purposes is the caller's responsibility. The legacy +1-day FS rule that critical-path already used now lives in fsAnchor itself — both critical-path and scheduler share that source of truth, eliminating the prior off-by-one drift between them. All pre-existing CP tests remain green; new tests cover: - FS chain across a weekend (Fri → next Mon is tight, no slack) - FS lag=2 violation when succ is pinned earlier than required wd - Holiday in the dependency gap forces a violation - Legacy-mode regression check Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…lpers Introduces the data shape and pure helper functions for Phase 2 of the Gantt UX polish — a per-project working-days calendar. - WorkingDaysConfig interface on tracker.Project (optional). Weekday mask uses bit 0=Mon..bit 6=Sun; holidays as UTC-midnight timestamps. Absence of the property means 'every day is a working day' (legacy mode). - plugins/tracker-resources/.../lib/working-days.ts: pure helpers isWorkingDay, nextWorkingDay, addWorkingDays, workingDaysBetween, plus the four anchor functions fs/ss/ff/sf and their reverse counterparts. All accept cfg | undefined so the same call-site serves legacy and working-days mode. - 44 Jest cases covering weekday mask, holidays, midnight rounding, cross-weekend arithmetic, negative spans, anchor semantics in both legacy (with the +1d FS fix) and Mo-Fr modes. Helpers are not yet wired into scheduler.ts or critical-path.ts; those follow in the next two commits to keep the diff readable. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…nt index GanttView's sortedRows post-sort reordering kept each row's buildLayout() y, which then drove the absolute position when the sidebar virtualizes. That made the sorted sidebar visually appear in pre-sort order. Now the sidebar derives vy = i × rowHeight from the current iteration index so the rendered order matches the iteration order regardless of any upstream sort or filter. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Three additional assertions covering the LayoutRow shape produced for group-header rows (collapsible=true, issue/milestone=null, groupKey/ Count/Label populated), the issue-row carry-through of groupKey for the canvas tint, and the preservation of y / height from the source group rows. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…ModeEditor Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
The mkIssue test fixture was using a Partial<Issue> spread + a literal 'string' for _id, which violates the branded Ref<Issue> shape under strict svelte-check. Replace with an explicit IssueOverrides interface that casts _id once and feeds the rest of the Issue fields through fixed defaults — keeps the test surface readable while making svelte-check happy. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…umn components GanttSidebarHeaderCell handles the sortable header label and the column resize handle on the right edge. Resize uses window-level mousemove/up listeners with clean teardown on mouseup or component destroy. GanttSidebarColumn dispatches per-column-key cell rendering: identifier (IssuePresenter), title (clickable openIssue), status (StatusBadge), priority/estimation/dates as read-only text, predecessors/slack reusing the existing helpers. Inline-edit popups are reserved for Phase 3a.v2 when the undo-manager (Phase 3c) is in place. EN+DE i18n added for the 16 column header labels, the extended-mode toggle and the sort-breaks-hierarchy warning tooltip. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…wnstream consumers Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Introduce SidebarColumnKey union, DEFAULT_COLUMNS, DEFAULT_WIDTHS map, MIN/MAX_WIDTH clamps and a defensive parseColumns coercer that always yields at least one valid column. 16 unit tests cover the legal and malformed input paths. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
GanttView.svelte: - Read ganttGroupBy from viewOptions (safe fallback 'none') - In-memory ganttFilter + collapsedGroups (per-mode reset on group switch) - filteredIssues feeds buildLayout (legacy) OR buildGroupedRows - onToggle routes 'group:*' ids to collapsedGroups - sortedRows short-circuits when groupBy active (sort applied within lane) - Toolbar-right gains: Filter button with badge + popup (priority chips), Group-By dropdown with overrides-hierarchy tooltip - Ctrl+F/Cmd+F shortcut toggles the filter popup (was reserved in Phase 1) GanttSidebar.svelte: - Renders 'group-header' rows in both legacy and extended-grid layouts with chevron, label, count; spans full grid width GanttCanvas.svelte: - Paints lane-tint band behind 'group-header' rows (.group-header-bg) lib/types.ts: - LayoutRow.kind union extended with 'group-header' - Optional groupKey/groupLabel/groupCount fields lib/build-rows.ts: - groupRowsToLayoutRows adapter so existing Sidebar/Canvas iterate the same LayoutRow[] for both legacy and grouped modes Strings: - 22 new EN+DE keys for GroupBy / Filter / sentinel labels 256 → 289 Jest tests (green); svelte-check passes. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Three pure modules and their Jest suites: - group-by: resolveGroupKey/sortGroupKeys/getGroupLabel + sentinels (__unassigned__, __no_component__, __no_milestone__, __no_label__, __unknown__). 17 tests. - build-rows: buildGroupedRows produces the flat row stream with discriminated 'group-header' | 'issue' rows and pre-computed y positions. Supports withinGroupCompare for the Phase-3a sort hook. 7 tests. - filter-predicate: applyFilter / countActiveFilters with AND-across-keys and OR-within-key semantics; unknown keys ignored for forward compat. 9 tests. 256 → 289 Jest tests (all green). Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…adeToken helper Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…orator Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…senceInTabs
The my-issues tab check used expect('.hulyComponent').not.toContainText(name),
but the empty-state renders the search echo (No issues found for "<name>"),
so the negative text assertion matched the echo and failed. Switch to the
established linesFromList row-count locator (toHaveCount 0/1), which targets a
real issue row and ignores the search echo. Strengthens the assertion; last
tracker uitest fail.
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…le split)
InlineFilterChipsOverflow receives hiddenStartIndex as a one-shot snapshot of
visibleCount while its {#each $filterStore} body stays live. When the filter
set changes with the popover open, the snapshot points at the wrong subset
(M-VF3). Subscribe to filterStore on open and close the popover on the first
real mutation; clean up the subscription on user-close and on destroy.
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…-safe (M-VF5) Verified that raw query_string field-targeting in FullTextAdapter.search cannot leak cross-space or cross-workspace data: workspaceId is a hard bool.must term, and the sole caller (fulltext /api/v1/search via FullTextMiddleware) sits below SpaceSecurityMiddleware, which either bakes the space constraint into the DB findAll or post-filters via clientFilterSpaces. The ES hits are only a candidate id-set, re-filtered downstream. No whitelist gate needed; record the proof. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…y (M-G1) Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…ng (M-G4) Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…hing parents (M-G5) Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…ponses (M-G7) Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
… (M-G9) Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…y (L-G3) detectCycle previously ran on the full unfiltered relation graph before the scheduled filter, so a cycle among purely unscheduled issues wrongly disabled the whole critical-path panel. Move the check after activeRels is derived so only cycles among scheduled relations degrade the result. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…(L-G1/L-G2/L-G4/L-G9) - L-G1: generation-guard the async editableIssueIds IIFE so an older, slower canEdit chain can no longer overwrite the Set with a stale value. - L-G4: gate the Tab/Arrow/+/- shortcuts behind isTextInputFocused() and only trap Tab when a bar has focus, so text inputs inside the Gantt root keep native typing/caret behaviour and keyboard users are never stuck. - L-G9: precompute a Set of issues touched by a violated relation once per change instead of rescanning all relations for every rendered row. - L-G2: inject the Issue/IssueRelation class refs into UndoManager (defaults preserved for the unit mocks) and align the apply() JSDoc/adapter with the real TxOperations.apply(scope,...) — the marker is the apply scope. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…preserved (L-G5) gotoAllIssues truncates the route to the allIssues special view and does not carry the search text. The header comment claimed the opposite; align the doc/comment with the actual behaviour instead of adding a dead query param. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
… (L-G6) changeStartDate/changeTargetDate persisted a new bound without checking the other, allowing startDate > targetDate. Pull the opposite bound along so an inverted range is never written. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Precise the JSDoc: the function only strips edit affordances from guest roles; space membership and the actual write authority are enforced upstream by the space-security layer, not here. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…L-G10) SEARCH_VIEW_OPTIONS is appended to issuesOptions() but builder.createDoc is idempotent, so existing workspaces never received the new entries on the stored IssueList/IssueKanban viewlet docs. Add addSearchViewOptions, mirroring addGanttPhase1ViewOptions, to merge the missing keys by key. Idempotent. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…tion (L-VF1) removeFilter/updateFilter mutated the stored array in place before set(), so reference-memoised consumers and reduceCalls queue coalescing could miss the change. Build a new array each time. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
queryNoLookup is rebuilt as a new object every cycle, but createQuery skips the callback for a deep-equal query. Resetting queryReady on object identity alone could strand it at false forever (callback never re-fires), leaving the result count / SearchEmptyState stale. Compare a serialised signature instead. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
splitHighlightSegments stripped only the first leading prefix and highlighted the whole trimmed query as one literal, so a multi-word search highlighted nothing. Strip all stacked leading prefixes and highlight each term via alternation, matching search semantics. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…(L-VF6) aria-expanded was hardcoded false; bind it to the live popover handle so AT users get the real disclosure state. Also drop the stale IconClose dead-code comment (the icon is used by the clear-all button). Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Date filters emit $lte/$gte, but the key-merge only handled $lt/$gt, so two date filters on one key fell through to Object.assign (last wins) instead of tightening the range. Add $lte/$gte branches keeping the tighter bound. Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
3759056 to
7702a05
Compare
…olors Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com> # Conflicts: # plugins/view-resources/src/components/filter/FilterBar.svelte
… the Tracker save-row path The develop merge brought in hcengineering#10969's canSaveFilteredView gate, but it only guarded the legacy chip-row save button. The branch-new showSaveRow path (Tracker IssuesView, hideChips=true) renders SaveAs/Save without the gate, so a ReadOnlyGuest/DocGuest would still see them. Add canSaveFilteredView to showSaveRow — in that path the row is save-buttons only, so hiding it for guests matches upstream intent (chips render separately via InlineFilterChips). Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
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.
Stack context
This PR sits on top of #10872 (PR9 — filter chips + advanced search + view-option toggles, currently Draft) which in turn sits on top of the #10851 PR1 → #10859 PR7 Gantt feature series.
The diff against
developtherefore shows the full dependent stack (PR1-PR7 + PR9 + bar-colors). The actual marginal content of this PR is documented below. Once the dependent PRs merge, this branch will be rebased onto upstreamdevelopand the diff collapses to bar-colors only.This PR is opened as Draft to give visibility into the planned feature surface and let CI run early — same convention as PR2-PR7.
Marginal bar-colors content (what this PR actually adds)
13 commits introducing the bar-coloring feature on top of the read-only/edit/dependencies/polish/tier2 viewlet, plus 3 small polish commits after the Plan-2 merge:
Core bar-coloring (13 commits)
1e10fc40b804eb240601GanttBarIssueLiketype +isPastDue/isBlockedpredicatesfa5da87709colorfield to Component and Milestone schemas459a3740d376bac888230ada4c51c0GanttSavedViewOptionswith 4 new toolbar fields04ac2090fab722d66c47323e93fbba3c0543807dColor bydropdown with 6 modes6a543620643a7be3d271ganttViewOptions(Customize-View popover)0547f5dcb0Post-Plan-2-merge polish (3 commits)
c228d5f7f7f71613c2d7Filter/view regression fixes (5 commits)
Regressions found and fixed during the last live-testing session:
fix(view): filter mutators emit fresh arrays (L-VF1)re-arm List queryReady (L-VF2)highlight each query term (L-VF3)aria-expanded on overflow badge (L-VF6)intersect $lte/$gte date bounds (L-VF7)Feature summary
Color bydropdown:Status(default) — issue lifecycle stagePriority— Urgent / High / Medium / Low / No-priorityAssignee— distinct hue per personComponent— uses the new optionalcolorfield on Component (falls back to a generated hue if unset)Milestone— same pattern with Milestone colorUniform— single color for all bars (good for screenshots / printing)GanttSavedViewOptions. The Customize-View popover (cog icon) exposes the same toggles throughganttViewOptionsfor users who prefer the popover surface.Test coverage
plugins/tracker-resourcesjest: 686 tests pass including the new bar-color resolver suitespackages/uijest: 62 tests pass (includes the encoder hardening + leading-hyphen escape from PR9)plugins/view-resourcesjest: 19 tests passsvelte-check: 0 errors across all three packagesDeployment
This branch (
feat/gantt-bar-colors) is currently deployed live at https://huly.uray.io ashardcoreeng/front:plan4-pr9-pr10for hands-on testing. The feature has been validated end-to-end in the browser including saved-view round-trips and dropdown UX.Companion docs PR
huly-docs#70 — includes
bar-coloring.mdx(the dedicated bar-colors reference) plus 8 screenshots of the feature in action.DCO
All commits in this PR are
Signed-off-by: Michael Uray.Note on rebasing
When PR9 merges upstream, this branch will be rebased to:
At that point the PR diff will be a clean bar-colors-only delta.