Summary
In a type:'gantt' view, when a user drags a dependency link that would be illegal (would form a cycle, e.g. A→B→C then C→A; or self-link / onto a locked / group row), the link is correctly not created — but there is zero user feedback: no dialog, no toast, no not-allowed cursor, no red target outline, and the drag hint shows only the source end, never → target. The user cannot tell why the link won't connect. The same drag onto a legal target succeeds first try, so it isn't an interaction-technique problem.
Why this is a platform (not app) issue
- The gantt view is the platform-native
type:'gantt' renderer; the app only supplies read/write endpoints.
- The app already implements a server-side cycle guard that throws a business message with
status: 400, and the write endpoint surfaces it as 422 { message }. So a human-readable rejection reason exists server-side.
- The gantt renderer has a write-failure toast channel (locale key
gantt.writeFailed = "保存失败,已恢复修改前状态" is present in the bundle).
- Yet for illegal-link rejection, the client appears to short-circuit before issuing the PATCH, so neither the server message nor any toast is ever shown. The app cannot intervene: there is no exposed "rejection reason" /
onBeforeDependencyCreate output path on the public gantt component.
Impact
- Users repeatedly try to draw a legitimate-looking dependency and get silent non-response, with no way to learn it's a cycle/locked/group constraint. Severity: medium (usability / dead-end interaction on an otherwise-correct guard).
Fix direction (any one; first two preferred)
- On an illegal drop target, show a negative affordance (
cursor:not-allowed + target-row outline) during hover, and a explanatory toast on drop (e.g. new keys gantt.link.rejected.cycle / .locked / .group).
- Expose a rejection path (e.g. surface
onBeforeDependencyCreate's reason) so the host can supply a message the gantt renders.
- At minimum, stop rejecting silently — today there isn't even a console warning.
Environment
@objectstack/console@17.0.0-rc.6 (also present in rc.5).
Steps to reproduce
type:'gantt' view with a dependenciesField; create tasks A, B, C.
- Connect A→B, then B→C.
- Drag from C's link handle onto A (would close the cycle).
Expected: a message/affordance explaining the link is rejected (cycle).
Actual: nothing happens — no dialog, no toast, no cursor/outline change; the drag hint never shows the target end.
Observed while building an ObjectStack 17 app.
Summary
In a
type:'gantt'view, when a user drags a dependency link that would be illegal (would form a cycle, e.g. A→B→C then C→A; or self-link / onto a locked / group row), the link is correctly not created — but there is zero user feedback: no dialog, no toast, no not-allowed cursor, no red target outline, and the drag hint shows only the source end, never→ target. The user cannot tell why the link won't connect. The same drag onto a legal target succeeds first try, so it isn't an interaction-technique problem.Why this is a platform (not app) issue
type:'gantt'renderer; the app only supplies read/write endpoints.status: 400, and the write endpoint surfaces it as422 { message }. So a human-readable rejection reason exists server-side.gantt.writeFailed= "保存失败,已恢复修改前状态" is present in the bundle).onBeforeDependencyCreateoutput path on the public gantt component.Impact
Fix direction (any one; first two preferred)
cursor:not-allowed+ target-row outline) during hover, and a explanatory toast on drop (e.g. new keysgantt.link.rejected.cycle/.locked/.group).onBeforeDependencyCreate's reason) so the host can supply a message the gantt renders.Environment
@objectstack/console@17.0.0-rc.6(also present in rc.5).Steps to reproduce
type:'gantt'view with adependenciesField; create tasks A, B, C.Expected: a message/affordance explaining the link is rejected (cycle).
Actual: nothing happens — no dialog, no toast, no cursor/outline change; the drag hint never shows the target end.
Observed while building an ObjectStack 17 app.