Skip to content

[scheduler-premium] Dependencies - Arrows and terminals for SS, FF and SF - #23524

Merged
rita-codes merged 24 commits into
mui:masterfrom
rita-codes:23394-scheduler-dependencies-arrows-and-terminals-for-ssffsf
Sep 17, 2026
Merged

rita-codes merged 24 commits into
mui:masterfrom
rita-codes:23394-scheduler-dependencies-arrows-and-terminals-for-ssffsf

Conversation

@rita-codes

@rita-codes rita-codes commented Sep 7, 2026 •

Copy link
Copy Markdown
Member

Closes #23394. Part of #22853.

Renders the Start-to-Start, Finish-to-Finish and Start-to-Finish dependencies on the timeline and lets users create them by gesture. The engine side (per-type formulas, lag) stays in #23393: until it lands, a non-FS dependency is drawn and described but not enforced.

What is covered

  • Model. SchedulerDependencyType widens to the four types, the minimum the rendering needs. The rest of the model work (lag, lagUnit, validation) belongs to [scheduler] Dependencies: SS/FF/SF and lag in the auto-scheduling engine #23393 with the engine formulas that consume it, and is not touched here. Helpers getDependencyEdges(type) and getDependencyType(sourceSide, targetSide). A dependency with an unknown type is ignored with a dev warning.
  • Arrows. Each type connects the edges it constrains. Routing works in a canonical frame where the source exits to the right: SF is FS mirrored, SS is FF mirrored. Two routers: the existing one for opposite edges (elbow, S detour when backward) and a new one for same edges (wraps around the outermost anchor, detours below the events at the same height). The arrowhead always enters horizontally, also at the timeline edges.
  • Terminals on both edges. The dragged edge and the dropped edge define the type. Terminals are drop targets themselves; dropping on the event body targets the start edge, so FS and SS need no aiming. Same behavior as Bryntum's DependencyCreation.
  • Gesture feedback. The hovered target shows its terminals and the one the drop would use grows in green; the provisional line snaps to that edge. The delete button of a selected arrow sits on the side the arrow comes from, and the terminal under it steps aside while the selection lasts.
  • Duplicates. Two dependencies of different types between the same events are allowed; a duplicate of the same type is rejected.
  • Accessibility. One sentence per dependency on the successor: "Cannot start until A finishes", "Cannot start until A starts", "Cannot finish until A finishes", "Cannot finish until A starts".

Also

  • The arrow geometry module is split into anchor resolver, routing and hit-area (pure move, first commit), each with its own tests.
  • The arrow path string is built lazily and the terminal leaf is memoized: a gesture transition re-renders only the terminals involved.
  • The experiments demo is a release day with every type and arrow shape once.

Out of scope

How to test

/x/react-scheduler/experiments/, section "Timeline dependency arrows": one dependency of each type in the data, hover an event for its terminals, drag from either edge onto another event or one of its terminals, select an arrow to delete it.

rita-codes and others added 6 commits September 7, 2026 13:02
Pure move: the anchor resolver, the orthogonal routing and the hit-area helpers
get a module each, so the routing changes for the new dependency types are
reviewable on their own.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
Widens SchedulerDependencyType to the four PDM types (the rendering is the
consumer; lag stays with the engine work) and routes the arrows in a canonical
frame: StartToStart and StartToFinish mirror the anchors around the events area,
leaving one router for opposite edges (the existing one) and one for same edges.
The arrow path is now built lazily, like the hit-area, so a row re-measure does
not rebuild the strings of off-screen arrows.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
…ions

Every event gets a terminal on both edges, and the terminals are drop targets
themselves: the dragged edge and the dropped edge resolve the dependency type
(the event body targets the start edge). While a gesture hovers a target, its
terminals are revealed by state so the user can pick the edge. Duplicate
detection now includes the type, the delete button sits on the side the arrow
comes from, and the successor description carries one sentence per type.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
While the gesture hovers a target, the terminal of the edge the drop would use
(the hovered terminal, or the start edge over the event body) carries
data-dependency-drop-target and grows in the creation color, like Bryntum's
active terminal.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
- Let the pointer through the terminals while a dependency is selected, so the
  delete button under the target's edge terminal stays reachable.
- Compare the revealed terminal set element by element: the two terminals of an
  appearance are culled separately and the set can grow on scroll.
- Drop the hover reveal of the source's other terminal at gesture start.
- Memoize the terminal leaf on primitive props so a gesture transition only
  re-renders the gesture's terminals.
- Ignore and warn about dependencies with an unknown type instead of throwing.
- Tests for the start terminal placement and clamp, the multi-resource gesture,
  the provisional line anchor, the StartToFinish edge cases and a FinishToFinish
  multi-resource fan-out; stale comments, dead code and duplicated CSS cleaned up.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
One dataset where every dependency has a business reason and each type and
arrow shape appears once, restricted to working hours so it fits the viewport.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
@rita-codes rita-codes self-assigned this Sep 7, 2026
@rita-codes rita-codes added type: new feature Expand the scope of the product to solve a new problem. scope: scheduler Changes related to the scheduler. labels Sep 7, 2026
@rita-codes rita-codes changed the title [scheduler-premium] Dependencies - Arrows and terminals for SS, FF and SF [DRAFT][scheduler-premium] Dependencies - Arrows and terminals for SS, FF and SF Sep 7, 2026
@rita-codes rita-codes added the plan: Premium Impact at least one Premium user. label Sep 7, 2026
@code-infra-dashboard

code-infra-dashboard Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

Deploy preview

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-scheduler 0B(0.00%) 0B(0.00%)
@mui/x-scheduler-premium 🔺+3.06KB(+0.54%) 🔺+887B(+0.56%)
@mui/x-chat 0B(0.00%) 0B(0.00%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

rita-codes and others added 11 commits September 8, 2026 12:02
Moves the resolver tests out of the geometry suite, shares the fixtures through
dependencyGeometryTestUtils, and pins the edge points per lane and row, the row
obstacles, the unmeasured rows and the precomputed positions directly.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
…ion build

The shared fixtures import test/utils, which the declaration build (rootDir src)
cannot follow; the tests folder is excluded from it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
…sffsf' of github.com:rita-codes/mui-x into 23394-scheduler-dependencies-arrows-and-terminals-for-ssffsf
…meline edges

The same-height branch of the same-edges router kept the raw anchors as its
endpoints, so a target ending at the timeline end (or starting at its start for
the mirrored types) lost its entry segment and the arrowhead pointed up. The
stubs now ride over the events like the other branches, and an invariant test
over the whole type matrix pins that every route ends horizontally into its
target edge.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
Hiding every terminal while a dependency is selected made a press on a visible
terminal fall through to whatever sits beneath it. Only the selected arrow's
target-edge terminal, the one the button covers, steps aside now.
Also: the routing invariant test checks the exit direction and orthogonality,
the fixtures shared by the dependency tests live in one place, and a few dead
bits and stale comments from the review go.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBYMarDHeuysLnbKifmMaP
@rita-codes rita-codes changed the title [DRAFT][scheduler-premium] Dependencies - Arrows and terminals for SS, FF and SF [scheduler-premium] Dependencies - Arrows and terminals for SS, FF and SF Sep 8, 2026
@rita-codes
rita-codes marked this pull request as ready for review September 8, 2026 14:48
@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Sep 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@flaviendelangle flaviendelangle left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR review

One non-blocking finding: an unknown dependency type can crash the timeline when that dependency is selected. All 251 executed dependency tests passed; browser tests were not run.

Bugs (1)

1. 🟠 Guard the selected dependency’s type before resolving its edges

Location: EventTimelinePremiumDependencyTerminals.tsx:362

: { eventId: selected.target, side: getDependencyEdges(selected.type).target };

Unknown types are filtered out of active arrows, but selectedModel still returns them. The selection cleanup also does not check the type. This lookup therefore returns undefined, and reading .target crashes rendering.

Failure scenario: Select a valid arrow, then refresh dependencies with the same ID and an unknown type. A local reproduction confirmed the TypeError at this line.

Fix: Guard unsupported types before resolving the selected dependency’s edges, clear their selection, and add a regression test for this update.

Tests (0)

No findings.

Simplifications (0)

No findings.

Docs (0)

No findings.

Verdict

Approve after nits - guard the selected-dependency lookup against malformed type updates.


🤖 Review generated with Codex

…ependencies-arrows-and-terminals-for-ssffsf

# Conflicts:
#	packages/x-scheduler-internals-premium/src/event-timeline-premium-selectors/eventTimelinePremiumDependencySelectors.ts
#	packages/x-scheduler-premium/src/event-timeline-premium/content/timeline-dependency-arrows/dependencyArrowGeometry.test.ts
#	packages/x-scheduler-premium/src/event-timeline-premium/content/timeline-dependency-arrows/dependencyArrowGeometry.ts
#	packages/x-scheduler-premium/src/event-timeline-premium/tests/dependencyTestUtils.tsx
…ows-and-terminals-for-ssffsf' into 23394-scheduler-dependencies-arrows-and-terminals-for-ssffsf
@github-actions github-actions Bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Sep 17, 2026
rita-codes and others added 3 commits September 17, 2026 11:23
… whose type becomes unknown

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@rita-codes

Copy link
Copy Markdown
Member Author

Good catch, thanks. The store effect that clears the selection only checked the endpoints, so it missed the "unknown type" case this PR introduced in the active-list selector.

Fixed in d7009e6 by extracting an isDependencyActive predicate (supported type + valid endpoints) shared by the active-list selector and the selection cleanup, so anything the arrows drop can no longer stay selected. Added a store test and a timeline test reproducing the TypeError on the same-id / unknown-type update.

@rita-codes
rita-codes merged commit e8e61f8 into mui:master Sep 17, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plan: Premium Impact at least one Premium user. scope: scheduler Changes related to the scheduler. type: new feature Expand the scope of the product to solve a new problem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[scheduler] Dependencies: arrows and terminals for SS/FF/SF

2 participants