|
2 | 2 | import Card from '$lib/Card.svelte';
|
3 | 3 |
|
4 | 4 | import { PendingValue, TeamVulnerabilityRiskScoreTrend, TeamVulnerabilityState } from '$houdini';
|
5 |
| - import CircleProgressBar from '$lib/components/CircleProgressBar.svelte'; |
6 | 5 | import Nais from '$lib/icons/Nais.svelte';
|
7 | 6 |
|
8 | 7 | import { page } from '$app/stores';
|
| 8 | + import CircleProgressBar from '$lib/components/CircleProgressBar.svelte'; |
| 9 | + import SummaryCard from '$lib/components/SummaryCard.svelte'; |
9 | 10 | import Vulnerability from '$lib/components/Vulnerability.svelte';
|
10 | 11 | import WorkloadsWithSbom from '$lib/components/WorkloadsWithSBOM.svelte';
|
11 | 12 | import GraphErrors from '$lib/GraphErrors.svelte';
|
|
38 | 39 | {@const team = $TeamVulnerabilities.data.team}
|
39 | 40 | <div class="grid">
|
40 | 41 | <Card columns={12}>
|
41 |
| - <div class="summaryCard" style="align-items: start; min-height: 90px"> |
| 42 | + <div class="vulnerabilitySummary"> |
42 | 43 | {#if team.vulnerabilitySummary.bomCount !== PendingValue}
|
43 | 44 | {#if team.vulnerabilitySummary.status.filter((status) => status.state !== TeamVulnerabilityState.OK).length > 0}
|
44 |
| - <div> |
45 |
| - <XMarkOctagonIcon font-size="66px" style="color: var(--a-icon-danger)" /> |
46 |
| - </div> |
| 45 | + <XMarkOctagonIcon font-size="66px" style="color: var(--a-icon-danger)" /> |
47 | 46 | {:else}
|
48 |
| - <div> |
49 |
| - <Nais |
50 |
| - size="66px" |
51 |
| - style="color: var(--a-icon-success)" |
52 |
| - aria-label="Team is nais" |
53 |
| - role="image" |
54 |
| - /> |
55 |
| - </div> |
| 47 | + <Nais |
| 48 | + size="66px" |
| 49 | + style="color: var(--a-icon-success)" |
| 50 | + aria-label="Team is nais" |
| 51 | + role="image" |
| 52 | + /> |
56 | 53 | {/if}
|
57 | 54 | {:else}
|
58 |
| - <div> |
59 |
| - <Skeleton variant="rounded" width="66px" height="66px" /> |
60 |
| - </div> |
| 55 | + <Skeleton variant="rounded" width="66px" height="66px" /> |
61 | 56 | {/if}
|
62 | 57 | <div class="summary">
|
63 | 58 | <h4>
|
|
98 | 93 | </div>
|
99 | 94 | </Card>
|
100 | 95 | <Card columns={3} style="display: flex; align-items:center;">
|
101 |
| - <div class="summaryCard"> |
102 |
| - <div> |
| 96 | + <SummaryCard title="SBOM coverage" color="grey" styled={false}> |
| 97 | + {#snippet icon()} |
103 | 98 | {#if team?.vulnerabilitySummary.coverage !== PendingValue}
|
104 | 99 | {#if team.vulnerabilitySummary.coverage >= 100}
|
105 | 100 | <Nais
|
106 |
| - size="66px" |
107 | 101 | style="color: var(--a-icon-success)"
|
108 | 102 | aria-label="Workload is nais"
|
109 | 103 | role="image"
|
110 | 104 | />
|
111 | 105 | {:else}
|
112 | 106 | <CircleProgressBar
|
113 |
| - size="66px" |
114 | 107 | progress={team.vulnerabilitySummary.coverage / 100}
|
115 | 108 | startColor="var(--a-icon-danger)"
|
116 | 109 | endColor="green"
|
117 | 110 | />
|
118 | 111 | {/if}
|
119 | 112 | {:else}
|
120 |
| - <div> |
121 |
| - <Skeleton variant="circle" width="66px" height="66px" /> |
122 |
| - </div> |
| 113 | + <Skeleton variant="circle" width="66px" height="66px" /> |
123 | 114 | {/if}
|
124 |
| - </div> |
125 |
| - <div class="summary"> |
126 |
| - <h4> |
127 |
| - SBOM coverage |
128 |
| - <HelpText title="Current SBOM coverage">Workloads with an SBOM.</HelpText> |
129 |
| - </h4> |
130 |
| - <p class="metric"> |
131 |
| - {#if team?.vulnerabilitySummary.bomCount !== PendingValue} |
132 |
| - {team.vulnerabilitySummary.bomCount} of {team.workloads?.pageInfo.totalCount} |
133 |
| - workloads |
| 115 | + {/snippet} |
| 116 | + {#if team !== undefined} |
| 117 | + {#if team.vulnerabilitySummary.bomCount !== PendingValue} |
| 118 | + {#if team.vulnerabilitySummary.bomCount > 0} |
| 119 | + {team.vulnerabilitySummary.bomCount} of {team.workloads?.pageInfo.totalCount} workloads |
| 120 | + have SBOM |
134 | 121 | {:else}
|
135 |
| - <Skeleton variant="text" width="44px" /> |
| 122 | + No workloads with SBOM found |
136 | 123 | {/if}
|
137 |
| - </p> |
138 |
| - </div> |
139 |
| - </div> |
| 124 | + {:else} |
| 125 | + <Skeleton variant="text" width="44px" /> |
| 126 | + {/if} |
| 127 | + {/if} |
| 128 | + </SummaryCard> |
140 | 129 | </Card>
|
141 | 130 | <Card columns={3} style="display: flex; align-items:center;">
|
142 |
| - <div class="summaryCard"> |
143 |
| - {#if team !== undefined} |
144 |
| - <div style="--bg-color: #C8C8C8; display:flex; align-items:center;"> |
145 |
| - {#if team.vulnerabilitySummary.critical == 0} |
146 |
| - <code class="check">✓</code> |
147 |
| - {:else} |
| 131 | + <SummaryCard title="Critical vulnerabilities" color={'grey'} styled={false}> |
| 132 | + {#snippet icon()} |
| 133 | + {#if team?.vulnerabilitySummary.critical !== PendingValue} |
| 134 | + {#if team.vulnerabilitySummary.critical > 0} |
148 | 135 | <Vulnerability
|
149 | 136 | count={team.vulnerabilitySummary.critical}
|
150 | 137 | severity="critical"
|
151 | 138 | size={'66px'}
|
152 | 139 | />
|
| 140 | + {:else} |
| 141 | + <code class="check">✓</code> |
153 | 142 | {/if}
|
154 |
| - </div> |
155 |
| - <div class="summary"> |
156 |
| - <h4>Critical vulnerabilities</h4> |
157 |
| - </div> |
| 143 | + {:else} |
| 144 | + <Skeleton variant="rounded" width="66px" height="66px" /> |
| 145 | + {/if} |
| 146 | + {/snippet} |
| 147 | + {#if team !== undefined} |
| 148 | + {#if team.vulnerabilitySummary.critical !== PendingValue} |
| 149 | + {team.vulnerabilitySummary.critical} critical vulnerabilities |
| 150 | + {:else} |
| 151 | + <Skeleton variant="text" width="44px" /> |
| 152 | + {/if} |
158 | 153 | {/if}
|
159 |
| - </div> |
| 154 | + </SummaryCard> |
160 | 155 | </Card>
|
161 | 156 | <Card columns={3}>
|
162 |
| - <div class="summaryCard"> |
163 |
| - <div class="summaryIcon" style="--bg-color: #C8C8C8"> |
| 157 | + <SummaryCard title="Total risk score" color={'grey'} styled={false}> |
| 158 | + {#snippet icon()} |
164 | 159 | {#if team?.vulnerabilitySummary.riskScoreTrend !== PendingValue}
|
165 | 160 | {#if team.vulnerabilitySummary.riskScoreTrend === TeamVulnerabilityRiskScoreTrend.UP}
|
166 | 161 | <TrendUpIcon title="RiskScore" font-size="80" style="color: var(--a-icon-danger)" />
|
|
180 | 175 | {:else}
|
181 | 176 | <Skeleton variant="rounded" width="66px" height="66px" />
|
182 | 177 | {/if}
|
183 |
| - </div> |
184 |
| - <div class="summary"> |
185 |
| - <h4> |
186 |
| - Total risk score |
187 |
| - <HelpText title="Current team total risk score" |
188 |
| - >The total risk score for the team's vulnerabilities. The icon will also show trend up |
189 |
| - or down since last month. |
190 |
| - </HelpText> |
191 |
| - </h4> |
192 |
| - <p class="metric"> |
193 |
| - {#if team?.vulnerabilitySummary.riskScore !== PendingValue} |
194 |
| - {team.vulnerabilitySummary.riskScore} |
195 |
| - {:else} |
196 |
| - <Skeleton variant="text" width="44px" /> |
197 |
| - {/if} |
198 |
| - </p> |
199 |
| - </div> |
200 |
| - </div> |
| 178 | + {/snippet} |
| 179 | + {#if team !== undefined} |
| 180 | + {#if team.vulnerabilitySummary.riskScore !== PendingValue} |
| 181 | + {team.vulnerabilitySummary.riskScore} |
| 182 | + {:else} |
| 183 | + <Skeleton variant="text" width="44px" /> |
| 184 | + {/if} |
| 185 | + {/if} |
| 186 | + </SummaryCard> |
201 | 187 | </Card>
|
202 | 188 | <!--Card columns={3}>
|
203 | 189 | <div class="summaryCard">
|
|
338 | 324 | font-weight: bold;
|
339 | 325 | font-size: 1rem;
|
340 | 326 | }
|
341 |
| - .summaryIcon { |
342 |
| - display: flex; |
343 |
| - justify-content: center; |
344 |
| - align-items: center; |
345 |
| - } |
| 327 | +
|
346 | 328 | .summary {
|
347 | 329 | width: 100%;
|
348 | 330 | min-height: 80px;
|
|
355 | 337 | color: var(--color-text-secondary);
|
356 | 338 | font-weight: bold;
|
357 | 339 | }
|
358 |
| - .summary > p { |
359 |
| - display: flex; |
360 |
| - justify-content: space-between; |
361 |
| - margin: 0; |
362 |
| - font-size: 1rem; |
363 |
| - color: var(--color-text-secondary); |
364 |
| - } |
365 |
| - .metric { |
366 |
| - font-size: 1.3rem; |
367 |
| - margin: 0; |
368 |
| - } |
369 |
| - .summaryCard { |
| 340 | +
|
| 341 | + .vulnerabilitySummary { |
370 | 342 | display: flex;
|
371 | 343 | align-items: center;
|
372 | 344 | gap: 20px;
|
| 345 | + align-items: start; |
| 346 | + min-height: 90px; |
373 | 347 | }
|
374 | 348 | .env-filter {
|
375 | 349 | display: flex;
|
|
0 commit comments