mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
feat(ui): Add hydration in status to dashboard application tiles (#24319)
Signed-off-by: Aditya Raj <adityaraj10600@gmail.com>
This commit is contained in:
parent
5a8b427322
commit
2229f9d6fc
6 changed files with 63 additions and 2 deletions
|
|
@ -29,6 +29,7 @@ var appFields = map[string]func(app *v1alpha1.Application) any{
|
|||
"metadata.creationTimestamp": func(app *v1alpha1.Application) any { return app.CreationTimestamp },
|
||||
"metadata.deletionTimestamp": func(app *v1alpha1.Application) any { return app.DeletionTimestamp },
|
||||
"spec": func(app *v1alpha1.Application) any { return app.Spec },
|
||||
"status.sourceHydrator": func(app *v1alpha1.Application) any { return app.Status.SourceHydrator },
|
||||
"status.sync.status": func(app *v1alpha1.Application) any { return app.Status.Sync.Status },
|
||||
"status.health": func(app *v1alpha1.Application) any { return app.Status.Health },
|
||||
"status.summary": func(app *v1alpha1.Application) any { return app.Status.Summary },
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ const APP_FIELDS = [
|
|||
'metadata.deletionTimestamp',
|
||||
'spec',
|
||||
'operation.sync',
|
||||
'status.sourceHydrator',
|
||||
'status.sync.status',
|
||||
'status.sync.revision',
|
||||
'status.health',
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const PieChart = require('react-svg-piechart').default;
|
|||
import {COLORS} from '../../../shared/components';
|
||||
import * as models from '../../../shared/models';
|
||||
import {HealthStatusCode, SyncStatusCode} from '../../../shared/models';
|
||||
import {ComparisonStatusIcon, HealthStatusIcon} from '../utils';
|
||||
import {ComparisonStatusIcon, HealthStatusIcon, HydrateOperationPhaseIcon} from '../utils';
|
||||
|
||||
const healthColors = new Map<models.HealthStatusCode, string>();
|
||||
healthColors.set('Unknown', COLORS.health.unknown);
|
||||
|
|
@ -19,11 +19,22 @@ syncColors.set('Unknown', COLORS.sync.unknown);
|
|||
syncColors.set('Synced', COLORS.sync.synced);
|
||||
syncColors.set('OutOfSync', COLORS.sync.out_of_sync);
|
||||
|
||||
const hydratorColors = new Map<string, string>();
|
||||
hydratorColors.set('Hydrating', COLORS.operation.running);
|
||||
hydratorColors.set('Hydrated', COLORS.operation.success);
|
||||
hydratorColors.set('Failed', COLORS.operation.failed);
|
||||
hydratorColors.set('None', COLORS.sync.unknown);
|
||||
|
||||
export const ApplicationsSummary = ({applications}: {applications: models.Application[]}) => {
|
||||
const sync = new Map<string, number>();
|
||||
applications.forEach(app => sync.set(app.status.sync.status, (sync.get(app.status.sync.status) || 0) + 1));
|
||||
const health = new Map<string, number>();
|
||||
applications.forEach(app => health.set(app.status.health.status, (health.get(app.status.health.status) || 0) + 1));
|
||||
const hydrator = new Map<string, number>();
|
||||
applications.forEach(app => {
|
||||
const phase = app.status.sourceHydrator?.currentOperation?.phase || 'None';
|
||||
hydrator.set(phase, (hydrator.get(phase) || 0) + 1);
|
||||
});
|
||||
|
||||
const attributes = [
|
||||
{
|
||||
|
|
@ -38,6 +49,10 @@ export const ApplicationsSummary = ({applications}: {applications: models.Applic
|
|||
title: 'HEALTHY',
|
||||
value: applications.filter(app => app.status.health.status === 'Healthy').length
|
||||
},
|
||||
{
|
||||
title: 'HYDRATED',
|
||||
value: applications.filter(app => app.status.sourceHydrator?.currentOperation?.phase === 'Hydrated').length
|
||||
},
|
||||
{
|
||||
title: 'CLUSTERS',
|
||||
value: new Set(applications.map(app => app.spec.destination.server || app.spec.destination.name)).size
|
||||
|
|
@ -58,6 +73,11 @@ export const ApplicationsSummary = ({applications}: {applications: models.Applic
|
|||
title: 'Health',
|
||||
data: Array.from(health.keys()).map(key => ({title: key, value: health.get(key), color: healthColors.get(key as models.HealthStatusCode)})),
|
||||
legend: healthColors as Map<string, string>
|
||||
},
|
||||
{
|
||||
title: 'Hydrator',
|
||||
data: Array.from(hydrator.keys()).map(key => ({title: key, value: hydrator.get(key), color: hydratorColors.get(key)})),
|
||||
legend: hydratorColors as Map<string, string>
|
||||
}
|
||||
];
|
||||
return (
|
||||
|
|
@ -97,6 +117,21 @@ export const ApplicationsSummary = ({applications}: {applications: models.Applic
|
|||
<li style={{listStyle: 'none', whiteSpace: 'nowrap'}} key={key}>
|
||||
{chart.title === 'Health' && <HealthStatusIcon state={{status: key as HealthStatusCode, message: ''}} noSpin={true} />}
|
||||
{chart.title === 'Sync' && <ComparisonStatusIcon status={key as SyncStatusCode} noSpin={true} />}
|
||||
{chart.title === 'Hydrator' && key !== 'None' && (
|
||||
<HydrateOperationPhaseIcon
|
||||
operationState={{
|
||||
phase: key as any,
|
||||
startedAt: '',
|
||||
message: '',
|
||||
drySHA: '',
|
||||
hydratedSHA: '',
|
||||
sourceHydrator: {} as any
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{chart.title === 'Hydrator' && key === 'None' && (
|
||||
<i className='fa fa-minus-circle' style={{color: hydratorColors.get(key)}} />
|
||||
)}
|
||||
{` ${key} (${getLegendValue(key)})`}
|
||||
</li>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
.applications-list__table-row.applications-table-row--with-hydrator {
|
||||
.columns.small-4,
|
||||
.columns.small-6 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.applications-table-source {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@ export const ApplicationsTable = (props: {
|
|||
key={AppUtils.appInstanceName(app)}
|
||||
className={`argo-table-list__row
|
||||
applications-list__entry applications-list__entry--health-${app.status.health.status} ${selectedApp === i ? 'applications-tiles__selected' : ''}`}>
|
||||
<div className={`row applications-list__table-row`} onClick={e => ctx.navigation.goto(`/${AppUtils.getAppUrl(app)}`, {}, {event: e})}>
|
||||
<div
|
||||
className={`row applications-list__table-row ${app.status.sourceHydrator?.currentOperation ? 'applications-table-row--with-hydrator' : ''}`}
|
||||
onClick={e => ctx.navigation.goto(`/${AppUtils.getAppUrl(app)}`, {}, {event: e})}>
|
||||
<div className='columns small-4'>
|
||||
<div className='row'>
|
||||
<div className=' columns small-2'>
|
||||
|
|
@ -129,6 +131,12 @@ export const ApplicationsTable = (props: {
|
|||
|
||||
<div className='columns small-2'>
|
||||
<AppUtils.HealthStatusIcon state={app.status.health} /> <span>{app.status.health.status}</span> <br />
|
||||
{app.status.sourceHydrator?.currentOperation && (
|
||||
<>
|
||||
<AppUtils.HydrateOperationPhaseIcon operationState={app.status.sourceHydrator.currentOperation} />{' '}
|
||||
<span>{app.status.sourceHydrator.currentOperation.phase}</span> <br />
|
||||
</>
|
||||
)}
|
||||
<AppUtils.ComparisonStatusIcon status={app.status.sync.status} />
|
||||
<span>{app.status.sync.status}</span> <OperationState app={app} quiet={true} />
|
||||
<DropDownMenu
|
||||
|
|
|
|||
|
|
@ -202,6 +202,13 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
|
|||
<div className='columns small-9' qe-id='applications-tiles-health-status'>
|
||||
<AppUtils.HealthStatusIcon state={app.status.health} /> {app.status.health.status}
|
||||
|
||||
{app.status.sourceHydrator?.currentOperation && (
|
||||
<>
|
||||
<AppUtils.HydrateOperationPhaseIcon operationState={app.status.sourceHydrator.currentOperation} />{' '}
|
||||
{app.status.sourceHydrator.currentOperation.phase}
|
||||
|
||||
</>
|
||||
)}
|
||||
<AppUtils.ComparisonStatusIcon status={app.status.sync.status} /> {app.status.sync.status}
|
||||
|
||||
<OperationState app={app} quiet={true} />
|
||||
|
|
|
|||
Loading…
Reference in a new issue