EDM-4809: Catalog now has improved Backend support - #757
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughCatalog handling now uses typed catalog-item references instead of metadata labels across catalog management, device and fleet forms, install/edit workflows, dynamic volumes, and image promotion. Shared lookup, resolution, validation, patch, display, and volume conversion utilities were added. ChangesCatalog reference foundation
Catalog management
Install and edit workflows
Device, fleet, and form migration
Promotion and supporting updates
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 15✅ Passed checks (15 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 28
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx (1)
65-78: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winHandle failed parent catalog resolution before initializing the form.
useCatalogItemsLookupsetsisLoadingtofalseafter a failed request. This component then callsgetInitialValues(undefined)and does not show the lookup error. A user can receive an uninitialized promotion form instead of an error for the parent promotion.Read
errorfrom the lookup hook. When creating from a parent promotion, block initialization and show an error if the catalog item cannot resolve.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx` around lines 65 - 78, Update the ImagePromotionModal lookup flow to destructure the catalog lookup error alongside catalogItemLoading. For parentPromotion creation, handle a failed catalog item resolution before computing initialValues by displaying the lookup error and preventing form initialization, while preserving the existing loading state and normal resolved-item behavior.libs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsTabContent/ConfigurationsContent.tsx (1)
73-91: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winResolve the fleet-owned OS reference in the catalog lookup.
For a non-package-mode device,
ownerFleet.spec.template.spec.os.catalogItemRefcan be absent fromdevice.spec.DeviceDetailsPagedoes not request that ID.useResolvedCatalogRefthen uses the existing context and skips its local lookup.useSystemImagehas no desired URI, soDeviceOsreports a mismatch even when the fleet-selected image is running.Include the effective fleet OS ID in the lookup, or make
useResolvedCatalogReffall back on a context miss. Add a fleet-owned device test where the catalog reference exists only in the fleet template.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsTabContent/ConfigurationsContent.tsx` around lines 73 - 91, Update the catalog-reference resolution used by the non-package-mode flow around osSpec and DeviceRunningOsImage so a catalogItemRef defined only in ownerFleet.spec.template.spec.os is resolved even when it is absent from device.spec. Pass the effective fleet OS reference into the existing lookup path or add the equivalent fallback in useResolvedCatalogRef, ensuring useSystemImage receives the desired URI and DeviceOs does not report a false mismatch. Add coverage for a fleet-owned device whose catalog reference exists only in the fleet template.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@libs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/TypeConfigStep.tsx`:
- Around line 127-130: Add explicit type annotation Record<string, string> to
the reduce accumulator object (the {} initializer) and rename the reduce
callback parameter from artifact to artifactType to avoid shadowing the outer
artifact parameter. This improves type safety and clarifies the distinction
between the iteration variable and the outer scope.
In `@libs/ui-components/src/components/Catalog/CatalogItemDetails.tsx`:
- Around line 164-174: Update CatalogItemPanelLink to parse and validate the
provided link’s protocol, allowing only http: and https: URLs; render disallowed
values as plain text rather than an anchor while preserving the existing N/A
behavior for missing links. Keep valid links using the current Button
configuration.
In `@libs/ui-components/src/components/Catalog/CatalogItemTitle.tsx`:
- Around line 46-59: Replace the description line’s Title element in
CatalogItemTitle with Content, matching the existing versionLine rendering,
while preserving the description conditional and displayed text.
- Line 1: Update the React import in CatalogItemTitle.tsx to use the namespace
import style, matching CatalogItemDetails.tsx and InstalledSoftwareItem.tsx and
the repository convention.
In `@libs/ui-components/src/components/Catalog/CatalogPage.tsx`:
- Around line 449-454: Update the onDeleteSuccess handler in CatalogPage so
catalogFilter.setCatalogs removes only the deleted catalog’s id via its updater
form, preserving all other selected catalogs. Use the catalog being deleted as
the removal target, then keep the existing refetchCatalogs and refetch calls
unchanged.
In `@libs/ui-components/src/components/Catalog/DeleteCatalogModal.tsx`:
- Around line 127-143: Update loadCatalogItems in DeleteCatalogModal to paginate
catalog item requests: set the API limit, append each page’s mapped items to the
accumulated collection, and use each response’s metadata.continue token to fetch
subsequent pages until it is absent. Preserve the existing success and error
state handling while ensuring catalogItems contains results from every page.
In `@libs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsx`:
- Around line 3-5: The imports in EditAppWizard.tsx and InstallWizard/utils.ts
mix runtime and type-only symbols. Update EditAppWizard.tsx imports for
FormikErrors, WizardStepType, RJSFValidationError, and AppUpdateFormik, and
update utils.ts imports for CatalogItem, FormikHelpers, and
DynamicFormConfigFormik to use import type or inline type specifiers while
leaving runtime imports unchanged.
In `@libs/ui-components/src/components/Catalog/EditWizard/EditOsWizard.tsx`:
- Line 2: Separate type-only imports from runtime imports in EditOsWizard.tsx
(line 2), moving WizardStepType to import type; in InstallOsWizard.tsx (line 6),
import Device, Fleet, ImageOrCatalogItemRefSpec, and PatchRequest as types; in
AppConfigStep.tsx (lines 3-4), import RJSFValidationError and FormikErrors as
types; in ReviewStep.tsx (line 20), import InstallAppFormik and InstallOsFormik
as types; and in SelectTargetStep.tsx (line 1), import Device, Fleet, and
ImageOrCatalogItemRefSpec as types. Leave runtime imports unchanged.
In `@libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx`:
- Around line 130-135: Update the empty-patch branch in the EditWizard update
flow to call setIsSpecUnchanged(true), since no PATCH request occurs when
allPatches is empty; keep setIsSpecUnchanged(false) after a non-empty patch is
successfully sent, and apply the same correction to the corresponding second
branch.
- Line 212: Update the active breadcrumb in EditWizard to use one t()
translation key for the complete catalogDisplayName/appName format, including
the parentheses, so translators can reorder both values; preserve the existing
omission of appName when it is unavailable.
- Around line 106-127: Validate values.channel against
catalogItemVersion.channels in EditOsWizard’s onUpdate callback before calling
buildCatalogItemRef; reject the update when the channel is not allowlisted,
while preserving the existing patch flow for valid channels.
In `@libs/ui-components/src/components/Catalog/InstalledSoftwareItem.tsx`:
- Line 9: Update the import from useSpecCatalogItems so ResolvedCatalogItemData
is marked as a type-only import, matching SpecAppCatalogItem and
SpecOsCatalogItem, since it is only used in type positions within
InstalledSoftwareItem.
In `@libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx`:
- Around line 187-191: Update the validation around catalogItemVersion in
InstallOsWizard so it also verifies that values.channel exists in
catalogItemVersion.channels before creating the patch. Reject missing or
mismatched version/channel pairs through the existing setError path, while
preserving the current behavior for valid selections.
- Line 181: Replace the type-assertion-based selection in the InstallOsWizard
flow with an explicit discriminated-union branch on values.target, reading
values.device only for the device variant and values.fleet only for the fleet
variant; preserve the resulting selectedResource behavior.
In
`@libs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsx`:
- Around line 39-48: Update isOsUnchanged to compare osRef.channel with the
target catalog item's channel as part of the complete catalog reference, and
ensure both call sites pass the corresponding channel value. Preserve the no-op
result only when item, catalog, version, and channel all match.
In
`@libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx`:
- Around line 341-345: Synchronize the no-op state with current specifications:
in SelectTargetStep.tsx, update onTargetSelected and its dependencies so
isSpecUnchanged is recomputed when the selected target, target type, version, or
channel changes; in InstallOsWizard.tsx, set the final no-op result from
allPatches.length === 0 after the fresh resource read.
In `@libs/ui-components/src/components/Catalog/useCatalogItems.ts`:
- Around line 126-133: Update useItemIsInUse to expose the deployment request’s
loading and error state and return false unless the request has completed
successfully with a confirmed empty deployment list; keep Delete disabled during
initial loading and failures. Build the deployments endpoint using the same
encoding approach as catalogItemEndpoint for both catalogItem.metadata.catalog
and catalogItem.metadata.name.
- Around line 57-58: Update the nameFilter handling in useCatalogItems so it
trims the value before the guard and selector construction, treating
whitespace-only input as empty. Escape backslashes, commas, and whitespace
according to flightctl field-selector rules (or validate against an explicit
allow-list), while preserving ! and = as valid RHS characters, then use the
sanitized value in metadata.name contains.
In `@libs/ui-components/src/components/Catalog/useCatalogItemsLookup.ts`:
- Around line 142-148: Stabilize the shared catalog hook results by memoizing
the returned value in
libs/ui-components/src/components/Catalog/useCatalogItemsLookup.ts lines 142-148
with dependencies getItem, isLoading, and error; also memoize the os/apps
derivation and returned object in
libs/ui-components/src/components/Catalog/useSpecCatalogItems.ts lines 48-97
using spec, lookup.getItem, lookup.isLoading, and lookup.error so the apps array
identity remains stable.
- Around line 109-139: Update the async catalog lookup around fetchGet and its
cleanup to create an AbortController, pass its signal to each fetchGet request,
and call abort() when the effect cleanup runs. In the rejected-results handling,
skip console.warn and firstError assignment for expected abort failures when the
controller signal is aborted, while preserving existing handling for other
errors.
In
`@libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts`:
- Around line 769-799: Update the OS patch-building logic to return no patch
whenever formOsSpec.catalogItemRef is set, before the image-change handling can
generate a remove patch. Preserve the existing currentOsSpec.catalogItemRef
guard and image patch behavior for non-catalog form specifications.
- Line 65: The FullAppVolume type is imported as a value import when it should
be imported as a type-only import since it is only used for type annotations and
not as a runtime value. Update the import statement to separate FullAppVolume
into a type-only import while keeping formVolumesToApi and toFormVolumes as
regular value imports from the volumes utility module.
In
`@libs/ui-components/src/components/Device/EditDeviceWizard/SystemImageDescriptionGroup.tsx`:
- Around line 26-47: Translate both user-visible fallback messages using
hardcoded translation keys. In
libs/ui-components/src/components/Device/EditDeviceWizard/SystemImageDescriptionGroup.tsx
lines 26-47, obtain t in SystemImageDisplay and replace the '-' fallback with a
static t() key. In
libs/ui-components/src/components/Device/EditDeviceWizard/steps/ReviewApplications.tsx
lines 9-16, replace the constructed template literal with a hardcoded
interpolation key passed to t(), preserving the image value through the
interpolation variable.
In `@libs/ui-components/src/components/DynamicForm/DynamicForm.tsx`:
- Line 24: Update the imports in
libs/ui-components/src/components/DynamicForm/DynamicForm.tsx at lines 24-24 and
libs/ui-components/src/components/form/validations.ts at lines 6-6: import
VolumeCatalogSelection and ImageOrCatalogItemRefSpec as type-only symbols, while
retaining AppType and ImagePullPolicy as value imports.
In `@libs/ui-components/src/components/form/validations.ts`:
- Around line 784-798: The imageSpecSchema validation test must handle an
undefined val when imageRequired is true. In imageSpecSchema, use optional
access for catalogItemRef and image so the missing value reaches
ociImageSchema(...).required(requiredMessage) and returns requiredMessage rather
than throwing; add coverage for the missing required imageSpec case.
In
`@libs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.ts`:
- Around line 38-44: Fix the skips initialization in the existing-item promotion
utility so the fallback is applied before calling split. Update the skips
expression around values.existingItem.skips to safely produce an empty array
when unset, while preserving trimming and filtering for provided skip values.
In `@libs/ui-components/src/components/ImagePromotion/ImagePromotionForm.tsx`:
- Around line 132-140: The catalog change flow around useCatalogItems must
prevent stale items from remaining selectable during the debounced refresh.
Consume its isUpdating result, clear or disable existing-item selection while
updating, and reset the dependent existingItem values whenever values.catalog
changes before ExistingItemForm can use the previous catalog’s items.
In `@libs/ui-components/src/types/deviceSpec.ts`:
- Around line 22-23: Update the imports in deviceSpec.ts to use a type-only
import for ApplicationVolumeForm, and re-export ApplicationVolumeForm from this
public subpath so existing consumers remain compatible.
---
Outside diff comments:
In
`@libs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsTabContent/ConfigurationsContent.tsx`:
- Around line 73-91: Update the catalog-reference resolution used by the
non-package-mode flow around osSpec and DeviceRunningOsImage so a catalogItemRef
defined only in ownerFleet.spec.template.spec.os is resolved even when it is
absent from device.spec. Pass the effective fleet OS reference into the existing
lookup path or add the equivalent fallback in useResolvedCatalogRef, ensuring
useSystemImage receives the desired URI and DeviceOs does not report a false
mismatch. Add coverage for a fleet-owned device whose catalog reference exists
only in the fleet template.
In `@libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx`:
- Around line 65-78: Update the ImagePromotionModal lookup flow to destructure
the catalog lookup error alongside catalogItemLoading. For parentPromotion
creation, handle a failed catalog item resolution before computing initialValues
by displaying the lookup error and preventing form initialization, while
preserving the existing loading state and normal resolved-item behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 64b29bae-2160-451f-809b-a9b556a0c9c1
⛔ Files ignored due to path filters (15)
libs/i18n/locales/en/translation.jsonis excluded by!libs/i18n/locales/en/translation.jsonlibs/types/alpha/models/CatalogItemDeployment.tsis excluded by!libs/types/alpha/models/**libs/types/alpha/models/CatalogItemDeploymentList.tsis excluded by!libs/types/alpha/models/**libs/types/models/CatalogItemRefApplicationProviderSpec.tsis excluded by!libs/types/models/**libs/types/models/CatalogItemRefSpec.tsis excluded by!libs/types/models/**libs/types/models/ComposeApplication.tsis excluded by!libs/types/models/**libs/types/models/ContainerApplication.tsis excluded by!libs/types/models/**libs/types/models/DeviceOsSpec.tsis excluded by!libs/types/models/**libs/types/models/Event.tsis excluded by!libs/types/models/**libs/types/models/HelmApplication.tsis excluded by!libs/types/models/**libs/types/models/ImageApplicationProviderSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageOrCatalogItemRefSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageVolumeSource.tsis excluded by!libs/types/models/**libs/types/models/QuadletApplication.tsis excluded by!libs/types/models/**
📒 Files selected for processing (78)
libs/types/alpha/index.tslibs/types/index.tslibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/ReviewStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/TypeConfigStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/VersionStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/utils.tslibs/ui-components/src/components/Catalog/CatalogItemCard.tsxlibs/ui-components/src/components/Catalog/CatalogItemDetails.tsxlibs/ui-components/src/components/Catalog/CatalogItemTitle.tsxlibs/ui-components/src/components/Catalog/CatalogItemsContext.tsxlibs/ui-components/src/components/Catalog/CatalogPage.tsxlibs/ui-components/src/components/Catalog/DeleteCatalogModal.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditOsWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/steps/UpdateStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallAppWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/UpdateSuccessPage.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/AppConfigStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/SpecificationsStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/types.tslibs/ui-components/src/components/Catalog/InstallWizard/utils.tslibs/ui-components/src/components/Catalog/InstalledSoftware.tsxlibs/ui-components/src/components/Catalog/InstalledSoftwareItem.tsxlibs/ui-components/src/components/Catalog/ResourceCatalog/ResourceCatalogPage.tsxlibs/ui-components/src/components/Catalog/const.tslibs/ui-components/src/components/Catalog/useCatalogItems.tslibs/ui-components/src/components/Catalog/useCatalogItemsLookup.tslibs/ui-components/src/components/Catalog/useResolvedCatalogRef.tslibs/ui-components/src/components/Catalog/useSpecCatalogItems.tslibs/ui-components/src/components/Catalog/utils.tslibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsCatalog.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsTabContent/ConfigurationsContent.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceOs.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/EditDeviceWizard.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/SystemImageDescriptionGroup.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.tslibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.csslibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/DeviceTemplateStep.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ReviewApplications.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ReviewDeviceStep.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/useSystemImage.tslibs/ui-components/src/components/Device/EditDeviceWizard/utils.tslibs/ui-components/src/components/DynamicForm/DynamicForm.tsxlibs/ui-components/src/components/DynamicForm/FieldTemplate.tsxlibs/ui-components/src/components/DynamicForm/VolumeImageField.tsxlibs/ui-components/src/components/Events/useEvents.tslibs/ui-components/src/components/Fleet/CreateFleet/CreateFleetWizard.tsxlibs/ui-components/src/components/Fleet/CreateFleet/steps/ReviewStep.tsxlibs/ui-components/src/components/Fleet/CreateFleet/utils.tslibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsCatalog.tsxlibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsContent.tsxlibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsPage.tsxlibs/ui-components/src/components/Fleet/FleetRow.tsxlibs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/NewVersionImageBuildWizard.tsxlibs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.tslibs/ui-components/src/components/ImagePromotion/ImagePromotionForm.tsxlibs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsxlibs/ui-components/src/components/common/LabelsView.tsxlibs/ui-components/src/components/form/ApplicationPortMappingField.tsxlibs/ui-components/src/components/form/ImageOrCatalogRefField.tsxlibs/ui-components/src/components/form/LabelsField.tsxlibs/ui-components/src/components/form/validations.tslibs/ui-components/src/hooks/useAppLinks.tslibs/ui-components/src/types/deviceSpec.tslibs/ui-components/src/utils/catalog.tslibs/ui-components/src/utils/volumes.ts
💤 Files with no reviewable changes (5)
- libs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsCatalog.tsx
- libs/ui-components/src/components/Catalog/const.ts
- libs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.css
- libs/ui-components/src/components/Catalog/utils.ts
- libs/ui-components/src/components/form/LabelsField.tsx
97883c6 to
3eb9c83
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx (1)
220-225: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDerive no-op status from the final specification comparison.
The success pages must report whether the submitted specification changed. Do not keep a stale selection-time value or mark an empty patch as changed.
libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx#L220-L225: set the success state fromallPatches.length === 0after the fresh resource read.libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx#L177-L182: setisSpecUnchangedtotruewhenallPatchesis empty.libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx#L340-L358: recompute or deferisSpecUnchangedwhen the target, version, or channel changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx` around lines 220 - 225, Derive no-op success status from the final patch comparison: in libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx lines 220-225, set the success state from allPatches.length === 0 after the fresh resource read; in libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx lines 177-182, set isSpecUnchanged to true when allPatches is empty; and in libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx lines 340-358, recompute or defer isSpecUnchanged whenever the target, version, or channel changes.libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts (2)
9-9: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUse type-only imports for the new type symbols.
CatalogItemRefApplicationProviderSpec,ImageOrCatalogItemRefSpec, andImageVolumeSourceare used only in type positions. Mark them withtypeor move them to animport typedeclaration. (raw.githubusercontent.com)Proposed import fix
- CatalogItemRefApplicationProviderSpec, + type CatalogItemRefApplicationProviderSpec, ... - ImageOrCatalogItemRefSpec, + type ImageOrCatalogItemRefSpec, - ImageVolumeSource, + type ImageVolumeSource,#!/bin/bash set -euo pipefail sed -n '1,30p' libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.tsAs per path instructions:
**/*.{ts,tsx}requires types used only for checking to be imported withimport type.Also applies to: 20-22
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts` at line 9, Update the imports in deviceSpecUtils.ts so CatalogItemRefApplicationProviderSpec, ImageOrCatalogItemRefSpec, and ImageVolumeSource are imported via import type or marked as type-only, while leaving any runtime imports unchanged.Sources: Path instructions, MCP tools
535-555: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winPreserve application-type filtering when serializing volumes.
If a volume form retains
mountPathafter a single-container application changes to Compose or Quadlet,formVolumesToApi(app.volumes)emits the unsupportedmountfield. Filter volume fields by application type in bothtoApiComposeAppandtoApiQuadletApp. Keep volume fields initialized for every application type, but include only supported fields in the API payload. Add a regression test for this application-type change.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts` around lines 535 - 555, Update toApiComposeApp and toApiQuadletApp to serialize volumes through application-type filtering, preventing retained mountPath values from producing unsupported mount fields while preserving initialization of volume fields for all types. Add a regression test covering a single-container application changed to Compose or Quadlet and verifying only supported volume fields reach the API payload.Sources: Learnings, MCP tools
♻️ Duplicate comments (2)
libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx (2)
212-212: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winTranslate the complete active breadcrumb label.
Line 212 leaves the literal
(${appName})outsidet(). Use one hardcoded translation key for the complete catalog/app format so translators can reorder both values.Proposed fix
-<BreadcrumbItem isActive>{`${catalogDisplayName}${appName ? ` (${appName})` : ''}`}</BreadcrumbItem> +<BreadcrumbItem isActive> + {appName + ? t('{{catalogName}} ({{appName}})', { catalogName: catalogDisplayName, appName }) + : catalogDisplayName} +</BreadcrumbItem>As per coding guidelines and path instructions, user-visible strings in
.tsxfiles must uset()with hardcoded translation keys.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx` at line 212, Update the active BreadcrumbItem label to pass the complete catalog-and-app format through t() using one hardcoded translation key, including the conditional app name value, so translators can reorder both values. Preserve the catalog-only label when appName is absent and use the existing translation mechanism.Sources: Coding guidelines, Path instructions
120-129: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winValidate
channelat every catalog-reference write boundary.Both flows persist
values.channelwithout proving that the selected catalog version declares it.
libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx#L120-L129: validatevalues.channelagainstcatalogItemVersion.channelsbefore callingbuildCatalogItemRef.libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx#L188-L191: reject the version/channel pair unlesscatalogItemVersion.channels.includes(values.channel)is true.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx` around lines 120 - 129, Validate values.channel against catalogItemVersion.channels before each catalog-reference write: in libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx lines 120-129, reject the pair before buildCatalogItemRef; in libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx lines 188-191, reject unless catalogItemVersion.channels.includes(values.channel) is true.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsx`:
- Line 3: Update the import in EditAppWizard.tsx so Wizard and WizardStep are
imported as runtime values, while only WizardStepType remains in the type-only
import. Preserve the existing JSX usage of the two React components.
In `@libs/ui-components/src/types/deviceSpec.ts`:
- Line 23: The ApplicationVolumeForm type is imported from ../utils/volumes in
the deviceSpec module but is no longer exported locally, breaking the public API
for consumers of the types/deviceSpec subpath. Add a re-export statement for
ApplicationVolumeForm to preserve access for existing consumers while keeping
the internal import intact.
---
Outside diff comments:
In `@libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx`:
- Around line 220-225: Derive no-op success status from the final patch
comparison: in
libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx
lines 220-225, set the success state from allPatches.length === 0 after the
fresh resource read; in
libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx lines
177-182, set isSpecUnchanged to true when allPatches is empty; and in
libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx
lines 340-358, recompute or defer isSpecUnchanged whenever the target, version,
or channel changes.
In
`@libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts`:
- Line 9: Update the imports in deviceSpecUtils.ts so
CatalogItemRefApplicationProviderSpec, ImageOrCatalogItemRefSpec, and
ImageVolumeSource are imported via import type or marked as type-only, while
leaving any runtime imports unchanged.
- Around line 535-555: Update toApiComposeApp and toApiQuadletApp to serialize
volumes through application-type filtering, preventing retained mountPath values
from producing unsupported mount fields while preserving initialization of
volume fields for all types. Add a regression test covering a single-container
application changed to Compose or Quadlet and verifying only supported volume
fields reach the API payload.
---
Duplicate comments:
In `@libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx`:
- Line 212: Update the active BreadcrumbItem label to pass the complete
catalog-and-app format through t() using one hardcoded translation key,
including the conditional app name value, so translators can reorder both
values. Preserve the catalog-only label when appName is absent and use the
existing translation mechanism.
- Around line 120-129: Validate values.channel against
catalogItemVersion.channels before each catalog-reference write: in
libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx lines
120-129, reject the pair before buildCatalogItemRef; in
libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx
lines 188-191, reject unless
catalogItemVersion.channels.includes(values.channel) is true.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 721f2444-232f-4852-9fee-379053532213
📒 Files selected for processing (14)
libs/ui-components/src/components/Catalog/CatalogItemTitle.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/utils.tslibs/ui-components/src/components/Catalog/InstalledSoftwareItem.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.tslibs/ui-components/src/components/Device/EditDeviceWizard/steps/DeviceTemplateStep.tsxlibs/ui-components/src/components/DynamicForm/DynamicForm.tsxlibs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.tslibs/ui-components/src/components/form/validations.tslibs/ui-components/src/types/deviceSpec.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts (1)
749-801: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winHandle catalog-reference OS transitions before building image patches.
DeviceSpecConfigFormValues.osSpecnow acceptscatalogItemRefinlibs/ui-components/src/types/deviceSpec.tsat Line 259.getFormOsSpecPatchesskips only a catalog-backed current specification and then readsformOsSpec.image.When the current OS uses an image and the form selects a catalog reference,
formOsSpec.imageis undefined and the function emits aremovepatch. This can delete the existing OS configuration. When the current OS uses a catalog reference and the form selects an image, the early return leaves the old catalog reference unchanged.Serialize catalog-reference add/replace patches, or reject both unsupported transitions before the image-only logic. Add regression tests for both directions.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts` around lines 749 - 801, Update getFormOsSpecPatches to handle transitions between image and catalogItemRef before the image-only patch logic: either serialize the appropriate catalogItemRef add/replace patches or reject both unsupported directions consistently, preventing image removal or stale catalog references. Preserve existing image-only behavior and add regression coverage for image-to-catalog and catalog-to-image transitions.libs/ui-components/src/components/DynamicForm/DynamicForm.tsx (1)
24-32: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winPreserve the
AssetSelectionexport or document the breaking API change.@flightctl/ui-componentsis publishable and exposes source paths through wildcard exports.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/DynamicForm/DynamicForm.tsx` around lines 24 - 32, The `AssetSelection` type was previously exported from DynamicForm.tsx as part of the public API for the publishable `@flightctl/ui-components` package, and its removal creates a breaking change. Either restore the export of AssetSelection alongside the existing DynamicFormContext export, or document this breaking change in release notes or a migration guide to help downstream consumers understand the impact and how to adapt their code.libs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.ts (1)
20-25: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winOmitted optional fields on existing catalog-item promotions will preserve stale values; users cannot clear them.
The
optionalTrimmedfunction and empty-array check (lines 38–50) convert blankreadme,displayName,replaces,skipRange, andskipsvalues toundefined. The comment at line 20 states this avoids false change detection when an associated catalog item updates. However, this design choice has a consequence: if the backend treats omitted optional fields as "no change" rather than "clear," a user who edits an existing promotion and empties a field will not clear that field in the stored promotion.Verify with the backend team whether omitted optional fields in the image-promotion API request mean:
- "Clear the field" (acceptable—current code works as intended)
- "Leave unchanged" (problematic—users cannot clear stale data)
If the backend interprets omitted fields as unchanged, the form must distinguish between "user cleared this" (send empty string or null) and "user left this alone" (omit the field).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.ts` around lines 20 - 25, Verify the image-promotion API semantics for omitted optional fields with the backend team. If omission means “leave unchanged,” update optionalTrimmed and the empty-array handling in the promotion request builder to distinguish untouched fields from user-cleared fields, sending the API’s supported empty value for cleared readme, displayName, replaces, skipRange, and skips fields while continuing to omit untouched fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In
`@libs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts`:
- Around line 749-801: Update getFormOsSpecPatches to handle transitions between
image and catalogItemRef before the image-only patch logic: either serialize the
appropriate catalogItemRef add/replace patches or reject both unsupported
directions consistently, preventing image removal or stale catalog references.
Preserve existing image-only behavior and add regression coverage for
image-to-catalog and catalog-to-image transitions.
In `@libs/ui-components/src/components/DynamicForm/DynamicForm.tsx`:
- Around line 24-32: The `AssetSelection` type was previously exported from
DynamicForm.tsx as part of the public API for the publishable
`@flightctl/ui-components` package, and its removal creates a breaking change.
Either restore the export of AssetSelection alongside the existing
DynamicFormContext export, or document this breaking change in release notes or
a migration guide to help downstream consumers understand the impact and how to
adapt their code.
In
`@libs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.ts`:
- Around line 20-25: Verify the image-promotion API semantics for omitted
optional fields with the backend team. If omission means “leave unchanged,”
update optionalTrimmed and the empty-array handling in the promotion request
builder to distinguish untouched fields from user-cleared fields, sending the
API’s supported empty value for cleared readme, displayName, replaces,
skipRange, and skips fields while continuing to omit untouched fields.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: b22e02e0-2a1e-4611-ac9e-408dc5177a28
📒 Files selected for processing (13)
libs/ui-components/src/components/Catalog/CatalogItemTitle.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/utils.tslibs/ui-components/src/components/Catalog/InstalledSoftwareItem.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.tslibs/ui-components/src/components/DynamicForm/DynamicForm.tsxlibs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.tslibs/ui-components/src/components/form/validations.tslibs/ui-components/src/types/deviceSpec.ts
Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
3eb9c83 to
2041661
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx (1)
65-78: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winHandle catalog lookup errors before initializing the form. The modal ignores
errorand falls back todefaultInitialValues, changing the target to a blank new catalog item. Although validation initially disables submission, users can fill the fallback form and create the wrong promotion. Render the lookup error and prevent form submission when the lookup fails.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx` around lines 65 - 78, Handle the catalog lookup error from useCatalogItemsLookup before building initialValues in ImagePromotionModal: render an error state instead of falling back to defaultInitialValues, and keep the form submission disabled when the lookup fails. Preserve the existing loading behavior and successful catalog-item initialization for parentPromotion.
♻️ Duplicate comments (3)
libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx (1)
342-347: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
isSpecUnchangedis captured at target selection and never reconciled with the patch result. The flag originates from a row-selection callback, so it reflects the version and channel that were active at that moment. The wizard lets the user return to the specifications step and change either value afterwards. The submit handler then computes the authoritative answer from the fresh resource read but discards it, and the success page renders the stale flag.Result: the wizard can send a real patch and still display "No action performed", or perform a genuine no-op and display "Update configuration successful". The footer label at
InstallOsWizard.tsxline 95 can also read "Close" while a patch is pending.
libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx#L342-L347: recomputeisSpecUnchangedwhenvalues.versionorvalues.channelchanges, not only whenonTargetSelectedfires. Add aReact.useEffectkeyed on the selected target,values.version, andvalues.channel.libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx#L230-L235: set the final result fromallPatches.length === 0after the fresh read, so the success page reports what actually happened. TakesetFieldValuefrom the second argument of the FormikonSubmithandler and callsetFieldValue('isSpecUnchanged', allPatches.length === 0)beforesetIsSuccessful(true).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx` around lines 342 - 347, The target-spec unchanged flag becomes stale after version or channel edits. In SelectTargetStep.tsx lines 342-347, add an effect keyed by the selected target, values.version, and values.channel to recompute isSpecUnchanged via isSameOsSpec. In InstallOsWizard.tsx lines 230-235, obtain setFieldValue from the Formik onSubmit second argument and set isSpecUnchanged from allPatches.length === 0 after the fresh read, before setIsSuccessful(true).libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx (2)
212-212: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winMove the parenthetical format into the translation key.
The parentheses around
appNameare user-visible text and sit outsidet(). Translators cannot reorder the two names or change the punctuation.🌐 Proposed change
- <BreadcrumbItem isActive>{`${catalogDisplayName}${appName ? ` (${appName})` : ''}`}</BreadcrumbItem> + <BreadcrumbItem isActive> + {appName + ? t('{{catalogName}} ({{appName}})', { catalogName: catalogDisplayName, appName }) + : catalogDisplayName} + </BreadcrumbItem>As per coding guidelines, "Flag user-visible strings in .tsx files that are not wrapped in the t() translation function." As per path instructions, "All user-visible strings must use the t() translation function."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx` at line 212, Update the BreadcrumbItem label in EditWizard to place the full catalog/app name format, including parentheses and spacing, inside the t() translation key; pass catalogDisplayName and appName as interpolation values while preserving the existing omission of parentheses when appName is absent.Sources: Coding guidelines, Path instructions
106-135: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winValidate
values.channelagainst the selected version before patching.
currentChannelis seeded from thechannelURL search parameter at line 108.EditOsWizardvalidatesversiononly.buildCatalogItemRefthen copiesvalues.channelinto the persistedcatalogItemRefwithout checking that the channel exists incatalogItemVersion.channels.
InstallOsWizardnow performs this check at lines 193-202. This edit path does not, so the two OS write paths disagree. A stale or hand-editedchannelparameter writes a device or fleet reference that tracks a channel which does not contain the selected version.🐛 Proposed guard
onUpdate={async (catalogItemVersion, values) => { + if (values.channel && !catalogItemVersion.channels.includes(values.channel)) { + throw new Error( + t('Invalid channel {{ channel }} for version {{ version }}', { + channel: values.channel, + version: catalogItemVersion.version, + }), + ); + } const allPatches: PatchRequest = [];🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx` around lines 106 - 135, Validate values.channel against catalogItemVersion.channels in the EditOsWizard onUpdate flow before constructing or submitting the patch, matching the guard used by InstallOsWizard. Reject or surface an invalid channel and prevent buildCatalogItemRef and patch from persisting it; keep valid-channel updates unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/ui-components/src/components/Catalog/CatalogItemTitle.tsx`:
- Line 119: Update the icon source used by CatalogItemTitle so the value from
getCatalogItemIcon is assigned to img only after validation against bundled
assets or the approved trusted origins; reject URLs and data URIs from untrusted
catalog item metadata, while preserving the existing fallback behavior for
disallowed icons.
In `@libs/ui-components/src/components/Catalog/InstalledSoftware.tsx`:
- Around line 66-94: Update SpecCatalogItemId in catalog.ts to a discriminated
union that requires appName for app entries, then remove the redundant appName
string assertions in InstalledSoftware and ResourceCatalogPage. Ensure app keys
and delete-modal resource names use the required appName while operating-system
variants continue using their formatted refs.
- Around line 45-47: Update the error branch in InstalledSoftware to import and
render getErrorMessage(error) as the Alert body, while preserving the existing
failure title and danger styling.
In
`@libs/ui-components/src/components/Catalog/InstallWizard/InstallAppWizard.tsx`:
- Line 216: Update the volumeSelection assignment in InstallAppWizard to pass an
empty array when operating in editor mode, preventing stale selections from
reaching getCatalogApiVolumes and restoring removed YAML catalog references.
In
`@libs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsx`:
- Around line 39-55: The OS comparison logic is duplicated and disagrees on
missing channels. In
libs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsx#L39-L55,
delete local isOsUnchanged and import the shared predicate. In
libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx#L45-L61,
move isSameOsSpec to libs/ui-components/src/utils/catalog.ts beside
buildCatalogItemRef, export it, and import it here; preserve || '' channel
normalization as the single behavior.
In
`@libs/ui-components/src/components/Device/EditDeviceWizard/steps/ReviewApplications.tsx`:
- Around line 13-14: Update the application label logic in ReviewApplications so
catalog-backed applications without a name or imageSpec.image fall back to the
formatted catalogItemRef. Preserve the existing imageSpec.image label when
available and ensure the result is not an empty string before appending the
application type.
In `@libs/ui-components/src/components/form/ApplicationPortMappingField.tsx`:
- Around line 285-378: Remove the redundant !isReadOnly conditional around
fieldContent and render the input Split content directly, eliminating the
unreachable null branch and unnecessary isDisabled={isReadOnly} props on the
port inputs. Keep the existing outer !isReadOnly guard for the input section,
and render the addedPortsContent StackItem only when addedPortsContent exists so
edit mode with no ports does not create empty gutter space.
In `@libs/ui-components/src/components/form/ImageOrCatalogRefField.tsx`:
- Around line 33-56: Update the value selection in ImageOrCatalogRefField so
catalog-backed fields display formatCatalogItemRef(catalogRef) whenever
resolved?.imageUri is unavailable, including loading, failure, and unresolved
states; continue showing the resolved image URI when present and preserve the
existing non-catalog value behavior.
In
`@libs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.ts`:
- Line 36: Update the new-target construction in the wizard utility to first
assign the object to a local explicitly typed as NewCatalogItemTarget, then pass
that validated local to promotionTarget. Remove the direct type assertion so
TypeScript performs structural and discriminator checks against the generated
schema.
In `@libs/ui-components/src/utils/catalog.ts`:
- Line 19: Update the TFunction import in catalog.ts to use a type-only import
because it is referenced only in type positions.
---
Outside diff comments:
In `@libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx`:
- Around line 65-78: Handle the catalog lookup error from useCatalogItemsLookup
before building initialValues in ImagePromotionModal: render an error state
instead of falling back to defaultInitialValues, and keep the form submission
disabled when the lookup fails. Preserve the existing loading behavior and
successful catalog-item initialization for parentPromotion.
---
Duplicate comments:
In `@libs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsx`:
- Line 212: Update the BreadcrumbItem label in EditWizard to place the full
catalog/app name format, including parentheses and spacing, inside the t()
translation key; pass catalogDisplayName and appName as interpolation values
while preserving the existing omission of parentheses when appName is absent.
- Around line 106-135: Validate values.channel against
catalogItemVersion.channels in the EditOsWizard onUpdate flow before
constructing or submitting the patch, matching the guard used by
InstallOsWizard. Reject or surface an invalid channel and prevent
buildCatalogItemRef and patch from persisting it; keep valid-channel updates
unchanged.
In
`@libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx`:
- Around line 342-347: The target-spec unchanged flag becomes stale after
version or channel edits. In SelectTargetStep.tsx lines 342-347, add an effect
keyed by the selected target, values.version, and values.channel to recompute
isSpecUnchanged via isSameOsSpec. In InstallOsWizard.tsx lines 230-235, obtain
setFieldValue from the Formik onSubmit second argument and set isSpecUnchanged
from allPatches.length === 0 after the fresh read, before setIsSuccessful(true).
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: e3cb60f2-e61f-46c2-94db-f80ac10cad33
⛔ Files ignored due to path filters (15)
libs/i18n/locales/en/translation.jsonis excluded by!libs/i18n/locales/en/translation.jsonlibs/types/alpha/models/CatalogItemDeployment.tsis excluded by!libs/types/alpha/models/**libs/types/alpha/models/CatalogItemDeploymentList.tsis excluded by!libs/types/alpha/models/**libs/types/models/CatalogItemRefApplicationProviderSpec.tsis excluded by!libs/types/models/**libs/types/models/CatalogItemRefSpec.tsis excluded by!libs/types/models/**libs/types/models/ComposeApplication.tsis excluded by!libs/types/models/**libs/types/models/ContainerApplication.tsis excluded by!libs/types/models/**libs/types/models/DeviceOsSpec.tsis excluded by!libs/types/models/**libs/types/models/Event.tsis excluded by!libs/types/models/**libs/types/models/HelmApplication.tsis excluded by!libs/types/models/**libs/types/models/ImageApplicationProviderSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageOrCatalogItemRefSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageVolumeSource.tsis excluded by!libs/types/models/**libs/types/models/QuadletApplication.tsis excluded by!libs/types/models/**
📒 Files selected for processing (78)
libs/types/alpha/index.tslibs/types/index.tslibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/ReviewStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/TypeConfigStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/VersionStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/utils.tslibs/ui-components/src/components/Catalog/CatalogItemCard.tsxlibs/ui-components/src/components/Catalog/CatalogItemDetails.tsxlibs/ui-components/src/components/Catalog/CatalogItemTitle.tsxlibs/ui-components/src/components/Catalog/CatalogItemsContext.tsxlibs/ui-components/src/components/Catalog/CatalogPage.tsxlibs/ui-components/src/components/Catalog/DeleteCatalogModal.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditOsWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/steps/UpdateStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallAppWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/UpdateSuccessPage.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/AppConfigStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/SpecificationsStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/types.tslibs/ui-components/src/components/Catalog/InstallWizard/utils.tslibs/ui-components/src/components/Catalog/InstalledSoftware.tsxlibs/ui-components/src/components/Catalog/InstalledSoftwareItem.tsxlibs/ui-components/src/components/Catalog/ResourceCatalog/ResourceCatalogPage.tsxlibs/ui-components/src/components/Catalog/const.tslibs/ui-components/src/components/Catalog/specCatalogItems.tslibs/ui-components/src/components/Catalog/useCatalogItems.tslibs/ui-components/src/components/Catalog/useCatalogItemsLookup.tslibs/ui-components/src/components/Catalog/useResolvedCatalogRef.tslibs/ui-components/src/components/Catalog/utils.tslibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsCatalog.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsTabContent/ConfigurationsContent.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceOs.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/EditDeviceWizard.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/SystemImageDescriptionGroup.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.tslibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.csslibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/DeviceTemplateStep.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ReviewApplications.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ReviewDeviceStep.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/useSystemImage.tslibs/ui-components/src/components/Device/EditDeviceWizard/utils.tslibs/ui-components/src/components/DynamicForm/DynamicForm.tsxlibs/ui-components/src/components/DynamicForm/FieldTemplate.tsxlibs/ui-components/src/components/DynamicForm/VolumeImageField.tsxlibs/ui-components/src/components/Events/useEvents.tslibs/ui-components/src/components/Fleet/CreateFleet/CreateFleetWizard.tsxlibs/ui-components/src/components/Fleet/CreateFleet/steps/ReviewStep.tsxlibs/ui-components/src/components/Fleet/CreateFleet/utils.tslibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsCatalog.tsxlibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsContent.tsxlibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsPage.tsxlibs/ui-components/src/components/Fleet/FleetRow.tsxlibs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/NewVersionImageBuildWizard.tsxlibs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.tslibs/ui-components/src/components/ImagePromotion/ImagePromotionForm.tsxlibs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsxlibs/ui-components/src/components/common/LabelsView.tsxlibs/ui-components/src/components/form/ApplicationPortMappingField.tsxlibs/ui-components/src/components/form/ImageOrCatalogRefField.tsxlibs/ui-components/src/components/form/LabelsField.tsxlibs/ui-components/src/components/form/validations.tslibs/ui-components/src/hooks/useAppLinks.tslibs/ui-components/src/types/deviceSpec.tslibs/ui-components/src/utils/catalog.tslibs/ui-components/src/utils/volumes.ts
💤 Files with no reviewable changes (4)
- libs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.css
- libs/ui-components/src/components/Catalog/utils.ts
- libs/ui-components/src/components/Catalog/const.ts
- libs/ui-components/src/components/form/LabelsField.tsx
2041661 to
06b31a7
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx (1)
65-78: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winShow the catalog lookup error before initializing the form.
If the parent promotion has a catalog reference and its lookup fails,
useCatalogItemsLookupclearscatalogItemLoadingand returns no item. Line 78 then callsgetInitialValues(undefined). The modal opens with fallback values instead of preserving or reporting the failed parent reference.Read and display the lookup error. Keep the form blocked while a requested catalog item is unresolved. Do not initialize parent-promotion values without the referenced item.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx` around lines 65 - 78, Update ImagePromotionModal around useCatalogItemsLookup, getItem, and the parentPromotion initialization path to read and display the catalog lookup error before initializing the form. Keep the modal blocked while a requested catalog item is loading or unresolved, surface the lookup failure when present, and do not call parent-promotion initial-value logic unless the referenced catalog item exists.
♻️ Duplicate comments (4)
libs/ui-components/src/components/Catalog/DeleteCatalogModal.tsx (1)
127-143: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftPaginate the catalog item request before deletion.
loadCatalogItemssends nolimitand ignoresmetadata.continuein the response. The list endpoint returns paginated results, so only the first page is loaded.deleteCatalogItemsthen deletes only that page, returnstrue, anddeleteCatalogAndItemsremoves the catalog while unmapped items remain on the server. The user sees success and the failure table stays empty.
useCatalogItems.tsalready implements the paging pattern in this codebase. Set alimit, accumulate each page, and followmetadata.continueuntil it is absent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/DeleteCatalogModal.tsx` around lines 127 - 143, Update loadCatalogItems to paginate catalog item requests like the existing useCatalogItems.ts pattern: set a page limit, accumulate items across responses, and continue requesting pages using metadata.continue until absent. Map the complete accumulated collection into catalogItems so deleteCatalogItems processes every item before catalog deletion.libs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/TypeConfigStep.tsx (1)
127-130: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueType the
reduceaccumulator and rename the shadowing callback parameter.The
{}accumulator permits an implicitanyindex write. The callback parameterartifactalso shadows the outervalues.artifacts.map((artifact, index) => ...)parameter at Line 116, which makes the block harder to read and easy to break during future edits.♻️ Proposed fix
- items={artifactTypes.reduce((acc, artifact) => { - acc[artifact.type] = getArtifactLabel(t, artifact); + items={artifactTypes.reduce<Record<string, string>>((acc, artifactType) => { + acc[artifactType.type] = getArtifactLabel(t, artifactType); return acc; - }, {})} + }, {})}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/TypeConfigStep.tsx` around lines 127 - 130, Update the reduce call in TypeConfigStep so its accumulator is explicitly typed as the string-label mapping expected by items, eliminating the implicit-any index write. Rename the reduce callback parameter from artifact to a distinct name, and update its references without changing the surrounding values.artifacts mapping.libs/ui-components/src/components/Catalog/InstalledSoftware.tsx (1)
45-47: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winShow the error detail in the failure Alert.
The Alert has a title but no body. The user sees no cause and cannot act. Sibling catalog components render
getErrorMessage(error)inside the Alert.♻️ Proposed fix
if (error) { - return <Alert isInline variant="danger" title={t('Failed to load installed software')} />; + return ( + <Alert isInline variant="danger" title={t('Failed to load installed software')}> + {getErrorMessage(error)} + </Alert> + ); }Add the import:
import { getErrorMessage } from '../../utils/error';🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/InstalledSoftware.tsx` around lines 45 - 47, Update InstalledSoftware’s failure Alert to include the underlying error text instead of only the title. Import and reuse getErrorMessage in InstalledSoftware.tsx, and render its result inside the existing Alert body when the error branch is hit so the user sees the cause, matching the pattern used by sibling catalog components.libs/ui-components/src/components/Catalog/CatalogPage.tsx (1)
449-454: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRemove only the deleted catalog from the filter.
catalogFilter.setCatalogs([])clears every selected catalog. If a user selects catalogs A and B and deletes A, the selection for B is also lost and the item list silently widens.setCatalogsaccepts an updater in this file (Lines 275-277), so a targeted removal is available.♻️ Proposed fix
onDeleteSuccess={() => { + const deletedId = catalogToDelete.metadata.name || ''; setCatalogToDelete(undefined); - catalogFilter.setCatalogs([]); + catalogFilter.setCatalogs((catalogs) => catalogs.filter((c) => c !== deletedId)); refetchCatalogs(); refetch(); }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/ui-components/src/components/Catalog/CatalogPage.tsx` around lines 449 - 454, Update the onDeleteSuccess handler in CatalogPage so deleting one catalog only removes that catalog from the current selection instead of clearing all selections. Replace the blanket catalogFilter.setCatalogs([]) call with the updater form already used in this file for setCatalogs, filtering out the deleted catalog while preserving any other selected catalogs before refetchCatalogs() and refetch() run.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/ui-components/src/components/Catalog/CatalogItemsContext.tsx`:
- Around line 24-36: Remove the local toFetchIds deduplication in
CatalogItemsProvider and reuse an exported helper from catalog.ts that performs
the shared catalog-item cache-key deduplication. Update the provider’s memoized
ids calculation to call that helper, while preserving the existing extraction
and fetch behavior.
In `@libs/ui-components/src/components/Catalog/CatalogItemTitle.tsx`:
- Line 104: Update the image alt text in CatalogItemTitle to use the t()
translation function with a hardcoded interpolation key, passing
item.metadata.name or an empty string as the name value so missing metadata does
not produce “undefined icon.”
In `@libs/ui-components/src/components/Catalog/InstalledSoftware.tsx`:
- Around line 66-93: Model SpecCatalogItemId in catalog.ts as a discriminated
union on type, requiring appName for app variants, then remove the type
assertions at InstalledSoftware.tsx lines 66-93 by using the narrowed appName
for the fragment key and resourceName, and at ResourceCatalogPage.tsx lines
44-58 by passing the narrowed appName to getRemoveAppPatches; do not add
fallback ref formatting once the type change is applied.
In `@libs/ui-components/src/components/Catalog/InstalledSoftwareItem.tsx`:
- Line 3: Update the import containing ActionsColumn and IAction so IAction is
imported type-only while ActionsColumn remains a runtime import, preserving
their existing usage in the component.
In
`@libs/ui-components/src/components/Catalog/InstallWizard/InstallAppWizard.tsx`:
- Line 80: Thread the no-op result from the empty allPatches path through
InstallAppWizardContentProps and the InstallAppWizard content flow, replacing
the hardcoded isSpecUnchanged={false} on UpdateSuccessPage with the tracked
value. Match the existing propagation pattern used by InstallOsWizard and
EditWizard so UpdateSuccessPageContent displays the no-op state when no patch is
submitted.
In `@libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx`:
- Around line 230-235: Synchronize the no-op flag with the authoritative
submit-time result: in
libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx#L230-L235,
set isSpecUnchanged from allPatches.length === 0 using the Formik helpers in
onSubmit before setIsSuccessful(true) in both branches; in
libs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsx#L323-L333,
recompute the flag whenever values.device, values.fleet, values.version, or
values.channel changes rather than only in the row-select handler, so the footer
and success page reflect the actual flow result.
In
`@libs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsx`:
- Around line 28-38: Update both isOsUpdate call sites in the ReviewStep
component to pass values.channel as the channel argument, and extend isOsUpdate
to compare the referenced channel with that value. Ensure same-item changes to
version or channel render the “Version update” alert instead of the OS
replacement alert.
In `@libs/ui-components/src/components/Catalog/useCatalogItems.ts`:
- Around line 45-55: Update isInvalidSelection in the catalog query-building
logic to account for the category constraint already produced by the preceding
category-filter handling. Append !spec.type only when the excluded type is the
sole remaining type and no category constraint was generated; otherwise preserve
the category-filtered query so combinations such as all application types plus
an excluded OS type return application items.
In `@libs/ui-components/src/components/Device/DeviceDetails/DeviceOs.tsx`:
- Around line 34-41: Replace the repeated optional property access and type
assertion with a local catalogItemRef in DeviceOs.tsx at lines 34-41; derive
hasCatalogRef from it and pass it directly to formatCatalogItemRef. Apply the
same change in SystemImageDescriptionGroup.tsx at lines 59-65: derive
isCatalogItemRef from catalogItemRef and format that narrowed value directly,
preserving the existing behavior.
---
Outside diff comments:
In `@libs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsx`:
- Around line 65-78: Update ImagePromotionModal around useCatalogItemsLookup,
getItem, and the parentPromotion initialization path to read and display the
catalog lookup error before initializing the form. Keep the modal blocked while
a requested catalog item is loading or unresolved, surface the lookup failure
when present, and do not call parent-promotion initial-value logic unless the
referenced catalog item exists.
---
Duplicate comments:
In
`@libs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/TypeConfigStep.tsx`:
- Around line 127-130: Update the reduce call in TypeConfigStep so its
accumulator is explicitly typed as the string-label mapping expected by items,
eliminating the implicit-any index write. Rename the reduce callback parameter
from artifact to a distinct name, and update its references without changing the
surrounding values.artifacts mapping.
In `@libs/ui-components/src/components/Catalog/CatalogPage.tsx`:
- Around line 449-454: Update the onDeleteSuccess handler in CatalogPage so
deleting one catalog only removes that catalog from the current selection
instead of clearing all selections. Replace the blanket
catalogFilter.setCatalogs([]) call with the updater form already used in this
file for setCatalogs, filtering out the deleted catalog while preserving any
other selected catalogs before refetchCatalogs() and refetch() run.
In `@libs/ui-components/src/components/Catalog/DeleteCatalogModal.tsx`:
- Around line 127-143: Update loadCatalogItems to paginate catalog item requests
like the existing useCatalogItems.ts pattern: set a page limit, accumulate items
across responses, and continue requesting pages using metadata.continue until
absent. Map the complete accumulated collection into catalogItems so
deleteCatalogItems processes every item before catalog deletion.
In `@libs/ui-components/src/components/Catalog/InstalledSoftware.tsx`:
- Around line 45-47: Update InstalledSoftware’s failure Alert to include the
underlying error text instead of only the title. Import and reuse
getErrorMessage in InstalledSoftware.tsx, and render its result inside the
existing Alert body when the error branch is hit so the user sees the cause,
matching the pattern used by sibling catalog components.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 7b661e03-c021-4bee-bf29-74c87f419f5c
⛔ Files ignored due to path filters (15)
libs/i18n/locales/en/translation.jsonis excluded by!libs/i18n/locales/en/translation.jsonlibs/types/alpha/models/CatalogItemDeployment.tsis excluded by!libs/types/alpha/models/**libs/types/alpha/models/CatalogItemDeploymentList.tsis excluded by!libs/types/alpha/models/**libs/types/models/CatalogItemRefApplicationProviderSpec.tsis excluded by!libs/types/models/**libs/types/models/CatalogItemRefSpec.tsis excluded by!libs/types/models/**libs/types/models/ComposeApplication.tsis excluded by!libs/types/models/**libs/types/models/ContainerApplication.tsis excluded by!libs/types/models/**libs/types/models/DeviceOsSpec.tsis excluded by!libs/types/models/**libs/types/models/Event.tsis excluded by!libs/types/models/**libs/types/models/HelmApplication.tsis excluded by!libs/types/models/**libs/types/models/ImageApplicationProviderSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageOrCatalogItemRefSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageSpec.tsis excluded by!libs/types/models/**libs/types/models/ImageVolumeSource.tsis excluded by!libs/types/models/**libs/types/models/QuadletApplication.tsis excluded by!libs/types/models/**
📒 Files selected for processing (78)
libs/types/alpha/index.tslibs/types/index.tslibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/ReviewStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/TypeConfigStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/steps/VersionStep.tsxlibs/ui-components/src/components/Catalog/AddCatalogItemWizard/utils.tslibs/ui-components/src/components/Catalog/CatalogItemCard.tsxlibs/ui-components/src/components/Catalog/CatalogItemDetails.tsxlibs/ui-components/src/components/Catalog/CatalogItemTitle.tsxlibs/ui-components/src/components/Catalog/CatalogItemsContext.tsxlibs/ui-components/src/components/Catalog/CatalogPage.tsxlibs/ui-components/src/components/Catalog/DeleteCatalogModal.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditOsWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/EditWizard.tsxlibs/ui-components/src/components/Catalog/EditWizard/steps/UpdateStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallAppWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/InstallWizard.tsxlibs/ui-components/src/components/Catalog/InstallWizard/UpdateSuccessPage.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/AppConfigStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/ReviewStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/SelectTargetStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/steps/SpecificationsStep.tsxlibs/ui-components/src/components/Catalog/InstallWizard/types.tslibs/ui-components/src/components/Catalog/InstallWizard/utils.tslibs/ui-components/src/components/Catalog/InstalledSoftware.tsxlibs/ui-components/src/components/Catalog/InstalledSoftwareItem.tsxlibs/ui-components/src/components/Catalog/ResourceCatalog/ResourceCatalogPage.tsxlibs/ui-components/src/components/Catalog/const.tslibs/ui-components/src/components/Catalog/specCatalogItems.tslibs/ui-components/src/components/Catalog/useCatalogItems.tslibs/ui-components/src/components/Catalog/useCatalogItemsLookup.tslibs/ui-components/src/components/Catalog/useResolvedCatalogRef.tslibs/ui-components/src/components/Catalog/utils.tslibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsCatalog.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceDetailsTabContent/ConfigurationsContent.tsxlibs/ui-components/src/components/Device/DeviceDetails/DeviceOs.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/EditDeviceWizard.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/SystemImageDescriptionGroup.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.tslibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.csslibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/DeviceTemplateStep.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ReviewApplications.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/steps/ReviewDeviceStep.tsxlibs/ui-components/src/components/Device/EditDeviceWizard/useSystemImage.tslibs/ui-components/src/components/Device/EditDeviceWizard/utils.tslibs/ui-components/src/components/DynamicForm/DynamicForm.tsxlibs/ui-components/src/components/DynamicForm/FieldTemplate.tsxlibs/ui-components/src/components/DynamicForm/VolumeImageField.tsxlibs/ui-components/src/components/Events/useEvents.tslibs/ui-components/src/components/Fleet/CreateFleet/CreateFleetWizard.tsxlibs/ui-components/src/components/Fleet/CreateFleet/steps/ReviewStep.tsxlibs/ui-components/src/components/Fleet/CreateFleet/utils.tslibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsCatalog.tsxlibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsContent.tsxlibs/ui-components/src/components/Fleet/FleetDetails/FleetDetailsPage.tsxlibs/ui-components/src/components/Fleet/FleetRow.tsxlibs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/NewVersionImageBuildWizard.tsxlibs/ui-components/src/components/ImageBuilds/NewVersionImageBuildWizard/utils.tslibs/ui-components/src/components/ImagePromotion/ImagePromotionForm.tsxlibs/ui-components/src/components/ImagePromotion/ImagePromotionModal.tsxlibs/ui-components/src/components/common/LabelsView.tsxlibs/ui-components/src/components/form/ApplicationPortMappingField.tsxlibs/ui-components/src/components/form/ImageOrCatalogRefField.tsxlibs/ui-components/src/components/form/LabelsField.tsxlibs/ui-components/src/components/form/validations.tslibs/ui-components/src/hooks/useAppLinks.tslibs/ui-components/src/types/deviceSpec.tslibs/ui-components/src/utils/catalog.tslibs/ui-components/src/utils/volumes.ts
💤 Files with no reviewable changes (4)
- libs/ui-components/src/components/Catalog/const.ts
- libs/ui-components/src/components/Catalog/utils.ts
- libs/ui-components/src/components/form/LabelsField.tsx
- libs/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.css
Deployment of catalog items is no longer controlled by defining labels in a fleet/device, but rather by updating the spec to include a
catalogItemReffor the specific catalog item.Summary
catalogItemRefvalues instead of fleet or device labels.libs/types/andlibs/types/alpha/.Area impact
libs/ui-components/: Major shared UI and data-model changes. This affects catalog management, device configuration, fleet configuration, image promotion, and deployment workflows.libs/types/: Added public catalog reference and deployment types.libs/i18n/: No changes reported.libs/cypress/: No changes reported.apps/standalone/: No direct changes reported.apps/ocp-plugin/: No direct changes reported.proxy/: No changes reported.packaging/: No changes reported..github/workflows/: No changes reported.Cross-cutting implications
Shared UI changes can affect both standalone and OCP plugin consumers. OS, application, and volume specifications now retain explicit catalog references. Label-based deployment behavior is removed.
Unresolved catalog references remain visible and deletable. Editing is disabled for unresolved references. External documentation links are restricted to HTTP(S) URLs before opening in a new tab.
The changes do not affect the Go authentication proxy, container builds, E2E tests, or CI configuration.