Skip to content

Sync release v1.1#563

Draft
VajiraPrabuddhaka wants to merge 40 commits into
openchoreo:release-v1.1.0-alpha-1from
VajiraPrabuddhaka:sync-release-v1.1
Draft

Sync release v1.1#563
VajiraPrabuddhaka wants to merge 40 commits into
openchoreo:release-v1.1.0-alpha-1from
VajiraPrabuddhaka:sync-release-v1.1

Conversation

@VajiraPrabuddhaka
Copy link
Copy Markdown
Contributor

Purpose

$subject

kaviththiranga and others added 30 commits May 12, 2026 11:07
…sh to GitHub Packages on tag (openchoreo#521)

* chore(deps): loosen @backstage/* pins to caret ranges and drop dead dep

Plugins pinned exact patch versions (e.g. "@backstage/config": "1.3.4"),
which prevented installation into external Backstage apps that resolve
slightly newer patches. Switch every @backstage/* dependency in the MVP
plugin set to caret ranges so consumers can dedupe against their own
Backstage version.

Also drop the unused @openchoreo/openchoreo-client-node dependency from
@openchoreo/backstage-plugin-react — the package never imports from it
and pulling a node-library into a web-library is a layering bug.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>

* feat(openchoreo): export OpenChoreoClient class for host-app registration

External Backstage hosts that install @openchoreo/backstage-plugin via
npm cannot rely on Backstage's plugin auto-discovery to register the
choreoPlugin API factory: discovery walks the static JSX tree, but the
Environments and CellDiagram extensions are mounted inside
EntitySwitch.Case branches that only render once an entity is loaded.

Hosts work around this by passing `plugins: [choreoPlugin]` to
createApp(), which is sufficient on its own. But hosts that need to
construct the client themselves (e.g. to wrap fetchApi with custom auth
header injection) also need access to the OpenChoreoClient class.
Exporting it makes that path supportable too.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>

* ci(release): publish @openchoreo/* packages to GitHub Packages on tag

  Wires npm publishing into the existing tag-triggered release workflow,
  which previously only retagged the Docker image in GHCR.

  - .github/workflows/release.yml: add setup-node, install, build:all,
    and `yarn changeset publish` steps after the Docker retag. Authenticate
    with YARN_NPM_AUTH_TOKEN=GITHUB_TOKEN — no new secrets needed since
    `packages: write` is already granted. Prerelease tags (vX.Y.Z-*) publish
    under the `next` dist-tag; stable tags use `latest`.
  - packages/{design-system,openapi-client-generator-node,openchoreo-auth,
    openchoreo-client-node}/package.json and
    plugins/permission-backend-module-openchoreo-policy/package.json: add
    `publishConfig.registry: https://npm.pkg.github.com`. Without these, the
    linked changeset group would publish 8/13 packages to GH Packages and
    attempt the remaining 5 against registry.npmjs.org mid-batch.
  - README.md: add "Releasing" section documenting the
    changesets → version PR → tag → CI publish flow, including local
    dry-run and re-run-idempotency notes.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>

* fix(release): publish npm before Docker retag

  If `yarn release:publish` failed under the previous ordering, the Docker
  image was already retagged to vX.Y.Z (and possibly `latest`) in GHCR
  while the @openchoreo/* packages never made it to GitHub Packages,
  leaving a half-published release with no clean rollback.

  Move the Node setup / install / build / publish steps ahead of the
  Docker login + retag + latest-tag steps so a publish failure aborts the
  workflow before GHCR is mutated.

  Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>

---------

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
…provider (openchoreo#522)

* refactor: remove Cilium feature flag and add DataPlane network policy provider

Signed-off-by: Akila-I <akila.99g@gmail.com>

* feat: enhance error handling and logging in ObservabilityService hooks

Signed-off-by: Akila-I <akila.99g@gmail.com>

---------

Signed-off-by: Akila-I <akila.99g@gmail.com>
Signed-off-by: Mevan <mevan.karu@gmail.com>
…penchoreo#529)

chore: improve the release-ochestrator and build-and-test workflows

Signed-off-by: Mevan <mevan.karu@gmail.com>
…enchoreo#527)

* feat: add conditions to authz role binding creation/update wizard

- Simplified RoleMappingsStep by moving inline editing to a modal dialog (RoleMappingDialog).
- Enhanced role mapping structure to include conditions for more granular access control.
- Updated SubjectStep layout to use Grid for better responsiveness and organization.
- Improved overall styling and user experience in the mappings wizard.

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

* test: update failing test cases

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

* fix: address requested changes

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

* test: add test cases for conditions wizard

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

* fix: lint issues

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

* feat: show expression validation errors post submission

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

* feat: move the wizard stepper inside the main card

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

* fix: address requested changes

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

* feat: remove redundant cancel button

Signed-off-by: binoyPeries <binoyperies98@gmail.com>

---------

Signed-off-by: binoyPeries <binoyperies98@gmail.com>
…running Backstage locally (openchoreo#534)

docs: update README with event driven catalog sync configuration for locally running Backstage
Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>
…in Backstage portal (openchoreo#525)

Signed-off-by: Nilushan Costa <nilushan@wso2.com>
…atus (openchoreo#535)

* chore: update release-ochestrator to check build-and-test workflow status

Signed-off-by: Mevan <mevan.karu@gmail.com>

* fix: prettier issue

Signed-off-by: Mevan <mevan.karu@gmail.com>

---------

Signed-off-by: Mevan <mevan.karu@gmail.com>
Signed-off-by: Mevan <mevan.karu@gmail.com>
…nchoreo#536)

* feat: add edit support and secret management feature flag to Secrets page

Adds an Edit dialog for managed secrets and gates the entire feature behind
OPENCHOREO_FEATURES_SECRET_MANAGEMENT_ENABLED (default off in production).
List view now combines the new /secrets API (for keys) with SecretReferences
(for targetPlane), since the new endpoint omits targetPlane.

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* chore: reformat README per prettier

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* test: cover EditSecretDialog and useSecrets.updateSecret

- Five EditSecretDialog cases: title/meta render, value prefill from decoded
  data, Save gating, submit payload, load-error surface.
- One useSecrets case for the new updateSecret happy path.
- Add a TextDecoder-less fallback in decodeBase64Utf8 for environments where
  jsdom or older runtimes don't provide it.

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

---------

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>
* feat: add runtime topology integration to CellDiagram

- Enhanced the CellDiagram component to allow users to select an environment and a time range for metrics.
- Updated the API client to support fetching cell diagram info with optional parameters for environment, start time, end time, and step.
- Added logic to handle HTTP metrics observations and display relevant information based on user selections.

Signed-off-by: Akila-I <akila.99g@gmail.com>

* feat: add tests for CellDiagram component and service

Signed-off-by: Akila-I <akila.99g@gmail.com>

* refactor: remove step parameter from runtime topology

Signed-off-by: Akila-I <akila.99g@gmail.com>

* refactor: refactor CellDiagram to use catalog API for environment loading

Signed-off-by: Akila-I <akila.99g@gmail.com>

* refactor: update metric names in observability API and related services

Signed-off-by: Akila-I <akila.99g@gmail.com>

* refactor: simplify CellDiagramInfoService by removing unused code

Signed-off-by: Akila-I <akila.99g@gmail.com>

* refactor: remove unused metric option from observability types

Signed-off-by: Akila-I <akila.99g@gmail.com>

---------

Signed-off-by: Akila-I <akila.99g@gmail.com>
Signed-off-by: yashodgayashan <yashodgayashan@gmail.com>
* chore: sync openchoreo-api spec from upstream main

Pulls 61 PRs since 2026-03-02 sync. Two upstream breaking changes
required consumer adaptations:

- DeploymentPipeline Environment target dropped requiresApproval /
  isManualApprovalRequired fields (openchoreo #2651): drop the fields
  from BFF types, entity translation, the lock-icon approval badge on
  PipelineEdge, the "(Approval Required)" Promote-button suffix, and
  the dead propagation through pipeline layout
- Secret API response shape changed from SecretResponse to K8s-style
  Secret on POST/PUT (openchoreo #3457): replace dead type alias with
  local interface, factor a projectSecret() helper, and fix the latent
  runtime cast in SecretsService.create/update (test mocks were
  masking that response.name/keys were always undefined)

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* chore: apply prettier to synced openchoreo-api.yaml

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

---------

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
* feat: migrate git secrets onto the generic secrets API

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* fix: address review feedback on git secret migration

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* test: cover secret category, SSH auth, and label routes

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

---------

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>
)

* feat(authz): honor ABAC constraints in permission policy

Surfaces OpenChoreo's CEL-based ABAC conditions (issue openchoreo#3407) in
the Backstage permission policy and gates per-environment UI actions
(#3408) with semantically correct, env-aware permission checks.

OpenAPI + types
- CapabilityResource.constraints now references a concrete
  CapabilityConstraints schema with expressions: string[] (was
  additionalProperties: true). Regen openchoreo-client-node TS types.
- Re-export CapabilityConstraints from openchoreo-common.

Policy backend
- AuthzProfileService.evaluate() calls POST /api/v1/authz/evaluates with
  context.resource.environment for ABAC-gated capability entries; results
  cached per (user, action, path, env) for the lifetime of the user's JWT.
- OpenChoreoPermissionPolicy resolves capabilities through a wildcard
  fallback chain (action -> resource:* -> *) and treats constrained
  entries correctly across basic, resource, scaffolder, and catalog paths.
- matchesCapability rule accepts JSON-encoded CapabilityResource[] and
  soft-allows constrained entries at visibility-time (CEL needs runtime
  attrs not available in a sync apply()). Constrained denies are skipped
  at visibility-time and enforced at action-time via the new endpoint.
- New POST /api/permission/evaluate-with-context route delegates to
  /authz/evaluates only when matching entries carry CEL expressions --
  unconstrained allows still take the fast path.

Permission model
- Two new resource-scoped permissions:
  - openchoreo.releasebinding.delete -> releasebinding:delete
  - openchoreo.releasebinding.view (resource-scoped sibling of the
    org-scoped read) -> releasebinding:view
- New env-aware frontend hooks:
  - useReleaseBindingUpdatePermission(env) -- clearer name for the
    releasebinding:update check. useUndeployPermission is kept as a
    backward-compat alias.
  - useRemoveDeploymentPermission(env) -- releasebinding:delete.
  - useReleaseBindingViewPermission(env) -- env-scoped releasebinding:view
    for per-env body hiding.
  - usePromoteToEnvPermission(targetEnv) -- composite of
    releasebinding:create AND releasebinding:update on the target.
- Shared useEnvScopedPermission combines the Backstage permission
  visibility check with a call to the new evaluate-with-context endpoint.

Env-detail surface gating (tightened from earlier draft)

| Button | Required permission |
|---|---|
| Configure overrides | releasebinding:update |
| Undeploy / Redeploy | releasebinding:update |
| Rollout restart | releasebinding:update |
| Remove deployment | releasebinding:delete |
| Promote (per target env) | releasebinding:create AND releasebinding:update |
| Env card body (mini + detail) | releasebinding:view per env -- denied envs keep the card but show "No permissions to view this environment" |

- usePromotionAction no longer bakes permission into its result;
  consumers (MiniEnvironmentNode, PromotePrimaryAction) render each
  promotion target through a small subcomponent that calls
  usePromoteToEnvPermission(target). Hooks can't loop, but subcomponents
  can.
- EnvironmentDetailPanel threads canModifyBinding into EnvironmentActions
  as canRolloutRestart so the button is gated without duplicating the
  hook call inside the component.
- Per-env useReleaseBindingViewPermission gates the body of both the
  mini env card and the detail panel: when denied, the outer card/header
  stays (so the user knows the env exists) but the body is replaced with
  a "No permissions" placeholder. The org-level useReleaseBindingPermission
  page-wrapper gate is unchanged.

Observability
- useLogsPermission, useMetricsPermission, useTracesPermission all
  accept an environment? argument.
- Logs / Metrics / Traces pages gate content and fetches per selected
  env and show a compact ForbiddenState when ABAC denies access.

Consumer-side wildcard handling (openchoreo#3409 slice)
- Capability lookup falls back through resource-class wildcards so a
  binding authored with releasebinding:* is honored alongside an
  exact-action match. Helper resolveCapability + unit tests in
  capabilityLookup.ts.

Tests
- 2395 tests passing (no regression vs upstream/main baseline). Existing
  policy module suite (135) plus new coverage for the env-aware hooks,
  per-env view gating, and the promote composite hook.
- Updated EnvironmentDetailPanel.test.tsx, MiniEnvironmentNode.test.tsx,
  EnvironmentActions.test.tsx, PromotePrimaryAction.test.tsx, and
  usePromotionAction.test.ts mocks to include the four new hooks.
- Verified end-to-end against k3d: an AuthzRoleBinding with effect: deny
  and expression: resource.environment == "production" scoped to
  team-shop disables Configure overrides, Undeploy, Rollout restart,
  Remove deployment, and Promote-to-prod for the developer, while
  dev/staging stay enabled and other teams are unaffected.

Related issues
- Closes openchoreo/openchoreo#3407
- Closes openchoreo/openchoreo#3408

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>

* fix(authz): encode env attribute as {namespace}/{name} for evaluates

The OpenChoreo authz layer formats namespace-scoped resource identifiers
that flow into CEL attributes (e.g. `resource.environment`) using
`FormatDualScopedResourceName` -- see
`internal/openchoreo-api/services/utils.go` and
`internal/observer/authz/helpers.go`:

    Namespace-scoped → "{namespace}/{name}"
    Cluster-scoped   → plain "{name}"

`Environment` is `scope: Namespaced` today so real bindings are authored
against the joined form, e.g. `resource.environment == "team-shop/production"`.
Our policy module previously sent the bare env name to
`POST /api/v1/authz/evaluates`, so canonical CEL conditions would never
match and the ABAC deny would be silently bypassed.

Add a `formatDualScopedName` helper that mirrors the Go signature
(including the `isClusterScoped` flag for forward-compatibility with a
future cluster-scoped Environment variant) and use it when building both
the outbound `EvaluateRequest.context.resource.environment` and the
local cache key. The cache encoding matters too -- otherwise the
namespace-isolated decisions from the backend would silently collapse
in our local cache.

New tests cover:
- Namespace-scoped: `production` + `ns/team-shop/...` path
  → `team-shop/production` on the wire and in the cache.
- Cluster-scoped fallback: `production` + bare `*` path
  → `production` on the wire.
- No-env input: `context` is omitted.

Verified end-to-end: updated the team-shop deny binding
to `resource.environment == "team-shop/production"` and confirmed all
Production action buttons disable with the expected
`/api/permission/evaluate-with-context` decisions.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>

---------

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
Signed-off-by: Mevan <mevan.karu@gmail.com>
…matically (openchoreo#542)

Signed-off-by: Nilushan Costa <nilushan@wso2.com>
Signed-off-by: yashodgayashan <yashodgayashan@gmail.com>
…tage hosts (openchoreo#544)

Flip 9 plugins from `private: true` to public so external Backstage apps
  can install the OpenChoreo OIDC sign-in provider plus the full set of
  Domain/System/Component entity-page tabs that the in-tree portal renders.

  - 9 plugins/*/package.json: drop `private`, add publishConfig.registry,
    loosen exact @backstage/* deps to caret ranges. Same shape as the MVP
    sweep, applied to: auth-backend-module-openchoreo-auth, openchoreo-{ci,
    ci-backend,observability,observability-backend,workflows,workflows-backend},
    thunder-idp-client-node, catalog-backend-module-openchoreo-users.
  - .changeset/config.json: extend the `linked` group from 13 to 22 packages
    so version bumps stay coordinated across the auth + tab packs.
  - plugins/openchoreo-observability/src/{plugin,index}.ts: export
    openchoreoObservabilityPlugin so external hosts can pass it to
    createApp({ plugins: [...] }) — matches the fix already in place for
    choreoPlugin / openchoreoCiPlugin / openchoreoWorkflowsPlugin.

  The 9 packages will publish on the next release tag under the existing
  GitHub Packages workflow.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
…ponent page namespace filter (openchoreo#545)

Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>
…enchoreo#548)

* fix: gate git secret create on feature flag; drop unused GitSecretField

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* feat: always set secret category label and preserve on update

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* style: apply prettier to CreateSecretDialog tests

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* test: cover labels passthrough in SecretsService.getSecret

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* style: prettier fix in NamespaceScopeFilter (unblocks CI)

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

* test: cover secret category label constants

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>

---------

Signed-off-by: Janaka Sandaruwan <janakasandaruwan1996@gmail.com>
…ace or category picker (openchoreo#547)

* refactor: make scaffolder namespace filter look consistent with categories filter

Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>

* refactor: update template list filters to conditionally render namespace or category picker
Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>

* refactor: improve code formatting in NamespaceScopeFilter component
Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>

---------

Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>
…valuation (openchoreo#549)

Cache key was `(userEntityRef, action, resourcePath, environment)` —
  stable across sign-outs. A stale ABAC decision from before a binding
  change survived re-login for the full JWT TTL (up to 24h), and the only
  recovery was restarting the backend or waiting it out.

  Fold a token-derived hash into the key (mirroring AuthzProfileCache's
  existing buildKey pattern) so a new sign-in produces a new key and
  re-evaluates against the current binding state.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
…#550)

Remove the warning-styled chip from canvas env tiles and reframe the
  detail-panel line as info ("Behind {upstream}") with an info icon.
  Drift is expected during normal promotion — not a problem.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
Signed-off-by: yashodgayashan <yashodgayashan@gmail.com>
rashadism and others added 10 commits May 15, 2026 21:53
…oreo#553)

The metrics page used a ref-tracked JSON.stringify diff to decide
whether filter values had changed before firing fetchMetrics. The ref
was initialized to the live filter values at first render, so when the
page mounted with env already resolved (URL has env, or environments
resolve synchronously from cache) the first effect run compared current
to itself, marked it unchanged, and skipped the fetch. The user then
saw "no metrics data" until refreshing or changing a filter.

useMetrics already guards its fetch on env + timeRange, so the manual
diff was duplicating that guard. Drop the ref and let the effect's
dep array do the work: fire when env, timeRange, canViewMetricsForEnv,
or fetchMetrics identity changes, and rely on the hook's internal
guard for the no-op case.

HTTPMetricsSection keeps its own ref-pattern fetch; it's separately
gated by useCiliumEnabled() and unaffected by this change.

Signed-off-by: Rashad Sirajudeen <rashad@wso2.com>
…bled (openchoreo#554)

The frontend env-scoped permission hook fired POST /evaluate-with-context
  on every render even when openchoreo.features.authz.enabled = false. The
  policy backend skips mounting that route under AllowAllPolicy, so the
  fetch 404'd and failed closed → every env tile body on the Deploy page
  showed "You do not have permission to view the deployment in {env}".

  Short-circuit useEnvScopedPermission to return baseCheck (which already
  reports allowed: true under AllowAllPolicy) when useAuthzEnabled() is
  false. One chokepoint covers all nine env-scoped consumer hooks.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
openchoreo#556)

Three small fixes to the release-diff experience:

  - Swap LHS/RHS in ComponentReleaseDiffDialog so the target env's current
    release is the "before" (left) and the upstream's incoming release is
    the "after" (right). Matches how reviewers actually read promotion
    diffs. The dialog title arrow still reflects promotion direction. Both
    callers (drift chip on the env detail panel and the promote action on
    the overrides page) pick up the new orientation automatically.

  - YamlDiffViewer: move height + overflow:auto onto .cm-mergeView per
    CodeMirror MergeView docs so both panes scroll as one unit instead of
    scrolling independently and breaking line alignment.

  - Rename the promote-flow button "View diff" -> "View release diff" to
    match the wording already used by the drift-chip button.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
…reo#555)

* fix: enhance entity reference extraction logic in CustomReviewStep
Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>

* fix: improve entity reference extraction in CustomReviewStep to utilize parseEntityRef for better accuracy
Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>
* feat: add ClusterResourceType end-to-end UI support

- 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>

* feat: add ResourceType end-to-end UI support

- 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>

* chore: sync openchoreo-api spec from openchoreo main

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>

* feat: add Resource end-to-end UI support

- 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>

* feat: add Deploy tab to Resource entity page

- 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>

* feat: extend Resource catalog list with Project filter and Project/Type columns

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* refactor: align Resource environment badge status terminology with Component

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* refactor: mirror Component Overview layout on Resource entity page

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* feat: generate per-type Resource scaffolder Templates from (Cluster)ResourceType

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* feat: add Resource browse-templates meta-card and list view on /create

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* feat: switch resource:create to structured input and add ResourceParametersField

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* feat: add Resource review step with section grouping and entity-ref unwrap

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* fix: resolve dotted namespaceField paths in ResourceNamePicker

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* fix: refresh Resource Template entities on per-event RT/CRT updates

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* chore: use CHOREO_ANNOTATIONS.RTD_GENERATED instead of literal string

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* fix: show namespace picker in mobile filter drawer for resources view

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* docs: update RT/CRT schema service docstrings to name the new consumer

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* feat: add Set up node and side panel to Resource Deploy tab

- 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>

* feat(api): add fetchResourceTypeSchema to frontend client

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>

* feat: add Step 1 wizard (Configure Resource) to Deploy tab

- 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>

* chore: drop local-plan references from Resource wizard docstrings

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* feat(api): expose resourceTypeEnvironmentConfigs on binding responses

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>

* feat: add per-environment overrides wizard to Resource Deploy tab

- 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>

* feat(api): expose ResourceRelease snapshot schema sections

- New BFF endpoint /resource-release-schema?namespaceName=&releaseName=&section=
- 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>

* feat: chain Resource configure wizard into per-env deploy

- 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>

* feat: prefill Resource override form from binding, fix RJSF baseline

- 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>

* fix: keep change detection accurate when binding has stored values

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>

* feat: align Resource deploy model with promote-only pipeline

- Drop the per-env Deploy button from the env detail panel — first
  deploy is now exclusively via the Set up flow on the pipeline canvas.
  Resources are coupled to Components via dependencies.resources[]
  envBindings; allowing direct per-env deploys lets the Resource and
  Component pipelines drift out of sync.
- Empty Not-Deployed panels now mirror Component shape: status header
  + a hint pointing to Set up + Configuration section with a disabled
  Configure overrides button. No actionable buttons in this state.
- Remove the unused handleDeploy callback, the onDeploy context entry,
  the deploy ActionKind, and the dead DeployButton + create-permission
  hook usage.
- Tests updated: the deploy-action test now asserts the Deploy button
  is absent; the detail-panel test replaces its Deploy-button case
  with an empty-state assertion.
- Server side stays flexible — PE/GitOps can still author bindings
  out of order via kubectl or occ; only the Backstage UI enforces the
  pipeline contract.

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* feat: restyle Resource env cards to match Component layout

- Restructure ResourceMiniEnvironmentNode with a colored left status
  stripe, an icon-prefixed header with a 3-dot Actions menu, a STATUS
  row, and a DEPLOYED relative-time row on bound envs.
- Status stripe colors derive from the binding state: green for Active,
  amber for Pending, red for Failed, gray for idle / not deployed.
- The 3-dot menu exposes Refresh (refetch envInfo) and Configure
  overrides (navigates into the env's overrides wizard; disabled when
  no binding exists). Inline Promote button and View release manifest
  are deferred.
- Drop the release hash and inline Behind badge from the tile — both
  already live in the detail panel and were visual noise on the compact
  tile.
- styles.ts gains stripe / body / topRow / metaRow / timeText /
  menuButton styles mirroring Component's MiniEnvironmentNode tokens.
- Tests rewritten: cover the new layout, the 3-dot menu open/close,
  Refresh wiring, and Configure-overrides disabled state for unbound
  envs.

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* feat: polish Resource env detail panel header and outputs

- Add a Refresh icon button to the panel header that re-fetches env
  status without leaving the panel.
- Add a Copy icon next to the release hash so the release name can be
  grabbed without selecting text.
- Add a DEPLOYED row using formatRelativeTime over env.lastDeployed on
  bound envs.
- Hide REASON / MESSAGE rows on the happy path (status === Ready).
  These were useful for debugging but added noise when everything is
  Ready; non-ready bindings still surface them.
- Add a per-row Copy icon to each output in ResourceOutputsList that
  copies the rendered text (value or Kind/name.key ref).
- Push toast notifications via the existing useNotification hook so
  copy actions confirm/fail consistently.

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* fix: use CloudIcon on Resource env cards to match Component

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>

* fix(bff): source Resource env "deployed" from Ready condition LTT

- 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>

* fix: guard configure wizard against unmount + empty pipeline

- 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>

* feat: polish Resource Deploy tab to match Component

- 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>

* feat: add inline Promote button to Resource env cards

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>

* feat: move Resource outputs into a wider View All dialog

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>

* feat: polish Resource outputs dialog

- 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>

* feat: add Danger zone to Resource env detail panel

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>

* feat: align Resource Promote with Component upstream-drift model

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>

* feat: align Resource env detail panel styling with Component

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>

* fix: promote uses K8s-safe target name instead of display name

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>

* fix: undeploy and retain use K8s-safe env name, not display name

- 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>

* fix: route catalog Create Resource to the browse-templates view

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>

* feat: reorder Platform Resources cards on the create page

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>

* fix: preserve dependencies.resources on endpoint dep edits

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>

* fix: track dependencies.resources changes in useWorkloadChanges

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>

* feat: show resource dependencies as read-only rows in workload editor

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>

* feat: add Component type chip to endpoint dependency rows

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>

* feat: expose (Cluster)ResourceType outputs schema for resource-dep editor

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>

* feat: add ResourceDependencyEditor for resource-dep envBindings/fileBindings

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>

* feat: enable add/edit/remove of resource dependencies in workload editor

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>

* feat: collapse resource dep rows to summary with Edit/Apply flow

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>

* refactor(resource-editor): align edit-mode actions and drop the row icon

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>

* refactor(resource-editor): pick resource via in-row Select, not a menu

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>

* refactor(resource-editor): split Add binding into env + file-mount buttons

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>

* refactor(resource-editor): per-kind remove buttons; stop auto-deleting 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>

* feat(cell-diagram): render workload resource dependencies

- 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>

* feat(resource-type-overview): add (Cluster)ResourceType Details card

- 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>

* feat(catalog): emit Resource instanceOf (Cluster)ResourceType relation

- 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>

* chore(resource-envs): fix eslint errors

- 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>

* chore: apply prettier formatting across the branch

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>

---------

Signed-off-by: Miraj Abeysekara <miraj@wso2.com>
…enchoreo#558)

* fix: set credentials include for direct-mode cross-origin fetches

Signed-off-by: Isala Piyarisi <mail@isala.me>

* fix: format OpenChoreoFetchApi for prettier

Signed-off-by: Isala Piyarisi <mail@isala.me>

---------

Signed-off-by: Isala Piyarisi <mail@isala.me>
Signed-off-by: yashodgayashan <yashodgayashan@gmail.com>
Signed-off-by: yashodgayashan <yashodgayashan@gmail.com>
* fix(console): refine console UI messages and error text

Signed-off-by: Kavishka Fernando <kavi@kavishka.local>

* fix(console): refine console UI messages and error text

Signed-off-by: Kavishka Fernando <kavi@kavishka.local>

* fix(console): fix console UI text issues

Signed-off-by: Kavishka Fernando <kavi@kavishka.local>

* fix(console): fix lint issues

Signed-off-by: Kavishka Fernando <kavi@kavishka.local>

* fix(console): fix test

Signed-off-by: Kavishka Fernando <kavi@kavishka.local>

* fix(console): fix test

Signed-off-by: Kavishka Fernando <kavi@kavishka.local>

---------

Signed-off-by: Kavishka Fernando <kavi@kavishka.local>
Co-authored-by: Kavishka Fernando <kavi@kavishka.local>
…es in catalog (openchoreo#562)

- Added tests for resource entities to validate project-level permissions based on PROJECT annotation.
- Implemented logic to ensure that denies on sibling components do not cascade to resources, while project-level denies still apply.
- Updated entity level definitions to include 'resource' and adjusted path validation accordingly.

Signed-off-by: Stefinie Fernando <minolispencer@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7c789a47-5e47-457e-97e4-1c23b4ed4141

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@VajiraPrabuddhaka VajiraPrabuddhaka marked this pull request as draft May 18, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.