fix(frontend): surface components an administrator disabled (#14614)
* fix(frontend): surface components an administrator disabled
Blocking a component removes it from /api/v1/all, so a node already saved in
a flow loses its template. checkCodeValidity detects exactly that and marks
the node blocked, but both places acting on the flag were gated on custom
components being disabled:
!allowCustomComponents
? isBlocked || isOutdated || hasBreakingChange
: (isOutdated || hasBreakingChange) && !isUserEdited && !dismissAll
With custom components allowed, which is the default, the flag was ignored.
The node looked healthy and the run failed later with a generic error, giving
no indication an administrator had disabled anything.
Surface a missing template regardless of that setting, reusing the existing
blocked banner, and stop the build the same way. Outdated components keep
their current behavior and are still only enforced in restricted mode.
The existing copy names the wrong cause here, so blocked nodes report the
catalog policy when custom components are allowed and keep the original
wording when they are not.
* fix(frontend): stop retrying saves a blocked component cannot pass
A component missing from the registry cannot be persisted, so autosave kept
issuing writes the server always rejects. Opening an affected flow produced a
stream of failed requests and error toasts before the user had touched
anything.
Skip autosave while a node is blocked and let the node's own banner report
the problem. Saving resumes once the component is removed, and no other
autosave condition changes.
Also keep that banner's label when the node is collapsed. A blocked node has
no update action, so the label is its only explanation, and previously a
collapsed one showed a coloured dot and a dismiss button with no words. The
collapsed row is narrow enough to truncate, so the full text is carried in
the title.
* [autofix.ci] apply automated fixes
* fix(frontend): say that saving is paused, not just stop saving
Skipping autosave for a blocked component removed the failed requests but
also removed any sign the flow had stopped saving, which is worse than the
noise it replaced: the user is left editing a flow that silently never
persists.
Report it once per occurrence instead, naming the components responsible and
what to do about them, rather than on every debounce tick. Removing the
component resets the notice along with resuming saves.
* fix(frontend): scope the blocked-component preflight to the built subgraph
buildFlow selects nodesToValidate for a partial build, but the component
preflight kept reading the whole flow. A component an administrator disabled
somewhere else in the canvas rejected a startNodeId or stopNodeId run that
never touched it.
Filter componentsToUpdate down to the nodes being built before deriving the
blocked and outdated lists. componentsToUpdate itself stays whole-flow so the
update banner keeps reporting every affected node.
Also cover the changed banner UI: GenericNode now shows a blocked node while
custom components are allowed and keeps showing it after a dismissal, and
NodeUpdateComponent names the catalog policy in that mode while restricted mode
keeps its original wording.
* fix(frontend): only pause autosave where the rejection is certain
Review found the autosave pause could stop persisting work on a false
positive, which is worse than the failed writes it replaced.
`blocked` means "no template for this type". That is also true of an
uninstalled bundle, a flow imported from another install, and every
code-bearing node while the registry is still loading: `templates` starts as
`{}`, which is truthy, so checkCodeValidity's `!templates` guard does not
catch it. A cold load therefore paused autosave and named every component in
the flow. The server, meanwhile, only rejects a write when a policy actually
blocks a key — validate_catalog_policy_for_flow returns early on an empty
blocklist — so on a default install there was never anything to pause for.
Pause only when a catalog policy is in force and the registry has loaded, and
hold the pending edit rather than discard it, so it still lands once the
blocking component is removed. The isLoading branch above already worked that
way.
The banner had the same overreach in the other direction: it inferred
"Disabled by administrator" from a missing template alone. It now names the
policy only when one applies, keeps the restricted-mode wording where that
setting is the cause, and says the component is unavailable when neither is
known to be. Restricted mode blocks an unknown code-bearing node on its own,
so it stays the stated cause when both apply.
The new keys were English-only, which renders raw key strings for everyone
else; de, es, fr, ja, pt and zh-Hans now carry all four. Translations are
mechanical and worth a native check.
Adds coverage for the cold registry, the no-policy install, the held edit and
the banner's unnamed-cause branch. The first two fail against the previous
guard.
* [autofix.ci] apply automated fixes
* style(frontend): order the autosave test imports as biome expects
* fix(frontend): only treat a missing template as blocked where it stops the node
A user-authored custom component has code and no registry template, which
is exactly the shape a policy-blocked component has. The banner and build
preflight read that shape alone, so they flagged legitimate custom
components and rejected their builds — the failure composio.spec.ts hit.
Both now go through blockedStopsExecution: a missing template only counts
where restricted mode or an actual catalog policy applies. An empty
registry means "still fetching", not "nothing is known". The autosave
pause shares the same predicate.
Drops the "Component unavailable" copy and its two keys: blocked without
a policy implies custom components are off, which already renders the
restricted-mode copy, so that branch was unreachable.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> K
keval shah committed
e177c9196b2c0c81c321c0d1e67385bb6e98cf3f
Parent: 4ce8208
Committed by GitHub <noreply@github.com>
on 8/19/2026, 6:54:36 PM