Card bulk-select, CF apps bulk delete, and CF-scoped apps navigation - #5665
Merged
norman-abramovitz merged 8 commits intoJul 21, 2026
Merged
Conversation
Card view treated columns[0] as the card title, so a list that puts its selection column first (routes, space-routes, space-apps) rendered a blank title, pushed the real title (the route URL) down to a body row, and hid the checkbox entirely -- bulk select was reachable only in table view. Pick the title as the first non-control column, and render the checkbox in the header cluster next to the star and kebab (star, checkbox, kebab), suppressing it and the title column as body rows. Every default-renderer card list is now consistent: with-kebab (routes, apps) and without-kebab (users) alike -- the users cards put the checkbox where the kebab would sit. Add a per-column `tooltip` so a title can show a different hover value than its visible text. Routes: the URL is the title now (the "Route" label is gone); a root-domain route with no host/path/port falls back to `(unnamed) <short-guid>` with the full guid on hover. Replaces the earlier top-left overlay, which only touched the custom cardTemplate path (autoscaler, kubernetes) -- neither has a checkbox column, so it never rendered. Guard tests assert the header checkbox drives the bulk bar, a leading checkbox does not blank the title, the tooltip, and that the title column is not also rendered as a body row.
The endpoint-wide CF Applications tab (all apps in one CNSI) had no selection column, so bulk delete was reachable only from the per-space Apps list -- the checkbox looked missing on the main Applications view. Mirror the space-apps wiring: a leading checkbox column plus a Delete bulk action wired to the shared CfAppsSignalConfigService.bulkDeleteApps, which POSTs to /pp/v1/cf/apps/:cnsi/bulk/delete so the fan-out runs on the backend. Selection can span orgs/spaces within the endpoint; CAPI deletes per guid, so no space grouping is needed. With the header-cluster formatting the checkbox sits as star, checkbox, kebab on each card. Guard test asserts the checkbox column and a non-empty Delete bulk action survive.
Clicking an org's "Applications" count on the org summary navigated to the global cross-CF wall (/applications) instead of the CF-scoped apps tab -- CF-scoped context should stay CF-scoped. goToAppWall predates the per-CF applications tab and was never repointed. Add goToCfApplications (sibling of goToAppWall) that navigates to /cloud-foundry/<cf>/applications with the org/space filter pre-set, and use it from the org summary. The count now lands on the CF tab filtered to the org (with the card bulk-select checkboxes), not the multi-endpoint wall. Also fix a latent race the switch exposed: the stale-selection reconciliation gated only on _hasLoadedOnce, but the per-CF tab loads its org/space catalog lazily -- so apps could finish loading (flipping the gate) while orgOptions was still just "All", and a valid pre-set org filter got cleared. Only clear a selection once its validating catalog actually has entries; a genuinely stale selection still clears once the catalog loads.
When an app opened from the per-CF applications tab (?breadcrumbs=cf) errors out (deleted from another tab, 404, permission revoked), the error-redirect effect hard-navigated to the global cross-CF wall (/applications), ignoring the breadcrumbs source -- inconsistent with the delete flow right beside it, which already returns to the CF tab. Route the bounce to /cloud-foundry/<cf>/applications when breadcrumbs=cf; the global wall stays the default for every other source. Target decision extracted to a static appErrorRedirect() with a guard test.
…mmary While a bulk delete runs, the bulk-action bar now shows a "Working..." spinner and disables its buttons. The work happens behind the confirm dialog, after run() returns, so the bar can't infer this itself -- the consumer drives a new optional SignalListConfig `bulkRunning` signal. On completion the snackbar reports the full roll-up, e.g. "Bulk delete: 7 succeeded, 1 pending, 2 failed", instead of just failed-of-total; pending = an async CF job still completing. Guard test covers the spinner + disabled state.
The v5.0.0-rc.1 release was withdrawn, so return the version to the dev line. dev.137 was the last dev before the rc, so the next is dev.138.
…ing" An async CF delete comes back PENDING (job still completing), which the BulkResult contract counts as non-error alongside succeeded. The breakdown message printed "pending" literally, which reads as stuck. Fold succeeded + pending into one "N applications delete requested" line; on partial failure show "M failed, N requested". True completion tracking (polling the per-item async jobs) is a follow-up.
norman-abramovitz
approved these changes
Jul 21, 2026
norman-abramovitz
left a comment
Contributor
There was a problem hiding this comment.
LGTM - needs a followup PR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Card view is the default for most CF lists, but multi-select and bulk operations were reachable only in table view. This restores bulk-select in card view, adds bulk delete to the CF Applications tab, and fixes a couple of navigation issues found along the way.
Card bulk-select (signal-list)
The default card renderer treated the first column as the card title, so any list whose selection column comes first (routes, space-routes, space-apps) rendered a blank title, pushed the real title down into a body row, and never showed the checkbox at all.
Routes: the URL is the card title (the redundant "Route" label is gone), and a root-domain route with no host/path/port falls back to
(unnamed) <short-guid>with the full guid on hover.Bulk delete on the CF Applications tab
The endpoint-wide CF Applications tab had no selection column, so bulk delete was reachable only from the per-space Apps list. It now mirrors the per-space wiring: a checkbox column plus a Delete bulk action wired to the existing backend fan-out (
POST /pp/v1/cf/apps/:cnsi/bulk/delete). Selection can span orgs/spaces within the endpoint; the backend deletes per guid, so no space grouping is needed.CF-scoped navigation stays CF-scoped
Two links jumped out to the global cross-CF applications wall from a CF-scoped context:
?breadcrumbs=cf), matching the delete flow beside it.Guard tests cover each surface, and the production build plus unit tests pass.