diff --git a/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx b/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx index 57ec1f122f915..f6284258b238e 100644 --- a/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx +++ b/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx @@ -1,4 +1,4 @@ -import {Checkbox, DropDown, Duration, NotificationType, Ticker} from 'argo-ui'; +import {Checkbox, DropDown, Duration, NotificationType, Ticker, HelpIcon} from 'argo-ui'; import * as moment from 'moment'; import * as PropTypes from 'prop-types'; import * as React from 'react'; @@ -15,6 +15,7 @@ interface Props { application: models.Application; operationState: models.OperationState; } +const buildResourceUniqueId = (res: Omit) => `${res.group}-${res.kind}-${res.version}-${res.namespace}-${res.name}`; const Filter = (props: {filters: string[]; setFilters: (f: string[]) => void; options: string[]; title: string; style?: React.CSSProperties}) => { const {filters, setFilters, options, title, style} = props; @@ -126,18 +127,60 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl } } const [filters, setFilters] = React.useState([]); + const [healthFilters, setHealthFilters] = React.useState([]); + const Healths = Object.keys(models.HealthStatuses); const Statuses = Object.keys(models.ResultCodes); const OperationPhases = Object.keys(models.OperationPhases); // const syncPhases = ['PreSync', 'Sync', 'PostSync', 'SyncFail']; // const hookPhases = ['Running', 'Terminating', 'Failed', 'Error', 'Succeeded']; + const resourceHealth = application.status.resources.reduce( + (acc, res) => { + if (res.health) { + acc[buildResourceUniqueId(res)] = res.health; + } - let filtered: models.ResourceResult[] = []; - if (syncResult) { - if (syncResult.resources && syncResult.resources.length > 0) { - filtered = syncResult.resources.filter(r => filters.length === 0 || filters.includes(getStatus(r))); + return acc; + }, + {} as Record + ); + + const combinedHealthSyncResult: models.SyncResourceResult[] = syncResult?.resources?.map(syncResultItem => { + const uniqueResourceName = buildResourceUniqueId(syncResultItem); + + const healthStatus = resourceHealth[uniqueResourceName]; + + const syncResultWithHealth: models.SyncResourceResult = { + ...syncResultItem + }; + + if (healthStatus) { + syncResultWithHealth.health = healthStatus; } + + return syncResultWithHealth; + }); + let filtered: models.SyncResourceResult[] = []; + + if (combinedHealthSyncResult && combinedHealthSyncResult.length > 0) { + filtered = combinedHealthSyncResult.filter(r => { + if (filters.length === 0 && healthFilters.length === 0) { + return true; + } + + let pass = true; + if (filters.length !== 0 && !filters.includes(getStatus(r))) { + pass = false; + } + + if (pass && healthFilters.length !== 0 && !healthFilters.includes(r.health?.status)) { + pass = false; + } + + return pass; + }); } + return (
@@ -155,6 +198,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl
+
@@ -166,6 +210,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl
NAMESPACE
NAME
STATUS
+
HEALTH
HOOK
MESSAGE
@@ -189,6 +234,16 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl
{getStatus(resource)}
+
+ {resource.health ? ( +
+ {resource.health?.status} + {resource.health.message && } +
+ ) : ( + <>{'-'} + )} +
{resource.hookType}
diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts index b3d54ba522621..69cec01076796 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -127,6 +127,10 @@ export interface ResourceResult { hookPhase: OperationPhase; } +export type SyncResourceResult = ResourceResult & { + health?: HealthStatus; +}; + export const AnnotationRefreshKey = 'argocd.argoproj.io/refresh'; export const AnnotationHookKey = 'argocd.argoproj.io/hook'; export const AnnotationSyncWaveKey = 'argocd.argoproj.io/sync-wave';