Skip to content

[dashboard] fix: allow clearing instanceType and preserve secret copy newlines#2135

Merged
kvaps merged 3 commits intomainfrom
fix/dashboard-allow-empty-instancetype
Mar 2, 2026
Merged

[dashboard] fix: allow clearing instanceType and preserve secret copy newlines#2135
kvaps merged 3 commits intomainfrom
fix/dashboard-allow-empty-instancetype

Conversation

@sircthulhu
Copy link
Contributor

@sircthulhu sircthulhu commented Mar 2, 2026

What this PR does

Updates the openapi-k8s-toolkit integration in the dashboard to fix two UX issues:

1. Allow clearing the instanceType field in VMInstance form

When instanceType has a default value, clearing the field in the form UI would
silently revert to the default, making it impossible to explicitly send an empty
value. This blocked use of custom KubeVirt resources without a named instance type.

Adds allowEmpty: true to the instanceType listInput field so the BFF preserves
an explicit empty value. Also introduces a generic persistType prop
('str' | 'number' | 'arr' | 'obj') to the listInput component, so the
allow-empty behaviour works correctly for any field type, not just strings.

Updates openapi-k8s-toolkit to release/1.4.0 (d6b9e4ad), which already includes
the FormListInput layout refactor — the previous formlistinput-value-binding.diff
patch is no longer needed.

Upstream PR: PRO-Robotech/openapi-k8s-toolkit#340

2. Preserve newlines when copying secrets with CMD+C

Native input[type=text] strips newlines on copy. Adds an onCopy handler to
the SecretBase64Plain component that intercepts the copy event and writes the full
decoded value (including newlines) to the clipboard.

Upstream PR: PRO-Robotech/openapi-k8s-toolkit#339

Release note

[dashboard] Fix clearing instanceType in VMInstance form: explicit empty value
is now correctly sent to the API instead of falling back to the schema default.
Fix CMD+C copying of secrets stripping newlines.

Summary by CodeRabbit

  • New Features

    • Dropdown fields now support configuration to allow empty selections
    • Enhanced empty value handling for form fields across multiple data types (string, number, array, object)
  • Bug Fixes

    • Fixed secret field copy functionality to preserve plain-text format when visible
  • Chores

    • Updated base image dependencies for dashboard build

sircthulhu and others added 3 commits March 2, 2026 22:18
Update openapi-k8s-toolkit to release/1.4.0 (d6b9e4ad). The previous
value-binding layout refactor is already included upstream, so drop the
formlistinput-value-binding.diff patch.

Add formlistinput-allow-empty.diff patch which introduces two props to
the listInput component:
- allowEmpty: when set, auto-persists the field so BFF sends an empty
  value instead of falling back to the schema default
- persistType: controls the type of empty value ('str' | 'number' | 'arr'
  | 'obj'), allowing the feature to work correctly for any field type

Set allowEmpty: true on the VMInstance instanceType field so users can
explicitly clear the selection and override the default instance type.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Kirill Ilin <[email protected]>
… toolkit

Update openapi-k8s-toolkit commit to d6b9e4ad (release/1.4.0) which
includes the FormListInput layout refactor, making formlistinput-value-binding.diff
obsolete.

Set allowEmpty: true on the VMInstance instanceType field so users can
explicitly clear the selection and override the default instance type.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Kirill Ilin <[email protected]>
Add onCopy handler to SecretBase64Plain inputs to intercept native browser
copy events and explicitly write the full decoded text (including newlines)
to the clipboard. Without this, input[type=text] strips newlines on copy.

Upstream PR: PRO-Robotech/openapi-k8s-toolkit#339

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Kirill Ilin <[email protected]>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

Updates the VMInstance configuration to support empty values in dropdown fields by adding an "allowEmpty" flag to the override schema. Includes modifications to patch files for form components to handle empty value persistence and type coercion, removes an obsolete FormListInput component, and updates Docker build configuration.

Changes

Cohort / File(s) Summary
Go Controller & Tests
internal/controller/dashboard/customformsoverride.go, internal/controller/dashboard/customformsoverride_test.go
Added "allowEmpty": true flag injection for VMInstance instanceType field in override schema. Updated test assertion to verify the new customProps setting.
Docker Configuration
packages/system/dashboard/images/openapi-ui/Dockerfile
Updated COMMIT ARG reference in openapi-k8s-toolkit-builder stage to new tarball commit hash.
Form Component Patches
packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/formlistinput-allow-empty.diff
Introduced allowEmpty and persistType optional props to form extension interface. Added auto-persistence side-effect and input normalization logic with type-appropriate defaults (0 for number, [] for array, {} for object, '' for string).
Form Component Removal
packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/formlistinput-value-binding.diff
Removed entire FormListInput.tsx component including UI composition, validation wiring, and tooltip rendering.
Secret Handling Enhancement
packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/secret-copy-preserve-newlines.diff
Added onCopy handlers to DisabledInput components in SecretBase64Plain.tsx to preserve plain-text clipboard copying when field is visible.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A dropdown now dares to be bare,
Empty values float through the air,
Type coercion with care,
Secrets copy with flair,
Forms evolving everywhere!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the two main UX fixes in the pull request: allowing clearing the instanceType field and preserving newlines in secret copy operations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/dashboard-allow-empty-instancetype

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses two user experience issues within the dashboard's openapi-k8s-toolkit integration. It resolves the problem where the instanceType field in VMInstance forms could not be explicitly cleared, which previously hindered the use of custom KubeVirt resources. Additionally, it fixes an issue preventing newlines from being copied correctly when interacting with secret fields, ensuring that full decoded values are transferred to the clipboard. These changes enhance the usability and reliability of form interactions and secret management within the dashboard.

Highlights

  • VMInstance Form instanceType Field Fix: Enabled explicit clearing of the instanceType field in VMInstance forms, preventing it from reverting to a default value and allowing the use of custom KubeVirt resources without a named instance type. This was achieved by adding allowEmpty: true and a generic persistType prop to the listInput component, and updating the openapi-k8s-toolkit dependency.
  • Secret Copy Newline Preservation: Implemented an onCopy handler for the SecretBase64Plain component to ensure that newlines are preserved when copying decoded secret values, addressing an issue where native input[type=text] strips newlines.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • internal/controller/dashboard/customformsoverride.go
    • Enabled allowEmpty for the instanceType field in VMInstance forms.
  • packages/system/dashboard/images/openapi-ui/Dockerfile
    • Updated openapi-k8s-toolkit dependency to release/1.4.0 (commit d6b9e4ad).
  • packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/formlistinput-allow-empty.diff
    • Added a new patch to support allowEmpty and persistType in FormListInput.
  • packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/formlistinput-value-binding.diff
    • Removed an obsolete patch as its functionality is now included in the updated openapi-k8s-toolkit.
  • packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/secret-copy-preserve-newlines.diff
    • Added a patch to ensure newlines are preserved when copying secret values from the UI.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses two user experience issues in the dashboard. First, it allows clearing the instanceType field in the VMInstance form by adding an allowEmpty property. Second, it ensures newlines are preserved when copying secrets. The changes are well-structured, with backend adjustments in Go and frontend fixes delivered as patches. The corresponding tests and dependency updates are also included. I've provided a couple of minor suggestions in the frontend patch files to enhance code clarity and reduce duplication. Overall, this is a solid improvement.

hasFeedback={designNewLayout ? { icons: feedbackIcons } : true}
style={{ flex: 1 }}
+ normalize={(value: unknown) => {
+ if (customProps.allowEmpty && (value === undefined || value === null)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For conciseness, you can use value == null to check for both undefined and null. This is a common JavaScript/TypeScript idiom.

            if (customProps.allowEmpty && value == null) {

Comment on lines +21 to +26
+ onCopy={e => {
+ if (!effectiveHidden) {
+ e.preventDefault()
+ e.clipboardData?.setData('text/plain', value)
+ }
+ }}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This onCopy handler logic is identical to the one added on lines 8-13. To avoid code duplication and improve maintainability, consider extracting this logic into a shared function within the component.

For example:

const handleCopy = (e: React.ClipboardEvent<HTMLInputElement>) => {
  if (!effectiveHidden) {
    e.preventDefault();
    e.clipboardData?.setData('text/plain', value);
  }
};

Then you can use onCopy={handleCopy} in both places where Styled.DisabledInput is used.

@sircthulhu sircthulhu marked this pull request as ready for review March 2, 2026 17:45
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Mar 2, 2026
Copy link
Contributor

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

🧹 Nitpick comments (1)
packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/secret-copy-preserve-newlines.diff (1)

8-13: Extract duplicated onCopy logic into a shared handler.

Same handler body is repeated twice; centralizing it will reduce drift and keep secret-copy behavior consistent.

♻️ Suggested refactor
+  const handleCopy = (e: React.ClipboardEvent<HTMLInputElement>) => {
+    if (effectiveHidden) return
+    e.preventDefault()
+    e.clipboardData?.setData('text/plain', value)
+  }
...
-                onCopy={e => {
-                  if (!effectiveHidden) {
-                    e.preventDefault()
-                    e.clipboardData?.setData('text/plain', value)
-                  }
-                }}
+                onCopy={handleCopy}
...
-              onCopy={e => {
-                if (!effectiveHidden) {
-                  e.preventDefault()
-                  e.clipboardData?.setData('text/plain', value)
-                }
-              }}
+              onCopy={handleCopy}

Also applies to: 21-26

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/secret-copy-preserve-newlines.diff`
around lines 8 - 13, The duplicated onCopy handler logic (the inline arrow that
checks effectiveHidden, calls e.preventDefault() and sets clipboardData with
value) should be extracted into a single function (e.g., handleSecretCopy or
onCopyHandler) and reused in both places where the same body appears; implement
the handler so it closes over or accepts effectiveHidden and value (or receives
them as parameters) and replace the two inline onCopy props with a reference to
this shared handler, removing the duplicated code to keep secret-copy behavior
consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/secret-copy-preserve-newlines.diff`:
- Around line 8-13: The duplicated onCopy handler logic (the inline arrow that
checks effectiveHidden, calls e.preventDefault() and sets clipboardData with
value) should be extracted into a single function (e.g., handleSecretCopy or
onCopyHandler) and reused in both places where the same body appears; implement
the handler so it closes over or accepts effectiveHidden and value (or receives
them as parameters) and replace the two inline onCopy props with a reference to
this shared handler, removing the duplicated code to keep secret-copy behavior
consistent.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a46195 and 99ee0e3.

📒 Files selected for processing (6)
  • internal/controller/dashboard/customformsoverride.go
  • internal/controller/dashboard/customformsoverride_test.go
  • packages/system/dashboard/images/openapi-ui/Dockerfile
  • packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/formlistinput-allow-empty.diff
  • packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/formlistinput-value-binding.diff
  • packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/secret-copy-preserve-newlines.diff
💤 Files with no reviewable changes (1)
  • packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/formlistinput-value-binding.diff

@kvaps kvaps added the backport Should change be backported on previus release label Mar 2, 2026
Copy link
Member

@kvaps kvaps left a comment

Choose a reason for hiding this comment

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

LGTM

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Mar 2, 2026
@kvaps kvaps merged commit 8d566a2 into main Mar 2, 2026
14 checks passed
@kvaps kvaps deleted the fix/dashboard-allow-empty-instancetype branch March 2, 2026 18:27
@github-actions
Copy link

github-actions bot commented Mar 2, 2026

kvaps added a commit that referenced this pull request Mar 2, 2026
…nd preserve secret copy newlines (#2137)

# Description
Backport of #2135 to `release-1.0`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport Should change be backported on previus release bug Something isn't working lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants