github.com/argoproj/argo-cd/v2@v2.10.9/ui/src/app/applications/components/applications-list/applications-summary.tsx (about) 1 import * as React from 'react'; 2 const PieChart = require('react-svg-piechart').default; 3 4 import {COLORS} from '../../../shared/components'; 5 import * as models from '../../../shared/models'; 6 import {HealthStatusCode, SyncStatusCode} from '../../../shared/models'; 7 import {ComparisonStatusIcon, HealthStatusIcon} from '../utils'; 8 9 const healthColors = new Map<models.HealthStatusCode, string>(); 10 healthColors.set('Unknown', COLORS.health.unknown); 11 healthColors.set('Progressing', COLORS.health.progressing); 12 healthColors.set('Suspended', COLORS.health.suspended); 13 healthColors.set('Healthy', COLORS.health.healthy); 14 healthColors.set('Degraded', COLORS.health.degraded); 15 healthColors.set('Missing', COLORS.health.missing); 16 17 const syncColors = new Map<models.SyncStatusCode, string>(); 18 syncColors.set('Unknown', COLORS.sync.unknown); 19 syncColors.set('Synced', COLORS.sync.synced); 20 syncColors.set('OutOfSync', COLORS.sync.out_of_sync); 21 22 export const ApplicationsSummary = ({applications}: {applications: models.Application[]}) => { 23 const sync = new Map<string, number>(); 24 applications.forEach(app => sync.set(app.status.sync.status, (sync.get(app.status.sync.status) || 0) + 1)); 25 const health = new Map<string, number>(); 26 applications.forEach(app => health.set(app.status.health.status, (health.get(app.status.health.status) || 0) + 1)); 27 28 const attributes = [ 29 { 30 title: 'APPLICATIONS', 31 value: applications.length 32 }, 33 { 34 title: 'SYNCED', 35 value: applications.filter(app => app.status.sync.status === 'Synced').length 36 }, 37 { 38 title: 'HEALTHY', 39 value: applications.filter(app => app.status.health.status === 'Healthy').length 40 }, 41 { 42 title: 'CLUSTERS', 43 value: new Set(applications.map(app => app.spec.destination.server)).size 44 }, 45 { 46 title: 'NAMESPACES', 47 value: new Set(applications.map(app => app.spec.destination.namespace)).size 48 } 49 ]; 50 51 const charts = [ 52 { 53 title: 'Sync', 54 data: Array.from(sync.keys()).map(key => ({title: key, value: sync.get(key), color: syncColors.get(key as models.SyncStatusCode)})), 55 legend: syncColors as Map<string, string> 56 }, 57 { 58 title: 'Health', 59 data: Array.from(health.keys()).map(key => ({title: key, value: health.get(key), color: healthColors.get(key as models.HealthStatusCode)})), 60 legend: healthColors as Map<string, string> 61 } 62 ]; 63 return ( 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 => { 82 const getLegendValue = (key: string) => { 83 const index = chart.data.findIndex((data: {title: string}) => data.title === key); 84 return index > -1 ? chart.data[index].value : 0; 85 }; 86 return ( 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 };