Skip to content

EDM-4160: Better UX when a single repository type can be chosen#698

Open
celdrake wants to merge 1 commit into
flightctl:mainfrom
celdrake:EDM-4160-clarify-disabled-repo-types
Open

EDM-4160: Better UX when a single repository type can be chosen#698
celdrake wants to merge 1 commit into
flightctl:mainfrom
celdrake:EDM-4160-clarify-disabled-repo-types

Conversation

@celdrake

@celdrake celdrake commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

When the UI shows the "Create repository" modal and a single repository type can be chosen, we now show the type as a read-only field with an explanation about why the type is restricted.

Fixes also a bug when clicking on "Create repository", that the dropdown would stay open and display on top of the already open modal.

A) In the Image builder section
image-builder-repos

B) In the fleet/device wizard, for Git/Http configurations
git-configurations

Summary

This PR improves the “Create repository” UX when the system allows only one repository type by rendering the repository type as a read-only value with a help popover explaining the restriction. It also fixes a UI layering bug where clicking “Create repository” could leave the dropdown open and show it on top of the already-open create modal.

Areas affected

  • libs/ui-components/ (shared UI used across both standalone and OCP plugin experiences)
  • libs/i18n/ (added the enforced-type help texts to translation.json)

Key changes

Shared UI component enhancements (cross-app)

  • libs/ui-components/src/components/form/RepositorySelect.tsx

    • Adds support for an options.enforcedRepoTypeMessage?: string.
    • Refactors the “Create repository” action wiring to use a derived addAction passed into FormSelect (removing the previous inline MenuFooter/button rendering), which prevents the dropdown/menu from remaining open and overlaying the create modal.
  • libs/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx

    • Threads enforcedRepoTypeMessage through the create-repository flow and updates the repository type UI to:
      • show an enforced single-type label under “Repository type”
      • display a question-mark Popover containing enforcedRepoTypeMessage.
  • libs/ui-components/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.tsx

    • Accepts options.enforcedRepoTypeMessage and forwards it into CreateRepositoryForm.

Context-specific integrations

  • Image builder

    • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/SourceImageStep.tsx
    • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/OutputImageStep.tsx
    • Pass enforcedRepoTypeMessage so the destination registry type is restricted to OCI registries.
  • Fleet/device wizard (Git/HTTP configs)

    • libs/ui-components/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.tsx
    • Pass enforcedRepoTypeMessage so the repository type is restricted with an i18n message (e.g., Git vs HTTP) consistent with the current wizard context.

i18n

  • libs/i18n/locales/en/translation.json
    • Adds/ensures entries for:
      • “Only OCI registries can be used for image builds.”
      • “Only Git repositories can be used for Git configurations.”

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: c86f4342-8061-46db-a51e-737a63a4fd6e

📥 Commits

Reviewing files that changed from the base of the PR and between 7088157 and 1dd54dc.

⛔ Files ignored due to path filters (1)
  • libs/i18n/locales/en/translation.json is excluded by !libs/i18n/locales/en/translation.json
📒 Files selected for processing (6)
  • libs/ui-components/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.tsx
  • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/OutputImageStep.tsx
  • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/SourceImageStep.tsx
  • libs/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx
  • libs/ui-components/src/components/form/RepositorySelect.tsx
  • libs/ui-components/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.tsx

Walkthrough

Adds an enforcedRepoTypeMessage prop through the repository UI stack: RepositorySelect, CreateRepositoryModal, CreateRepositoryForm, and RepositoryType. When a single repo type is enforced, RepositoryType now renders the type label with an optional question-mark Popover instead of disabled radio buttons. RepositorySelect also refactors the create-repository action from an inline MenuFooter/Button to an addAction prop on FormSelect.

Changes

Enforced Repo Type Message — Full Stack

Layer / File(s) Summary
CreateRepositoryForm contract and RepositoryType conditional rendering
libs/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx
Extends RepositoryForm and CreateRepositoryFormProps.options with enforcedRepoTypeMessage?: string. Adds Popover, OutlinedQuestionCircleIcon, and getRepoTypeLabel imports. RepositoryType accepts the new prop, detects single-allowed-type mode, renders the type label and an optional question-mark Popover, and drops isDisabled wiring from all three radio controls.
CreateRepositoryModal option forwarding
libs/ui-components/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.tsx
Adds enforcedRepoTypeMessage?: string to CreateRepositoryModalProps.options and threads it into CreateRepositoryForm options.
RepositorySelect addAction refactor and new option
libs/ui-components/src/components/form/RepositorySelect.tsx
Removes Button and MenuFooter imports, adds enforcedRepoTypeMessage?: string to the options type, computes an addAction object from canCreateRepo, and passes it to FormSelect in place of the previous inline footer.
Wizard step callers
libs/ui-components/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.tsx, libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/OutputImageStep.tsx, libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/SourceImageStep.tsx
Each wizard step passes a localized enforcedRepoTypeMessage to RepositorySelect: Git/HTTP restriction in the device config form and OCI-only restriction in both image build steps.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested labels

ui-components, i18n

Suggested reviewers

  • rawagner

Poem

A radio button once sat disabled and grey,
Now a popover politely explains the way.
"Only OCI here!" the little icon cries,
As enforcedRepoTypeMessage gently clarifies.
From wizard step to modal, the prop travels through —
Clean wiring and labels for a friendlier UI. 🔧

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
I18n-Compliance ⚠️ Warning CreateRepositoryForm.tsx line 300 contains hardcoded user-visible string 'Change repository type?' not wrapped in t() translation function, violating i18n compliance. Wrap the modal title string in t(): <ModalHeader title={t('Change repository type?')} titleIconVariant="warning" />
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main change: improving UX when a single repository type is available, which aligns with all file changes implementing enforcedRepoTypeMessage functionality.
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 No hardcoded secrets, API keys, tokens, passwords, base64 strings, or embedded credentials found. Changes are UI localization enhancements using i18n messages; all sensitive references are form fie...
No-Weak-Crypto ✅ Passed No weak cryptographic algorithms (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB), custom crypto implementations, or non-constant-time secret comparisons detected. PR contains UI improvements and i18n ch...
No-Injection-Vectors ✅ Passed No injection vectors found. All enforcedRepoTypeMessage values are hardcoded i18n strings passed through t() function, never from user/untrusted input. Safe rendering via PatternFly Popover.
Container-Privileges ✅ Passed PR contains only TypeScript/React UI components—no Docker/Kubernetes manifests with container security configurations are present or modified.
No-Sensitive-Data-In-Logs ✅ Passed No logging statements or sensitive data exposure detected. PR adds UI messages explaining repository type restrictions, with no console logging, logger calls, or sensitive information being logged...
Resource-Leaks ✅ Passed All Go files in proxy/ properly manage resources: goroutines communicate via error channels with defer cleanup; HTTP responses have Body.Close(); file operations use os.ReadFile() or http.FileServe...
Unchecked-Errors ✅ Passed PR contains only TypeScript/React (.tsx) UI component changes; check is for Go files in proxy/ directory, which are not modified.
Ai-Attribution ✅ Passed Commit contains proper AI attribution trailer "Made-with: Cursor" and no misuse of Co-Authored-By for AI tools.
Generated-Files-Not-Hand-Edited ✅ Passed PR modifies only component files (ConfigWithRepositoryTemplateForm, OutputImageStep, SourceImageStep, CreateRepositoryForm, RepositorySelect, CreateRepositoryModal). Translation.json and model file...

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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
`@libs/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx`:
- Around line 213-215: The icon-only Button component that serves as the trigger
for the Popover in CreateRepositoryForm has no accessible label, making it
inaccessible to assistive technologies. Add an aria-label prop to the Button
element with a descriptive label that explains the button's purpose (e.g.,
indicating it provides information about repository type enforcement). This will
provide assistive technology users with a clear understanding of what the button
does and make the help content discoverable.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 77e59335-6bdf-4f4d-8c87-228c66026c6d

📥 Commits

Reviewing files that changed from the base of the PR and between e097809 and 312047d.

⛔ Files ignored due to path filters (1)
  • libs/i18n/locales/en/translation.json is excluded by !libs/i18n/locales/en/translation.json
📒 Files selected for processing (6)
  • libs/ui-components/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.tsx
  • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/OutputImageStep.tsx
  • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/SourceImageStep.tsx
  • libs/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx
  • libs/ui-components/src/components/form/RepositorySelect.tsx
  • libs/ui-components/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.tsx

@celdrake celdrake force-pushed the EDM-4160-clarify-disabled-repo-types branch from 312047d to 7088157 Compare June 15, 2026 09:54
@celdrake celdrake force-pushed the EDM-4160-clarify-disabled-repo-types branch from 7088157 to 1dd54dc Compare June 15, 2026 10:00

@jkilzi jkilzi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Good UX improvement. Showing a plain text label + info popover when a single repo type is pre-selected is much clearer than disabled radio buttons with no explanation.

Nit — comment wording: the inline comment // When we don't want to hide the repository type, but a single repoType can be chosen... is a bit ambiguous. Consider: // When exactly one repo type is allowed, render it as read-only text with an optional explanation popover instead of showing disabled radio buttons.

Watch — merge conflict with #702: both this PR and #702 add const { t } = useTranslation() to ConfigWithRepositoryTemplateForm.tsx. Whoever merges second will hit a conflict on that line — a one-line fix, but needs attention. Suggested merge order: #692 → this PR → #702.

@celdrake

Copy link
Copy Markdown
Collaborator Author

Will fix conflicts after #692 since they touch the same component.

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.

2 participants