Skip to content

Conversation

@adamviktora
Copy link
Member

@adamviktora adamviktora commented Dec 8, 2025

📝 Description

  • refactoring of duplicated DescriptionItem (for labels, annotations, namespace)
  • also updates styling of labels description item to align with console

🎥 Demo

Before:
Screenshot 2025-12-08 at 12 52 40

After:
Screenshot 2025-12-08 at 12 52 49

Summary by CodeRabbit

  • Refactor

    • Unified label and annotation editing into new in-place editor components with external submit hooks
    • Replaced modal-based flows with inline editing across metadata and VM configuration views
    • Swapped legacy namespace/link rendering for a cluster-aware namespace display
    • Removed several legacy metadata components
  • Style

    • Removed unused CSS rules for metadata/label group styling
  • UX

    • Labels now act as clickable elements that navigate to search results

✏️ Tip: You can customize this high-level summary in your review settings.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Dec 8, 2025

@adamviktora: This pull request references CNV-73006 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 task to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

  • refactoring of duplicated DescriptionItem (for labels, annotations, namespace)
  • also updates styling of labels description item to align with console

🎥 Demo

Before:
Screenshot 2025-12-08 at 12 52 40

After:
Screenshot 2025-12-08 at 12 52 49

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 added the approved This issue is something we want to fix label Dec 8, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 8, 2025

📝 Walkthrough

Walkthrough

Changes add customization props (className, descriptionHeaderWrapper, onLabelsSubmit, onAnnotationsSubmit, isLabelEditor) to DescriptionItem and its child components, replace modal-based metadata editing with new DescriptionItemAnnotations/DescriptionItemLabels components across multiple views, introduce cluster-aware namespace linking, and remove deprecated MetadataTabLabels/MetadataTabAnnotations and related SCSS.

Changes

Cohort / File(s) Summary
Core DescriptionItem & children
src/utils/components/DescriptionItem/DescriptionItem.tsx, src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx, src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx, src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx
Added isLabelEditor to DescriptionItem; conditional layout/class logic and classNames import. Extended Annotations/Labels with className, descriptionHeaderWrapper, and optional async submit handlers. DescriptionItemNamespace now accepts model and resource, uses getCluster and FleetResourceLink.
Wizard components
src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx, src/views/catalog/wizard/tabs/metadata/WizardMetadataTab.tsx
Added isLabelEditor prop and conditional co-editable-label-group class on descriptions; metadata tab passes isLabelEditor for Labels.
Metadata editing refactor (VM & Catalog)
src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx, src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx, src/views/topology/components/vm/.../VMAnnotationsDetailsItem.tsx, src/views/topology/components/vm/.../VMLabelsDetailsItem.tsx
Replaced modal-based editing flows with DescriptionItemAnnotations / DescriptionItemLabels, wired model and resource, removed useModal and modal components, added descriptionHeaderWrapper usage and submit callbacks.
MetadataLabel component & styles
src/utils/components/MetadataLabels/MetadataLabels.tsx, src/utils/components/MetadataLabels/MetadataLabels.scss
Switched from Link to programmatic navigation (useNavigate) on label click; added translation for empty state; removed .metadata-labels-group SCSS block.
Deprecated components removed
src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabAnnotations/MetadataTabAnnotations.tsx, src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/MetadataTabLabels.tsx, src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/metadata-tab-labels.scss
Deleted MetadataTabAnnotations and MetadataTabLabels components and associated SCSS.
Overview tab namespace refactor
src/views/virtualmachines/details/tabs/overview/components/VirtualMachinesOverviewTabGeneral/VirtualMachinesOverviewTabGeneral.tsx
Replaced manual Namespace rendering with DescriptionItemNamespace, removed previous NamespaceModel/FleetResourceLink usage and related props.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Focus review on:
    • Consistency of new props (className, descriptionHeaderWrapper, submit handlers) across DescriptionItem components and callers
    • Correctness of modal-to-component migration (preserving validation/error handling and UX)
    • FleetResourceLink cluster wiring in DescriptionItemNamespace and all usage sites
    • Removal of deprecated components and associated SCSS references

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • Pedro-S-Abreu
  • lkladnit
  • metalice

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main refactoring objective: consolidating duplicated DescriptionItem usage across labels, annotations, and namespace components.
Description check ✅ Passed The description covers the main refactoring objective and includes before/after screenshots, though demo images may not display. All required template sections are present with appropriate content.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

❤️ Share

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

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Dec 8, 2025

@adamviktora: This pull request references CNV-73006 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 task to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

  • refactoring of duplicated DescriptionItem (for labels, annotations, namespace)
  • also updates styling of labels description item to align with console

🎥 Demo

Before:
Screenshot 2025-12-08 at 12 52 40

After:
Screenshot 2025-12-08 at 12 52 49

Summary by CodeRabbit

Release Notes

  • Refactor

  • Streamlined label and annotation editing experience across metadata views and configuration interfaces

  • Enhanced namespace resource linking with improved cluster awareness support

  • Improved metadata display and editing interactions in VM details and configuration panels

  • Style

  • Removed unused CSS styling rules for metadata label groups

✏️ Tip: You can customize this high-level summary in your review settings.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
src/utils/components/MetadataLabels/MetadataLabels.tsx (1)

16-24: Tighten typing around labels and simplify empty-check.

  • In the mapper (lines 28–39) labels is typed as optional but accessed as labels[key]. This is safe at runtime because labelsKeys is Object.keys(labels || {}), but TS won’t narrow labels from that. Consider either making labels non‑optional in props or using optional chaining:
    const value = labels?.[key]; const labelText = value ? \${key}=${value}` : key;`
  • For the empty state (lines 20–24), isEmpty(labelsKeys) works because labelsKeys is an array, but labelsKeys.length === 0 is more explicit and avoids relying on a generic helper for a simple array length check.

These tweaks improve type-safety and readability without changing behavior.

Also applies to: 28-39

src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMAnnotationsDetailsItem.tsx (1)

3-7: Annotations refactor looks correct; consider memoizing handlers if this becomes hot.

  • Wiring DescriptionItemAnnotations with model={VirtualMachineModel}, resource={vm}, descriptionHeaderWrapper using SearchItem, and onAnnotationsSubmit={(annotations) => updateAnnotation(vm, annotations)} matches the expected updateAnnotation signature and removes the modal complexity cleanly.
  • If this panel re-renders frequently and DescriptionItemAnnotations is memoized, you might later consider wrapping the submit/header callbacks with useCallback to keep props stable, but this is optional given current complexity. As per coding guidelines, memoization tools are encouraged where they materially reduce re-renders.

Also applies to: 17-23

src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx (1)

3-5: Good use of shared DescriptionItem components; double‑check SearchItem ids

The switch to DescriptionItemLabels/DescriptionItemAnnotations wired with VirtualMachineModel, resource={vm}, and the updateLabels/updateAnnotation callbacks looks correct and should centralize metadata editing nicely.

One thing to verify: SearchItem id="metadata" is now used both for the main tab title and again in the annotations header wrapper, while labels use id="labels". If the search/navigation logic expects ids to be unique per logical section, you might want a more specific id for annotations (for example metadata-annotations) to avoid ambiguity.

Also applies to: 23-36

src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx (1)

1-1: Behavioral extension looks good; consider tightening types for header wrapper and submit

The new props and fallback submit handler keep the old behavior while enabling external submit overrides and header customization. The onSubmit={onAnnotationsSubmit ?? onAnnotationsSubmitInternal} wiring is clean.

Two small type-level improvements:

  • descriptionHeaderWrapper currently takes a string, but conceptually it’s a wrapper around “whatever we use as the header”. Making it accept ReactNode gives you more flexibility without breaking current callers.
  • onAnnotationsSubmit is typed as Promise<any>, which goes against the “avoid any” guideline; Promise<unknown> (or a more concrete type like Promise<void> if callers don’t use the result) would be safer.

You can implement both with a local-only change:

-type DescriptionItemAnnotationsProps = {
-  className?: string;
-  descriptionHeaderWrapper?: (children: string) => ReactNode;
+type DescriptionItemAnnotationsProps = {
+  className?: string;
+  descriptionHeaderWrapper?: (children: ReactNode) => ReactNode;
   editable?: boolean;
   label?: string;
   model: K8sModel;
-  onAnnotationsSubmit?: (annotations: { [key: string]: string }) => Promise<any>;
+  onAnnotationsSubmit?: (annotations: { [key: string]: string }) => Promise<unknown>;
   resource: K8sResourceCommon;
 };

annotationsHeader is still a string, which is valid as a ReactNode, so no runtime change.

Also applies to: 12-18, 22-29, 37-38, 60-62, 70-72

src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx (1)

1-1: Nice generalization of label handling; align types with annotations and guidelines

The refactor to a shared DescriptionItemLabels with optional className, descriptionHeaderWrapper, and external onLabelsSubmit is well-structured. The internal onLabelsSubmitInternal fallback preserves the original k8sPatch behavior, and passing isLabelEditor into DescriptionItem is a clear way to toggle label-specific styling.

Similar to DescriptionItemAnnotations, you can tighten types a bit:

  • Allow descriptionHeaderWrapper to wrap a ReactNode rather than only a string.
  • Prefer Promise<unknown> (or another concrete type) over Promise<any for onLabelsSubmit.

Suggested diff:

-type DescriptionItemLabelsProps = {
-  className?: string;
-  descriptionHeaderWrapper?: (children: string) => ReactNode;
+type DescriptionItemLabelsProps = {
+  className?: string;
+  descriptionHeaderWrapper?: (children: ReactNode) => ReactNode;
   editable?: boolean;
   label?: string;
   model: K8sModel;
-  onLabelsSubmit?: (labels: { [key: string]: string }) => Promise<any>;
+  onLabelsSubmit?: (labels: { [key: string]: string }) => Promise<unknown>;
   resource: K8sResourceCommon;
 };

This keeps current callers valid while improving type safety and flexibility.

Also applies to: 13-19, 23-30, 34-35, 53-54, 57-59, 67-68, 70-73

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a0479d5 and a837759.

📒 Files selected for processing (16)
  • src/utils/components/DescriptionItem/DescriptionItem.tsx (5 hunks)
  • src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx (4 hunks)
  • src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx (3 hunks)
  • src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx (3 hunks)
  • src/utils/components/MetadataLabels/MetadataLabels.scss (0 hunks)
  • src/utils/components/MetadataLabels/MetadataLabels.tsx (1 hunks)
  • src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx (2 hunks)
  • src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx (4 hunks)
  • src/views/catalog/wizard/tabs/metadata/WizardMetadataTab.tsx (1 hunks)
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMAnnotationsDetailsItem.tsx (2 hunks)
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx (2 hunks)
  • src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx (2 hunks)
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabAnnotations/MetadataTabAnnotations.tsx (0 hunks)
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/MetadataTabLabels.tsx (0 hunks)
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/metadata-tab-labels.scss (0 hunks)
  • src/views/virtualmachines/details/tabs/overview/components/VirtualMachinesOverviewTabGeneral/VirtualMachinesOverviewTabGeneral.tsx (2 hunks)
💤 Files with no reviewable changes (4)
  • src/utils/components/MetadataLabels/MetadataLabels.scss
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/metadata-tab-labels.scss
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabAnnotations/MetadataTabAnnotations.tsx
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/MetadataTabLabels.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.tsx

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.tsx: Use .tsx file extension for all React components. One component per file. No nested components.
Use PascalCase for all component names (e.g., HeaderTop.tsx).
Use functional components by default. Use class components only for specific lifecycle methods unavailable in functional components (e.g., componentDidCatch).
Use default exports for all components.
Use React's memoization tools (React.memo, useMemo, useCallback) to avoid unnecessary re-renders. Lazy load components with React.lazy and Suspense.
Always specify dependencies in useEffect to avoid unnecessary re-renders or missed updates. Pass an empty array [] to run the effect only once if no dependencies are required.

Files:

  • src/views/virtualmachines/details/tabs/overview/components/VirtualMachinesOverviewTabGeneral/VirtualMachinesOverviewTabGeneral.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx
  • src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx
  • src/views/catalog/wizard/tabs/metadata/WizardMetadataTab.tsx
  • src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMAnnotationsDetailsItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx
  • src/utils/components/MetadataLabels/MetadataLabels.tsx
  • src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx
  • src/utils/components/DescriptionItem/DescriptionItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{tsx,ts}: Extract as much logic as possible from components into custom hooks or utility files to improve testability. Avoid bloated components.
Hooks should contain only logic and side effects, not return JSX. Keep JSX in components while using hooks for extracting reusable or unit-testable logic.

Files:

  • src/views/virtualmachines/details/tabs/overview/components/VirtualMachinesOverviewTabGeneral/VirtualMachinesOverviewTabGeneral.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx
  • src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx
  • src/views/catalog/wizard/tabs/metadata/WizardMetadataTab.tsx
  • src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMAnnotationsDetailsItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx
  • src/utils/components/MetadataLabels/MetadataLabels.tsx
  • src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx
  • src/utils/components/DescriptionItem/DescriptionItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx}: Use descriptive names for variables, functions, and components. Avoid abbreviations unless widely recognized.
Prefer using type instead of interface for defining the shapes of objects or functions in TypeScript.
Avoid using any type in TypeScript as it compromises type safety. Use unknown instead and narrow the type as needed.
Always explicitly define return types for functions in TypeScript rather than relying on type inference.

Files:

  • src/views/virtualmachines/details/tabs/overview/components/VirtualMachinesOverviewTabGeneral/VirtualMachinesOverviewTabGeneral.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx
  • src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx
  • src/views/catalog/wizard/tabs/metadata/WizardMetadataTab.tsx
  • src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMAnnotationsDetailsItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx
  • src/utils/components/MetadataLabels/MetadataLabels.tsx
  • src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx
  • src/utils/components/DescriptionItem/DescriptionItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-04T14:08:48.257Z
Learning: Add a main PR comment that explains referenced links, Jira, documentation, use cases, and current/required state. Include videos and/or screenshots for visual changes.
📚 Learning: 2025-12-04T14:08:48.257Z
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-04T14:08:48.257Z
Learning: Applies to **/*.tsx : Use React's memoization tools (`React.memo`, `useMemo`, `useCallback`) to avoid unnecessary re-renders. Lazy load components with `React.lazy` and `Suspense`.

Applied to files:

  • src/utils/components/DescriptionItem/DescriptionItem.tsx
🧬 Code graph analysis (6)
src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx (1)
src/views/virtualmachines/details/tabs/configuration/details/utils/utils.ts (1)
  • updateMetadata (96-112)
src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMAnnotationsDetailsItem.tsx (2)
src/views/virtualmachines/details/tabs/configuration/utils/search.ts (1)
  • SearchItem (6-11)
src/views/virtualmachines/details/tabs/configuration/details/utils/utils.ts (1)
  • updateAnnotation (114-115)
src/utils/components/MetadataLabels/MetadataLabels.tsx (2)
src/utils/utils/utils.ts (1)
  • isEmpty (32-33)
src/utils/components/Labels/LabelList.tsx (1)
  • Label (17-35)
src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx (2)
src/views/virtualmachines/details/tabs/configuration/utils/search.ts (1)
  • SearchItem (6-11)
src/views/virtualmachines/details/tabs/configuration/details/utils/utils.ts (2)
  • updateLabels (117-118)
  • updateAnnotation (114-115)
src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx (1)
cypress/views/selector-common.ts (1)
  • label (110-110)
src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx (1)
src/multicluster/helpers/selectors.ts (1)
  • getCluster (6-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-test
  • GitHub Check: i18n
  • GitHub Check: build
🔇 Additional comments (7)
src/views/catalog/wizard/tabs/metadata/WizardMetadataTab.tsx (1)

32-62: isLabelEditor wiring for wizard labels looks consistent.

Using isLabelEditor on the labels WizardDescriptionItem aligns with the new styling behavior in WizardDescriptionItem without affecting the existing modal-based edit flow.

src/views/virtualmachines/details/tabs/overview/components/VirtualMachinesOverviewTabGeneral/VirtualMachinesOverviewTabGeneral.tsx (1)

9-12: Good reuse of DescriptionItemNamespace for VM namespace.

Swapping the inline namespace DescriptionItem for DescriptionItemNamespace with model={VirtualMachineModel} and resource={vm} is a nice consolidation and ensures consistent, cluster-aware namespace linking across views.

Also applies to: 52-53

src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx (1)

2-3: isLabelEditor integration in WizardDescriptionItem is clean and backward compatible.

The new isLabelEditor prop defaults to false and only affects CSS (co-editable-label-group) on the description area, leaving existing consumers unchanged and enabling the wizard labels view to opt in explicitly.

Also applies to: 37-39, 61-62, 142-148

src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx (1)

3-5: CustomizeInstanceType metadata refactor to shared DescriptionItems looks solid.

  • updateMetadata returning Promise.resolve(updateCustomizeInstanceType(...)) fits the expected async on...Submit contract without changing updateCustomizeInstanceType semantics.
  • Using DescriptionItemLabels/DescriptionItemAnnotations with model={VirtualMachineModel}, resource={vm}, and the appropriate SearchItem wrappers keeps behavior consistent while removing modal plumbing.

Also applies to: 20-28, 37-50

src/utils/components/DescriptionItem/DescriptionItem.tsx (1)

2-3: isLabelEditor addition to DescriptionItem cleanly scopes label-editor styling.

The new isLabelEditor flag and classNames usage correctly adjust the header layout (space-between + full width) and apply co-editable-label-group to the description wrapper only when needed, without affecting existing consumers that don’t opt in.

Also applies to: 32-33, 52-53, 96-100, 132-135

src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx (1)

8-10: Ensure K8sResourceCommon is available and verify cluster handling on FleetResourceLink.

  • Line 15 uses resource: K8sResourceCommon but there is no import for K8sResourceCommon in this file. If it is not provided via global typings, this will fail TS compilation; please import it from @openshift-console/dynamic-plugin-sdk (e.g. import { K8sModel, K8sResourceCommon, getGroupVersionKindForModel } from '@openshift-console/dynamic-plugin-sdk';) or confirm it is globally declared.
  • Lines 25–37: cluster may be undefined when getCluster(resource) returns nothing. Please confirm FleetResourceLink accepts an undefined/optional cluster prop and falls back correctly, or gate the prop (e.g. pass cluster={cluster} only when truthy).

As per coding guidelines, this keeps typings and external component usage robust.

Also applies to: 12-16, 25-39

src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx (1)

3-6: Labels refactor to DescriptionItemLabels looks sound

Using DescriptionItemLabels with model={VirtualMachineModel}, resource={vm}, and onLabelsSubmit={(labels) => updateLabels(vm, labels)} preserves the previous behavior while de‑duplicating the logic and aligning the header with SearchItem id="labels". No issues from a typing or behavioral perspective here.

Also applies to: 17-23

Copy link
Member

@galkremer1 galkremer1 left a comment

Choose a reason for hiding this comment

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

Looking good, just a couple of nits.

<LabelGroup className="metadata-labels-group" numLabels={10}>
{Object.keys(labels || {})?.map((key) => {
<LabelGroup numLabels={10}>
{labelsKeys?.map((key) => {
Copy link
Member

Choose a reason for hiding this comment

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

According to the code labelsKeys will always be an array so there is no need for the optional chaining here.

@adamviktora adamviktora force-pushed the refactoring-desc-items branch from a837759 to a72711e Compare December 9, 2025 07:10
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Dec 9, 2025

@adamviktora: This pull request references CNV-73006 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 task to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

  • refactoring of duplicated DescriptionItem (for labels, annotations, namespace)
  • also updates styling of labels description item to align with console

🎥 Demo

Before:
Screenshot 2025-12-08 at 12 52 40

After:
Screenshot 2025-12-08 at 12 52 49

Summary by CodeRabbit

  • Refactor

  • Unified label and annotation editing into new in-place editor components with external submit hooks

  • Replaced modal-based flows with inline editing across metadata and VM configuration views

  • Swapped legacy namespace/link rendering for a cluster-aware namespace display

  • Removed several legacy metadata components

  • Style

  • Removed unused CSS rules for metadata/label group styling

  • UX

  • Labels now act as clickable elements that navigate to search results

✏️ Tip: You can customize this high-level summary in your review settings.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/utils/components/MetadataLabels/MetadataLabels.tsx (1)

6-6: Consider simplifying the empty-state check for labels

labelsKeys is always an array, so using isEmpty is a bit indirect. A direct length check is simpler and removes the extra dependency.

-import { isEmpty } from '@kubevirt-utils/utils/utils';
+// isEmpty no longer needed

   const MetadataLabels: FC<MetadataLabelsProps> = ({ labels, model }) => {
@@
-  const labelsKeys = Object.keys(labels || {});
-
-  if (isEmpty(labelsKeys)) {
+  const labelsKeys = Object.keys(labels || {});
+
+  if (labelsKeys.length === 0) {
     return <div className="pf-v6-u-text-color-subtle">{t('No labels')}</div>;
   }

Also applies to: 20-24

src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx (1)

25-39: Consider guarding for missing namespace/cluster before rendering FleetResourceLink

If getNamespace(resource) or getCluster(resource) can be undefined (e.g., for cluster-scoped resources or single-cluster cases), FleetResourceLink may render a broken link. Consider a small guard and fallback text (or a non-clickable element) when either value is missing, so the UI degrades gracefully instead of showing an invalid link.

src/utils/components/DescriptionItem/DescriptionItem.tsx (1)

64-90: Add isEdit to the useMemo dependency list for correctness

The memoized description uses isEdit in its condition but isEdit is not in the dependency array. If isEdit can change over the lifecycle of this component, the memoized value may become stale. Including it keeps the memo in sync with the actual edit state.

   const description = useMemo(
@@
-      ),
-    [
+      ),
+    [
       descriptionData,
       isDisabled,
+      isEdit,
       onEditClick,
       messageOnDisabled,
       testId,
       additionalContent,
       showEditOnTitle,
     ],
   );
src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx (1)

23-35: Double-check SearchItem id used for annotations header

For labels you use SearchItem id="labels", but for annotations the wrapper uses id="metadata":

<SearchItem id="metadata">{t('Metadata')}</SearchItem>   // title
...
descriptionHeaderWrapper={(children) => (
  <SearchItem id="metadata">{children}</SearchItem>      // annotations header
)}

If id is used as a search/filter key, a more specific value like "annotations" might be clearer and avoid collisions with the top-level metadata section. Worth confirming this aligns with how SearchItem ids are consumed.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a837759 and a72711e.

📒 Files selected for processing (16)
  • src/utils/components/DescriptionItem/DescriptionItem.tsx (5 hunks)
  • src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx (4 hunks)
  • src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx (3 hunks)
  • src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx (3 hunks)
  • src/utils/components/MetadataLabels/MetadataLabels.scss (0 hunks)
  • src/utils/components/MetadataLabels/MetadataLabels.tsx (1 hunks)
  • src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx (2 hunks)
  • src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx (4 hunks)
  • src/views/catalog/wizard/tabs/metadata/WizardMetadataTab.tsx (1 hunks)
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMAnnotationsDetailsItem.tsx (2 hunks)
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx (2 hunks)
  • src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx (2 hunks)
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabAnnotations/MetadataTabAnnotations.tsx (0 hunks)
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/MetadataTabLabels.tsx (0 hunks)
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/metadata-tab-labels.scss (0 hunks)
  • src/views/virtualmachines/details/tabs/overview/components/VirtualMachinesOverviewTabGeneral/VirtualMachinesOverviewTabGeneral.tsx (2 hunks)
💤 Files with no reviewable changes (4)
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/metadata-tab-labels.scss
  • src/utils/components/MetadataLabels/MetadataLabels.scss
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabLabels/MetadataTabLabels.tsx
  • src/views/virtualmachines/details/tabs/configuration/metadata/components/MetadataTabAnnotations/MetadataTabAnnotations.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/views/catalog/wizard/tabs/metadata/WizardMetadataTab.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMAnnotationsDetailsItem.tsx
  • src/views/virtualmachines/details/tabs/overview/components/VirtualMachinesOverviewTabGeneral/VirtualMachinesOverviewTabGeneral.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemLabels.tsx
  • src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeMetadataTab.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.tsx

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.tsx: Use .tsx file extension for all React components. One component per file. No nested components.
Use PascalCase for all component names (e.g., HeaderTop.tsx).
Use functional components by default. Use class components only for specific lifecycle methods unavailable in functional components (e.g., componentDidCatch).
Use default exports for all components.
Use React's memoization tools (React.memo, useMemo, useCallback) to avoid unnecessary re-renders. Lazy load components with React.lazy and Suspense.
Always specify dependencies in useEffect to avoid unnecessary re-renders or missed updates. Pass an empty array [] to run the effect only once if no dependencies are required.

Files:

  • src/utils/components/MetadataLabels/MetadataLabels.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx
  • src/utils/components/DescriptionItem/DescriptionItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx
  • src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx
  • src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{tsx,ts}: Extract as much logic as possible from components into custom hooks or utility files to improve testability. Avoid bloated components.
Hooks should contain only logic and side effects, not return JSX. Keep JSX in components while using hooks for extracting reusable or unit-testable logic.

Files:

  • src/utils/components/MetadataLabels/MetadataLabels.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx
  • src/utils/components/DescriptionItem/DescriptionItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx
  • src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx
  • src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx}: Use descriptive names for variables, functions, and components. Avoid abbreviations unless widely recognized.
Prefer using type instead of interface for defining the shapes of objects or functions in TypeScript.
Avoid using any type in TypeScript as it compromises type safety. Use unknown instead and narrow the type as needed.
Always explicitly define return types for functions in TypeScript rather than relying on type inference.

Files:

  • src/utils/components/MetadataLabels/MetadataLabels.tsx
  • src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx
  • src/utils/components/DescriptionItem/DescriptionItem.tsx
  • src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx
  • src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx
  • src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-04T14:08:48.257Z
Learning: Add a main PR comment that explains referenced links, Jira, documentation, use cases, and current/required state. Include videos and/or screenshots for visual changes.
📚 Learning: 2025-12-04T14:08:48.257Z
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-04T14:08:48.257Z
Learning: Applies to **/*.tsx : Use React's memoization tools (`React.memo`, `useMemo`, `useCallback`) to avoid unnecessary re-renders. Lazy load components with `React.lazy` and `Suspense`.

Applied to files:

  • src/utils/components/DescriptionItem/DescriptionItem.tsx
🧬 Code graph analysis (4)
src/utils/components/MetadataLabels/MetadataLabels.tsx (2)
src/utils/utils/utils.ts (1)
  • isEmpty (32-33)
src/utils/components/Labels/LabelList.tsx (1)
  • Label (17-35)
src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx (2)
src/views/virtualmachines/details/tabs/configuration/utils/search.ts (1)
  • SearchItem (6-11)
src/views/virtualmachines/details/tabs/configuration/details/utils/utils.ts (1)
  • updateLabels (117-118)
src/utils/components/DescriptionItem/components/DescriptionItemNamespace.tsx (1)
src/multicluster/helpers/selectors.ts (1)
  • getCluster (6-7)
src/views/virtualmachines/details/tabs/configuration/metadata/MetadataTab.tsx (2)
src/views/virtualmachines/details/tabs/configuration/utils/search.ts (1)
  • SearchItem (6-11)
src/views/virtualmachines/details/tabs/configuration/details/utils/utils.ts (2)
  • updateLabels (117-118)
  • updateAnnotation (114-115)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-test
  • GitHub Check: i18n
  • GitHub Check: build
🔇 Additional comments (4)
src/views/topology/components/vm/VMDetailsPanel/components/VMDetailsPanelLeftColumn/components/VMLabelsDetailsItem.tsx (1)

17-22: Labels wiring via DescriptionItemLabels looks consistent

DescriptionItemLabels receives the VM model, resource, SearchItem-wrapped header, and onLabelsSubmit tied to updateLabels(vm, labels); this aligns cleanly with the new shared labels editor pattern.

src/views/catalog/wizard/components/WizardDescriptionItem/WizardDescriptionItem.tsx (1)

37-39: Well-scoped isLabelEditor styling hook

Adding isLabelEditor with a default of false and conditionally applying the co-editable-label-group class on DescriptionListDescription keeps label-editor-specific styling isolated without affecting existing WizardDescriptionItem usages.

Also applies to: 61-62, 142-144

src/utils/components/DescriptionItem/DescriptionItem.tsx (1)

32-33: isLabelEditor-driven layout changes look correct

Using isLabelEditor to:

  • switch justifyContent to space-between,
  • add pf-v6-u-w-100 on the header Flex, and
  • apply co-editable-label-group on DescriptionListDescription

provides the needed full-width, editable-label layout while leaving non-label usages unchanged.

Also applies to: 52-53, 96-100, 132-135

src/utils/components/DescriptionItem/components/DescriptionItemAnnotations.tsx (1)

1-3: Flexible annotations header and submit wiring looks good

The additions of:

  • className passthrough to DescriptionItem,
  • descriptionHeaderWrapper to optionally wrap the "Annotations" header, and
  • onAnnotationsSubmit with a sensible fallback to onAnnotationsSubmitInternal

make this component reusable across contexts (e.g., VM details, metadata tab) without breaking existing behavior. The onSubmit={onAnnotationsSubmit ?? onAnnotationsSubmitInternal} pattern keeps the default patch flow intact while allowing callers to override it.

Also applies to: 11-18, 21-29, 37-38, 50-57, 60-62, 70-73

Copy link
Member

@galkremer1 galkremer1 left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci bot added the lgtm Passed code review, ready for merge label Dec 9, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 9, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: adamviktora, galkremer1

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

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [adamviktora,galkremer1]

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

@openshift-merge-bot openshift-merge-bot bot merged commit e637630 into kubevirt-ui:main Dec 9, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved This issue is something we want to fix jira/valid-reference lgtm Passed code review, ready for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants