OU-1139: feat: allow to import and migrate a dashboard#779
Conversation
|
@jgbernalp: This pull request references OU-1139 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.22.0" version, but no target version was set. DetailsIn response to this:
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. |
|
@jgbernalp: This pull request references OU-1139 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.22.0" version, but no target version was set. DetailsIn response to this:
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. |
📝 WalkthroughWalkthroughAdds a dashboard actions menu with Create and Import flows, converts the create dialog to a controlled component, introduces a large dashboard import modal (file/editor, parsing, Grafana→Perses migration), adds a migration API/hook, updates i18n keys, adds a code-editor dependency, and a data-test id. Changes
Sequence DiagramsequenceDiagram
actor User
participant UI as Dashboard UI
participant Parser as Format Detector/Parser
participant MigrationAPI as Migration Service
participant PersesAPI as Perses API
participant Router as Router
User->>UI: Upload file or paste dashboard (JSON/YAML)
UI->>Parser: Parse input & detect format
alt Format valid
Parser-->>UI: Detected Grafana or Perses
alt Grafana detected
UI->>MigrationAPI: POST migrate (Grafana -> Perses)
MigrationAPI-->>UI: Migrated Perses dashboard
else Perses detected
Parser-->>UI: Parsed Perses dashboard
end
User->>UI: Select target project
UI->>PersesAPI: POST import dashboard
PersesAPI-->>UI: Import success (dashboard id)
UI->>Router: Navigate to new dashboard
UI-->>User: Show success alert
else Invalid input / size / type
Parser-->>UI: Error (invalid format / parsing / size / type)
UI-->>User: Show error alert
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/package.json`:
- Line 68: The project has a dependency mismatch: the added dependency
"@patternfly/react-code-editor" (entry "@patternfly/react-code-editor":
"^6.4.1") requires "@patternfly/react-core@^6.4.1" while the project currently
pins "@patternfly/react-core" to 6.2.x; fix by either updating the project's
"@patternfly/react-core" version in package.json to at least "6.4.1" (and run
install/lockfile update) or replace/pin the "@patternfly/react-code-editor"
entry to a 6.2.x compatible release so both packages share a compatible version
range. Ensure package.json reflects the chosen option and regenerate the
lockfile.
In `@web/src/components/dashboards/perses/dashboard-actions-menu.tsx`:
- Around line 70-73: The Import DropdownItem is missing the test hook; update
the DropdownItem rendering for the Import action (the element using DropdownItem
and onClick={handleImportClick}) to include the data-test attribute with
persesDashboardDataTestIDs.importDashboardButtonToolbar so E2E selectors can
target it; ensure the attribute name matches the test suite expectation (e.g.,
data-test or data-testid) consistent with other components.
In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx`:
- Line 305: The Import button can stay enabled when a parse/validation error
exists because the guard only checks parsedDashboard, selectedProject and
isImporting; update the guard for canImport to also require no parseError so
stale/invalid parsed data cannot be imported. Locate the const canImport
declaration and change it to include && !parseError (ensuring parseError is in
scope), so the expression uses parsedDashboard && selectedProject &&
!isImporting && !parseError.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (1)
web/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (8)
web/locales/en/plugin__monitoring-plugin.jsonweb/package.jsonweb/src/components/dashboards/perses/dashboard-actions-menu.tsxweb/src/components/dashboards/perses/dashboard-create-dialog.tsxweb/src/components/dashboards/perses/dashboard-header.tsxweb/src/components/dashboards/perses/dashboard-import-dialog.tsxweb/src/components/dashboards/perses/migrate-api.tsweb/src/components/data-test.ts
web/src/components/dashboards/perses/dashboard-import-dialog.tsx
Outdated
Show resolved
Hide resolved
|
/cherry-pick release-coo-0.5 |
|
@jgbernalp: once the present PR merges, I will cherry-pick it on top of DetailsIn response to this:
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. |
web/src/components/dashboards/perses/dashboard-import-dialog.tsx
Outdated
Show resolved
Hide resolved
fa00fad to
8537252
Compare
|
@jgbernalp: This pull request references OU-1139 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.22.0" version, but no target version was set. DetailsIn response to this:
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. |
8537252 to
fc85fef
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (2)
web/src/components/dashboards/perses/dashboard-actions-menu.tsx (1)
70-73:data-testattribute missing on ImportDropdownItem.
persesDashboardDataTestIDs.importDashboardButtonToolbaris defined but not applied to the ImportDropdownItem, preventing E2E selectors from targeting it.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-actions-menu.tsx` around lines 70 - 73, The Import DropdownItem is missing the E2E selector; add the data-test attribute using the existing identifier persesDashboardDataTestIDs.importDashboardButtonToolbar to the Import <DropdownItem> (the one rendering {t('Import')} and using onClick={handleImportClick}) so tests can target it; ensure the attribute is added to the JSX element alongside the key and onClick attributes.web/src/components/dashboards/perses/dashboard-import-dialog.tsx (1)
174-184:⚠️ Potential issue | 🟡 MinorEarly MIME/size validation returns without clearing
parsedDashboard— root cause of stale import guard.When file-type or size validation fails, the function returns early after setting
parseErrorbut leaves any previously-setparsedDashboardintact. This meanscanImport(Line 305) can still evaluate totruedespite a live parse error, allowing the user to import stale data from a prior successful parse. The previous review already flagged adding!parseErrortocanImport; clearing the parsed state on these early-exit paths fixes it at the source.🐛 Proposed fix
if (file.type && !ALLOWED_MIME_TYPES.includes(file.type)) { setParseError( t('Invalid file type. Please upload a JSON or YAML file (.json, .yaml, .yml)'), ); + setParsedDashboard(undefined); return; } if (file.size > MAX_FILE_SIZE) { setParseError(t('File size exceeds maximum allowed size of 5MB')); + setParsedDashboard(undefined); return; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 174 - 184, The early-return validation branches set parseError but don’t clear the existing parsed dashboard, leaving parsedDashboard stale and allowing canImport to remain true; update the file-type and file-size failure paths in the import handler to call setParsedDashboard(null) (or the appropriate empty state) immediately before setParseError and return so parsedDashboard is cleared whenever parseError is set, ensuring canImport correctly reflects the error state; reference the setParseError and setParsedDashboard state setters and the parsedDashboard/canImport logic in dashboard-import-dialog.tsx when applying the change.
🧹 Nitpick comments (2)
web/src/components/dashboards/perses/dashboard-import-dialog.tsx (1)
246-274: MigrationonErrorsilently updates only inline state — no toast alert shown.When Grafana migration fails, the
onErrorcallback (Lines 268–273) callssetFormErrorsbut omitsaddAlert. By contrast, every other failure path in this function (Lines 261–264, Lines 280–283) calls both. Users who have scrolled past the modal's inline error banner will miss migration failures entirely.🔧 Proposed fix
- onError: (error) => { - const errorMessage = - getErrorMessage(error) || t('Migration failed. Please try again.'); - setFormErrors({ general: errorMessage }); - }, + onError: (error) => { + const errorMessage = + getErrorMessage(error) || t('Migration failed. Please try again.'); + addAlert( + t('Error importing dashboard: {{error}}', { error: errorMessage }), + 'danger', + ); + setFormErrors({ general: errorMessage }); + },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 246 - 274, The migration onError handler for migrateMutation.mutate currently only calls setFormErrors and so fails to surface failures to users; update the onError callback in migrateMutation.mutate to also call addAlert with the composed error message (use getErrorMessage(error) || t('Migration failed. Please try again.')) — mirror the pattern used in the import onSuccess catch and other error paths so both addAlert(...) and setFormErrors({ general: errorMessage }) are invoked in the onError handler.web/src/components/dashboards/perses/migrate-api.ts (1)
24-27: Error context discarded on migration failure.
new Error(Failed to migrate dashboard: ${message})replaces the original error, dropping any HTTP status, response body details, or structured error data thatconsoleFetchJSONwould have included. Callers only see the generic message string.Consider re-throwing or appending the original error as a
causeto preserve debuggability:♻️ Proposed fix
- throw new Error(`Failed to migrate dashboard: ${message}`); + throw new Error(`Failed to migrate dashboard: ${message}`, { cause: error });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/migrate-api.ts` around lines 24 - 27, The catch block that currently does "const message = error instanceof Error ? error.message : 'Unknown error'; throw new Error(`Failed to migrate dashboard: ${message}`);" discards the original error details; update it to preserve the original error as the cause (e.g., throw new Error(`Failed to migrate dashboard: ${message}`, { cause: error })) or attach the original error object to the thrown error (e.g., set a .cause or .originalError property) so callers can access HTTP status/response/body from consoleFetchJSON; keep the existing message but pass the original error through using the Error constructor's cause option or by re-throwing the original error after augmenting it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/dashboards/perses/dashboard-actions-menu.tsx`:
- Around line 1-17: The file uses React namespace types (e.g.,
React.FunctionComponent in DashboardActionsMenu and
React.Ref<MenuToggleElement>) but doesn't import the React namespace; add the
missing import by inserting "import React from 'react'" at the top of the file
so React is in scope for those type references (match the project's pattern used
in files like dashboard-header.tsx).
In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx`:
- Around line 159-166: The Modal's aria-labelledby points to an id that doesn't
exist; update the Modal and ModalHeader to share a real id via ModalHeader's
labelId prop. Concretely, create a single id string (e.g. "modal-with-dropdown"
or "modal-with-dropdown-title"), set the Modal's aria-labelledby to that id, and
pass the same id into the ModalHeader via its labelId prop (and ensure the
header's title uses that id through the labelId mechanism). Modify the Modal
usage and the ModalHeader invocation in dashboard-create-dialog.tsx so they
reference the same id instead of leaving aria-labelledby pointing to a
non-existent element.
In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx`:
- Around line 307-315: The Modal's aria-labelledby points to a missing id
("import-dashboard-modal") so screen readers can't find the title; fix by giving
the ModalHeader the matching id or removing aria-labelledby. Update the JSX
where Modal and ModalHeader are used (the Modal element with props
isOpen/onClose/onEscapePress and the ModalHeader component) so that ModalHeader
receives id="import-dashboard-modal" (or remove aria-labelledby from Modal to
let PatternFly handle it) to ensure the label reference resolves.
- Around line 364-374: The editor language is hardcoded to JSON
(language={Language.json}) causing wrong highlighting for YAML uploads; update
the component to derive the language dynamically (e.g., from the uploaded file
name or content) and pass that instead of Language.json. Add a small helper like
determineLanguageFromFilename(filename) (or content-sniffing) and a state
variable (e.g., editorLanguage) that gets set when the file is uploaded or
dashboardInput changes, then replace language={Language.json} with
language={editorLanguage} and ensure the upload handler or
handleDashboardInputChange sets editorLanguage appropriately for .yaml/.yml =>
Language.yaml and .json => Language.json (fall back to a default).
- Line 1: The file uses React.FunctionComponent<DashboardImportDialogProps> but
doesn't import the React namespace; add an import for React (e.g., import React
from 'react';) at the top of the file alongside the existing imports so the
React identifier is defined for the React.FunctionComponent type used in the
DashboardImportDialog component declaration.
---
Duplicate comments:
In `@web/src/components/dashboards/perses/dashboard-actions-menu.tsx`:
- Around line 70-73: The Import DropdownItem is missing the E2E selector; add
the data-test attribute using the existing identifier
persesDashboardDataTestIDs.importDashboardButtonToolbar to the Import
<DropdownItem> (the one rendering {t('Import')} and using
onClick={handleImportClick}) so tests can target it; ensure the attribute is
added to the JSX element alongside the key and onClick attributes.
In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx`:
- Around line 174-184: The early-return validation branches set parseError but
don’t clear the existing parsed dashboard, leaving parsedDashboard stale and
allowing canImport to remain true; update the file-type and file-size failure
paths in the import handler to call setParsedDashboard(null) (or the appropriate
empty state) immediately before setParseError and return so parsedDashboard is
cleared whenever parseError is set, ensuring canImport correctly reflects the
error state; reference the setParseError and setParsedDashboard state setters
and the parsedDashboard/canImport logic in dashboard-import-dialog.tsx when
applying the change.
---
Nitpick comments:
In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx`:
- Around line 246-274: The migration onError handler for migrateMutation.mutate
currently only calls setFormErrors and so fails to surface failures to users;
update the onError callback in migrateMutation.mutate to also call addAlert with
the composed error message (use getErrorMessage(error) || t('Migration failed.
Please try again.')) — mirror the pattern used in the import onSuccess catch and
other error paths so both addAlert(...) and setFormErrors({ general:
errorMessage }) are invoked in the onError handler.
In `@web/src/components/dashboards/perses/migrate-api.ts`:
- Around line 24-27: The catch block that currently does "const message = error
instanceof Error ? error.message : 'Unknown error'; throw new Error(`Failed to
migrate dashboard: ${message}`);" discards the original error details; update it
to preserve the original error as the cause (e.g., throw new Error(`Failed to
migrate dashboard: ${message}`, { cause: error })) or attach the original error
object to the thrown error (e.g., set a .cause or .originalError property) so
callers can access HTTP status/response/body from consoleFetchJSON; keep the
existing message but pass the original error through using the Error
constructor's cause option or by re-throwing the original error after augmenting
it.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (1)
web/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (8)
web/locales/en/plugin__monitoring-plugin.jsonweb/package.jsonweb/src/components/dashboards/perses/dashboard-actions-menu.tsxweb/src/components/dashboards/perses/dashboard-create-dialog.tsxweb/src/components/dashboards/perses/dashboard-header.tsxweb/src/components/dashboards/perses/dashboard-import-dialog.tsxweb/src/components/dashboards/perses/migrate-api.tsweb/src/components/data-test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- web/package.json
web/src/components/dashboards/perses/dashboard-import-dialog.tsx
Outdated
Show resolved
Hide resolved
|
@jgbernalp: This pull request references OU-1139 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.22.0" version, but no target version was set. DetailsIn response to this:
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. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
web/src/components/dashboards/perses/dashboard-create-dialog.tsx (2)
97-97:⚠️ Potential issue | 🟡 MinorDashboard name duplicate error bypasses i18n.
Line 97 uses a template literal instead of
t(). A matching locale key already exists:"Dashboard name '{{dashboardName}}' already exists in '{{projectName}}' project!"— use it withselectedProjectasprojectName.🌐 Proposed fix
- setFormErrors({ - dashboardName: `Dashboard name "${dashboardName}" already exists in this project`, - }); + setFormErrors({ + dashboardName: t( + "Dashboard name '{{dashboardName}}' already exists in '{{projectName}}' project!", + { dashboardName, projectName: selectedProject }, + ), + });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx` at line 97, Replace the hard-coded template string that constructs the duplicate name error with a call to the i18n translator; in the component (dashboard-create-dialog.tsx) where you currently build dashboardName: `Dashboard name "${dashboardName}" already exists in this project`, use the existing locale key "Dashboard name '{{dashboardName}}' already exists in '{{projectName}}' project!" via t(...) and pass { dashboardName, projectName: selectedProject } so the message is localized and includes the project name.
132-132:⚠️ Potential issue | 🟡 MinorSuccess and error alerts on Lines 132 and 143 are not translated.
Both
addAlertcalls use hardcoded English template literals while the import dialog equivalents correctly uset(). These need botht()wrappers and corresponding locale keys added (e.g.,"Dashboard \"{{name}}\" created successfully"and"Error creating dashboard: {{error}}").🌐 Proposed fix
- addAlert(`Dashboard "${dashboardName}" created successfully`, 'success'); + addAlert(t('Dashboard "{{name}}" created successfully', { name: dashboardName }), 'success');- addAlert(`Error creating dashboard: ${errorMessage}`, 'danger'); + addAlert(t('Error creating dashboard: {{error}}', { error: errorMessage }), 'danger');🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx` at line 132, Replace the hardcoded English template literals passed to addAlert with translated strings using t() and interpolation: wrap the success message (where addAlert(`Dashboard "${dashboardName}" created successfully`, 'success') is called) as t('dashboard.created_success', { name: dashboardName }) and wrap the error alert (the addAlert call on failure) as t('dashboard.create_error', { error: errorMessageOrErr }); update the locale files with keys "dashboard.created_success": "Dashboard \"{{name}}\" created successfully" and "dashboard.create_error": "Error creating dashboard: {{error}}". Ensure you reference the exact variables used in the function (dashboardName and the caught error variable) when passing interpolation values to t().
♻️ Duplicate comments (6)
web/src/components/dashboards/perses/dashboard-import-dialog.tsx (4)
1-65:⚠️ Potential issue | 🔴 CriticalAdd missing
Reactimport forReact.FunctionComponent.Line 65 uses
React.FunctionComponent<DashboardImportDialogProps>butReactis never imported. With"jsx": "react-jsx", the JSX transform is automatic, but namespace-qualified type references likeReact.FunctionComponentstill require theReactidentifier to be in scope. This is a TypeScript compilation error.🔧 Proposed fix
+import React from 'react'; import { useMemo, useState, ChangeEvent } from 'react';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 1 - 65, The file references React.FunctionComponent in the DashboardImportDialog declaration but never imports the React identifier, causing a TypeScript error; fix by adding a top-level import for React (so React is in scope) or change the component type to use the standalone FunctionComponent/FC type from 'react' and import that instead (e.g., import React, { FunctionComponent } from 'react' or import { FunctionComponent } from 'react' and use FunctionComponent<DashboardImportDialogProps> on DashboardImportDialog).
364-374:CodeEditorlanguage is hardcoded toLanguage.jsonregardless of uploaded file type.Valid YAML content uploaded via the file picker will still receive JSON syntax highlighting, producing misleading red markers. Derive the language from the
filenamestate already available in this component.♻️ Proposed fix
+ const editorLanguage = + filename.endsWith('.yaml') || filename.endsWith('.yml') ? Language.yaml : Language.json; + <CodeEditor id="import-dashboard-code-editor" code={dashboardInput} onChange={handleDashboardInputChange} - language={Language.json} + language={editorLanguage} height="300px" isLineNumbersVisible isDarkTheme={theme === 'dark'} />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 364 - 374, The CodeEditor is always using Language.json causing YAML uploads to be highlighted incorrectly; change the language prop on the CodeEditor (component instance with id "import-dashboard-code-editor") to be derived from the component's filename state instead of hardcoding Language.json: implement a small mapping from filename extension (e.g., .yaml/.yml -> Language.yaml, .json -> Language.json) or a utility like getLanguageFromFilename(filename) and pass that result to the language prop, leaving dashboardInput and handleDashboardInputChange unchanged so uploads pick the correct syntax highlighting.
308-315:⚠️ Potential issue | 🟡 Minor
aria-labelledby="import-dashboard-modal"references a non-existent element ID.The PF6
Modalprop documentation states thataria-labelledby"should include the ModalHeaderlabelId." SinceModalHeaderdoes not have anidprop and no element in the render tree carriesid="import-dashboard-modal", screen readers cannot resolve this reference. UseModalHeader'slabelIdprop to generate the matching ID.♿ Proposed fix
- aria-labelledby="import-dashboard-modal" + aria-labelledby="import-dashboard-modal-title" > - <ModalHeader title={t('Import Dashboard')} /> + <ModalHeader title={t('Import Dashboard')} labelId="import-dashboard-modal-title" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 308 - 315, The Modal's aria-labelledby references "import-dashboard-modal" which doesn't exist; update the ModalHeader usage to supply a matching labelId and use that labelId value for the Modal's aria-labelledby prop (e.g., generate a constant id like labelId = 'import-dashboard-modal' and pass it to ModalHeader via its labelId prop, then set Modal aria-labelledby={labelId}); modify the JSX around Modal and ModalHeader to wire the same unique id string to both components so screen readers can resolve the label.
151-160: Show only the relevant parse error, not both JSON and YAML errors concatenated.When input fails both parsers, the combined
"JSON: ..., YAML: ..."detail string gives users two low-level error messages with no clear actionable path. Since the input can be sniffed (starts with{→ JSON, otherwise YAML), only the relevant parser's error should be surfaced.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 151 - 160, The catch block currently concatenates both jsonError and yamlError messages; change it to surface only the relevant parser error: determine which parser was expected by sniffing the trimmed input (e.g., if trimmedInput.startsWith('{') treat as JSON else YAML), then pick only jsonError.message or yamlError.message accordingly; keep the existing calls to setParsedDashboard(undefined) and setParseError but build details from the chosen error (fallback to the other error only if the chosen one is absent) using the same user-facing prefix text.web/src/components/dashboards/perses/dashboard-create-dialog.tsx (1)
159-167:⚠️ Potential issue | 🟡 Minor
aria-labelledby="modal-with-dropdown"references a non-existent element ID.PF6 Modal's
aria-labelledby"should include the ModalHeaderlabelId." No element in the rendered output hasid="modal-with-dropdown", so screen readers cannot resolve the reference.♿ Proposed fix
- aria-labelledby="modal-with-dropdown" + aria-labelledby="create-dashboard-modal-title" > - <ModalHeader title={t('Create Dashboard')} /> + <ModalHeader title={t('Create Dashboard')} labelId="create-dashboard-modal-title" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx` around lines 159 - 167, The Modal currently sets aria-labelledby="modal-with-dropdown" which doesn't match any rendered element; update the Modal/ModalHeader usage so the Modal's aria-labelledby references the ModalHeader's actual label id (use the ModalHeader's labelId prop value or pass a matching id down), e.g. ensure Modal aria-labelledby equals the ModalHeader's labelId string (locate the Modal component and the ModalHeader call in dashboard-create-dialog.tsx around isOpen/handleClose and change the attribute to the ModalHeader's labelId or add a matching id prop to ModalHeader).web/src/components/dashboards/perses/dashboard-actions-menu.tsx (1)
1-17:⚠️ Potential issue | 🔴 CriticalAdd missing
Reactimport forReact.FunctionComponentandReact.Ref.Line 17 uses
React.FunctionComponentand Line 49 usesReact.Ref<MenuToggleElement>, but the React namespace is never imported. This is a TypeScript compilation error; the"react-jsx"transform only covers JSX syntax, not namespace type references.🔧 Proposed fix
+import React from 'react'; import { useState } from 'react';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-actions-menu.tsx` around lines 1 - 17, The file references React namespace types (React.FunctionComponent and React.Ref<MenuToggleElement>) but does not import the React namespace; add an explicit import for the React namespace (e.g. insert "import React from 'react';" at the top) or alternatively replace the namespace types with named imports (import { FunctionComponent, Ref } from 'react' and use FunctionComponent and Ref<MenuToggleElement>) so that DashboardActionsMenu and the React.Ref<MenuToggleElement> usage compile correctly.
🧹 Nitpick comments (1)
web/src/components/dashboards/perses/dashboard-create-dialog.tsx (1)
113-115:error?.messageonunknown-typed catch variable; use a sharedgetErrorMessagehelper.Lines 115 and 142 access
.messagedirectly onunknown-typed catch variables (projectError,error). This is a TypeScript error underuseUnknownInCatchVariables(enabled bystrictmode). The import dialog already defines a correctgetErrorMessage(error)utility — extract it to a shared utils module and import it here instead of duplicating the pattern.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx` around lines 113 - 115, The catch blocks in dashboard-create-dialog.tsx access .message on unknown-typed variables (projectError and error); extract the existing getErrorMessage helper from the import dialog into a shared utils module (e.g., utils/errors or similar), export it, then import that shared getErrorMessage into dashboard-create-dialog.tsx and replace direct property access with calls to getErrorMessage(projectError) and getErrorMessage(error) (also update any other occurrences in this file such as the handler around line 142) to satisfy TypeScript's useUnknownInCatchVariables rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx`:
- Around line 249-274: The migrateMutation.onError handler currently only calls
setFormErrors and does not surface a toast; update the failure path so the user
sees a toast by either switching the call site to await
migrateMutation.mutateAsync inside a try/catch and calling addAlert(...) in the
catch, or by adding an addAlert(...) invocation inside the existing onError
callback in migrateMutation.mutate (use the same error message logic as the
onSuccess catch: const errorMessage = getErrorMessage(error) || t('Migration
failed. Please try again.') and call addAlert(t('Error migrating dashboard:
{{error}}', { error: errorMessage }), 'danger') before setFormErrors({ general:
errorMessage })). Ensure you reference migrateMutation.mutate/mutateAsync,
onError, addAlert, setFormErrors and getErrorMessage when making the change.
---
Outside diff comments:
In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx`:
- Line 97: Replace the hard-coded template string that constructs the duplicate
name error with a call to the i18n translator; in the component
(dashboard-create-dialog.tsx) where you currently build dashboardName:
`Dashboard name "${dashboardName}" already exists in this project`, use the
existing locale key "Dashboard name '{{dashboardName}}' already exists in
'{{projectName}}' project!" via t(...) and pass { dashboardName, projectName:
selectedProject } so the message is localized and includes the project name.
- Line 132: Replace the hardcoded English template literals passed to addAlert
with translated strings using t() and interpolation: wrap the success message
(where addAlert(`Dashboard "${dashboardName}" created successfully`, 'success')
is called) as t('dashboard.created_success', { name: dashboardName }) and wrap
the error alert (the addAlert call on failure) as t('dashboard.create_error', {
error: errorMessageOrErr }); update the locale files with keys
"dashboard.created_success": "Dashboard \"{{name}}\" created successfully" and
"dashboard.create_error": "Error creating dashboard: {{error}}". Ensure you
reference the exact variables used in the function (dashboardName and the caught
error variable) when passing interpolation values to t().
---
Duplicate comments:
In `@web/src/components/dashboards/perses/dashboard-actions-menu.tsx`:
- Around line 1-17: The file references React namespace types
(React.FunctionComponent and React.Ref<MenuToggleElement>) but does not import
the React namespace; add an explicit import for the React namespace (e.g. insert
"import React from 'react';" at the top) or alternatively replace the namespace
types with named imports (import { FunctionComponent, Ref } from 'react' and use
FunctionComponent and Ref<MenuToggleElement>) so that DashboardActionsMenu and
the React.Ref<MenuToggleElement> usage compile correctly.
In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx`:
- Around line 159-167: The Modal currently sets
aria-labelledby="modal-with-dropdown" which doesn't match any rendered element;
update the Modal/ModalHeader usage so the Modal's aria-labelledby references the
ModalHeader's actual label id (use the ModalHeader's labelId prop value or pass
a matching id down), e.g. ensure Modal aria-labelledby equals the ModalHeader's
labelId string (locate the Modal component and the ModalHeader call in
dashboard-create-dialog.tsx around isOpen/handleClose and change the attribute
to the ModalHeader's labelId or add a matching id prop to ModalHeader).
In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx`:
- Around line 1-65: The file references React.FunctionComponent in the
DashboardImportDialog declaration but never imports the React identifier,
causing a TypeScript error; fix by adding a top-level import for React (so React
is in scope) or change the component type to use the standalone
FunctionComponent/FC type from 'react' and import that instead (e.g., import
React, { FunctionComponent } from 'react' or import { FunctionComponent } from
'react' and use FunctionComponent<DashboardImportDialogProps> on
DashboardImportDialog).
- Around line 364-374: The CodeEditor is always using Language.json causing YAML
uploads to be highlighted incorrectly; change the language prop on the
CodeEditor (component instance with id "import-dashboard-code-editor") to be
derived from the component's filename state instead of hardcoding Language.json:
implement a small mapping from filename extension (e.g., .yaml/.yml ->
Language.yaml, .json -> Language.json) or a utility like
getLanguageFromFilename(filename) and pass that result to the language prop,
leaving dashboardInput and handleDashboardInputChange unchanged so uploads pick
the correct syntax highlighting.
- Around line 308-315: The Modal's aria-labelledby references
"import-dashboard-modal" which doesn't exist; update the ModalHeader usage to
supply a matching labelId and use that labelId value for the Modal's
aria-labelledby prop (e.g., generate a constant id like labelId =
'import-dashboard-modal' and pass it to ModalHeader via its labelId prop, then
set Modal aria-labelledby={labelId}); modify the JSX around Modal and
ModalHeader to wire the same unique id string to both components so screen
readers can resolve the label.
- Around line 151-160: The catch block currently concatenates both jsonError and
yamlError messages; change it to surface only the relevant parser error:
determine which parser was expected by sniffing the trimmed input (e.g., if
trimmedInput.startsWith('{') treat as JSON else YAML), then pick only
jsonError.message or yamlError.message accordingly; keep the existing calls to
setParsedDashboard(undefined) and setParseError but build details from the
chosen error (fallback to the other error only if the chosen one is absent)
using the same user-facing prefix text.
---
Nitpick comments:
In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx`:
- Around line 113-115: The catch blocks in dashboard-create-dialog.tsx access
.message on unknown-typed variables (projectError and error); extract the
existing getErrorMessage helper from the import dialog into a shared utils
module (e.g., utils/errors or similar), export it, then import that shared
getErrorMessage into dashboard-create-dialog.tsx and replace direct property
access with calls to getErrorMessage(projectError) and getErrorMessage(error)
(also update any other occurrences in this file such as the handler around line
142) to satisfy TypeScript's useUnknownInCatchVariables rule.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (1)
web/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (8)
web/locales/en/plugin__monitoring-plugin.jsonweb/package.jsonweb/src/components/dashboards/perses/dashboard-actions-menu.tsxweb/src/components/dashboards/perses/dashboard-create-dialog.tsxweb/src/components/dashboards/perses/dashboard-header.tsxweb/src/components/dashboards/perses/dashboard-import-dialog.tsxweb/src/components/dashboards/perses/migrate-api.tsweb/src/components/data-test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- web/src/components/dashboards/perses/migrate-api.ts
- web/package.json
- web/src/components/dashboards/perses/dashboard-header.tsx
fc85fef to
2b45216
Compare
Signed-off-by: Gabriel Bernal <gbernal@redhat.com>
2b45216 to
8d6fef7
Compare
|
@jgbernalp: This pull request references OU-1139 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.22.0" version, but no target version was set. DetailsIn response to this:
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. |
There was a problem hiding this comment.
♻️ Duplicate comments (6)
web/src/components/dashboards/perses/dashboard-create-dialog.tsx (2)
159-167:⚠️ Potential issue | 🟡 MinorEnsure
aria-labelledbypoints to an actual title element.
aria-labelledby="modal-with-dropdown"doesn’t match any element id in the modal. Wire it to the header’s id (or removearia-labelledbyand rely on default labeling).♿ Suggested fix (verify PatternFly ModalHeader props)
- <Modal - variant={ModalVariant.small} - isOpen={isOpen} - onClose={handleClose} - onEscapePress={handleClose} - aria-labelledby="modal-with-dropdown" - > - <ModalHeader title={t('Create Dashboard')} /> + <Modal + variant={ModalVariant.small} + isOpen={isOpen} + onClose={handleClose} + onEscapePress={handleClose} + aria-labelledby="create-dashboard-modal-title" + > + <ModalHeader title={t('Create Dashboard')} labelId="create-dashboard-modal-title" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx` around lines 159 - 167, The Modal's aria-labelledby value ("modal-with-dropdown") does not match any element id; update the ModalHeader used in dashboard-create-dialog.tsx so its rendered title element has id="modal-with-dropdown" (or remove the aria-labelledby prop and rely on Modal/ModalHeader default labeling) — locate the Modal and ModalHeader components in this file and either add the matching id to ModalHeader or delete the aria-labelledby attribute from the Modal to satisfy accessibility requirements.
32-40:⚠️ Potential issue | 🟠 MajorImport React (or type-only equivalents) for React.FunctionComponent.
React.FunctionComponentrequires the React namespace unless it’s globally declared; otherwise TS will fail.🔧 Suggested fix
-import { useMemo, useState } from 'react'; +import React, { useMemo, useState } from 'react';#!/bin/bash # Check whether React is globally declared/allowed rg -n "allowUmdGlobalAccess|jsx" web/tsconfig.json rg -n "export as namespace React|namespace React|declare global" web/src -g'*.d.ts'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx` around lines 32 - 40, The component is using the React namespace type React.FunctionComponent but React isn't imported; either add an import to satisfy the namespace (e.g. import React from 'react') or switch to a type-only import and explicit type (e.g. import type { FunctionComponent } from 'react' and annotate DashboardCreateDialog as FunctionComponent<DashboardCreateDialogProps>); update the file so DashboardCreateDialog and DashboardCreateDialogProps compile without relying on a global React declaration.web/src/components/dashboards/perses/dashboard-actions-menu.tsx (1)
1-49:⚠️ Potential issue | 🟠 MajorImport React (or type-only equivalents) for React namespace types.
React.FunctionComponentandReact.Ref<MenuToggleElement>require the React namespace unless it’s globally declared; otherwise this is a TS error.🔧 Suggested fix
-import { useState } from 'react'; +import React, { useState } from 'react';#!/bin/bash # Check whether React is globally declared/allowed rg -n "allowUmdGlobalAccess|jsx" web/tsconfig.json rg -n "export as namespace React|namespace React|declare global" web/src -g'*.d.ts'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-actions-menu.tsx` around lines 1 - 49, The TS build error comes from using React namespace types (React.FunctionComponent and React.Ref<MenuToggleElement>) without importing React; update the top of the DashboardActionsMenu file to import React (or import type { Ref } from 'react' and use FunctionComponent from 'react' or use type-only imports) so the symbols used in DashboardActionsMenu and the toggle callback signature (React.Ref<MenuToggleElement>) resolve; ensure you either add a default import like "import React from 'react'" or add appropriate type-only imports to satisfy the compiler.web/src/components/dashboards/perses/dashboard-import-dialog.tsx (3)
23-66:⚠️ Potential issue | 🟠 MajorImport React (or type-only equivalents) for React.FunctionComponent.
React.FunctionComponentneeds the React namespace unless it’s globally declared; otherwise TS will fail.🔧 Suggested fix
-import { ChangeEvent, useMemo, useState } from 'react'; +import React, { ChangeEvent, useMemo, useState } from 'react';#!/bin/bash # Check whether React is globally declared/allowed rg -n "allowUmdGlobalAccess|jsx" web/tsconfig.json rg -n "export as namespace React|namespace React|declare global" web/src -g'*.d.ts'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 23 - 66, The file uses React.FunctionComponent for the DashboardImportDialog type but never imports React, which breaks TypeScript unless React's global namespace is declared; fix by adding an import: either import React from 'react' (to provide the React namespace) or import the type explicitly (import type { FunctionComponent } from 'react') and update the component signature to use FunctionComponent<DashboardImportDialogProps> or React.FC<DashboardImportDialogProps>; update the top imports accordingly where DashboardImportDialog is declared to ensure the type is resolved.
307-315:⚠️ Potential issue | 🟡 MinorEnsure
aria-labelledbypoints to an actual title element.
aria-labelledby="import-dashboard-modal"doesn’t match any element id in the modal. Wire it to the header’s id (or removearia-labelledbyand rely on default labeling).♿ Suggested fix (verify PatternFly ModalHeader props)
- <Modal - variant={ModalVariant.large} - isOpen={isOpen} - onClose={handleClose} - onEscapePress={handleClose} - aria-labelledby="import-dashboard-modal" - > - <ModalHeader title={t('Import Dashboard')} /> + <Modal + variant={ModalVariant.large} + isOpen={isOpen} + onClose={handleClose} + onEscapePress={handleClose} + aria-labelledby="import-dashboard-modal-title" + > + <ModalHeader title={t('Import Dashboard')} labelId="import-dashboard-modal-title" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 307 - 315, The Modal's aria-labelledby="import-dashboard-modal" does not match any element id; either give the ModalHeader a matching id (e.g. add id="import-dashboard-modal" to the ModalHeader component) or remove the aria-labelledby prop so the Modal uses its default labeling. Update the ModalHeader (component name: ModalHeader) to include the id that matches the Modal's aria-labelledby value, or delete the aria-labelledby attribute on the Modal component to resolve the mismatch.
246-273:⚠️ Potential issue | 🟡 MinorSurface Grafana migration failures via toast for consistency.
Other failure paths call
addAlert, but migrateonErroronly sets inline errors, so users may miss it.🔧 Suggested fix
onError: (error) => { const errorMessage = getErrorMessage(error) || t('Migration failed. Please try again.'); + addAlert( + t('Error importing dashboard: {{error}}', { error: errorMessage }), + 'danger', + ); setFormErrors({ general: errorMessage }); },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx` around lines 246 - 273, The Grafana migration failure path only calls setFormErrors in migrateMutation.mutate onError, so users don't get a toast; update the onError handler for migrateMutation.mutate (invoked when currentParsedDashboard.kind === 'grafana') to also call addAlert with a message built from getErrorMessage(error) || t('Migration failed. Please try again.') (same style used elsewhere) and keep the existing setFormErrors({ general: errorMessage }) behavior so both inline and toast notifications are shown.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@web/src/components/dashboards/perses/dashboard-actions-menu.tsx`:
- Around line 1-49: The TS build error comes from using React namespace types
(React.FunctionComponent and React.Ref<MenuToggleElement>) without importing
React; update the top of the DashboardActionsMenu file to import React (or
import type { Ref } from 'react' and use FunctionComponent from 'react' or use
type-only imports) so the symbols used in DashboardActionsMenu and the toggle
callback signature (React.Ref<MenuToggleElement>) resolve; ensure you either add
a default import like "import React from 'react'" or add appropriate type-only
imports to satisfy the compiler.
In `@web/src/components/dashboards/perses/dashboard-create-dialog.tsx`:
- Around line 159-167: The Modal's aria-labelledby value ("modal-with-dropdown")
does not match any element id; update the ModalHeader used in
dashboard-create-dialog.tsx so its rendered title element has
id="modal-with-dropdown" (or remove the aria-labelledby prop and rely on
Modal/ModalHeader default labeling) — locate the Modal and ModalHeader
components in this file and either add the matching id to ModalHeader or delete
the aria-labelledby attribute from the Modal to satisfy accessibility
requirements.
- Around line 32-40: The component is using the React namespace type
React.FunctionComponent but React isn't imported; either add an import to
satisfy the namespace (e.g. import React from 'react') or switch to a type-only
import and explicit type (e.g. import type { FunctionComponent } from 'react'
and annotate DashboardCreateDialog as
FunctionComponent<DashboardCreateDialogProps>); update the file so
DashboardCreateDialog and DashboardCreateDialogProps compile without relying on
a global React declaration.
In `@web/src/components/dashboards/perses/dashboard-import-dialog.tsx`:
- Around line 23-66: The file uses React.FunctionComponent for the
DashboardImportDialog type but never imports React, which breaks TypeScript
unless React's global namespace is declared; fix by adding an import: either
import React from 'react' (to provide the React namespace) or import the type
explicitly (import type { FunctionComponent } from 'react') and update the
component signature to use FunctionComponent<DashboardImportDialogProps> or
React.FC<DashboardImportDialogProps>; update the top imports accordingly where
DashboardImportDialog is declared to ensure the type is resolved.
- Around line 307-315: The Modal's aria-labelledby="import-dashboard-modal" does
not match any element id; either give the ModalHeader a matching id (e.g. add
id="import-dashboard-modal" to the ModalHeader component) or remove the
aria-labelledby prop so the Modal uses its default labeling. Update the
ModalHeader (component name: ModalHeader) to include the id that matches the
Modal's aria-labelledby value, or delete the aria-labelledby attribute on the
Modal component to resolve the mismatch.
- Around line 246-273: The Grafana migration failure path only calls
setFormErrors in migrateMutation.mutate onError, so users don't get a toast;
update the onError handler for migrateMutation.mutate (invoked when
currentParsedDashboard.kind === 'grafana') to also call addAlert with a message
built from getErrorMessage(error) || t('Migration failed. Please try again.')
(same style used elsewhere) and keep the existing setFormErrors({ general:
errorMessage }) behavior so both inline and toast notifications are shown.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (1)
web/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (8)
web/locales/en/plugin__monitoring-plugin.jsonweb/package.jsonweb/src/components/dashboards/perses/dashboard-actions-menu.tsxweb/src/components/dashboards/perses/dashboard-create-dialog.tsxweb/src/components/dashboards/perses/dashboard-header.tsxweb/src/components/dashboards/perses/dashboard-import-dialog.tsxweb/src/components/dashboards/perses/migrate-api.tsweb/src/components/data-test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- web/src/components/dashboards/perses/migrate-api.ts
- web/src/components/dashboards/perses/dashboard-header.tsx
- web/src/components/data-test.ts
|
/label qe-approved |
|
@jgbernalp: This pull request references OU-1139 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.22.0" version, but no target version was set. DetailsIn response to this:
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. |
|
/test ? |
|
/lgtm |
|
/test e2e-monitoring |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jgbernalp, PeterYurkovich The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/retest |
|
/test e2e-monitoring |
|
/override ci/prow/e2e-aws-ovn |
|
@jgbernalp: Overrode contexts on behalf of jgbernalp: ci/prow/e2e-aws-ovn DetailsIn response to this:
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. |
|
@jgbernalp: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions 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. I understand the commands that are listed here. |
|
@jgbernalp: #779 failed to apply on top of branch "release-coo-0.5": DetailsIn response to this:
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. |
This PR adds the import button as part of a new menu which also includes the create option as default, following UX suggestions:
Screen.Recording.2026-02-24.at.13.00.03.mov
Summary by CodeRabbit
New Features
Bug Fixes / UX
Documentation