From 829bb77107905a9acb1a1b998575f35846d11e9e Mon Sep 17 00:00:00 2001 From: Keith Chong Date: Fri, 17 Jul 2026 11:22:37 -0400 Subject: [PATCH 1/3] Externalize strings Signed-off-by: Keith Chong --- locales/en/plugin__gitops-plugin.json | 4 +++- locales/ja/plugin__gitops-plugin.json | 4 +++- locales/ko/plugin__gitops-plugin.json | 4 +++- locales/zh/plugin__gitops-plugin.json | 4 +++- .../application/ApplicationResourcesView.tsx | 14 +++++++------- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/locales/en/plugin__gitops-plugin.json b/locales/en/plugin__gitops-plugin.json index b532aea5a..d9117e16c 100644 --- a/locales/en/plugin__gitops-plugin.json +++ b/locales/en/plugin__gitops-plugin.json @@ -32,6 +32,8 @@ "Name": "Name", "Namespace": "Namespace", "Sync Wave": "Sync Wave", + "No Sync Status": "No Sync Status", + "None": "None", "Kind": "Kind", "Type": "Type", "Repository": "Repository", @@ -284,7 +286,6 @@ "Create Rollout": "Create Rollout", "Pods": "Pods", "Selector": "Selector", - "No labels": "No labels", "Rollout Status": "Rollout Status", "Revisions": "Revisions", "There was an error retrieving the rollout. Check your connection and reload the page.": "There was an error retrieving the rollout. Check your connection and reload the page.", @@ -322,6 +323,7 @@ "There was an error retrieving applicationsets. Check your connection and reload the page.": "There was an error retrieving applicationsets. Check your connection and reload the page.", "ApplicationSets": "ApplicationSets", "Create ApplicationSet": "Create ApplicationSet", + "No labels": "No labels", "Name must be unique within a namespace.": "Name must be unique within a namespace.", "Namespace defines the space within which each name must be unique.": "Namespace defines the space within which each name must be unique.", "Map of string keys and values that can be used to organize and categorize (scope and select) objects.": "Map of string keys and values that can be used to organize and categorize (scope and select) objects.", diff --git a/locales/ja/plugin__gitops-plugin.json b/locales/ja/plugin__gitops-plugin.json index 9bf0165f9..e30d7c626 100644 --- a/locales/ja/plugin__gitops-plugin.json +++ b/locales/ja/plugin__gitops-plugin.json @@ -32,6 +32,8 @@ "Name": "Name", "Namespace": "Namespace", "Sync Wave": "Sync Wave", + "No Sync Status": "No Sync Status", + "None": "None", "Kind": "Kind", "Type": "Type", "Repository": "Repository", @@ -284,7 +286,6 @@ "Create Rollout": "Create Rollout", "Pods": "Pods", "Selector": "Selector", - "No labels": "No labels", "Rollout Status": "Rollout Status", "Revisions": "Revisions", "There was an error retrieving the rollout. Check your connection and reload the page.": "There was an error retrieving the rollout. Check your connection and reload the page.", @@ -322,6 +323,7 @@ "There was an error retrieving applicationsets. Check your connection and reload the page.": "There was an error retrieving applicationsets. Check your connection and reload the page.", "ApplicationSets": "ApplicationSets", "Create ApplicationSet": "Create ApplicationSet", + "No labels": "No labels", "Name must be unique within a namespace.": "Name must be unique within a namespace.", "Namespace defines the space within which each name must be unique.": "Namespace defines the space within which each name must be unique.", "Map of string keys and values that can be used to organize and categorize (scope and select) objects.": "Map of string keys and values that can be used to organize and categorize (scope and select) objects.", diff --git a/locales/ko/plugin__gitops-plugin.json b/locales/ko/plugin__gitops-plugin.json index b23d99ce1..84efc1ccc 100644 --- a/locales/ko/plugin__gitops-plugin.json +++ b/locales/ko/plugin__gitops-plugin.json @@ -32,6 +32,8 @@ "Name": "Name", "Namespace": "Namespace", "Sync Wave": "Sync Wave", + "No Sync Status": "No Sync Status", + "None": "None", "Kind": "Kind", "Type": "Type", "Repository": "Repository", @@ -284,7 +286,6 @@ "Create Rollout": "Create Rollout", "Pods": "Pods", "Selector": "Selector", - "No labels": "No labels", "Rollout Status": "Rollout Status", "Revisions": "Revisions", "There was an error retrieving the rollout. Check your connection and reload the page.": "There was an error retrieving the rollout. Check your connection and reload the page.", @@ -322,6 +323,7 @@ "There was an error retrieving applicationsets. Check your connection and reload the page.": "There was an error retrieving applicationsets. Check your connection and reload the page.", "ApplicationSets": "ApplicationSets", "Create ApplicationSet": "Create ApplicationSet", + "No labels": "No labels", "Name must be unique within a namespace.": "Name must be unique within a namespace.", "Namespace defines the space within which each name must be unique.": "Namespace defines the space within which each name must be unique.", "Map of string keys and values that can be used to organize and categorize (scope and select) objects.": "Map of string keys and values that can be used to organize and categorize (scope and select) objects.", diff --git a/locales/zh/plugin__gitops-plugin.json b/locales/zh/plugin__gitops-plugin.json index e8ce9c289..0ab083b71 100644 --- a/locales/zh/plugin__gitops-plugin.json +++ b/locales/zh/plugin__gitops-plugin.json @@ -32,6 +32,8 @@ "Name": "Name", "Namespace": "Namespace", "Sync Wave": "Sync Wave", + "No Sync Status": "No Sync Status", + "None": "None", "Kind": "Kind", "Type": "Type", "Repository": "Repository", @@ -284,7 +286,6 @@ "Create Rollout": "Create Rollout", "Pods": "Pods", "Selector": "Selector", - "No labels": "No labels", "Rollout Status": "Rollout Status", "Revisions": "Revisions", "There was an error retrieving the rollout. Check your connection and reload the page.": "There was an error retrieving the rollout. Check your connection and reload the page.", @@ -322,6 +323,7 @@ "There was an error retrieving applicationsets. Check your connection and reload the page.": "There was an error retrieving applicationsets. Check your connection and reload the page.", "ApplicationSets": "ApplicationSets", "Create ApplicationSet": "Create ApplicationSet", + "No labels": "No labels", "Name must be unique within a namespace.": "Name must be unique within a namespace.", "Namespace defines the space within which each name must be unique.": "Namespace defines the space within which each name must be unique.", "Map of string keys and values that can be used to organize and categorize (scope and select) objects.": "Map of string keys and values that can be used to organize and categorize (scope and select) objects.", diff --git a/src/gitops/components/application/ApplicationResourcesView.tsx b/src/gitops/components/application/ApplicationResourcesView.tsx index a069b7cc5..7faf51a9f 100644 --- a/src/gitops/components/application/ApplicationResourcesView.tsx +++ b/src/gitops/components/application/ApplicationResourcesView.tsx @@ -327,13 +327,13 @@ const filters = (resources: ApplicationResourceStatus[]): RowFilter[] => { { filterGroupName: t('Sync Status'), type: 'resource-sync', - reducer: (resource) => (resource.status ? resource.status : 'No Sync Status'), + reducer: (resource) => (resource.status ? resource.status : t('No Sync Status')), filter: (input, resource) => { if (input.selected?.length) { if (resource?.status) { return input.selected.includes(resource.status); } else { - return input.selected.includes('No Sync Status'); + return input.selected.includes(t('No Sync Status')); } } return true; @@ -341,8 +341,8 @@ const filters = (resources: ApplicationResourceStatus[]): RowFilter[] => { items: resources .map((resource) => { return { - id: resource.status ? resource.status : 'No Sync Status', - title: resource.status ? resource.status : 'No Sync Status', + id: resource.status ? resource.status : t('No Sync Status'), + title: resource.status ? resource.status : t('No Sync Status'), }; }) .reduce(function (result: RowFilterItem[], resource: RowFilterItem) { @@ -355,7 +355,7 @@ const filters = (resources: ApplicationResourceStatus[]): RowFilter[] => { { filterGroupName: t('Health Status'), type: 'resource-health', - reducer: (resource) => (resource.health ? resource.health.status : 'None'), + reducer: (resource) => (resource.health ? resource.health.status : t('None')), filter: (input, resource) => { if (input.selected?.length) { if (resource?.health?.status) { @@ -370,8 +370,8 @@ const filters = (resources: ApplicationResourceStatus[]): RowFilter[] => { items: resources .map((resource) => { return { - id: resource.health && resource.health.status ? resource.health.status : 'None', - title: resource.health && resource.health.status ? resource.health.status : 'None', + id: resource.health && resource.health.status ? resource.health.status : t('None'), + title: resource.health && resource.health.status ? resource.health.status : t('None'), }; }) .reduce(function (result: RowFilterItem[], resource: RowFilterItem) { From b01fbe0b878abb5a8a727e8c6f357f11d0ad6709 Mon Sep 17 00:00:00 2001 From: Keith Chong Date: Fri, 17 Jul 2026 12:10:51 -0400 Subject: [PATCH 2/3] Make all action dropdown have unique id. common up ResourceActionsCell Signed-off-by: Keith Chong --- .../application/ApplicationResourcesView.tsx | 23 ++----------- .../application/ApplicationSyncStatusTab.tsx | 24 ++------------ .../imageupdater/ImageUpdaterList.tsx | 7 ++-- src/gitops/components/project/ProjectList.tsx | 7 ++-- src/gitops/components/rollout/RolloutList.tsx | 7 ++-- .../rollout/components/PodList/PodList.tsx | 7 ++-- .../components/shared/ApplicationList.tsx | 6 ++-- .../components/shared/ApplicationSetList.tsx | 6 ++-- .../ResourceActionsCell.tsx | 33 +++++++++++++++++++ 9 files changed, 59 insertions(+), 61 deletions(-) create mode 100644 src/gitops/components/shared/ResourceActionsCell/ResourceActionsCell.tsx diff --git a/src/gitops/components/application/ApplicationResourcesView.tsx b/src/gitops/components/application/ApplicationResourcesView.tsx index 7faf51a9f..ba920b5c7 100644 --- a/src/gitops/components/application/ApplicationResourcesView.tsx +++ b/src/gitops/components/application/ApplicationResourcesView.tsx @@ -1,13 +1,10 @@ import * as React from 'react'; -import { useResourceActionsProvider } from '@gitops/hooks/useResourceActionsProvider'; import HealthStatus from '@gitops/Statuses/HealthStatus'; import SyncStatus from '@gitops/Statuses/SyncStatus'; -import ActionDropDown from '@gitops/utils/components/ActionDropDown/ActionDropDown'; import { t } from '@gitops/utils/hooks/useGitOpsTranslation'; import { ApplicationKind, ApplicationResourceStatus } from '@gitops-models/ApplicationModel'; import { - Action, K8sGroupVersionKind, ListPageFilter, ResourceLink, @@ -29,6 +26,7 @@ import { CubesIcon } from '@patternfly/react-icons'; import { Tbody, Td, Tr } from '@patternfly/react-table'; import { GitOpsDataViewTable, useGitOpsDataViewSort } from '../shared/DataView'; +import ResourceActionsCell from '../shared/ResourceActionsCell/ResourceActionsCell'; import { ApplicationGraphView } from './graph/ApplicationGraphView'; import ApplicationResourcesToolbar from './ApplicationResourcesToolbar'; @@ -297,7 +295,7 @@ const useResourceRowsDV = ( }, { id: 'actions-' + index, - cell: , + cell: , props: { style: { paddingTop: 8, paddingRight: 0, paddingLeft: 0, width: 10 } }, }, ]); @@ -305,23 +303,6 @@ const useResourceRowsDV = ( return rows; }; -const ResourceActionsCell: React.FC<{ - resource: ApplicationResourceStatus; - app: ApplicationKind; - argoBaseURL: string; -}> = ({ resource, app, argoBaseURL }) => { - const actionList: [actions: Action[]] = useResourceActionsProvider(resource, app, argoBaseURL); - return ( -
- -
- ); -}; - const filters = (resources: ApplicationResourceStatus[]): RowFilter[] => { return [ { diff --git a/src/gitops/components/application/ApplicationSyncStatusTab.tsx b/src/gitops/components/application/ApplicationSyncStatusTab.tsx index 481a73f4b..8134dad0c 100644 --- a/src/gitops/components/application/ApplicationSyncStatusTab.tsx +++ b/src/gitops/components/application/ApplicationSyncStatusTab.tsx @@ -3,15 +3,12 @@ import { RouteComponentProps } from 'react-router'; import classNames from 'classnames'; import { useArgoServer } from '@gitops/hooks/useArgoServer'; -import { useResourceActionsProvider } from '@gitops/hooks/useResourceActionsProvider'; import { OperationState } from '@gitops/Statuses/OperationState'; import SyncStatus from '@gitops/Statuses/SyncStatus'; -import ActionDropDown from '@gitops/utils/components/ActionDropDown/ActionDropDown'; import { getApplicationArgoUrl, getDuration } from '@gitops/utils/gitops'; import { t } from '@gitops/utils/hooks/useGitOpsTranslation'; import { ApplicationKind, ApplicationResourceStatus } from '@gitops-models/ApplicationModel'; import { - Action, K8sGroupVersionKind, ResourceLink, Timestamp, @@ -38,6 +35,7 @@ import { Tbody, Td, ThProps, Tr } from '@patternfly/react-table'; import { DetailsDescriptionGroup } from '../shared/BaseDetailsSummary/BaseDetailsSummary'; import { GitOpsDataViewTable, useGitOpsDataViewSort } from '../shared/DataView'; +import ResourceActionsCell from '../shared/ResourceActionsCell/ResourceActionsCell'; import { ConditionsPopover } from './Conditions/ConditionsPopover'; @@ -402,7 +400,7 @@ const useResourceRowsDV = ( }, { id: 'actions-' + index, - cell: , + cell: , props: { style: { paddingTop: 8, paddingRight: 0, paddingLeft: 0, width: 10 }, className: 'dropdown-kebab-pf pf-c-table__action', @@ -413,22 +411,4 @@ const useResourceRowsDV = ( return rows; }; -const ResourceActionsCell: React.FC<{ - resource: ApplicationResourceStatus; - app: ApplicationKind; - argoBaseURL: string; -}> = ({ resource, app, argoBaseURL }) => { - const actionList: [actions: Action[]] = useResourceActionsProvider(resource, app, argoBaseURL); - - return ( -
- -
- ); -}; - export default ApplicationSyncStatusTab; diff --git a/src/gitops/components/imageupdater/ImageUpdaterList.tsx b/src/gitops/components/imageupdater/ImageUpdaterList.tsx index bb3307ea1..9a183b0d2 100644 --- a/src/gitops/components/imageupdater/ImageUpdaterList.tsx +++ b/src/gitops/components/imageupdater/ImageUpdaterList.tsx @@ -402,7 +402,7 @@ export const useImageUpdaterRowsDV = ( }, { id: 'actions-' + index, - cell: , + cell: , props: { className: 'gitops-imageupdater-list__actions-cell' }, }, ]); @@ -412,13 +412,14 @@ export const useImageUpdaterRowsDV = ( const ImageUpdaterActionsCell: React.FC<{ imageUpdater: ImageUpdaterKind; -}> = ({ imageUpdater }) => { + index: number; +}> = ({ imageUpdater, index }) => { const actionList: Action[] = useImageUpdaterActionsProvider(imageUpdater); return (
diff --git a/src/gitops/components/project/ProjectList.tsx b/src/gitops/components/project/ProjectList.tsx index dbfcac004..3eddd7d6f 100644 --- a/src/gitops/components/project/ProjectList.tsx +++ b/src/gitops/components/project/ProjectList.tsx @@ -528,7 +528,7 @@ export const useProjectsRowsDV = ( }, { id: 'actions-' + index, - cell: , + cell: , props: { style: { paddingTop: 8, paddingRight: 0, paddingLeft: 0, width: 10 } }, }, ]); @@ -538,13 +538,14 @@ export const useProjectsRowsDV = ( const ProjectActionsCell: React.FC<{ project: AppProjectKind; -}> = ({ project }) => { + index: number; +}> = ({ project, index }) => { const actionList: Action[] = useProjectActionsProvider(project); return (
diff --git a/src/gitops/components/rollout/RolloutList.tsx b/src/gitops/components/rollout/RolloutList.tsx index 4f47f3b05..d83524c49 100644 --- a/src/gitops/components/rollout/RolloutList.tsx +++ b/src/gitops/components/rollout/RolloutList.tsx @@ -445,7 +445,7 @@ export const useRolloutsRowsDV = (rolloutsList, namespace): DataViewTr[] => { }, { id: 'actions-' + index, - cell: , + cell: , props: { style: { paddingTop: 8, paddingRight: 0, paddingLeft: 0, width: 10 } }, }, ]); @@ -455,13 +455,14 @@ export const useRolloutsRowsDV = (rolloutsList, namespace): DataViewTr[] => { const RolloutActionsCell: React.FC<{ app: RolloutKind; -}> = ({ app }) => { + index: number; +}> = ({ app, index }) => { const actionList: [actions: Action[]] = useRolloutActionsProvider(app); return (
diff --git a/src/gitops/components/rollout/components/PodList/PodList.tsx b/src/gitops/components/rollout/components/PodList/PodList.tsx index 28ae41064..3a4a3ef34 100644 --- a/src/gitops/components/rollout/components/PodList/PodList.tsx +++ b/src/gitops/components/rollout/components/PodList/PodList.tsx @@ -317,7 +317,7 @@ const usePodRowsDV = (podsList: PodKind[], memResults, cpuResults, namespace): D }, { id: 'actions-' + index, - cell: , + cell: , props: { className: 'dropdown-kebab-pf pf-c-table__action' }, }, ]); @@ -327,13 +327,14 @@ const usePodRowsDV = (podsList: PodKind[], memResults, cpuResults, namespace): D const PodRowActions: React.FC<{ pod: PodKind; -}> = ({ pod }) => { + index: number; +}> = ({ pod, index }) => { const actionList: [actions: Action[]] = usePodActionsProvider(pod); return (
diff --git a/src/gitops/components/shared/ApplicationList.tsx b/src/gitops/components/shared/ApplicationList.tsx index 4c5388cc3..9afa12f2d 100644 --- a/src/gitops/components/shared/ApplicationList.tsx +++ b/src/gitops/components/shared/ApplicationList.tsx @@ -335,14 +335,14 @@ export const sortData = ( }); }; -const ApplicationActionsCell: React.FC<{ app: ApplicationKind }> = ({ app }) => { +const ApplicationActionsCell: React.FC<{ app: ApplicationKind, index: number }> = ({ app, index}) => { const actionList: [actions: Action[]] = useApplicationActionsProvider(app); return (
@@ -444,7 +444,7 @@ const useApplicationRowsDV = (applicationsList, namespace): DataViewTr[] => { }, { id: 'actions-' + index, - cell: , + cell: , props: { style: { paddingTop: 8, paddingRight: 0, paddingLeft: 0, width: 10 } }, }, ]); diff --git a/src/gitops/components/shared/ApplicationSetList.tsx b/src/gitops/components/shared/ApplicationSetList.tsx index 96f799663..0e74f387c 100644 --- a/src/gitops/components/shared/ApplicationSetList.tsx +++ b/src/gitops/components/shared/ApplicationSetList.tsx @@ -294,11 +294,11 @@ const ApplicationSetList: React.FC = ({ ); }; -const ApplicationSetActionsCell: React.FC<{ appSet: ApplicationSetKind }> = ({ appSet }) => { +const ApplicationSetActionsCell: React.FC<{ appSet: ApplicationSetKind, index: number }> = ({ appSet, index }) => { const [actions] = useApplicationSetActionsProvider(appSet); return (
- +
); }; @@ -353,7 +353,7 @@ const useApplicationSetRowsDV = ( }, { id: 'actions-' + index, - cell: , + cell: , props: { style: { paddingTop: 8, paddingRight: 0, paddingLeft: 0, width: 10 } }, }, ]); diff --git a/src/gitops/components/shared/ResourceActionsCell/ResourceActionsCell.tsx b/src/gitops/components/shared/ResourceActionsCell/ResourceActionsCell.tsx new file mode 100644 index 000000000..54b5843b1 --- /dev/null +++ b/src/gitops/components/shared/ResourceActionsCell/ResourceActionsCell.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; + +import { useResourceActionsProvider } from '@gitops/hooks/useResourceActionsProvider'; +import ActionDropDown from '@gitops/utils/components/ActionDropDown/ActionDropDown'; +import { ApplicationKind, ApplicationResourceStatus } from '@gitops-models/ApplicationModel'; + +type ResourceActionsCellProps = { + resource: ApplicationResourceStatus; + app: ApplicationKind; + argoBaseURL: string; + index: number; +}; + +export const ResourceActionsCell: React.FC = ({ + resource, + app, + argoBaseURL, + index, +}) => { + const actionList = useResourceActionsProvider(resource, app, argoBaseURL); + + return ( +
+ +
+ ); +}; + +export default ResourceActionsCell; From 3f188791ac6c4f388ba510fd12bff3574126f2f6 Mon Sep 17 00:00:00 2001 From: Keith Chong Date: Fri, 17 Jul 2026 12:20:13 -0400 Subject: [PATCH 3/3] Assisted-by: Cursor Grok, coderabbitai - Signed-off-by: Keith Chong --- src/gitops/components/application/ApplicationResourcesView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gitops/components/application/ApplicationResourcesView.tsx b/src/gitops/components/application/ApplicationResourcesView.tsx index ba920b5c7..18e12c249 100644 --- a/src/gitops/components/application/ApplicationResourcesView.tsx +++ b/src/gitops/components/application/ApplicationResourcesView.tsx @@ -341,7 +341,7 @@ const filters = (resources: ApplicationResourceStatus[]): RowFilter[] => { if (input.selected?.length) { if (resource?.health?.status) { return input.selected.includes(resource.health.status); - } else if (input.selected.includes('None')) { + } else if (input.selected.includes(t('None'))) { return true; } return false;