Skip to content

OSAC-2936: add catalog item create wizard for Cluster, VM, and Bare Metal - #102

Open
ElayAharoni wants to merge 33 commits into
osac-project:mainfrom
ElayAharoni:OSAC-2936-catalog-item-create-wizard
Open

OSAC-2936: add catalog item create wizard for Cluster, VM, and Bare Metal#102
ElayAharoni wants to merge 33 commits into
osac-project:mainfrom
ElayAharoni:OSAC-2936-catalog-item-create-wizard

Conversation

@ElayAharoni

@ElayAharoni ElayAharoni commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

OSAC-2936: Shared wizard components and CSP Admin create wizard

Jira: https://redhat.atlassian.net/browse/OSAC-2936
Story type: [UI]

Summary

Adds the catalog item create wizard at /admin/catalog/:type/create for CSP Admin and Tenant Admin: kind-specific wizards for Cluster (4 steps), VM (3 steps), and Bare Metal (3 steps), built from four shared field-definition authoring primitives (String/Number/Boolean/ResourceSelector) plus a Cluster-only NodeSetsFieldEditor, a shared General-info step, and role-aware data/create hooks for templates and catalog items.

Branches off main (not the still-open OSAC-2932 branch) since there's no formal Jira dependency between the two stories — see the Notes section below for the small number of places this creates temporary divergence from OSAC-2932's in-flight conventions.

Changes

Shared field-definition system

  • StringFieldDefinition, NumberFieldDefinition, BooleanFieldDefinition, ResourceSelectorFieldDefinition — the four primitives every Configuration/Networking/Access field is built from
  • NodeSetsFieldEditor — Cluster-only node_sets map editor (add/remove rows, host-type de-dup, admin editable/allow-add-remove/size-constraint controls)
  • fieldDefinitionValue.tsFieldDefinitionValue<T>, buildFieldDefinition(), fieldDefinitionValueSchema() (shared "default required when non-editable" Yup rule)
  • plainToProtobufValue() — write-direction counterpart to the existing protobufValueToPlain()
  • SwitchField — new shared Formik-bound PatternFly Switch

Shared General step

  • CatalogItemGeneralFields — Name (title), Description, Template dropdown, role-branched Scope (CSP Admin: General/Organization; Tenant Admin: Organization/Project)

Per-kind step components

  • Cluster: ClusterConfigurationStep, ClusterNetworkingStep, ClusterAccessStep
  • VM: VMConfigurationStep (incl. an additional-disks add/remove editor), VMAccessStep
  • Bare Metal: BMConfigurationStep, BMAccessStep

API hooks

  • Template list hooks for all three kinds (useClusterTemplates, useComputeInstanceTemplates, useBareMetalInstanceTemplates) plus role-aware useAdmin*Templates variants
  • useProjects() (new)
  • Role-aware useCreate*CatalogItem() mutations for all three kinds
  • Exported BareMetalInstanceTemplates, Project, Projects from the public @osac/types barrel — these existed on disk (generated from proto) but were never wired in

Wizard pages and routing

  • ClusterCatalogItemCreatePage, ComputeInstanceCatalogItemCreatePage, BareMetalInstanceCatalogItemCreatePage — each wires Formik, step-scoped Yup validation, the create payload, and navigation
  • AdminCatalogRoutes.tsx:type/create now dispatches to the correct kind-specific page (was a placeholder <div/>)

Testing

  • Unit tests: 98 new tests across 28 files — every new component, hook, and utility has direct behavioral coverage (primitives, NodeSetsFieldEditor, CatalogItemGeneralFields for both roles, all per-kind steps, all API hooks including role-based client selection, slugify(), the three wizard pages, and the routing dispatcher)
  • Integration tests: N/A — this repo has no E2E layer (tracked separately in osac-test-infra, OSAC-2943)
  • Coverage: Qualitatively comprehensive; no numeric coverage gate configured in this repo's CI

Acceptance Criteria

  • The create page is a kind-specific PatternFly Wizard accessible at /admin/catalog/:type/create
  • Wizard steps mirror the provisioning wizard: General → Configuration → [Networking for clusters] → Access
  • Step 1 (General): Name (required), Description (optional), Template (dropdown), and role-dependent Scope
  • Step 2 (Configuration): per-kind step component with shared field definition primitives; Cluster includes NodeSetsFieldEditor
  • Step 3 (Networking — clusters only): ClusterNetworkingStep with pod_cidr/service_cidr; not shown for VM or Bare Metal
  • Step 4 (Access): per-kind access step with ssh_public_key/ssh_key and pull_secret, default editable
  • VM catalog items auto-include network_attachments in the API payload (not shown in wizard); Bare Metal has no networking fields
  • The wizard validates required fields with Yup at each step transition and on final submit
  • On submit, a POST is sent to the kind-specific catalog item endpoint with published: false by default
  • Kind-specific create pages exist for Cluster (4 steps), VM (3 steps), and Bare Metal (3 steps)
  • Tenant Admin uses the same wizard — scope selector shows Organization or Project options
  • All user-visible strings are defined as i18next translation keys

Notes for reviewers

  • Scope also delivered here, ahead of OSAC-2937: OSAC-2936's own acceptance criteria require the shared field-definition primitives and NodeSetsFieldEditor, so this PR builds them in full rather than deferring to OSAC-2937 ("Shared field definition primitives and per-kind step components"). Recommend re-triaging OSAC-2937's remaining scope once this merges.
  • node_sets.allowAddRemove is captured in the UI/Formik state but not sent in the create payload — the real FieldDefinition proto message has no field for it (the design doc's own JSON example includes a key that doesn't exist on the wire type). Flagging for the design/API owner.
  • image (VM) and run_strategy (VM, Bare Metal) are plain StringFieldDefinition (free text) rather than the design's resource-picker/enum widgets — no images-list API exists in this codebase, and the shared primitives don't yet support enum constraints.
  • Post-create navigation goes to the list page (/admin/catalog), not the detail page the design doc describes — that route is still a placeholder, tracked under the OSAC-2929 epic.
  • Template selection does not yet trigger reactive pre-population of field defaults — described in the design doc, but not required by this story's Jira ACs; left as a follow-up.
  • If OSAC-2932 merges before this PR, worth a follow-up pass to adopt its CatalogItemScopeBadge/CatalogItemStatusLabel/CatalogItemPublishToggle conventions where they overlap.

Assisted-by: Claude Code noreply@anthropic.com

Summary by CodeRabbit

  • New Features
    • Added admin catalog create routing and multi-step wizards for cluster, virtual machine, and bare metal items.
    • Introduced role-aware API hooks and new catalog management form components, including reusable wizard footer controls.
    • Added tenant support in wizards, plus new template/resource selection and node-set editing.
    • Added DNS-safe slug generation and protobuf value conversion helpers.
  • Bug Fixes
    • Unknown catalog create types now redirect back to the catalog page.
  • Tests
    • Expanded UI and hook test coverage for wizards, routing, role-based behavior, field editors, and CIDR validation.
  • General step:
image image image

Cluster catalog creation:

  • Configurations:
image

nodeSets:
image

  • Networking:
image
  • Access:
image

VM catalog creation:

  • Configurations:
image image image
  • Access:
image

BM catalog creation:

  • Configurations:
image
  • Access:
image

@openshift-ci-robot

openshift-ci-robot commented Jul 27, 2026

Copy link
Copy Markdown

@ElayAharoni: This pull request references OSAC-2936 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

OSAC-2936: Shared wizard components and CSP Admin create wizard

Jira: https://redhat.atlassian.net/browse/OSAC-2936
Story type: [UI]

Summary

Adds the catalog item create wizard at /admin/catalog/:type/create for CSP Admin and Tenant Admin: kind-specific wizards for Cluster (4 steps), VM (3 steps), and Bare Metal (3 steps), built from four shared field-definition authoring primitives (String/Number/Boolean/ResourceSelector) plus a Cluster-only NodeSetsFieldEditor, a shared General-info step, and role-aware data/create hooks for templates and catalog items.

Branches off main (not the still-open OSAC-2932 branch) since there's no formal Jira dependency between the two stories — see the Notes section below for the small number of places this creates temporary divergence from OSAC-2932's in-flight conventions.

Changes

Shared field-definition system

  • StringFieldDefinition, NumberFieldDefinition, BooleanFieldDefinition, ResourceSelectorFieldDefinition — the four primitives every Configuration/Networking/Access field is built from
  • NodeSetsFieldEditor — Cluster-only node_sets map editor (add/remove rows, host-type de-dup, admin editable/allow-add-remove/size-constraint controls)
  • fieldDefinitionValue.tsFieldDefinitionValue<T>, buildFieldDefinition(), fieldDefinitionValueSchema() (shared "default required when non-editable" Yup rule)
  • plainToProtobufValue() — write-direction counterpart to the existing protobufValueToPlain()
  • SwitchField — new shared Formik-bound PatternFly Switch

Shared General step

  • CatalogItemGeneralFields — Name (title), Description, Template dropdown, role-branched Scope (CSP Admin: General/Organization; Tenant Admin: Organization/Project)

Per-kind step components

  • Cluster: ClusterConfigurationStep, ClusterNetworkingStep, ClusterAccessStep
  • VM: VMConfigurationStep (incl. an additional-disks add/remove editor), VMAccessStep
  • Bare Metal: BMConfigurationStep, BMAccessStep

API hooks

  • Template list hooks for all three kinds (useClusterTemplates, useComputeInstanceTemplates, useBareMetalInstanceTemplates) plus role-aware useAdmin*Templates variants
  • useProjects() (new)
  • Role-aware useCreate*CatalogItem() mutations for all three kinds
  • Exported BareMetalInstanceTemplates, Project, Projects from the public @osac/types barrel — these existed on disk (generated from proto) but were never wired in

Wizard pages and routing

  • ClusterCatalogItemCreatePage, ComputeInstanceCatalogItemCreatePage, BareMetalInstanceCatalogItemCreatePage — each wires Formik, step-scoped Yup validation, the create payload, and navigation
  • AdminCatalogRoutes.tsx:type/create now dispatches to the correct kind-specific page (was a placeholder <div/>)

Testing

  • Unit tests: 98 new tests across 28 files — every new component, hook, and utility has direct behavioral coverage (primitives, NodeSetsFieldEditor, CatalogItemGeneralFields for both roles, all per-kind steps, all API hooks including role-based client selection, slugify(), the three wizard pages, and the routing dispatcher)
  • Integration tests: N/A — this repo has no E2E layer (tracked separately in osac-test-infra, OSAC-2943)
  • Coverage: Qualitatively comprehensive; no numeric coverage gate configured in this repo's CI

Acceptance Criteria

  • The create page is a kind-specific PatternFly Wizard accessible at /admin/catalog/:type/create
  • Wizard steps mirror the provisioning wizard: General → Configuration → [Networking for clusters] → Access
  • Step 1 (General): Name (required), Description (optional), Template (dropdown), and role-dependent Scope
  • Step 2 (Configuration): per-kind step component with shared field definition primitives; Cluster includes NodeSetsFieldEditor
  • Step 3 (Networking — clusters only): ClusterNetworkingStep with pod_cidr/service_cidr; not shown for VM or Bare Metal
  • Step 4 (Access): per-kind access step with ssh_public_key/ssh_key and pull_secret, default editable
  • VM catalog items auto-include network_attachments in the API payload (not shown in wizard); Bare Metal has no networking fields
  • The wizard validates required fields with Yup at each step transition and on final submit
  • On submit, a POST is sent to the kind-specific catalog item endpoint with published: false by default
  • Kind-specific create pages exist for Cluster (4 steps), VM (3 steps), and Bare Metal (3 steps)
  • Tenant Admin uses the same wizard — scope selector shows Organization or Project options
  • All user-visible strings are defined as i18next translation keys

Notes for reviewers

  • Scope also delivered here, ahead of OSAC-2937: OSAC-2936's own acceptance criteria require the shared field-definition primitives and NodeSetsFieldEditor, so this PR builds them in full rather than deferring to OSAC-2937 ("Shared field definition primitives and per-kind step components"). Recommend re-triaging OSAC-2937's remaining scope once this merges.
  • node_sets.allowAddRemove is captured in the UI/Formik state but not sent in the create payload — the real FieldDefinition proto message has no field for it (the design doc's own JSON example includes a key that doesn't exist on the wire type). Flagging for the design/API owner.
  • image (VM) and run_strategy (VM, Bare Metal) are plain StringFieldDefinition (free text) rather than the design's resource-picker/enum widgets — no images-list API exists in this codebase, and the shared primitives don't yet support enum constraints.
  • Post-create navigation goes to the list page (/admin/catalog), not the detail page the design doc describes — that route is still a placeholder, tracked under the OSAC-2929 epic.
  • Template selection does not yet trigger reactive pre-population of field defaults — described in the design doc, but not required by this story's Jira ACs; left as a follow-up.
  • If OSAC-2932 merges before this PR, worth a follow-up pass to adopt its CatalogItemScopeBadge/CatalogItemStatusLabel/CatalogItemPublishToggle conventions where they overlap.

Assisted-by: Claude Code noreply@anthropic.com

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci

openshift-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ElayAharoni

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds routed catalog creation wizards for cluster, compute instance, and bare metal items, with role-aware API hooks, Formik field editors, validation, protobuf serialization, transport registry wiring, translations, and tests.

Changes

Catalog creation flow

Layer / File(s) Summary
Create route dispatch
apps/app-frontend/src/shell/AdminCatalogRoutes.tsx, apps/app-frontend/src/shell/AdminCatalogRoutes.test.tsx
Maps catalog type routes to the corresponding create page and redirects unknown types to the catalog list.
Role-aware API hooks
libs/ui-components/src/api/v1/*, libs/ui-components/src/api/types.ts, libs/types/src/index.ts
Adds public/private template, project, tenant, and catalog-item hooks with role-based service selection, route types, generated exports, and tests.
Form and field-definition components
libs/ui-components/src/components/Form/*, libs/ui-components/src/components/catalogManagement/*
Adds Formik-bound controls, scope handling, field-definition editors, conditional validation, and dynamic node-set/disk editing.
Wizard steps and pages
libs/ui-components/src/components/catalogManagement/steps/*, libs/ui-components/src/pages/admin/*
Adds wizard steps and cluster, compute-instance, and bare-metal creation pages with validation, payload construction, submission handling, and navigation.
Value conversion and validation
libs/ui-components/src/components/catalogProvision/*, libs/ui-components/src/utils/*, libs/ui-components/src/validation/*
Adds protobuf value encoding, DNS-compatible slug generation, IPv4 CIDR pattern validation, and associated tests.
Transport registry and localization
apps/app-frontend/src/wellKnownTypeRegistry.ts, apps/app-frontend/src/main.tsx, libs/i18n/locales/en/translation.json
Registers well-known protobuf schemas for transport decoding and adds English labels, prompts, and validation messages for catalog wizards.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: lgtm

Suggested reviewers: batzionb

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed Exact-pattern scan of all changed files found 0 sensitive-var or embedded-URL matches; no hardcoded secrets or credential literals were added.
No-Weak-Crypto ✅ Passed No weak algorithms or custom crypto found; the only crypto use is crypto.randomUUID() for non-secret IDs/slug suffixes.
No-Injection-Vectors ✅ Passed Searched the touched app/libs trees and found no dangerouslySetInnerHTML, eval/exec, shell=True, yaml.load, os.system, pickle.loads, or SQL string-concat sinks; inputs are only validated/serialized.
Container-Privileges ✅ Passed HEAD changes only TS files; no manifest-like files changed and no privileged/hostNetwork/hostIPC/allowPrivilegeEscalation/SYS_ADMIN settings were found.
No-Sensitive-Data-In-Logs ✅ Passed No new console/logger calls appear in the PR’s touched files; submit failures only surface via inline alerts, not logs.
Ai-Attribution ✅ Passed Current commit includes an Assisted-by trailer for Claude Code, and no Co-Authored-By AI attribution was found.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding create wizards for Cluster, VM, and Bare Metal catalog items.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@ElayAharoni
ElayAharoni marked this pull request as ready for review July 27, 2026 05:39
@openshift-ci
openshift-ci Bot requested review from jhernand and rawagner July 27, 2026 05:39
@ElayAharoni
ElayAharoni requested review from batzionb and removed request for jhernand July 27, 2026 05:39

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

🤖 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 `@apps/app-frontend/src/shell/AdminCatalogRoutes.test.tsx`:
- Around line 1-5: Update the test module’s React imports and the ListPage props
typing: import ReactNode from react, then replace the React.ReactNode reference
in ListPage with the imported ReactNode type.

In `@libs/ui-components/src/api/v1/baremetal-instance-templates.test.ts`:
- Around line 19-41: Extract the duplicated hook test harnesses into
libs/ui-components/src/api/v1/test-utils.tsx, exporting the list/admin
renderWithTransport variant with optional role and the mutation variant with
required role. In
libs/ui-components/src/api/v1/baremetal-instance-templates.test.ts (lines
19-41), cluster-templates.test.ts (lines 16-38), and
compute-instance-templates.test.ts (lines 19-41), remove local harnesses and
import the shared list/admin helper; do the same with the mutation helper in
baremetal-instance.test.ts (lines 16-38), cluster-catalog-item.test.ts (lines
16-38), and compute-instance-catalog-item.test.ts (lines 16-38). Replace the
inline wrapper in projects.test.ts (lines 19-25) with the shared no-role helper.

In
`@libs/ui-components/src/components/catalogManagement/CatalogItemGeneralFields.tsx`:
- Around line 26-35: Normalize the initial scope level for non-providerAdmin
roles so it matches an available option: update the wizard pages’ scope.level
initialization or the scopeOptions handling in CatalogItemGeneralFields to use
organization instead of general when general is not offered. Preserve general
for providerAdmin and ensure the radio group always has a selected valid scope.

In
`@libs/ui-components/src/components/catalogManagement/fieldDefinitions/BooleanFieldDefinition.tsx`:
- Around line 12-32: Create a shared field-definition wrapper for the repeated
FormFieldGroup/FormFieldGroupHeader layout, fieldDefinitions.${path} naming, and
Editable SwitchField, accepting label, fieldId, path, and children. Update
BooleanFieldDefinition.tsx lines 12-32 to use it with only the boolean default
SwitchField as children, and update ResourceSelectorFieldDefinition.tsx lines
15-44 to use it with only the SelectField as children; preserve each field’s
existing labels and field names.

In
`@libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx`:
- Around line 51-60: Update NodeSetsFieldEditor to consume the error state
returned by useHostTypes, display an appropriate error message when the
host-types query fails, and prevent the “Add node set” action while the fetch is
unsuccessful. Preserve the existing loading and successful-data behavior.
- Around line 37-43: Update NodeSetsFormValues to reuse the exported
NodeSetsFieldValue for fieldDefinitions.node_sets instead of defining a narrower
inline object type. Preserve the existing Formik field paths while ensuring
editable, allowAddRemove, sizeMin, sizeMax, and entries remain fully typed.
- Around line 122-131: Update the remove button rendered in the node-set row
actions to generate a unique aria-label for each row, incorporating its
row-specific identifier such as rowIndex or the node set name, while preserving
the existing conditional rendering and removeRow(rowIndex) behavior.

In `@libs/ui-components/src/components/catalogProvision/protobuf-value.test.ts`:
- Around line 37-51: Add a composite round-trip case to the
“plainToProtobufValue / protobufValueToPlain round trip” tests that nests arrays
and objects together, such as an object containing an array of objects, and
assert the converted result equals the original value.

In
`@libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.tsx`:
- Around line 216-233: Update the payload construction in the
createBareMetalInstanceCatalogItem flow to assign the object literal to a typed
MessageInitShape variable before calling the function, removing the blanket
Parameters<typeof createBareMetalInstanceCatalogItem>[0] assertion. Let
TypeScript validate fields such as template, tenant, and metadata.project, and
retain only a narrowly scoped cast for any individual property that genuinely
requires it.
- Around line 149-165: The handleNextOrSubmit flow in
libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.tsx
(lines 149-165) must validate all wizard fields before submitting, using a
full-form schema composed from all three step schemas; retain the active step
schema for Next navigation. Apply the same change in
libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx
(lines 191-207) so final submission cannot bypass earlier-step validation.

In `@libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx`:
- Around line 121-124: Update the 'configuration' schema and
buildNodeSetsDefault so node_sets.entries must contain at least one row with a
non-empty hostType and positive size, and duplicate host types are rejected
rather than overwritten. Remove the silent continue/overwrite behavior in
buildNodeSetsDefault, ensuring invalid or duplicate rows produce validation
feedback and valid rows are preserved in node_sets.default.
- Around line 82-84: Update CIDR_PATTERN to validate IPv4 octets within 0–255
and the prefix length within 0–32, rather than only limiting digit counts. Keep
the existing CIDR format and SSH_PUBLIC_KEY_PATTERN unchanged.

In
`@libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.test.tsx`:
- Around line 74-85: Update the submission assertions in the create-instance
test to inspect serialized field-definition defaults, not only their paths.
Assert that a ref-backed field such as instance_type uses the expected
serialized default payload and that at least one scalar field has its expected
default value, while retaining the existing path assertion.

In
`@libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx`:
- Around line 164-231: Extract the duplicated
ComputeInstanceCatalogItemWizardFooter and
BareMetalInstanceCatalogItemWizardFooter into a generic
CatalogItemWizardFooter<TStepId> under components/catalogManagement/, preserving
their existing navigation, validation, pending-state, and submit behavior;
update both create pages to consume it. Move ScopeValues and the shared
role-based scope-to-payload mapping into a common helper, and replace both local
implementations with that helper while preserving each page’s existing behavior
and correcting any inconsistent run_strategy default casing.
- Line 129: Update the instance_type argument in buildFieldDefinition to pass
the underlying reference value (values.fieldDefinitions.instance_type.value)
rather than the full labeled resource-ref object, matching the flattening used
for values.template.value before serialization.

In `@libs/ui-components/src/utils/slug.ts`:
- Around line 4-17: Update slugify to Unicode-normalize input and remove
combining diacritic marks before generating the base slug, preserving the
existing trimming, prefixing, length, and fallback behavior. Also update the
three create-page call sites that derive metadata.name from slugify to append a
short random suffix, ensuring titles that produce the same slug remain unique.
🪄 Autofix (Beta)

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: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 965e4ed6-811a-43d4-ba27-4263b4dcc04a

📥 Commits

Reviewing files that changed from the base of the PR and between 51dccc5 and 6bd5747.

📒 Files selected for processing (59)
  • apps/app-frontend/src/shell/AdminCatalogRoutes.test.tsx
  • apps/app-frontend/src/shell/AdminCatalogRoutes.tsx
  • libs/i18n/locales/en/translation.json
  • libs/types/src/index.ts
  • libs/ui-components/src/api/types.ts
  • libs/ui-components/src/api/v1/baremetal-instance-templates.test.ts
  • libs/ui-components/src/api/v1/baremetal-instance-templates.ts
  • libs/ui-components/src/api/v1/baremetal-instance.test.ts
  • libs/ui-components/src/api/v1/baremetal-instance.ts
  • libs/ui-components/src/api/v1/cluster-catalog-item.test.ts
  • libs/ui-components/src/api/v1/cluster-catalog-item.ts
  • libs/ui-components/src/api/v1/cluster-templates.test.ts
  • libs/ui-components/src/api/v1/cluster-templates.ts
  • libs/ui-components/src/api/v1/compute-instance-catalog-item.test.ts
  • libs/ui-components/src/api/v1/compute-instance-catalog-item.ts
  • libs/ui-components/src/api/v1/compute-instance-templates.test.ts
  • libs/ui-components/src/api/v1/compute-instance-templates.ts
  • libs/ui-components/src/api/v1/projects.test.ts
  • libs/ui-components/src/api/v1/projects.ts
  • libs/ui-components/src/components/Form/SwitchField.test.tsx
  • libs/ui-components/src/components/Form/SwitchField.tsx
  • libs/ui-components/src/components/catalogManagement/CatalogItemGeneralFields.test.tsx
  • libs/ui-components/src/components/catalogManagement/CatalogItemGeneralFields.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/BooleanFieldDefinition.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/BooleanFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NumberFieldDefinition.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NumberFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/ResourceSelectorFieldDefinition.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/ResourceSelectorFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/StringFieldDefinition.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/StringFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.test.ts
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.ts
  • libs/ui-components/src/components/catalogManagement/steps/baremetal-instance/BMAccessStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/baremetal-instance/BMAccessStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/baremetal-instance/BMConfigurationStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/baremetal-instance/BMConfigurationStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterAccessStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterAccessStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterConfigurationStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterConfigurationStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterNetworkingStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterNetworkingStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/compute-instance/VMAccessStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/compute-instance/VMAccessStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/compute-instance/VMConfigurationStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/compute-instance/VMConfigurationStep.tsx
  • libs/ui-components/src/components/catalogProvision/protobuf-value.test.ts
  • libs/ui-components/src/components/catalogProvision/protobuf-value.ts
  • libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.tsx
  • libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx
  • libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx
  • libs/ui-components/src/utils/slug.test.ts
  • libs/ui-components/src/utils/slug.ts

Comment thread apps/app-frontend/src/shell/AdminCatalogRoutes.test.tsx
Comment thread libs/ui-components/src/api/v1/baremetal-instance-templates.test.ts Outdated
Comment thread libs/ui-components/src/utils/slug.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx (1)

104-108: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Persist allowAddRemove or remove this control.

This editable Formik value is not serialized into the node-set payload, so admins can change it but the submitted catalog item silently drops the setting. Serialize it before release, or hide the control until the wire contract supports it. The PR objective explicitly lists this serialization as deferred.

🤖 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/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx`
around lines 104 - 108, Update the form submission and node-set payload
serialization flow associated with NodeSetsFieldEditor and NODE_SETS_NAME so the
allowAddRemove value is persisted in the submitted catalog item; if the wire
contract cannot support it in this change, remove or hide the SwitchField
control instead.
libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.ts (1)

23-32: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Validate field-specific validation metadata before serializing it.

The shared schema checks only editable and default, while StringFieldDefinition and NumberFieldDefinition emit validation.pattern, minimum, and maximum; buildFieldDefinition then JSON-stringifies them unchanged. Invalid regexes or non-finite/inverted numeric bounds can be persisted, and pathological regexes can cause ReDoS in a downstream backtracking evaluator. Add per-kind validation, including a safe regex policy and minimum <= maximum, and enforce the same contract server-side.

Also applies to: 46-67

🤖 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/catalogManagement/fieldDefinitions/fieldDefinitionValue.ts`
around lines 23 - 32, Update buildFieldDefinition and the
StringFieldDefinition/NumberFieldDefinition validation schemas to validate
kind-specific metadata before JSON serialization: enforce a safe, compilable
regex policy for validation.pattern and finite numeric minimum/maximum values
with minimum no greater than maximum. Apply the identical validation contract
server-side wherever these field definitions are accepted, while preserving
existing editable/default validation.

Source: Path instructions

libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.test.tsx (1)

97-115: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert the serialized node_sets default, not just published/title.

fillFirstNodeSet is the only thing exercising buildNodeSetsDefault, yet nothing checks what it produced. A regression that drops the row or keys it by label instead of host-type id would still pass. Assert the node_sets field definition's default contains the small/size-3 entry. The new duplicate-host-type rule is also untested.

🤖 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/pages/admin/cluster/ClusterCatalogItemCreatePage.test.tsx`
around lines 97 - 115, Update the test around renderPage and the createFn
request assertion to inspect the serialized node_sets field definition default
produced by buildNodeSetsDefault, verifying it contains the small host-type
entry with size 3. Also add coverage for the duplicate-host-type rule by
exercising duplicate input and asserting the expected behavior.
libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx (1)

97-97: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use the correct baremetal_instance run_strategy enum value in this catalog default. BareMetalInstanceRunStrategy.ALWAYS serializes as Always, so ...default: 'ALWAYS' can create malformed bare-metal catalog items. Update this (and the matching tests) to use the canonical Always string unless the backend intentionally uses the enum text.

🤖 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/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx`
at line 97, Update the run_strategy defaults in
ComputeInstanceCatalogItemCreatePage.tsx:97 and
BareMetalInstanceCatalogItemCreatePage.tsx:79 to use the canonical serialized
value Always rather than ALWAYS. Update the matching tests to assert Always,
preserving the editable/default structure and backend enum contract.
🤖 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/catalogManagement/CatalogItemWizardFooter.tsx`:
- Around line 30-41: The isLast calculation in CatalogItemWizardFooter must not
compare activeStep.index with stepIds.length, since those values can diverge
when the wizard contains additional steps. Derive the active position using
stepIds.indexOf(activeStepId), then determine isLast from that position reaching
the final step while preserving the existing first-step behavior.
- Around line 65-75: Update the full-form validation flow around
fullFormSchema.isValid in CatalogItemWizardFooter so validation failures
populate Formik’s field errors using the schema’s validation details, rather
than only setting the generic validation alert. Ensure the user can identify and
navigate to the offending field or its owning step, while preserving the
existing submit path for valid forms.

In
`@libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.test.ts`:
- Around line 83-108: Add regression tests alongside the existing
fieldDefinitionValueSchema format tests covering malformed regex patterns,
nonnumeric minimum/maximum bounds, and configurations where minimum exceeds
maximum. Assert each invalid validation metadata configuration is rejected with
the appropriate validation error.

In `@libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx`:
- Around line 80-85: Unify the CIDR validation used by isValidCidr and the
tenant-facing validation.pattern so both accept and reject exactly the same
inputs, including rejecting leading-zero octets such as 010.0.0.0/8. Prefer
deriving the pattern from the shared validation rule; otherwise validate both
against the same fixture set before allowing an admin default to be saved.

In
`@libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx`:
- Around line 124-133: Update the configuration-step and full-form schemas in
libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx
(lines 124-133) to validate additional_disks as an array of objects whose
size_gib uses fieldDefinitionValueSchema(t). Update both corresponding schemas
in
libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.tsx
(lines 85-108) to include user_data with fieldDefinitionValueSchema(t). Keep the
existing step behavior unchanged; the longer-term schema composition refactor is
out of scope.

---

Outside diff comments:
In
`@libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.ts`:
- Around line 23-32: Update buildFieldDefinition and the
StringFieldDefinition/NumberFieldDefinition validation schemas to validate
kind-specific metadata before JSON serialization: enforce a safe, compilable
regex policy for validation.pattern and finite numeric minimum/maximum values
with minimum no greater than maximum. Apply the identical validation contract
server-side wherever these field definitions are accepted, while preserving
existing editable/default validation.

In
`@libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx`:
- Around line 104-108: Update the form submission and node-set payload
serialization flow associated with NodeSetsFieldEditor and NODE_SETS_NAME so the
allowAddRemove value is persisted in the submitted catalog item; if the wire
contract cannot support it in this change, remove or hide the SwitchField
control instead.

In
`@libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.test.tsx`:
- Around line 97-115: Update the test around renderPage and the createFn request
assertion to inspect the serialized node_sets field definition default produced
by buildNodeSetsDefault, verifying it contains the small host-type entry with
size 3. Also add coverage for the duplicate-host-type rule by exercising
duplicate input and asserting the expected behavior.

In
`@libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx`:
- Line 97: Update the run_strategy defaults in
ComputeInstanceCatalogItemCreatePage.tsx:97 and
BareMetalInstanceCatalogItemCreatePage.tsx:79 to use the canonical serialized
value Always rather than ALWAYS. Update the matching tests to assert Always,
preserving the editable/default structure and backend enum contract.
🪄 Autofix (Beta)

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: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 109c3c1e-f438-415f-b892-3eead363058c

📥 Commits

Reviewing files that changed from the base of the PR and between 6bd5747 and f8deee7.

📒 Files selected for processing (29)
  • apps/app-frontend/src/shell/AdminCatalogRoutes.test.tsx
  • libs/ui-components/src/api/v1/baremetal-instance-templates.test.ts
  • libs/ui-components/src/api/v1/baremetal-instance.test.ts
  • libs/ui-components/src/api/v1/cluster-catalog-item.test.ts
  • libs/ui-components/src/api/v1/cluster-templates.test.ts
  • libs/ui-components/src/api/v1/compute-instance-catalog-item.test.ts
  • libs/ui-components/src/api/v1/compute-instance-templates.test.ts
  • libs/ui-components/src/components/catalogManagement/CatalogItemWizardFooter.test.tsx
  • libs/ui-components/src/components/catalogManagement/CatalogItemWizardFooter.tsx
  • libs/ui-components/src/components/catalogManagement/catalogItemScope.test.ts
  • libs/ui-components/src/components/catalogManagement/catalogItemScope.ts
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/BooleanFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/FieldDefinitionGroup.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NumberFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/ResourceSelectorFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/StringFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.test.ts
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.ts
  • libs/ui-components/src/components/catalogProvision/protobuf-value.test.ts
  • libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.tsx
  • libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx
  • libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx
  • libs/ui-components/src/test-utils/renderHookWithTransport.tsx
  • libs/ui-components/src/utils/slug.test.ts
  • libs/ui-components/src/utils/slug.ts

Comment thread libs/ui-components/src/components/catalogManagement/CatalogItemWizardFooter.tsx Outdated
Comment thread libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx Outdated
@batzionb

Copy link
Copy Markdown
Contributor

Seems node sets requirements changed, host types should match only what's in the template, this effects the design and implementation

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 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/catalogManagement/fieldDefinitions/fieldDefinitionValue.ts`:
- Around line 41-48: Update isValidRegexPattern to reject unsafe or overly
complex regex patterns before validation.pattern is serialized into
validationSchema; use the project’s safe-regex validation mechanism or enforce
the established length/complexity limits. Preserve acceptance of valid safe
patterns and ensure only bounded patterns reach tenant catalog-value validation.

In
`@libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx`:
- Around line 111-134: Update the InputField instances rendered by the
templateNodeSetKeys map to use a unique accessible label containing the current
node-set key, while preserving the existing Nodes wording and field names.
Ensure each row’s input is distinguishable to screen readers without relying on
the surrounding FormFieldGroup heading.

In `@libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx`:
- Around line 130-144: Extend nodeSetsSchema to validate each node set’s sizeMin
and sizeMax relationship, ensuring that when both bounds are provided sizeMin is
less than or equal to sizeMax. Apply the cross-field check in the bespoke
node_sets schema while preserving the existing positive-number validation for
sizeByKey.
- Around line 118-123: Update templateRequiredSchema to validate the selected
value with one trimmed Yup string required check, removing the parent-level
template-selected test. Preserve the existing translated “Template is required”
message while ensuring blank and whitespace-only values produce a single
validation error on the value field.

In `@libs/ui-components/src/validation/cidr-validation.ts`:
- Around line 7-13: Align IPV4_CIDR_PATTERN and isValidCidr whitespace behavior
at their shared validation boundary: ensure surrounding whitespace is
consistently trimmed before validation or consistently rejected by both paths.
Preserve the existing CIDR range and leading-zero rules, and add a regression
fixture covering a CIDR with surrounding spaces.
🪄 Autofix (Beta)

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: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 98f0c4ef-5889-4d0b-b005-235ad789ba6f

📥 Commits

Reviewing files that changed from the base of the PR and between f8deee7 and 27575f9.

📒 Files selected for processing (15)
  • libs/i18n/locales/en/translation.json
  • libs/ui-components/src/components/catalogManagement/CatalogItemWizardFooter.test.tsx
  • libs/ui-components/src/components/catalogManagement/CatalogItemWizardFooter.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.test.ts
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.ts
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterConfigurationStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterConfigurationStep.tsx
  • libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.tsx
  • libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx
  • libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx
  • libs/ui-components/src/validation/cidr-validation.test.ts
  • libs/ui-components/src/validation/cidr-validation.ts

Comment thread libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx Outdated
Comment thread libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx Outdated
Comment thread libs/ui-components/src/validation/cidr-validation.ts
@batzionb

Copy link
Copy Markdown
Contributor

add screenshots please

…ization

Signed-off-by: Elay Aharoni <elayaha@gmail.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
…tion

Signed-off-by: Elay Aharoni <elayaha@gmail.com>
… admin wizard

Signed-off-by: Elay Aharoni <elayaha@gmail.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
CatalogItemCard, catalogItemSubtitle, and searchableCatalogItemText all
treat title as the catalog item's displayed name; metadata.name is a
separate identifier. NameField (RFC 1035 DNS-label validation) was the
wrong binding for a free-text display name.

Signed-off-by: Elay Aharoni <elayaha@gmail.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
The public API's Organizations service was removed in favor of Tenants
(OSAC-1532), but libs/types/src/index.ts still exported the stale
organization_type/organizations_service barrel entries, so the catalog
item wizard's tenant-scope lookup 404'd. Switch the wizard to a new
useTenants hook backed by the private Tenants service (CSP Admin only,
same as the other private lookups it already uses).

Also stop polling the wizard's reference-data lookups (templates,
projects) via the global 10s refetchInterval default — they only need
to be fetched once while the wizard is open, and the interval refetch
was visibly reloading the open template dropdown.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 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/api/v1/cluster-catalog-item.test.ts`:
- Around line 41-81: Extract the duplicated create-hook role-dispatch tests into
a shared createCatalogCreateHookTests helper, following the existing
createCatalogHookTests pattern. In
libs/ui-components/src/api/v1/cluster-catalog-item.test.ts:41-81, replace the
useCreateClusterCatalogItem describe block with the helper using
useCreateClusterCatalogItem, ClusterCatalogItems, and
PrivateClusterCatalogItems; make the equivalent replacements in
libs/ui-components/src/api/v1/baremetal-instance.test.ts:53-93 using
useCreateBareMetalInstanceCatalogItem, BareMetalInstanceCatalogItems, and
PrivateBareMetalInstanceCatalogItems, and
libs/ui-components/src/api/v1/compute-instance-catalog-item.test.ts:44-84 using
useCreateComputeInstanceCatalogItem, ComputeInstanceCatalogItems, and
PrivateComputeInstanceCatalogItems.

In `@libs/ui-components/src/api/v1/cluster-templates.test.ts`:
- Around line 26-58: Extract the duplicated admin-template role-dispatch tests
into a shared createAdminTemplateHookTests helper. In
libs/ui-components/src/api/v1/cluster-templates.test.ts lines 26-58, replace the
useAdminClusterTemplates block and parameterize it with
useAdminClusterTemplates, ClusterTemplates, and PrivateClusterTemplates; apply
the same replacement in
libs/ui-components/src/api/v1/compute-instance-templates.test.ts lines 29-65
using useAdminComputeInstanceTemplates, ComputeInstanceTemplates, and
PrivateComputeInstanceTemplates, preserving the providerAdmin private-client and
tenantAdmin public-client assertions.

In `@libs/ui-components/src/api/v1/tenant.ts`:
- Around line 9-17: Update useTenants to gate the private-tenants query on
provider-admin access, using the available role value or a caller-provided
condition so tenant admins do not issue the request. Preserve the existing
enabled behavior for provider admins and ensure CatalogItemGeneralFields passes
or supplies the role condition if useTenants cannot access it directly.

In
`@libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.tsx`:
- Around line 85-112: Update getStepValidationSchema and
getFullFormValidationSchema to validate template.value as required and add scope
validation. Restrict scope.level to role-valid values, requiring
scope.tenant.value for organization scope and scope.project.value for project
scope, so buildScopePayloadFields cannot submit an empty or invalid target.

In
`@libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx`:
- Around line 104-135: Update both getStepValidationSchema’s configuration case
and getFullFormValidationSchema to validate fieldDefinitions.instance_type by
checking its nested value property, rather than applying
fieldDefinitionValueSchema directly to the {value, label} resource reference.
Ensure an empty instance_type.value is rejected in both step validation and
final submission, matching the flattening behavior in buildFieldDefinitions.

In `@libs/ui-components/src/validation/cidr-validation.test.ts`:
- Around line 32-50: Normalize CIDR input by trimming surrounding whitespace at
the form/serialization boundary before validation and submission, ensuring both
IPV4_CIDR_PATTERN and isValidCidr receive the same normalized value. Update the
IPV4_CIDR_PATTERN fixtures and assertions to cover whitespace-padded CIDRs using
that normalized value while preserving existing parity checks.
🪄 Autofix (Beta)

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: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f3068ff0-4842-4a3f-9359-58e4f3dca080

📥 Commits

Reviewing files that changed from the base of the PR and between 27575f9 and 21b3583.

📒 Files selected for processing (69)
  • apps/app-frontend/src/shell/AdminCatalogRoutes.test.tsx
  • apps/app-frontend/src/shell/AdminCatalogRoutes.tsx
  • libs/i18n/locales/en/translation.json
  • libs/types/src/index.ts
  • libs/ui-components/src/api/types.ts
  • libs/ui-components/src/api/v1/baremetal-instance-templates.test.ts
  • libs/ui-components/src/api/v1/baremetal-instance-templates.ts
  • libs/ui-components/src/api/v1/baremetal-instance.test.ts
  • libs/ui-components/src/api/v1/baremetal-instance.ts
  • libs/ui-components/src/api/v1/cluster-catalog-item.test.ts
  • libs/ui-components/src/api/v1/cluster-catalog-item.ts
  • libs/ui-components/src/api/v1/cluster-templates.test.ts
  • libs/ui-components/src/api/v1/cluster-templates.ts
  • libs/ui-components/src/api/v1/compute-instance-catalog-item.test.ts
  • libs/ui-components/src/api/v1/compute-instance-catalog-item.ts
  • libs/ui-components/src/api/v1/compute-instance-templates.test.ts
  • libs/ui-components/src/api/v1/compute-instance-templates.ts
  • libs/ui-components/src/api/v1/organization.ts
  • libs/ui-components/src/api/v1/projects.test.ts
  • libs/ui-components/src/api/v1/projects.ts
  • libs/ui-components/src/api/v1/tenant.ts
  • libs/ui-components/src/components/Form/SwitchField.test.tsx
  • libs/ui-components/src/components/Form/SwitchField.tsx
  • libs/ui-components/src/components/catalogManagement/CatalogItemGeneralFields.test.tsx
  • libs/ui-components/src/components/catalogManagement/CatalogItemGeneralFields.tsx
  • libs/ui-components/src/components/catalogManagement/CatalogItemWizardFooter.test.tsx
  • libs/ui-components/src/components/catalogManagement/CatalogItemWizardFooter.tsx
  • libs/ui-components/src/components/catalogManagement/catalogItemScope.test.ts
  • libs/ui-components/src/components/catalogManagement/catalogItemScope.ts
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/BooleanFieldDefinition.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/BooleanFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/FieldDefinitionGroup.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NodeSetsFieldEditor.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NumberFieldDefinition.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/NumberFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/ResourceSelectorFieldDefinition.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/ResourceSelectorFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/StringFieldDefinition.test.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/StringFieldDefinition.tsx
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.test.ts
  • libs/ui-components/src/components/catalogManagement/fieldDefinitions/fieldDefinitionValue.ts
  • libs/ui-components/src/components/catalogManagement/steps/baremetal-instance/BMAccessStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/baremetal-instance/BMAccessStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/baremetal-instance/BMConfigurationStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/baremetal-instance/BMConfigurationStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterAccessStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterAccessStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterConfigurationStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterConfigurationStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterNetworkingStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/cluster/ClusterNetworkingStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/compute-instance/VMAccessStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/compute-instance/VMAccessStep.tsx
  • libs/ui-components/src/components/catalogManagement/steps/compute-instance/VMConfigurationStep.test.tsx
  • libs/ui-components/src/components/catalogManagement/steps/compute-instance/VMConfigurationStep.tsx
  • libs/ui-components/src/components/catalogProvision/protobuf-value.test.ts
  • libs/ui-components/src/components/catalogProvision/protobuf-value.ts
  • libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/baremetal-instance/BareMetalInstanceCatalogItemCreatePage.tsx
  • libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/cluster/ClusterCatalogItemCreatePage.tsx
  • libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.test.tsx
  • libs/ui-components/src/pages/admin/compute-instance/ComputeInstanceCatalogItemCreatePage.tsx
  • libs/ui-components/src/test-utils/renderHookWithTransport.tsx
  • libs/ui-components/src/utils/slug.test.ts
  • libs/ui-components/src/utils/slug.ts
  • libs/ui-components/src/validation/cidr-validation.test.ts
  • libs/ui-components/src/validation/cidr-validation.ts
💤 Files with no reviewable changes (1)
  • libs/ui-components/src/api/v1/organization.ts

Comment thread libs/ui-components/src/api/v1/cluster-catalog-item.test.ts
Comment thread libs/ui-components/src/api/v1/cluster-templates.test.ts
Comment thread libs/ui-components/src/api/v1/tenant.ts Outdated
Comment thread libs/ui-components/src/validation/cidr-validation.test.ts
Comment thread libs/ui-components/src/utils/slug.ts Outdated
…decode

The Connect transport's JSON codec has no type registry, so any response
containing a google.protobuf.Any-packed value (e.g. a ClusterTemplate or
ComputeInstanceTemplate parameter's default) throws "... is not in the type
registry" while decoding — the request succeeds at the network level, but the
query fails client-side, leaving the wizard's template dropdown empty even
though the response body is fully populated. BareMetal templates worked only
because none of the sampled data happened to have a populated Any default.

Register the well-known wrapper, Struct/Value/ListValue, and Timestamp/
Duration types — the full set ClusterTemplateParameterDefinition.default is
documented to pack — on the shared transport's jsonOptions.registry.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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 `@apps/app-frontend/src/wellKnownTypeRegistry.test.ts`:
- Around line 8-18: Add table cases in the well-known type registry test’s
it.each dataset for google.protobuf.BytesValue, FloatValue, UInt32Value, and
UInt64Value, using representative values matching each type’s expected JSON
representation. Keep the existing cases unchanged so every schema registered by
the registry is exercised.
🪄 Autofix (Beta)

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: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 639f129d-715c-4912-ad03-276f4c1628d9

📥 Commits

Reviewing files that changed from the base of the PR and between 21b3583 and c24a572.

📒 Files selected for processing (3)
  • apps/app-frontend/src/main.tsx
  • apps/app-frontend/src/wellKnownTypeRegistry.test.ts
  • apps/app-frontend/src/wellKnownTypeRegistry.ts

Comment thread apps/app-frontend/src/wellKnownTypeRegistry.test.ts
Fixes 7 issues found during manual testing of the catalog item creation
wizard:

- Require selecting a template for VM and Bare Metal catalog items, not just
  Cluster (shared templateRequiredSchema).
- Stop calling the private Tenants API as a Tenant Admin, who has no
  permission for it — useTenants() is now gated to providerAdmin only.
- Show a project's display title instead of its raw id in the project
  scope selector (Project has a separate spec.title, same split as
  ClusterTemplate.title vs metadata.name).
- Add gap between scope radio buttons (RadioButtonField had none).
- Require picking an organization/project once that scope level is
  selected, via a new scopeValidationSchema — previously the wizard let
  admins advance with an empty selection.
- Wrap every catalogManagement wizard step in the shared OsacForm
  component, matching the pattern the tenant-user provisioning wizard
  already uses (proper PatternFly form spacing/width/grid). This also
  surfaces PatternFly's built-in red required-field asterisk on fields
  that are now correctly marked isRequired, with no custom CSS needed.

Also fixes a duplicate DOM id (RadioButtonField's generated id for the
"Project" scope option collided with the project SelectField's fieldId),
found while adding test coverage for the project-title fix.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
Correction to the earlier fix — projects display their human-entered name
directly in metadata.name (unlike templates, which are auto-populated from
ansible roles and split display title from metadata.name). spec.title is
not the right field here.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
rawagner: stop deriving the catalog item's resource name from its
display title via slugify — show both fields explicitly instead, using
the same buildMetadataNameSchema (RFC 1035 DNS-label validation) the
tenant-provisioning wizard already uses for the equivalent field.
Removes the now-unused slug.ts/slug.test.ts.

Remaining fixes are still-valid CodeRabbit findings verified against
current code (several other CodeRabbit comments were already stale —
fixed independently earlier this session, or resolved as a side effect
of the resource-name change):

- Node-set size inputs all shared the same accessible label ("Nodes");
  disambiguate with the node-set key.
- Cluster catalog items' node-set sizeMin/sizeMax were never
  cross-validated, so an admin could ship an unsatisfiable size
  constraint (min > max) to tenants.
- IPV4_CIDR_PATTERN (shipped verbatim as a tenant-facing validation
  constraint) rejected surrounding whitespace that isValidCidr()
  already trims, so a value the admin's own wizard accepted could still
  fail for a tenant. Aligned both, added a regression fixture.
- VM catalog items' instance_type field was completely unvalidated —
  a non-editable instance_type with an empty default silently shipped.
  Extracted resourceRefRequiredSchema (generalizing the existing
  templateRequiredSchema) to require it only when non-editable.
- wellKnownTypeRegistry's test table didn't exercise every well-known
  type the registry actually registers (BytesValue, FloatValue,
  UInt32Value, UInt64Value were missing).

A CodeRabbit-suggested test-harness DRY refactor (dedup the
admin-template/create-mutation hook test dispatch pattern across ~9
files) was attempted and reverted: the public/private generated types
are nominally distinct, so a single generic type param broke the
type-safety the existing createCatalogHookTests helper deliberately
preserves — not worth trading for a "Trivial"-tagged nice-to-have.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
- Move "Host type: X" into FormFieldGroupHeader's titleDescription slot
  instead of a loose Content paragraph mixed in with the input — this is
  the slot PatternFly's own styles already treat as a subtitle (muted
  text under the group heading), so it now reads as context for the group
  rather than an unstyled aside.
- Group the size-constraint controls (Editable switch, Minimum/Maximum
  size) into their own labeled FormFieldGroup ("Size constraints") with a
  one-line explanation of what they affect, separating "applies to every
  node set" settings from the per-node-set list below.
- Put Minimum/Maximum size side by side via Flex instead of stacked full
  width — they're a paired range, and stacking obscured that.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
Every Configuration/Access/Networking field ("Release Image", "Cores",
"SSH Public Key", node sets, ...) rendered its FormFieldGroup heading as
plain text — PatternFly's FormFieldGroupHeader doesn't apply any
font-size/weight to titleText by default, so each field's name blended
into the surrounding form instead of reading as a section title. Wrap
each heading in PatternFly's own Title component (h4/md) instead, shared
via FieldDefinitionGroup so every field-definition primitive picks it up
uniformly, plus the two headings in NodeSetsFieldEditor for consistency.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
Every other field-definition editor (Release Image, Cores, ...) starts
with its own bold heading naming the field, so admins always know what
they're configuring. NodeSetsFieldEditor was the exception — it jumped
straight into a "Size constraints" heading with nothing identifying that
the whole section is the node_sets field, making it read as an unrelated
top-level block rather than something scoped to Node Sets.

Wrap the whole editor in the same FieldDefinitionGroup scaffold every
other field uses, labeled "Node Sets" — this also picks up its "Editable"
switch for free, so the one that was manually added inside "Size
constraints" is removed (it's a property of the node_sets field as a
whole, not just the size bounds). "Size constraints" and the per-node-set
groups now render as smaller (h5) sub-headings, visually nested under the
"Node Sets" (h4) title instead of looking like peer sections.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
@ElayAharoni

Copy link
Copy Markdown
Contributor Author

add screenshots please

added snapshots and fixed comments please review @batzionb

@ElayAharoni
ElayAharoni requested a review from rawagner July 29, 2026 06:39
@ElayAharoni
ElayAharoni requested a review from liatb-rh July 29, 2026 07:00
Comment thread apps/app-frontend/src/shell/AdminCatalogRoutes.tsx Outdated
Comment thread libs/ui-components/src/api/v1/baremetal-instance-templates.ts
Comment thread libs/ui-components/src/api/v1/projects.ts Outdated
Comment thread libs/ui-components/src/api/v1/tenant.ts Outdated
These are now fully implied by the selected instance_type (whose own
spec already carries cores/memory, shown right in the picker's option
label via formatInstanceTypeOptionLabel), so they no longer need to be
independently configurable catalog item field definitions.

- VMConfigurationStep.tsx: drop the two NumberFieldDefinition fields.
- ComputeInstanceCatalogItemCreatePage.tsx: remove cores/memory_gib from
  the form values interface, initial values, both validation schemas,
  and buildFieldDefinitions — no ComputeInstanceCatalogItem will ever
  carry these paths in field_definitions again.
- catalogFieldDefinition.ts: drop cores/memory_gib from
  CATALOG_ITEM_RESOURCE_FIELD_PATHS — these paths can never match a
  field_definitions entry anymore, so the catalog card resource-summary
  line naturally drops CPU/memory (boot disk remains). Updated the
  matching fallback label map and regression test accordingly.

Left untouched: instance type's own cores/memoryGib spec fields
(vm/utils.ts, unrelated — that's what the picker label already surfaces),
VM details-page display of a provisioned instance's actual spec, and the
tenant-provisioning wizard's generic field_definitions handling (which
must keep working for whatever paths any catalog item defines, using
"cores" only as an arbitrary example fixture in tests, not asserting on
this specific field).

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
@ElayAharoni
ElayAharoni removed the request for review from liatb-rh July 29, 2026 08:47
…e optional

- "Display name" -> "Title" (maps to CatalogItem.title, unchanged: the
  free-text label shown when browsing the catalog), now optional.
- "Resource name" -> "Name" (maps to metadata.name, the RFC 1035
  DNS-label resource identifier), remains required — it's the only
  field that must be unique/valid enough to serve as the object's name.
- Added a regression test proving the General step now advances with
  only Name filled in, no Title.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
… Ref

- Remove the is_windows BooleanFieldDefinition from the VM configuration
  step entirely (deprecated) — dropped from the form values interface,
  initial values, and buildFieldDefinitions. BooleanFieldDefinition
  itself is left in place as shared field-definition primitive
  infrastructure, even though nothing currently uses it.
- Rename "Image" to "Source Ref" and correct its path from the top-level
  scalar `image` to `image.source_ref` — ComputeInstanceSpec.image is
  actually a nested ComputeInstanceImage message (source_type +
  source_ref), not a plain string, so the field definition needs to
  target the specific leaf field the admin is setting.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
@batzionb

Copy link
Copy Markdown
Contributor

Node sets should be a list of items one item per host type in the template
Each item has three fields: default value, minimum nodes and maximum nodes

@batzionb

Copy link
Copy Markdown
Contributor

This wizard should be consistent with the creation wizard:

  1. Every label uses Title Case for full compound terms ("SSH Public Key," "Pull Secret," "Release Image," "Instance Type," "User Data"), while the resource-wizard's own fallback/default strings consistently use sentence case or the resource-wizard's own translation-key vocabulary ("SSH public key," "Pull secret," "Release image," "Instance type," "User data," "VM image," "Boot disk," "Source Ref")
  2. Configuration field order differs: catalog item = Instance Type → Image → Boot Disk → Additional Disks → Run Strategy → User Data; resource wizard = Image → Instance Type → Boot Disk → User Data (instance type and image are swapped).

rawagner:
- Drop the CatalogItemCreateRoute :type switch in AdminCatalogRoutes in
  favor of three explicit static routes.
- Move private-only query hooks (tenant, and the admin template hooks'
  private branch) into api/v1/private/, matching the existing
  usePrivate* convention for catalog-item hooks.
- Drop refetchInterval: false from projects/tenant/template hooks so
  they inherit the app's default poll interval like every other query.
- Convert the ComputeInstance and BareMetal catalog-item wizards from
  useFormik + FormikProvider to the <Formik> component. The Cluster
  wizard keeps useFormik + FormikProvider, documented inline: its
  validationSchema depends on formik.values.template.value, which
  <Formik>'s render-prop can't expose before the schema is built.

batzionb:
- Restructure node sets so each template-defined host type carries its
  own independent default/minimum/maximum, instead of one default per
  key plus a single global min/max pair applied to all of them.
- Align field labels across the three admin catalog-item wizards with
  the tenant-facing resource wizard's sentence-case vocabulary, and
  reorder the VM configuration step to match (image before instance
  type). "Source Ref" is kept as-is per an explicit earlier request in
  this same work, for a field that's genuinely different from the
  resource wizard's higher-level "VM image" picker.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
@ElayAharoni
ElayAharoni requested a review from rawagner July 30, 2026 06:09
- Drop the "Node set:" prefix from each node-set group header, showing
  just the capitalized template key (e.g. "Workers", "Masters").
- Move the host type out of the header's muted description line into a
  Label badge in the header actions slot, so it reads as a distinct,
  visible attribute of the group rather than blending into the title.
- Drop the redundant "({{key}})" from the default/min/max field labels
  now that the group header alone identifies which node set they
  belong to.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
A node set always maps to exactly one host type, so showing both a
key-based header (e.g. "Workers") and a separate "Host type: Small"
badge duplicated the same identity. Collapse the two into a single
header that names the host type directly, making it unambiguous which
host type each set of default/min/max fields configures.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants