Skip to content

feat: add Image Updater to GitOPS console#244

Open
dkarpele wants to merge 3 commits into
redhat-developer:mainfrom
dkarpele:dk-GITOPS-9213
Open

feat: add Image Updater to GitOPS console#244
dkarpele wants to merge 3 commits into
redhat-developer:mainfrom
dkarpele:dk-GITOPS-9213

Conversation

@dkarpele
Copy link
Copy Markdown

@dkarpele dkarpele commented May 26, 2026

I tested this against Image Updater v1.2.1 that is a part of GitOPS 1.21. status field below is available starting from v1.2.0.

% oc get imageupdater/image-updater-004 -n openshift-gitops -o yaml 
apiVersion: argocd-image-updater.argoproj.io/v1alpha1
kind: ImageUpdater
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"argocd-image-updater.argoproj.io/v1alpha1","kind":"ImageUpdater","metadata":{"annotations":{},"labels":{"app.kubernetes.io/managed-by":"kustomize","app.kubernetes.io/name":"image-updater"},"name":"image-updater-004","namespace":"openshift-gitops"},"spec":{"applicationRefs":[{"commonUpdateSettings":{"updateStrategy":"semver"},"images":[{"alias":"test-nginx","imageName":"nginx:1.17.10"},{"alias":"test-memcached","imageName":"memcached:1.6.10"}],"namePattern":"app-2"}]}}
  creationTimestamp: "2026-05-26T16:43:54Z"
  finalizers:
  - resources-finalizer.argocd-image-updater.argoproj.io
  generation: 1
  labels:
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/name: image-updater
  name: image-updater-004
  namespace: openshift-gitops
  resourceVersion: "212194"
  uid: 329b0f84-2084-43dd-8638-17c40958ef22
spec:
  applicationRefs:
  - commonUpdateSettings:
      forceUpdate: false
      updateStrategy: semver
    images:
    - alias: test-nginx
      imageName: nginx:1.17.10
    - alias: test-memcached
      imageName: memcached:1.6.10
    namePattern: app-2
    useAnnotations: false
status:
  applicationsMatched: 1
  conditions:
  - lastTransitionTime: "2026-05-26T16:43:55Z"
    message: Last check completed. Awaiting next cycle.
    observedGeneration: 1
    reason: Idle
    status: "False"
    type: Reconciling
  - lastTransitionTime: "2026-05-26T16:43:55Z"
    message: No errors during last reconciliation.
    observedGeneration: 1
    reason: NoErrors
    status: "False"
    type: Error
  - lastTransitionTime: "2026-05-26T16:43:55Z"
    message: Reconciled 1 applications, 2 images updated.
    observedGeneration: 1
    reason: ReconcileSucceeded
    status: "True"
    type: Ready
  imagesManaged: 2
  lastCheckedAt: "2026-05-26T16:43:55Z"
  lastUpdatedAt: "2026-05-26T16:43:55Z"
  observedGeneration: 1
  recentUpdates:
  - alias: test-nginx
    applicationsUpdated: 1
    image: nginx
    message: Updated from 1.17.0 to 1.17.10.
    newVersion: 1.17.10
    updatedAt: "2026-05-26T16:43:55Z"
  - alias: test-memcached
    applicationsUpdated: 1
    image: memcached
    message: Updated from 1.6.0 to 1.6.10.
    newVersion: 1.6.10
    updatedAt: "2026-05-26T16:43:55Z"
image image image image image image image image image image

Signed-off-by: dkarpele <karpelevich@gmail.com>
@openshift-ci openshift-ci Bot requested review from keithchong and wtam2018 May 26, 2026 16:35
@ranakan19
Copy link
Copy Markdown
Collaborator

@coderabbitai do you have any thoughts? inital review of the changes?

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get PR details and file list
gh pr view 244 --repo redhat-developer/gitops-console-plugin --json title,body,files,additions,deletions,changedFiles 2>/dev/null | jq '{title, additions, deletions, changedFiles, files: [.files[].path]}'

Length of output: 1356


🏁 Script executed:

#!/bin/bash
# Get the diff for the PR
gh pr diff 244 --repo redhat-developer/gitops-console-plugin 2>/dev/null | head -2000

Length of output: 67810



PR description images show:

  1. ImageUpdaters list view — table with Name, Namespace, Apps, Images, Last Checked, Ready columns and a "Create ImageUpdater" button.
  2. Create form — YAML editor with live schema docs panel.
  3. Filter dropdown — "Has Apps / No Apps" and "Ready / Not Ready" row filters.
  4. Detail page — name, namespace, labels, annotations, conditions table.
  5. Recent Updates tab — alias, image, new version, apps updated, updated at, message.
  6. YAML tab — full resource YAML with edit/save/download.
  7. Kebab menu — Edit labels, Edit annotations, Edit ImageUpdater, Delete ImageUpdater.
  8. Empty states — "No ImageUpdaters" and "No recent updates".

@ranakan19 — overall this is a solid, well-structured feature addition that follows the existing patterns for AppProjects and Rollouts nicely. The UI screenshots look polished. Here are my thoughts broken into severity levels:


🔴 Bugs

1. Multi-select filter short-circuits incorrectly (ImageUpdaterList.tsx)

When a user selects both "Has Apps" and "No Apps" (or both "Ready" and "Not Ready"), the filter should return true for all items, but currently it returns only the result of the first matching includes branch:

// Current — if both 'has-apps' and 'no-apps' are in input.selected,
// only the first if-branch fires (returns hasApps), never checking the second
filter: (input, item) => {
  if (input.selected?.length) {
    const hasApps = apps > 0;
    if (input.selected.includes('has-apps')) { return hasApps; }   // ← short-circuits
    if (input.selected.includes('no-apps'))  { return !hasApps; }
  }
  return true;
},

Suggested fix:

filter: (input, item) => {
  if (!input.selected?.length) return true;
  const apps = (item as ImageUpdaterKind).status?.applicationsMatched;
  const hasApps = apps > 0;
  return (
    (input.selected.includes('has-apps') && hasApps) ||
    (input.selected.includes('no-apps') && !hasApps)
  );
},

Same pattern applies to the ready-status filter.


2. Direct prop mutation (ImageUpdaterList.tsx, line ~83)

// ❌ mutates the destructured parameter
if (listAllNamespaces) {
  namespace = null;
}

Use a local variable instead:

const effectiveNamespace = listAllNamespaces ? null : namespace;
// then use effectiveNamespace everywhere below

🟠 Medium Issues

3. Missing flags guard on navigation entry (console-extensions.json)

The console.navigation/resource-ns for imageupdater has no flags guard, so the nav entry will always appear in the sidebar even when the ImageUpdater CRD is not installed:

// ❌ missing flags
{
  "type": "console.navigation/resource-ns",
  "properties": {
    "id": "imageupdater",
    ...
  }
}
// ✅ add flags guard
{
  "type": "console.navigation/resource-ns",
  "properties": { "id": "imageupdater", ... },
  "flags": { "required": ["IMAGEUPDATER"] }
}

The separator below it should also carry the same guard.


4. Hardcoded GVK literals instead of modelToGroupVersionKind (ImageUpdaterList.tsx, ImageUpdaterNavPage.tsx)

// ❌ hardcoded in two places
groupVersionKind: {
  group: 'argocd-image-updater.argoproj.io',
  kind: 'ImageUpdater',
  version: 'v1alpha1',
},
// ✅ use the model
groupVersionKind: modelToGroupVersionKind(ImageUpdaterModel),

5. Import style inconsistency (ImageUpdaterNavPage.tsx)

The file mixes @gitops alias imports with relative imports — all other imports in the same file use ../../:

// ❌ inconsistent with the rest of the file
import ImageUpdaterDetailsTab from "`@gitops/components/imageupdater/ImageUpdaterDetailsTab`";
import ImageUpdaterRecentUpdatesTab from "`@gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab`";

Should be:

import ImageUpdaterDetailsTab from './ImageUpdaterDetailsTab';
import ImageUpdaterRecentUpdatesTab from './ImageUpdaterRecentUpdatesTab';

6. abbr inconsistency between model and console-extensions.json

ImageUpdaterModel.ts has abbr: 'imageupdater' while console-extensions.json has "abbr": "IU". The model abbreviation is also used as a CSS class for the resource badge icon, so a long string like 'imageupdater' will not display correctly in the badge circle. It should be 'IU' to match.


7. Loose equality checks

// ❌ use === instead of ==
if (imageUpdaterList == undefined || imageUpdaterList.length == 0)
if (showTitle == undefined)

🟡 Minor / Style

8. IIFE in JSX (ImageUpdaterDetailsTab.tsx)

The {(() => { ... })()} pattern is harder to read. A simple extracted variable or ternary would be cleaner:

// ❌
{(() => {
  const readyCondition = status.conditions?.find((c) => c.type === 'Ready');
  if (!readyCondition) return '-';
  return readyCondition.status === 'True' ? t('True') : t('False');
})()}

// ✅
{status.conditions?.find((c) => c.type === 'Ready')
  ? status.conditions.find((c) => c.type === 'Ready')!.status === 'True' ? t('True') : t('False')
  : '-'}
// or extract to a variable above the return

9. if (!obj) return null guard placement (ImageUpdaterRecentUpdatesTab.tsx)

The guard is currently placed near the bottom of the component body, after all hooks (useMemo, useGitOpsDataViewSort, etc.) have already run. While this technically complies with Rules of Hooks (hooks must not be conditional), it's confusing. Consider either placing the guard before non-hook logic or restructuring so all data derivation happens inside the render path.

10. PF class names

imageupdater-list.scss uses pf-c-table and ImageUpdaterDetailsTab.tsx uses pf-c-description-list — these are PatternFly v4 prefixes. If the project has migrated to PF v5, these should be pf-v5-c-table / pf-v5-c-description-list. Worth checking for consistency with other SCSS files in the project.

11. spec type missing from ImageUpdaterKind

ImageUpdaterKind only defines status. Even a minimal spec?: { applicationRefs?: unknown[] } would aid future work and improve type safety.


✅ What's done well

  • Clean separation of concerns across files (NavPage, DetailsTab, RecentUpdatesTab, List, ListTab, ActionsProvider).
  • Consistent use of useK8sWatchResource + HorizontalNav pattern as seen in AppProject/ApplicationSet.
  • All string literals are i18n-wrapped and locale files are updated.
  • Empty states, error states, and loading states are all handled properly.
  • The status.conditions section is conditionally rendered when conditions are present — good defensive coding.
  • useImageUpdaterActionsProvider with accessReview on each action is correct.
  • The console.yaml-template registration for the Create form is a nice touch (screenshot 2).

Comment on lines +54 to +56
if (listAllNamespaces) {
namespace = null;
}
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.

We should avoid mutating function parameters here may be something like?

Suggested change
if (listAllNamespaces) {
namespace = null;
}
const effectiveNamespace = listAllNamespaces ? null : namespace;

import ResourceYAMLTab from '../shared/ResourceYAMLTab/ResourceYAMLTab';

import { useImageUpdaterActionsProvider } from './hooks/useImageUpdaterActionsProvider';
import ImageUpdaterDetailsTab from "@gitops/components/imageupdater/ImageUpdaterDetailsTab";
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.

use single quotes here for consistency, same as line 14

namespace: string | undefined,
): DataViewTr[] => {
const rows: DataViewTr[] = [];
if (imageUpdaterList == undefined || imageUpdaterList.length == 0) {
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.

Suggested change
if (imageUpdaterList == undefined || imageUpdaterList.length == 0) {
if (imageUpdaterList === undefined || imageUpdaterList.length === 0) {

title={t('Applications Matched')}
help={t('Number of applications matched by this ImageUpdater.')}
>
{status.applicationsMatched != null ? String(status.applicationsMatched) : '-'}
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.

Consider using ?? operator here and the lines below instead?

Comment on lines +120 to +121
const useColumnsDV = (getSortParams: (columnIndex: number) => ThProps['sort']): DataViewTh[] => {
const { t } = useTranslation('plugin__gitops-plugin');
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.

For consistency, prefer useGitOpsTranslation() throughout the file.

Suggested change
const useColumnsDV = (getSortParams: (columnIndex: number) => ThProps['sort']): DataViewTh[] => {
const { t } = useTranslation('plugin__gitops-plugin');
+const useColumnsDV = (
+ getSortParams: (columnIndex: number) => ThProps['sort'],
+ t: (key: string) => string,
+): DataViewTh[] => {

then update the line 34!


const { sortBy, direction, getSortParams } = useGitOpsDataViewSort(columnSortConfig);

const columnsDV = useColumnsDV(getSortParams);
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.

Suggested change
const columnsDV = useColumnsDV(getSortParams);
const columnsDV = useColumnsDV(getSortParams, t);

if (!sortBy || !direction) return data;

return [...data].sort((a, b) => {
let aValue: any, bValue: any;
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.

Lines 159 and throughout the switch statement use any for aValue and bValue. Consider more specific types for sort values for better type safety.

{
id: 'last-checked',
cell: obj.status?.lastCheckedAt ? (
<div style={{ whiteSpace: 'nowrap' }}>
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.

Inline styles at lines 381, 397, and 409. Consider moving them to the SCSS file.

Also might apply to lines: 395-398, 407-416

@aali309
Copy link
Copy Markdown
Collaborator

aali309 commented May 27, 2026

Ahh I see Coderabbit has some of my review comments, I got them after refreshing the page. Looks good just a few comments! my cluster died when I was testing. I will run another quick test when I am back.

Signed-off-by: dkarpele <karpelevich@gmail.com>
@dkarpele
Copy link
Copy Markdown
Author

Thanks for the review Atif!
I addressed all comments

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Review Change Stack

Warning

Review limit reached

@dkarpele, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 25 minutes and 34 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: b1c0ef41-b09e-4e83-a226-259d4855f31a

📥 Commits

Reviewing files that changed from the base of the PR and between 2fc86de and 6b5dd46.

📒 Files selected for processing (4)
  • console-extensions.json
  • src/gitops/components/imageupdater/ImageUpdaterList.tsx
  • src/gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab.tsx
  • src/gitops/components/imageupdater/imageupdater-list.scss
📝 Walkthrough

Walkthrough

This PR adds complete console plugin support for the Argo CD Image Updater resource type, including TypeScript data models, React UI components for listing and viewing ImageUpdaters, console extension wiring with navigation and pages, and internationalized UI strings across multiple locales.

Changes

ImageUpdater Console Plugin Support

Layer / File(s) Summary
ImageUpdater Data Model & Templates
src/gitops/models/ImageUpdaterModel.ts, src/gitops/templates/imageupdater-yaml.ts, src/gitops/templates/index.ts
Define ImageUpdaterKind type with status fields (conditions, recent updates, counts), export K8sModel descriptor, and provide YAML template for resource creation.
Core UI Components
src/gitops/components/imageupdater/ImageUpdaterDetailsPage.tsx, ImageUpdaterNavPage.tsx, ImageUpdaterDetailsTab.tsx, ImageUpdaterList.tsx, ImageUpdaterListTab.tsx
Implement entry-point details page, tabbed navigation orchestration, details tab rendering of status/conditions, and full list page with sorting/filtering by name, namespace, app/image counts, and ready status, plus row actions.
Recent Updates Tab
src/gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab.tsx
Render Recent Updates tab with table of update history, client-side sorting by alias/image/version/apps-updated/timestamp, and column definitions with translations.
Actions & Styling
src/gitops/components/imageupdater/hooks/useImageUpdaterActionsProvider.tsx, imageupdater-list.scss
Wire per-row actions (edit labels/annotations/YAML, delete) with access reviews and modal launchers; apply CSS for list table cell truncation and alignment.
Console Extension Wiring
console-extensions.json
Register ImageUpdater model metadata, flag-to-model mapping, navigation sections, resource list/details pages, and YAML template, all gated by IMAGEUPDATER feature flag.
Plugin Module Exports
plugin-metadata.ts
Expose ImageUpdaterList and ImageUpdaterDetailsPage components via plugin module interface.
Internationalization
locales/en/plugin__gitops-plugin.json, locales/ja/plugin__gitops-plugin.json, locales/ko/plugin__gitops-plugin.json, locales/zh/plugin__gitops-plugin.json
Add ImageUpdater UI strings (actions, status labels, counts, timestamps, empty/error states) and update AppProjects list messaging across four language locales, removing duplicate key entries.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add Image Updater to GitOPS console' clearly and concisely summarizes the primary change—adding Image Updater support to the GitOPS console plugin.
Description check ✅ Passed The description provides context about Image Updater v1.2.1 compatibility, includes a concrete YAML example of an ImageUpdater resource, and contains 10 screenshots demonstrating the feature implementation across list, details, and editor views.
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.

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


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.

Copy link
Copy Markdown

@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: 6

🧹 Nitpick comments (1)
src/gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab.tsx (1)

190-194: ⚡ Quick win

Simplify nested ternary operators for readability.

The nested ternary expressions reduce code clarity and are flagged by ESLint's no-nested-ternary rule. Using if-else statements makes the comparison logic more explicit and easier to maintain.

♻️ Proposed refactor to use if-else
-    if (direction === 'asc') {
-      return aValue < bValue ? -1 : aValue > bValue ? 1 : 0;
-    } else {
-      return aValue > bValue ? -1 : aValue < bValue ? 1 : 0;
-    }
+    if (aValue < bValue) {
+      return direction === 'asc' ? -1 : 1;
+    }
+    if (aValue > bValue) {
+      return direction === 'asc' ? 1 : -1;
+    }
+    return 0;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab.tsx` around
lines 190 - 194, The comparison block in ImageUpdaterRecentUpdatesTab (the code
that returns sort order based on direction and aValue/bValue) uses nested
ternary operators which hurts readability; replace the nested ternaries with
explicit if/else branches so the logic is clearer: check if direction === 'asc'
then use if (aValue < bValue) return -1; else if (aValue > bValue) return 1;
else return 0; and for the else (descending) branch use if (aValue > bValue)
return -1; else if (aValue < bValue) return 1; else return 0; so the comparison
logic around aValue, bValue and direction is identical but written with clear
if/else statements.
🤖 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 `@console-extensions.json`:
- Around line 391-397: There are duplicate console.navigation/separator entries
using the same properties.id "argocd-separator" which can cause unstable nav
behavior; locate the console.navigation/separator blocks (look for type
"console.navigation/separator" with properties.perspective "admin" and section
"gitops-navigation-section") and give each properties.id a unique value (e.g.,
"argocd-separator" and "argocd-separator-2" or a semantic variant) so they no
longer collide, ensuring any insertAfter references (like "imageupdater") remain
correct.

In `@locales/ja/plugin__gitops-plugin.json`:
- Around line 108-154: The new ImageUpdater UI strings (e.g., "Edit
ImageUpdater", "Delete ImageUpdater", "ImageUpdater details", "Images Managed",
"Last Checked At", "There are no ImageUpdaters in this namespace.", etc.) are
still in English for the ja/ko/zh locales — update the locale JSON entries for
these keys in the Japanese (ja), Korean (ko), and Chinese (zh)
plugin__gitops-plugin.json files with proper translations (or mark them for
follow-up), ensuring each English key is replaced by the corresponding
translated string and preserves the exact JSON keys and punctuation.

In `@plugin-metadata.ts`:
- Around line 22-23: The newly added module paths for ImageUpdaterList and
ImageUpdaterDetailsPage use double quotes and violate the project's prettier
quote style; update the string literals in plugin-metadata.ts for the keys
ImageUpdaterList and ImageUpdaterDetailsPage to use single quotes (i.e., change
"./gitops/..." to './gitops/...') so the file conforms to the configured
lint/prettier rules.

In `@src/gitops/components/imageupdater/imageupdater-list.scss`:
- Around line 2-22: The truncation rules currently target all PatternFly tables
via selectors like ".pf-c-table tbody td[data-label='Name'], .pf-c-table tbody
td[data-label='Namespace']" and ".pf-c-table tbody
td[data-label='Description']"; scope these rules to the ImageUpdater list by
prefixing both selector groups with the ImageUpdater wrapper class (for example
".image-updater-list" or the component's top-level class used in the
ImageUpdater list). Update the two selector blocks so they read "<wrapper>
.pf-c-table tbody td[data-label='Name'], <wrapper> .pf-c-table tbody
td[data-label='Namespace']" and "<wrapper> .pf-c-table tbody
td[data-label='Description']", preserving the existing properties (white-space,
overflow, text-overflow, and inner a/.co-resource-item styles) and keep the
!important only if necessary for specificity.

In `@src/gitops/components/imageupdater/ImageUpdaterList.tsx`:
- Around line 58-68: The sort-key list in columnSortConfig inserts 'namespace'
incorrectly because the ternary condition is inverted; change the logic so
'namespace' is only included when listAllNamespaces is true (i.e., include
['namespace'] when listAllNamespaces is true, otherwise []). Update the
expression building the array in columnSortConfig (the place that currently uses
!listAllNamespaces || !effectiveNamespace || effectiveNamespace === '' to decide
insertion) to use listAllNamespaces ? ['namespace'] : [], and ensure the
React.useMemo dependencies still include listAllNamespaces (and
effectiveNamespace only if you keep it in the condition).

In `@src/gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab.tsx`:
- Around line 18-42: The null-check for obj is after several React hook calls
which violates the Rules of Hooks; move the early return (if (!obj) return null)
to the very top of the ImageUpdaterRecentUpdatesTab component so that no hooks
(useGitOpsTranslation, useGitOpsDataViewSort, useColumnsDV, useRowsDV,
React.useMemo/sortData) are invoked when obj is null, preserving unconditional
hook order and preventing "rendered fewer hooks" errors.

---

Nitpick comments:
In `@src/gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab.tsx`:
- Around line 190-194: The comparison block in ImageUpdaterRecentUpdatesTab (the
code that returns sort order based on direction and aValue/bValue) uses nested
ternary operators which hurts readability; replace the nested ternaries with
explicit if/else branches so the logic is clearer: check if direction === 'asc'
then use if (aValue < bValue) return -1; else if (aValue > bValue) return 1;
else return 0; and for the else (descending) branch use if (aValue > bValue)
return -1; else if (aValue < bValue) return 1; else return 0; so the comparison
logic around aValue, bValue and direction is identical but written with clear
if/else statements.
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 2fe87c26-f7ba-4849-b90c-aa12ca8e5278

📥 Commits

Reviewing files that changed from the base of the PR and between 246fd14 and 2fc86de.

📒 Files selected for processing (17)
  • console-extensions.json
  • locales/en/plugin__gitops-plugin.json
  • locales/ja/plugin__gitops-plugin.json
  • locales/ko/plugin__gitops-plugin.json
  • locales/zh/plugin__gitops-plugin.json
  • plugin-metadata.ts
  • src/gitops/components/imageupdater/ImageUpdaterDetailsPage.tsx
  • src/gitops/components/imageupdater/ImageUpdaterDetailsTab.tsx
  • src/gitops/components/imageupdater/ImageUpdaterList.tsx
  • src/gitops/components/imageupdater/ImageUpdaterListTab.tsx
  • src/gitops/components/imageupdater/ImageUpdaterNavPage.tsx
  • src/gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab.tsx
  • src/gitops/components/imageupdater/hooks/useImageUpdaterActionsProvider.tsx
  • src/gitops/components/imageupdater/imageupdater-list.scss
  • src/gitops/models/ImageUpdaterModel.ts
  • src/gitops/templates/imageupdater-yaml.ts
  • src/gitops/templates/index.ts

Comment thread console-extensions.json
Comment thread locales/ja/plugin__gitops-plugin.json
Comment thread plugin-metadata.ts
Comment thread src/gitops/components/imageupdater/imageupdater-list.scss Outdated
Comment thread src/gitops/components/imageupdater/ImageUpdaterList.tsx Outdated
Comment thread src/gitops/components/imageupdater/ImageUpdaterRecentUpdatesTab.tsx Outdated
Signed-off-by: dkarpele <karpelevich@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants