fix(frontend): gate the add component affordance on the pending permission check (#14523)
* refactor(frontend): expose the pending half of the flow permission gate useIsFlowReadOnly conflates two states: the query is still resolving, and the user is denied. Controls that invoke a gated mutation need to tell them apart to disable themselves only while the answer is in flight and to name the reason correctly. Adds useIsFlowPermissionPending next to it, reading the same provider so both predicates can never disagree. No behaviour change on its own. * fix(frontend): gate sidebar component items on the pending permission check The add path already refused to run while the permission query resolved, but the item stayed draggable, double-clickable and kept an enabled add button, so the click was discarded with nothing reported. The row now carries the same not-allowed affordance it already uses for placement constraints, and the add button is disabled for that window. A constraint violation is a verdict and still hides the button; a pending check is transient, so it only suspends it and the control keeps its place. Refs LE-2176 * fix(frontend): gate New Custom Component on the pending permission check Same discarded-click window as the component items, on the sidebar footer button. It already had a disabled channel wired to the component-types load, so the pending permission state joins it. Because the button opts out of the base class with unstyled, the disabled look is spelled out at the call site — without it the control would block the click while still looking exactly like a working one. Refs LE-2176 * test(frontend): cover the add affordance during the pending permission check Splits the two halves of the gate on the hook, then asserts on both add surfaces that the control refuses the click visibly instead of discarding it, and that a placement constraint still wins the reason when both apply. Checked against the base: 5 of the 8 item assertions and 3 of the 4 button assertions fail without the fix; the rest are the resolved-state controls and the constraint regression guard. Refs LE-2176 * test(frontend): add e2e guard for the discarded add click Holds the permission response open so the window is deterministic instead of racing a round trip that is milliseconds wide on localhost, then asserts the control is unavailable during it and that the same single click adds a node once the answer arrives. Asserts the request actually happened: without that the test would pass vacuously on any build where the editor stops querying permissions. Refs LE-2176 * test(frontend): poll the intercepted permission request instead of reading it once The counter is incremented by the route handler on the Node side, while the visibility assertion it follows resolves on the browser side. Nothing orders the two, so on a loaded runner the guard could read zero and fail a test that is otherwise correct. Addresses the CodeRabbit review on #14523. * fix(frontend): dim the custom component button for both refusal reasons The button was disabled by the component-types load and by the pending permission check, but only the second one dimmed it. Same control looking refused for one cause and working for the other reads as a bug, and the load case fires on every flow open, so it is the more frequently hit half. Hoists the condition so disabled and the disabled look cannot diverge. Addresses I1 of the review on #14523. * fix(frontend): refuse the add affordance for denied write, not just in flight The gate the add path uses is read-only, which is true both while the permission answer travels and, permanently, when it denies write. Gating the controls on the pending half alone left a read-only collaborator with a fully interactive sidebar whose every add is discarded, with nothing reported — the same defect, except it never resolves. Both surfaces now key off useIsFlowReadOnly, the exact predicate that refuses the click, and useIsFlowPermissionPending only picks which reason to show: still checking, or read-only access. A placement constraint keeps hiding the add button; the permission cases only disable it, so a denied user still sees the layout everyone else does. Addresses I2 of the review on #14523. --------- Co-authored-by: Eric Hare <ericrhare@gmail.com>
T
Tarcio committed
0a2d167ade70e7ed43187090212ddaf75ac57c97
Parent: e0859c4
Committed by GitHub <noreply@github.com>
on 8/14/2026, 9:20:44 PM