feat: add Backstage UI for resource abstractions#546
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
- Wire catalog ingestion: new Backstage kind, processor, translator, and OpenChoreoEntityProvider + EventDeltaApplier integration - Add PlatformResourceService backend routes (GET/PUT/DELETE) for /api/v1/clusterresourcetypes via the typed openchoreo-api client - Add Definition tab support via the generic ResourceDefinition flow - Add Scaffolder create flow: action, template, custom YAML editor - Add cluster-scoped permissions (create/update/delete) wired through openchoreo-common, openchoreo-react hooks, and the permission-backend policy rule - Update PE/developer/SRE role templates in RoleDialog - Add display polish: LayersIcon, gray color tokens, EntityPage route, catalog Create button, search modal icon, graph labels Part of openchoreo#3336. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Wire catalog ingestion: new Backstage kind, processor (emits partOf
Domain), translator, and OpenChoreoEntityProvider per-namespace fetch
+ EventDeltaApplier integration
- Add PlatformResourceService backend routes (GET/PUT/DELETE) for
/api/v1/namespaces/{ns}/resourcetypes via the typed openchoreo-api
client, plus VALID_PLATFORM_RESOURCE_KINDS entry on the router
- Add Definition tab support via the generic ResourceDefinition flow
- Add Scaffolder create flow: action, template, custom YAML editor
- Add namespace-scoped permissions (create/update/delete) wired through
openchoreo-common, openchoreo-react hooks, and the permission-backend
policy rules (matchesCapability NAMESPACE_SCOPED_KINDS,
matchesCatalogEntityCapability KIND_TO_ENTITY_LEVEL, and
OpenChoreoPermissionPolicy scaffolderCreateActions)
- Update PE/developer/SRE role templates in RoleDialog
- Add display polish: LayersIcon, gray color tokens, EntityPage route,
catalog Create button, search modal icon, graph labels
Part of openchoreo#3336.
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Pulls 24 upstream PRs since 2026-05-14 sync. Two openapi-touching changes: - expose workload.dependencies.resources in the wire schema, including the new WorkloadResourceDependency type (openchoreo #3506) — unblocks Component.spec.dependsOn population for the resource-abstractions Backstage slice - add ScopeResource as a sibling sub-scope under project, extending the authz ResourceHierarchy and TargetScope shapes (openchoreo #3448) Regenerated TS client types; yarn tsc clean (no consumer adaptations needed — both upstream changes are additive). Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Wire catalog ingestion for kind:Resource: translator, per-namespace
fetch, EventDeltaApplier dispatch, and Component.spec.dependsOn
population from workload.dependencies.resources[] so Backstage emits
the Component -> Resource relation natively
- Add BFF endpoints (/resource-release-bindings, /resource-type-schema,
/cluster-resource-type-schema) plus the resources arm on
PlatformResourceService and transformResourceReleaseBinding
- Add openchoreoResource{Create,Update,Delete} permissions, the
useResourceCreatePermission hook, and wire resource into existing
permission maps (KIND_TO_PERMISSIONS, KIND_TO_ENTITY_LEVEL=component,
scaffolderCreateActions, with opportunistic backfill of missing
clustercomponenttype/clusterresourcetype create entries) plus
PE/dev/SRE role templates
- Add the Resource entity page with three Overview cards (type and
parameters, per-env binding summary, consuming components) via an
EntitySwitch on the generic resourcePage so other plugins'
kind:Resource entities keep the default layout
- Add the scaffolder create flow: openchoreo:resource:create action,
template, and a two-step ResourceYamlEditor field extension
(kind+name picker -> RJSF schema-driven form -> YAML composition)
- Add Storage and StorageOutlined icons across App.tsx, apis.ts,
CustomTemplateCard, CustomSearchModal; add resource entries to
graphUtils kind labels, DeleteEntity hooks, ResourceDefinition
utils, the Platform Overview Developer Resources view, and the
ALL_FILTERABLE_KINDS dropdown
- Extend buildScopeFilter in the policy backend so DB-level capability
filtering narrows Resource entities by their PROJECT annotation
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Add fetchResourceEnvironmentInfo BFF endpoint that joins environments, release bindings, project deployment pipeline, and Resource latestRelease into one per-env response - Add updateResourceReleaseBinding (GET-or-POST-or-PUT upsert) and deleteResourceReleaseBinding BFF routes wrapping the openchoreo-api resourcereleasebindings CRUD; no openchoreo-api change required - Propagate ResourceReleaseBinding status.outputs through the transformer with secret/configMap key references only (no resolved secret values cross the wire) - Add resourcereleasebinding:update/create/delete permissions and matching React hooks for env-scoped permission checks - Add split-pane Deploy tab on the Resource entity page: pipeline DAG canvas (reuses dagre + zoom infra from openchoreo-react) plus per-env detail panel with Promote, Deploy, Undeploy, and retainPolicy toggle actions - Render outputs with type-aware formatting (value / secretRef Secret/x.y / configMapRef ConfigMap/x.y) - Show "Behind" badge inline with the release pin when binding lags Resource.status.latestRelease - Poll every 10s while any binding is mid-rollout (reuses Component-side useEnvironmentPolling hook) - Add confirmation dialog for Undeploy that surfaces retainPolicy semantics (Retain holds via finalizer, Delete cascades) - Update slice-3 ResourceBindingsCard to use design-system StatusBadge instead of raw MUI Chip for visual consistency with the Deploy tab Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…pe columns Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…mponent Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…esourceType Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…metersField Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…nwrap Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Add ResourceSetupCard leading tile on the deploy DAG (uses the shared setup node already emitted by buildEnvPipelineNodes) - Add ResourceSetupDetailPane with the Configure & Deploy entry into the resource configuration wizard (wizard route lands in a follow-up) - Mutually-exclusive selection between Setup tile and env tiles in the right-side panel - Drop the redundant page-padding wrapper so the layout no longer overflows BackstageContent's own padding (matches Component side) Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Wraps the existing BFF /resource-type-schema and /cluster-resource-type-schema routes that previously had no client API exposure. Reads RESOURCE_TYPE + RESOURCE_TYPE_KIND annotations off the Resource entity to pick the namespace-scoped vs cluster-scoped endpoint. Consumed by the Step 1 wizard landing in the follow-up commit. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Extract the existing deploy view into ResourceEnvironmentsList so the /environments tab can host sub-routes - Make ResourceEnvironments a thin Routes wrapper with two paths: / for the deploy view, /parameters-config for the new wizard - New ResourceParametersConfigPage renders an RJSF form against the (Cluster)ResourceType schema. Save & Close PUTs the Resource via the existing platform-resource update path; the controller auto-cuts a new ResourceRelease from the spec hash change - Wire the Set up panel's Configure & Deploy button to navigate into the new wizard route - Tests updated to wrap in MemoryRouter and target the extracted list Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Passes the per-environment override map through the binding GET path so callers can read existing overrides off a ResourceReleaseBinding. Mirrors the symmetry already present on the Update side, which has accepted the field in the body since the binding's REST surface landed. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- New ResourceEnvironmentOverridesPage renders an RJSF form against the (Cluster)ResourceType schema, with Save / Clear actions that PUT the ResourceReleaseBinding with resourceTypeEnvironmentConfigs - New ResourceEnvironmentOverridesWrapper mounts the page under /environments/overrides/:envName; Back uses path-relative navigation so it lands on the deploy view instead of climbing the parent route - Detail panel grows a Configure overrides action that navigates with env.resourceName (the K8s ref the binding lookups key on) - Existing parameters-config wrapper switched to the same path-relative back navigation for consistency - Detail panel test wraps in MemoryRouter for the new useNavigate hop Override pre-population on load is deferred — the wizard currently starts fresh; persisted overrides land on the binding either way. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- New BFF endpoint /resource-release-schema?namespaceName=&releaseName=§ion= - Returns the openAPIV3Schema for either the parameters or environmentConfigs section snapshotted on the ResourceRelease - Frontend client wrapper fetchResourceReleaseSchema(namespace, release, section) - Pinned-release flows now validate against what the release was cut against, not the live (Cluster)ResourceType which may have drifted Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Configure Resource wizard's Next button PUTs the Resource then polls fetchResourceEnvironmentInfo every 1s up to 30s until the controller-cut release name differs from the pre-save baseline, then navigates to the overrides wizard pinned to that release - Skips PUT+poll when parameters are unchanged; still chains forward with the existing release name - Overrides wizard accepts a releaseFromUrl prop that pins the binding to the URL-specified release on save and labels the primary action Deploy instead of Save Overrides - Schema now comes from the pinned release's snapshot environmentConfigs section (was: live ResourceType parameters), so the form matches the contract the controller actually renders against - Edit-mode entry from the env detail panel is unchanged Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Overrides wizard now fetches fetchResourceReleaseBindings on load, finds the binding for the current env, and seeds the form with the stored resourceTypeEnvironmentConfigs map. Returning to the wizard shows the values the user previously saved instead of an empty form. - Both wizards capture the first RJSF onChange as the change-detection baseline. RJSF normalizes formData on initial render (expanding schema defaults for missing fields), so treating that normalized snapshot as the baseline keeps hasChanges accurate to what the user actually typed. - Track a separate hasActualOverrides flag from the backend's perspective so Clear Overrides reflects whether overrides exist on the binding, not whether the form differs from schema defaults. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
The form-initialized ref was being reset to false on every load, which made the user's first real edit get captured as the baseline whenever the backend already had values to seed the form with. Result: Save stayed disabled even after unticking a populated checkbox. Only allow the RJSF-normalization capture when the backend payload was empty (the case where mount-time default expansion needs to be absorbed into the baseline). When there are stored values, those values are the baseline directly. Same fix in both wizards. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Read the Ready condition's lastTransitionTime as the env-info lastDeployed timestamp. The aggregate Ready flips on each successful Resources reroll after a promote, so per-env cards now show a real per-promote signal instead of all bindings reporting the same creationTimestamp. - Synced alone was unreliable: its message embeds the RenderedRelease name which is binding-stable across promotes, so SetStatusCondition saw the message as unchanged and never refreshed the timestamp on subsequent renders. - Falls back to creationTimestamp on bindings the controller has not yet reconciled. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Suppress the catch-clause setSaveError when cancelledRef is set so a navigate-during-save does not trip React's unmounted-component warning. - Add an inline info Alert when fetchResourceEnvironmentInfo returns zero envs. The Continue button is correctly disabled in that case, but until now the user had no signal explaining why; the banner points to the deployment pipeline as the missing piece. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Start with no env selected; render an empty-state hero with the
AllInbox icon and copy "Select an environment to view details, or
click Set up to update configuration." Clicking empty canvas space
deselects the currently active card.
- Update the Set up panel subtitle to describe what Configure &
Deploy actually does ("Manage resource configuration and deploy a
new version.") instead of the misleading project-scoped wording.
- Add a View release manifest modal that fetches the ResourceRelease
CR and renders the snapshot as YAML. Reachable from both the env
card 3-dot menu and the Release row in the detail panel; disabled
when no release is pinned on the env.
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Pushes the current env's release forward to the next env(s) in the pipeline. Mirrors Component: direct Promote button when there is a single promotion target, Promote dropdown with per-target items when there are several, and a disabled Promoted state when every target already has this release. Hidden when the env has no binding or no promotion targets (last env). Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
The side panel's inline outputs list was cramped at 380px — long values like the postgres host FQDN and adminURL wrapped across several lines. Replace the inline list with an Outputs (N) header + View All link that opens a roomier modal. Each output renders in its own block with a kind chip (VALUE / SECRETREF / CONFIGMAPREF), the value or ref in a wrappable monospace box, and a per-row copy button. Deletes the now-unused ResourceOutputsList component since the modal is the only display surface. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Link http(s) values so admin URLs and dashboards open in a new tab on click. Non-URL values stay as plain monospace text. - Hide Secret / ConfigMap references behind a per-row Show reference toggle. Defaults to a short "Stored in Secret" / "Stored in ConfigMap" placeholder so the K8s ref shape, which is internal plumbing for developers, doesn't crowd the modal. Expanding reveals the Kind/name.key string with a copy button for SRE debugging. - Drop the VALUE / SECRETREF / CONFIGMAPREF chips and inline the reference toggle on the right of the output name. The placeholder text already names the kind for refs, and value outputs don't need a chip to identify a visible value. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
The destructive surface (retainPolicy toggle + Remove deployment) moves into a collapsed-by-default Danger zone accordion at the bottom of the panel, mirroring Component. Inline retainPolicy row and Actions-row Undeploy are dropped so the panel has a single destructive surface. - retainPolicy: gates Remove deployment. Retain disables the button with "Set retain policy to Delete to allow removal." tooltip. Switching Retain → Delete pops a confirm dialog warning that stored data may be lost; Delete → Retain applies one-click. - Remove deployment: outlined error-tinted button. Confirm dialog explains the binding + overrides + underlying K8s teardown, with the "stored data may be lost depending on the resource type implementation" qualifier so we don't over- or under-promise. - BFF resolves effective retainPolicy by fetching the referenced (Cluster)ResourceType and applying the chain: binding override → ResourceType default → built-in Delete. Soft-fails on fetch error so a transient API issue never blocks the env-info response. - Danger zone styling matches Component: alpha-tinted red background and border, error.dark for icon + title. Replaces the old UndeployConfirmDialog with a Resource-flavored ResourceRemoveDeploymentDialog and adds a small ResourceRetainPolicySwitchDialog for the Retain → Delete confirm. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Card and detail panel now show the same Promote button state for the same env: both promote this env's release forward to the next env(s) in the pipeline (mirrors Component). Drops the old panel behind-latest semantic — the panel no longer shows a separate "advance-to-latest" Promote. - New computeResourceReleaseDrift helper ports Component's release- name equality against direct upstreams. Drift map is computed once in ResourceEnvironmentsList and threaded through context. - Env card surfaces a lowercase "behind" badge with a warning-tinted background when at least one direct upstream is on a different resourceRelease. Tooltip lists the upstream env and its release name. - Panel drops the behind-latest badge. Panel Promote reads plain "Promote" (matches Component) but routes through the same handler as the card so the action is consistent across surfaces. Spec edit drift on the first env (Dev edited via kubectl without a promote) intentionally falls out of this signal; the canvas Set up flow is the entry point for first-deploys and re-deploys. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Rewrites the panel layout to mirror Component's visual rhythm so the two surfaces feel like the same product. Header - Restructure to two rows: CloudIcon + env name + refresh/close on top, StatusBadge on its own row below. Drops the inline name + badge layout. - Drop the header borderBottom; per-section borderTop now provides the dividers. - Use an explicit envName fontSize/ellipsis class instead of variant=h6 (which is theme-dependent). Drop the redundant Tooltip wrapper around Refresh. Body + sections - Body has padding 0 + overflowY auto; sections own their own padding spacing(2, 2.5) + borderTop, producing full-width horizontal dividers between Release, Outputs, Actions, and the Danger zone. - Section title typography becomes the uppercase 0.78rem caption style (textTransform: uppercase, letterSpacing 0.6, fontWeight 600) replacing the body2 fontWeight 500 pattern. - metaRow loses its per-row padding now that section gap handles spacing. Release row - Drop the 140px grid layout. Release and Deployed are now inline flex rows where the small caption label sits next to the value. - Release name uses a monospace caption with ellipsis at 280px and a tooltip showing the full name on hover. - View release icon now precedes Copy (Component order). Icons use fontSize=inherit so they match the caption baseline. - Deployed value uses body2 / text.secondary instead of monospace. Section layout - Drop the standalone Configuration section entirely. Configure overrides moves into Actions, sitting right-aligned next to Promote in the section title row. - Reorder so Outputs sits above Actions. - Style Configure overrides as outlined primary with SettingsOutlinedIcon and textTransform=none, matching Component. Setup pane - Add dedicated setupHeader (with borderBottom) + setupBody (with padding) so the Set up tile's right pane reads as a single body of prose + action button instead of trying to use the env panel's padding-less body. Mirrors Component's split. Danger zone - Sits in its own section so the borderTop divider + section padding give Component-style breathing room between the Actions buttons and the destructive surface. Drop the now-redundant marginTop and expanded-state margin override on the accordion. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
The card and panel Promote handlers passed target.name (the env display name like "Production") to onPromote, which the BFF then stitched into a binding metadata.name like "orders-db-Production". The K8s apiserver rejects that with 422 because RFC 1123 subdomain names must be lowercase. Prefer target.resourceName ?? target.name everywhere promote is initiated — single-target click on card and panel, multi-target dropdown items, and the in-flight detection (pendingAction.env is now the resource name so the "Promoting..." state also keyed on the resource name). isTargetAlreadyPromoted keeps using the display name since it looks up against environments[].name which is the display name. Regression test asserts promote sends `production` when the target exposes both `name: "Production"` and `resourceName: "production"`. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Coerce env.resourceName ?? env.name at every BFF call site for undeploy and retain-policy toggle (handleUndeployConfirm + handleRetainPolicyChange). Lookups and pendingAction now key off the resource name, mirroring the promote precedent in 68d268c. isRemoving on the confirm dialog and isUndeploying/isUpdatingRetainPolicy in the detail panel updated to the same comparator so the "Removing..." button state and busy guards still trigger. - Add a verification poll in handleUndeployConfirm: after DELETE returns, poll fetchResourceEnvironmentInfo every 1.5s for up to 15s and only fire the success toast when the env reports no binding. Catches both the BFF silent-success case and the Resource controller's two-phase finalizer deferring cluster-side removal for several seconds. - Pre-flight GET in BFF deleteResourceReleaseBinding so a wrong-name DELETE surfaces as 404 instead of the openchoreo-api's 204 over a no-op. Defense in depth for the same bug class as the frontend coercion. - Drop the Reason row from the NotReady panel and switch Message to the Release-row pattern: caption label, truncated value with ellipsis, full text in hover tooltip, copy button. Replaces the two-column metaRow layout whose 140px label + wordBreak: break-all chopped values mid-token at the panel's ~150px value width. - Two regression tests (undeploy + retain) lock in resourceName vs name for the client call; one new BFF test covers the pre-flight 404 path and the existing happy path test updated to mock the GET first. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
The catalog list's `Create Resource` button still pointed at the
deleted create-openchoreo-resource scaffolder template, surfacing
the pre-slice-5b wizard (orphan textbox, "Create a new component"
tab title) instead of the per-type browse pattern Component already
uses.
- useKindCreateConfig.ts: resource case routes to
${scaffolderRoot}?view=resources, mirroring the component case.
- app-config.yaml / app-config.production.yaml: drop the dangling
scaffolder location entries that targeted the deleted
templates/create-openchoreo-resource/template.yaml. Stops backstage
from re-ingesting the cached entity on every restart.
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Sort the platformTemplates list by PLATFORM_TYPES index so the order becomes explicit instead of relying on the catalog-list response order. Reshuffles the array into a foundation-first layout matching Application Resources (Project → Component → Resource): Namespace → Environment → Deployment Pipeline → ClusterComponentType → ComponentType → ClusterTrait → Trait → ClusterResourceType → ResourceType → ClusterWorkflow → Workflow Cluster-scoped sits before namespace-scoped within each pair so the pairs stay adjacent and read "platform-wide template → namespace-local variant". Topology types come first (foundation, one-time bootstrap), then template types grouped by concept — workload shape, cross-cutting concerns, infra deps, automation. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
The workload editor's three endpoint dependency handlers each wrote
`dependencies: { endpoints: ... }` wholesale, dropping any
`dependencies.resources[]` already on the workload. A developer who
added or edited an endpoint dep on a workload with resource deps wired
in YAML would silently lose every resource dep on save.
- Add a single `updateDependencies({ endpoints?, ... })` helper that
merges the patch into the existing `dependencies` object so the other
side survives.
- Rewire the three endpoint handlers (replace / add / remove) to use it.
- Add a new `WorkloadEditor.test.tsx` covering the three handler paths
plus the no-resources happy path.
The same helper is the seam future resource-dep handlers will hook into,
so the symmetric bug (endpoints dropped on resource edits) cannot be
reintroduced.
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
The dirty-state hook only diffed `dependencies.endpoints`, so mutations to `dependencies.resources[]` were invisible to it. Save buttons and unsaved-changes prompts wouldn't fire on resource-dep edits even though the workload had changed. - Extract `diffNamedArray` so endpoint and resource diffs share the same add/remove/modify walk. - Add `resourceDependencyLabel` (returns the ref) and a parallel resource diff call; merge the result into the existing dependencies bucket. - New `useWorkloadChanges.test.ts` covers add / remove / modify / mixed endpoint+resource / no-change cases. Forward-guards the read-only resource-dep display so its dirty-state plumbing isn't sitting on a silent landmine. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Developers can now see `Workload.spec.dependencies.resources[]` entries in
the Dependencies tab. Editing still happens via the YAML view; the
inline editor lands with the two-button Add bar in a follow-up.
- Add `ResourceDependency` type alias in openchoreo-common that re-exports
the generated `WorkloadResourceDependency` shape.
- New `ResourceDependencyDisplay` component in openchoreo-react renders a
resource entry as a read-only card with a `Resource` chip and lists
envBindings and fileBindings as `output → target` rows.
- `DependencyList` accepts an optional `resources` prop and renders the
display rows below the existing endpoint rows.
- `DependencyContent` and `WorkloadEditor` pass `formData.dependencies.resources`
through. The Dependencies tab count badge counts both endpoint and
resource entries.
- Drop hardcoded `dependencies: { endpoints: [] }` from the new-workload
default in `WorkloadConfigPage`; an undefined dependencies block
produces no diff and matches the Resource side's shape.
Tests: 5 ResourceDependencyDisplay specs covering ref + chip rendering,
env/file binding rows, and empty bindings; 1 new WorkloadEditor spec
locking in that both endpoint and resource counts reach DependencyContent.
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Endpoint dependency rows now carry a small outlined `Component` chip in their read-only display, matching the `Resource` chip on resource rows. The two row types are now visually distinguishable when the editor renders mixed dependencies (or once 9c/9d add a second add-button and inline resource editor). New DependencyEditor.test.tsx covers the chip's presence and the component-name fallback path. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…itor The upcoming resource-dependency editor needs to enumerate the outputs a ResourceType declares so it can render one row per output with the appropriate env/file binding controls. The openchoreo-api already serves the full (Cluster)ResourceType via GET, so this adds a thin BFF wrapper that extracts spec.outputs and a frontend client method that dispatches by RESOURCE_TYPE_KIND annotation. - New fetchResourceTypeOutputs on ResourceTypeInfoService and fetchClusterResourceTypeOutputs on ClusterResourceTypeInfoService; both call the existing GET and return spec.outputs (empty array when absent). - New /resource-type-outputs and /cluster-resource-type-outputs router endpoints mirroring the schema routes. - New ResourceTypeOutput type and fetchResourceTypeOutputs(entity) on OpenChoreoClient, dispatching on the Resource entity's RESOURCE_TYPE_KIND annotation the same way fetchResourceTypeSchema already does. Tests: 6 new service specs (happy path, empty outputs, upstream error) across both BFF services. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…indings The component renders a list of wired outputs for a single resource dependency, with per-row env-var name and mount-path fields and a bottom `+ Add binding` dropdown listing the (Cluster)ResourceType's remaining unbound outputs. Mount-path is disabled for value-kind outputs since the backend rejects mounting value-kind values as files. - New `ResourceTypeOutput` alias in openchoreo-common re-exports the generated `WorkloadResourceDependency`/`ResourceTypeOutput` shapes. - `ResourceDependencyEditor` in openchoreo-react: controlled component (state lives in parent), emits the updated dependency on every change, supports add / edit / remove for both binding maps. - Empty target values are tolerated mid-edit so users can type freely; validation gating happens upstream where save logic lives. Component is built in isolation here — wiring into DependencyList (two `+ Add` buttons + row dispatch) and into WorkloadEditor (the new handlers and BFF-driven outputs fetch) ship in the follow-up. 15 specs cover rendering, field edits, remove (both row-level and top-level), and the Add-binding dropdown (unbound-only listing, new row creation, disabled-when-empty state). Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Completes the resource-dependency story in the workload editor. The
Dependencies tab now exposes the same CRUD surface for
`dependencies.resources[]` as it has for `dependencies.endpoints[]`:
two add buttons at the bottom (`+ Add Component Dependency` and
`+ Add Resource Dependency`), inline editors per row, and a picker
dropdown that lists project-owned Resource entities not yet bound.
- New handlers `handleResourceDependencyReplace`, `addResourceDependency`,
`removeResourceDependency` on WorkloadEditor, all going through the
`updateDependencies` helper so endpoint deps survive resource edits.
- `updateDependencies` signature extended to accept `{ resources }`.
- DependencyContent lists project Resource entities from the catalog
and fetches outputs[] for each wired ref via the BFF endpoint added
in the previous commit; results cached by ref so FORM<->YAML mode
switches don't re-fetch.
- DependencyList swapped from the read-only `ResourceDependencyDisplay`
to the editable `ResourceDependencyEditor` (built in isolation in
the previous commit); two `+ Add` buttons replace the single one.
- WorkloadEditor.test.tsx adds the symmetric regression test: endpoint
deps survive resource-dep add / replace / remove.
Live-validated on `orders-api`: existing orders-db + orders-cache deps
render as editable rows with their bindings; picking `orders-events`
from the dropdown appends a new row; YAML view confirms all three
resources end up in `spec.dependencies.resources[]`.
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
The Dependencies tab now treats resource dependencies the same way it treats endpoint dependencies: each row collapses to a compact one-line summary in read-only mode and expands into a full per-output binding form when Edit is clicked. Apply commits the buffered changes; Cancel discards them (and removes new rows). At most one row across either type can be in edit mode at a time, and the Add buttons + every other row's Edit/Remove button are disabled while editing. Also moves both Add buttons to the top of the list so they stay visible regardless of how many dependencies the workload accumulates. - New useResourceDependencyEditBuffer hook in openchoreo-react mirrors the endpoint side's hook with resource-specific validity (ref present, no empty binding targets). - ResourceDependencyEditor accepts isEditing/onEdit/onApply/onCancel props; read-only render shows ref + Resource chip + "N env, M file bindings" summary + Edit + Remove buttons; edit render keeps the existing per-output binding form and adds an Apply/Cancel/Remove footer. - DependencyList wires the new resource buffer alongside the endpoint buffer; `anyRowEditing` ORs both states so cross-type editing is blocked. Tests: 15 ResourceDependencyEditor specs cover both modes (read-only summary + button clicks; expanded edit fields + apply/cancel + add-binding dropdown + applyDisabled gating). Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Two small polish items to bring ResourceDependencyEditor visually flush with the endpoint DependencyEditor: - Drop the leading StorageIcon from both read-only and edit modes; the endpoint editor has no icon and the Resource chip already conveys the type. - Move Apply / Cancel / Remove from a bottom row of named buttons to a right-side vertical IconButton stack (Check / Close / Delete) matching the endpoint editor's edit-mode layout, including aria-labels. Pure visual cleanup; no behavior change. Existing 15 specs still green because the action buttons are queried by accessible name. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Align resource-dep add flow with the endpoint-dep flow: clicking
`+ Add Resource Dependency` now drops an empty row into edit mode and
the user picks the resource via a Select dropdown inside the row's
form (mirroring how endpoints are picked via Project / Component /
Endpoint dropdowns). The old behavior — a popover Menu off the Add
button — is gone.
- DependencyList drops the Menu/anchor state; the Add button calls
`onAddResourceDependency('')` and starts the buffer with no initial.
Each rendered editor row receives `availableResources` filtered to
exclude refs claimed by OTHER rows so duplicates don't appear.
- ResourceDependencyEditor accepts `availableResources` (ResourceOption
shape) and renders an outlined Resource Select in the edit-mode
header. The selected ref always remains in the option list so users
don't lose their pick when the parent's filter excludes it.
Switching the ref clears `envBindings` and `fileBindings` — outputs
are per-ResourceType, so existing bindings don't transfer.
- DependencyContent now pre-fetches outputs for every project Resource
entity (not just wired ones) so picks render the right form instantly.
Tests: 3 new specs for the in-row picker (options listed,
ref-change emits cleared bindings, current ref stays selectable).
All 18 ResourceDependencyEditor specs green.
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…ttons A binding row used to render both an env-var field and a mount-path field regardless of how the developer intended to wire the output. The single "Add binding" handler inserted the picked output into `envBindings` with an empty value, which made it impossible to add a file-mount-only binding cleanly (the empty env entry would block Apply, and the user had no obvious way to drop it). Replaces the single Add button + Menu with two: - `+ Add env binding` — lists any output not currently in envBindings. All kinds are eligible. - `+ Add file mount` — lists outputs not currently in fileBindings, filtering out value-kind outputs (the backend rejects mounting a literal value as a file). Each handler adds the output to its target map only; the row renders only the fields actually wired. An output bound in both maps shows both fields side by side as before. Tests updated: 4 specs cover the two dropdowns (env list excludes already-bound; file list excludes already-mounted and value-kind); the previous "renders both fields" test is replaced by two narrower specs locking env-only and file-only rendering. 21 specs total green. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…g on empty
Two related fixes:
- For an output wired in both envBindings and fileBindings, there was no
way to remove just one kind — the row-level trash dropped both. Adds a
small ✕ icon next to each wired field; clicking it removes only that
binding kind from its map.
- Clearing a field used to silently auto-delete the binding, which was
surprising during edits ("I just wanted to retype, why did my binding
disappear?"). Field edits now set the value as-is, including empty
strings; empty values keep the buffer invalid (Apply disabled) until
the user fills them in or explicitly clicks the ✕.
The asymmetry between adding (inserts empty, requires fill) and
clearing (silently removed) is gone — both add and remove are now
explicit actions.
Tests updated: 1 spec replaced (no-auto-delete on empty), 2 new specs
locking in per-kind remove behavior. 23 specs total green.
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Walk workload.spec.dependencies.resources[] in CellDiagramInfoService alongside endpoints[], emitting one ConnectionType.Datastore connection per resource dep with onPlatform: true - @wso2/cell-diagram auto-synthesizes a DatabaseIcon-styled node per Datastore connection (projectUtils.js:237-243, ConnectionHead.js:44) and routes edges through its connection-node namespace, so no resource node emission is needed on our side - Switch internal types from hand-rolled bff-types (WorkloadResponse / Dependency / WorkloadEndpoint / ComponentResponse) to generated OpenAPI schemas via @openchoreo/openchoreo-client-node, aligning with the rest of the codebase (WorkloadEditor, resource-dependency editor, etc.) - Fix latent mock-queue leak in CellDiagramInfoService.test.ts: test 4 enqueued a 3rd error mock that bled into test 5 because clearAllMocks does not drain mockResolvedValueOnce queues Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Mirror ComponentTypeOverviewCard shape with kind-aware title
- Side-by-side Parameters / Outputs with name + type/kind columns
- Recursive flatten for nested params (dot-paths) and array types
- Synthesize ref-entity to call existing fetchResourceType{Outputs,Schema}
- Wire into resourceTypePage + clusterResourceTypePage Overview tabs
Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Add ResourceEntityProcessor mirroring ComponentEntityProcessor - Read RESOURCE_TYPE + RESOURCE_TYPE_KIND annotations, emit INSTANCE_OF + HAS_INSTANCE both directions - Populates Relations graph on (Cluster)ResourceType pages with consuming Resources, and Resource pages with their type - 4 new processor tests Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
- Convert ResourceEnvironmentDetailContent to function declaration for hoisting - Flatten nested ternaries in OverridesPage, MiniEnvironmentNode, ParametersConfigPage - Add missing setSelectedEnvName to useMemo deps in ResourceEnvironmentsList Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Pre-existing prettier drift across 47 files was masked by failing eslint in earlier CI runs (eslint step short-circuited before prettier --check ran). Now that eslint is green, run `yarn prettier --write .` to clear the remaining 'Check formatting' job. Pure cosmetic; no logic changes. Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
Purpose
Adds Backstage UI support for the Resource Abstractions feature
(openchoreo/openchoreo#3336)
Resource Type Overview
Resource Overview
Cell Diagram with Resources
Resource Creation Flow
resource_creation.mov
Workload Resource Dependency Management Flow
workload-wire.mov
Related Issues
Related openchoreo/openchoreo#3336
Checklist