Skip to content

feat(tracker): Gantt scheduling schema (startDate + IssueRelation) + version bump#10851

Open
MichaelUray wants to merge 7 commits into
hcengineering:developfrom
MichaelUray:feat/gantt-upstream-pr1-schema
Open

feat(tracker): Gantt scheduling schema (startDate + IssueRelation) + version bump#10851
MichaelUray wants to merge 7 commits into
hcengineering:developfrom
MichaelUray:feat/gantt-upstream-pr1-schema

Conversation

@MichaelUray
Copy link
Copy Markdown

@MichaelUray MichaelUray commented May 18, 2026

Stack overview

This PR is the foundation of a 10-PR Gantt-chart feature series for Tracker. The full stack is opened as Drafts to give visibility into the planned scope; this PR (#10851) is the only one currently ready for maintainer review / merge. Each follow-up rebases onto develop once its predecessor merges.

graph TD
  D[develop @ hcengineering/platform]:::base
  D --> P1["#10851 — Scheduling schema foundation"]:::ready
  P1 --> P2["#10853 — Read-only Gantt viewlet"]:::draft
  P2 --> P3a["#10854 — Editable bars (drag / resize / dnd)"]:::draft
  P3a --> P3b["#10855 — Dependencies, cascade scheduling, critical path"]:::draft
  P3b --> P4["#10856 — Visual + UX polish"]:::draft
  P4 --> P5["#10857 — Power-user features (undo, saved views, bulk, auto-schedule)"]:::draft
  P5 --> P6["#10858 — Y-axis virtualization for large projects"]:::draft
  P6 --> P7["#10859 — Mobile + tree-view + predecessor column + shift notifications"]:::draft
  P7 --> P9["#10872 — Inline filter chips + advanced search bar"]:::draft
  P9 --> P10["#10873 — Bar coloring (6 modes) + past-due/blocked overlays + sub-issue progress"]:::draft

  M[main @ hcengineering/huly-docs]:::base
  M --> Docs["huly-docs #70 — Full reference (15 pages, 33 screenshots)"]:::ready

  P10 -.documents.-> Docs

  classDef base fill:#e7e7e7,stroke:#555,color:#222
  classDef ready fill:#d4edda,stroke:#28a745,color:#155724
  classDef draft fill:#fff3cd,stroke:#ffc107,color:#856404
Loading

Legend: 🟢 ready-for-review · 🟡 draft (depends on predecessor) · ⚪ upstream base branch

ℹ️ Screenshots below reflect the integrated feature stack (snapshot 2026-05-21 from a staging deployment running the tip of all 10 branches together). They do not match the visual state of any individual PR taken in isolation — earlier PRs in the chain render simpler UI than what is shown. Each screenshot is intended as a feature reference, not a per-PR regression baseline.

Suggested merge order

  1. This PR (feat(tracker): Gantt scheduling schema (startDate + IssueRelation) + version bump #10851) — pure schema, safe foundation
  2. feat(tracker): Gantt — #2 read-only viewlet #10853feat(tracker): Gantt — #7 tier-4 (mobile, tree-view, predecessor column, visual deps, shift notify) #10859 in order — visual stack, each rebases onto develop after the previous merges
  3. feat(tracker): Gantt — #9 inline filter chips + advanced search + view-option toggles #10872feat(tracker): Gantt — #10 bar coloring + overlays + sub-issue progress #10873 — currently draft visibility PRs; they should be rebased / marked ready after feat(tracker): Gantt — #7 tier-4 (mobile, tree-view, predecessor column, visual deps, shift notify) #10859 merges
  4. huly-docs#70 — independent of code merge timing, can merge anytime after the relevant PRs are in

Local verification has passed for the branches touched in the latest update. Some GitHub Actions on draft / fork PRs may still require maintainer approval before they run. Every commit is Signed-off-by. All PRs have maintainer_can_modify=true — feel free to push fixes or rebase directly.

What each follow-up PR does (expand for details + screenshots)

Visual stack (PR2 → PR7)

  • #10853 — Read-only Gantt viewlet
    New view type next to List and Board. Each issue is rendered as a horizontal bar spanning from its startDate (left edge) to dueDate (right edge) on a time axis. Zoom levels: Day, Week, Month, Quarter. Read-only — bars cannot be dragged yet.

    Read-only Gantt overview

  • #10854 — Editable bars (drag / resize / dnd)
    Drag a bar horizontally to reschedule (start + due move together). Resize either edge to change duration. Drag-and-drop rows to reorder issues. Mouse + touch.

  • #10855 — Dependencies, cascade scheduling, critical path
    Visible directional arrows between dependent issues. When you drag a predecessor, its dependents shift forward automatically (cascade). The longest dependency chain is highlighted in red as the critical path.

    Dependency arrows + critical path

  • #10856 — Visual + UX polish
    Typography alignment, focus states, hover feedback, dark/light theme parity, keyboard navigation refinements across the viewlet.

  • #10857 — Power-user features
    Four independent additions:

    • Undo/redo for drag, resize, dnd, dependency-create actions
    • Saved views — capture current filter + grouping + zoom + time window as a named view, personal or shared with project members
    • Bulk select — Cmd-click or Shift-click to select multiple bars and drag them together
    • Auto-scheduling — optional mode that nudges pinned bars out of the way when a manual drag creates a collision

    Saved views dropdown

  • #10858 — Y-axis virtualization
    Performance improvement for large projects. Only visible rows are rendered to the DOM; scrolling stays smooth on projects with thousands of issues.

  • #10859 — Mobile + tree-view + predecessor column + shift notifications
    Five smaller additions that round out the feature:

    • Mobile — responsive layout, pinch-zoom, touch-friendly drag handles
    • Tree-view — parent → sub-issue hierarchy in the sidebar
    • Predecessor column in the issue list (shows dependency IDs)
    • Visual dependency arrows on hover even outside the active issue
    • Shift notifications — Telegram / inbox notify when a cascade shift moves an issue you own

    Mobile view

Companion track (PR9 + PR10, stacked on PR7)

  • #10872 — Inline filter chips + advanced search bar
    Reusable across List, Board, and Gantt viewlets:

    • Inline filter chips — All / Active / Backlog quick-filter row directly on the toolbar
    • Advanced search — field-prefix syntax (title:loader, id:HULY-, comments:fixed); Lucene-reserved chars escaped properly so title:C++ and title:POC: design don't crash the parser
    • Customize-View popoverSearch in... scope dropdown (Title / Title+Description / Title+Description+Comments), highlight-search-matches toggle, quick-filter visibility toggle
    • Empty-state card — friendly zero-results screen with reset actions

    Inline filter chips + active search

  • #10873 — Bar coloring + overlays + sub-issue progress
    Six color modes selectable from a toolbar Color by dropdown:

    • Status (default) — issue lifecycle stage
    • Priority — Urgent / High / Medium / Low / No-priority
    • Assignee — distinct hue per person
    • Component — uses a new optional color field on Component
    • Milestone — same pattern with Milestone color
    • Uniform — single color for all bars (for screenshots / printing)

    Plus an overlay layer that works on top of any color mode:

    • Past-due bars get a red left-stripe
    • Blocked bars (finish-to-start predecessor not Done) get a diagonal hatch
    • Sub-issue progress fill (Status mode only) shows how much of the parent's work is Done

    All toolbar state persists in saved views.

    Color by Status

    Past-due + blocked overlays

Documentation

  • huly-docs#70 — Full Gantt-chart reference (open for review, independent of code)
    15 mdx pages under tracker/gantt/ covering overview, bar coloring, dependencies, cascade scheduling, critical path, working-days awareness, filtering & grouping, advanced search, no-search-results state, saved views, bulk operations, auto vs manual scheduling, keyboard shortcuts, export, mobile/tablet. 33 light-theme screenshots all taken from a live deployment of the feature stack.

This PR — Scheduling schema foundation

Adds the schema foundation a Gantt-style scheduling view needs: an Issue.startDate field alongside the existing dueDate, an IssueRelation Mixin describing typed predecessor/successor links between issues, and a Milestone.startDate so milestones become real ranges instead of single points. The migration backfills startDate for existing issues (modifiedOn-fallback) and bumps the fulltext model version so deployed workspaces accept the new schema fields.

This is the first of the 10-PR series shown above. Each follow-up PR builds linearly on this one. Happy to discuss the broader feature plan before continuing — I can hold the follow-ups in draft or split / merge them differently if that fits the roadmap better.

What's in this PR (7 commits)

  • feat(tracker) add Gantt scheduling schema (startDate + IssueRelation)
  • feat(model-tracker) migrateAddStartDate operation + Jest tests
  • feat(tracker) expose Issue.startDate / Milestone.startDate in the UI; tighten typing
  • fix(tracker) explicit @Prop ranks for Milestone date fields
  • fix(tracker-resources) EditMilestone renders Status / Start / Target in chronological order
  • fix(fulltext) bump model version to 0.7.423 to match deployed workspaces (otherwise the fulltext pod silently rejects Tx events that mention the new fields)

How to review

Cumulative diff against develop. PR1 contains 7 commits across 31 files (+336 / −11). The schema change itself is the single largest semantic step; the rest are migration + UI plumbing that follow directly from it.

Testing

  • Jest tests on migrateAddStartDate cover the backfill behaviour for issues with / without dueDate.
  • Validated on a production-style deployment on 2026-05-18: schema migration runs cleanly on a workspace that pre-existed at model version 0.7.422, fulltext pod accepts the new fields, no rejected Tx events.

DCO

All 7 commits are Signed-off-by.

Schema-only foundation for the upcoming Gantt-chart view in tracker.
No UI in this PR.

Changes:
- Issue.startDate: Timestamp | null (interface + IssueDraft + @prop with @Index)
- Milestone.startDate: Timestamp | null (interface + @prop, reusing the
  existing tracker.string.StartDate IntlString)
- New DependencyKind type ('finish-to-start' | 'start-to-start' |
  'finish-to-finish' | 'start-to-finish')
- New IssueRelation AttachedDoc class with kind: DependencyKind, signed
  lag: number — registered in models/tracker via TIssueRelation
- 7 new IntlString keys: IssueStartDate, GanttDependency,
  GanttDependency{FinishToStart,StartToStart,FinishToFinish,StartToFinish},
  GanttLag — all 13 locales updated
- Cross-plugin literal updates in importer + github sync to satisfy the new
  required Issue.startDate / Milestone.startDate fields:
  - packages/importer/src/importer/importer.ts: AttachedData<Issue> literal
  - services/github/pod-github/src/sync/issueBase.ts: 'startDate' added to
    GithubIssueData Omit list (github sync does not own scheduling)
  - services/github/pod-github/src/sync/issues.ts + pullrequests.ts:
    AttachedData<Issue|GithubPullRequest> literals

Out of scope (deferred to follow-up PRs):
- UI for Gantt view, drag/resize, dependency editor, critical path
- blockedBy → IssueRelation migration (ships atomically with the writer
  redirect in the dependency-UI PR)
- LinkIssues permission (tracker uses forbid-style permissions; needs
  maintainer discussion)
- Activity-feed wiring for IssueRelation (needs a producer to test against)
- IssueTemplate.startDate (template propagation semantics undecided)

Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
3 tests covering migrateAddStartDate:
- writes startDate=null to Issues in DOMAIN_TASK with the right filter
- writes startDate=null to Milestones in DOMAIN_TRACKER with the right filter
- issues exactly two update calls (one per class)

Follows the MigrationClient mock pattern from
models/chat/src/__tests__/migration.test.ts.

Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…tion

Backfills startDate=null on existing Issues (DOMAIN_TASK) and Milestones
(DOMAIN_TRACKER) so the new schema field has a defined value on every
pre-existing document. Idempotent via the standard tryMigrate state-key
mechanism (state: 'gantt-add-startdate').

Verified domain choices against existing migration helpers:
- migrateIdentifiers / passIdentifierToParentInfo use DOMAIN_TASK for
  Issues (lines 145, 161 in this file).
- TMilestone @model decorator confirms DOMAIN_TRACKER for Milestones
  (models/tracker/src/types.ts:372).

Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…ghten typing

UI changes (so the new schema fields are actually editable, in chronological
order Start → Due/Target):

- New StartDateEditor.svelte (mirrors DueDateEditor.svelte for startDate)
- ControlPanel: render Start Date row above Due Date row in the issue
  side panel; both always-visible (no `!== null` guard) so users can set
  them on issues that don't have a date yet
- NewMilestone form: Start Date input above Target Date input
- Milestone list view: Start Date column before Target Date column

- TIssueRelation: tighten interface to `extends AttachedDoc<Issue, 'relations'>`
  so attachedTo + collection are statically typed. The model class
  re-declares `collection: 'relations'` to match the narrower base.
- Drop 4 unused Dependency-kind IntlString keys (FinishToFinish,
  FinishToStart, StartToFinish, StartToStart) — they had no consumer
  in PR 1; will be re-introduced in PR 4 (dependency editor).
- Simplify migration.ts comments — drop ageing line-references.

Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
The DocAttributeBar side panel sorts attributes by attr.rank ?? toRank(_id)
(see plugins/view-resources/src/components/ClassAttributeBar.svelte:42-47),
so without explicit ranks the visible order on a Milestone was hash-based
(startDate before Status, breaking the chronological flow the user expects).

Set ranks so the side panel renders Status → Start date → Target date.
Comments and attachments stay where they are (they're collections, filtered
out of the attribute panel by categorizeFields).

Issues are unaffected — the Issue side panel is the custom ControlPanel.svelte
which renders Start date / Due date in explicit slots (see PR 1's UI commit).

Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…body in chronological order

The right-side DocAttributeBar sorts attributes by attr.rank ?? toRank(_id),
giving startDate before status (toRank('startDate') < toRank('status')
lexicographically). Setting an explicit rank via @prop's third arg did not
propagate through the workspace upgrade for existing Attribute documents
in the model TX log — the rank made it into the bundled txes but the
existing Attribute creation TXes are not replaced on upgrade-workspace.

Pivot: render Status, Start date, Target date in the EditMilestone body
in explicit chronological order, and add 'status', 'startDate', 'targetDate'
to ignoreKeys so they don't appear duplicated in the side panel. This
mirrors how Issue's ControlPanel.svelte handles its date fields.

Reverts the no-op @prop rank attempt.

Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
…aces

The fulltext-pod's compiled model version (baked into bundle/model.json via
common/scripts/version.txt at build time) lags whenever the workspaces have
been migrated to a newer patch but the pod was not rebuilt. In that state the
indexer rejects every incoming Tx with a `wrong version` warning, new issues
silently fail to land in Elasticsearch, and search returns empty results for
any document created after the migration.

Bumping `version.txt` aligns the compiled model with the workspaces. All
future builds (front, transactor, workspace, tool, fulltext) will emit
0.7.423, the indexer accepts the Tx stream again, and the deferred backlog
gets consumed automatically — no manual reindex needed.

This commit is the build-side companion to the schema migration in this
same PR. Without it the fulltext-pod cannot consume the migrated workspace's
Tx events.

Signed-off-by: Michael Uray <michaeluray@users.noreply.github.com>
@huly-github-staging
Copy link
Copy Markdown

Connected to Huly®: UBERF-16441

@BykhovDenis
Copy link
Copy Markdown
Member

Hello @MichaelUray Thank you for your contribution. We would happy to review your PRs, but we need some time for it

@MichaelUray
Copy link
Copy Markdown
Author

Update to the original stack overview — two new PRs opened on the side of the original 7-PR series, both companion to this Gantt feature work:

Companion docs PR (covers both this PR1-PR7 series plus the bar-coloring follow-up): huly-docs#70 — now 15 mdx pages + 33 screenshots.

@MichaelUray
Copy link
Copy Markdown
Author

Stack overview update — PR10 is now also open as Draft: #10873 (Gantt bar coloring + overlays + sub-issue progress + saved-view bar-color snapshot). It is stacked on top of #10872 PR9. Companion docs page bar-coloring.mdx already in huly-docs#70.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants