argo-cd
115 строк · 5.6 Кб
1import * as React from 'react';
2const PieChart = require('react-svg-piechart').default;
3
4import {COLORS} from '../../../shared/components';
5import * as models from '../../../shared/models';
6import {HealthStatusCode, SyncStatusCode} from '../../../shared/models';
7import {ComparisonStatusIcon, HealthStatusIcon} from '../utils';
8
9const healthColors = new Map<models.HealthStatusCode, string>();
10healthColors.set('Unknown', COLORS.health.unknown);
11healthColors.set('Progressing', COLORS.health.progressing);
12healthColors.set('Suspended', COLORS.health.suspended);
13healthColors.set('Healthy', COLORS.health.healthy);
14healthColors.set('Degraded', COLORS.health.degraded);
15healthColors.set('Missing', COLORS.health.missing);
16
17const syncColors = new Map<models.SyncStatusCode, string>();
18syncColors.set('Unknown', COLORS.sync.unknown);
19syncColors.set('Synced', COLORS.sync.synced);
20syncColors.set('OutOfSync', COLORS.sync.out_of_sync);
21
22export const ApplicationsSummary = ({applications}: {applications: models.Application[]}) => {
23const sync = new Map<string, number>();
24applications.forEach(app => sync.set(app.status.sync.status, (sync.get(app.status.sync.status) || 0) + 1));
25const health = new Map<string, number>();
26applications.forEach(app => health.set(app.status.health.status, (health.get(app.status.health.status) || 0) + 1));
27
28const attributes = [
29{
30title: 'APPLICATIONS',
31value: applications.length
32},
33{
34title: 'SYNCED',
35value: applications.filter(app => app.status.sync.status === 'Synced').length
36},
37{
38title: 'HEALTHY',
39value: applications.filter(app => app.status.health.status === 'Healthy').length
40},
41{
42title: 'CLUSTERS',
43value: new Set(applications.map(app => app.spec.destination.server)).size
44},
45{
46title: 'NAMESPACES',
47value: new Set(applications.map(app => app.spec.destination.namespace)).size
48}
49];
50
51const charts = [
52{
53title: 'Sync',
54data: Array.from(sync.keys()).map(key => ({title: key, value: sync.get(key), color: syncColors.get(key as models.SyncStatusCode)})),
55legend: syncColors as Map<string, string>
56},
57{
58title: 'Health',
59data: Array.from(health.keys()).map(key => ({title: key, value: health.get(key), color: healthColors.get(key as models.HealthStatusCode)})),
60legend: healthColors as Map<string, string>
61}
62];
63return (
64<div className='white-box applications-list__summary'>
65<div className='row'>
66<div className='columns large-3 small-12'>
67<div className='white-box__details'>
68<p className='row'>SUMMARY</p>
69{attributes.map(attr => (
70<div className='row white-box__details-row' key={attr.title}>
71<div className='columns small-8'>{attr.title}</div>
72<div style={{textAlign: 'right'}} className='columns small-4'>
73{attr.value}
74</div>
75</div>
76))}
77</div>
78</div>
79<div className='columns large-9 small-12'>
80<div className='row chart-group'>
81{charts.map(chart => {
82const getLegendValue = (key: string) => {
83const index = chart.data.findIndex((data: {title: string}) => data.title === key);
84return index > -1 ? chart.data[index].value : 0;
85};
86return (
87<React.Fragment key={chart.title}>
88<div className='columns large-6 small-12'>
89<div className='row chart'>
90<div className='large-8 small-6'>
91<h4 style={{textAlign: 'center'}}>{chart.title}</h4>
92<PieChart data={chart.data} />
93</div>
94<div className='large-3 small-1'>
95<ul>
96{Array.from(chart.legend.keys()).map(key => (
97<li style={{listStyle: 'none', whiteSpace: 'nowrap'}} key={key}>
98{chart.title === 'Health' && <HealthStatusIcon state={{status: key as HealthStatusCode, message: ''}} noSpin={true} />}
99{chart.title === 'Sync' && <ComparisonStatusIcon status={key as SyncStatusCode} noSpin={true} />}
100{` ${key} (${getLegendValue(key)})`}
101</li>
102))}
103</ul>
104</div>
105</div>
106</div>
107</React.Fragment>
108);
109})}
110</div>
111</div>
112</div>
113</div>
114);
115};
116