@replicated/portal-components 0.0.18 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/components/metadata/registry.json +2 -2
  2. package/components/metadata/registry.md +2 -2
  3. package/dist/actions/change-team.d.mts +10 -0
  4. package/dist/actions/change-team.d.ts +10 -0
  5. package/dist/actions/change-team.js +458 -0
  6. package/dist/actions/change-team.js.map +1 -0
  7. package/dist/actions/index.d.mts +4 -1
  8. package/dist/actions/index.d.ts +4 -1
  9. package/dist/actions/index.js +1232 -430
  10. package/dist/actions/index.js.map +1 -1
  11. package/dist/actions/install-actions.d.mts +4 -0
  12. package/dist/actions/install-actions.d.ts +4 -0
  13. package/dist/actions/install-actions.js +680 -0
  14. package/dist/actions/install-actions.js.map +1 -0
  15. package/dist/actions/service-account.d.mts +4 -0
  16. package/dist/actions/service-account.d.ts +4 -0
  17. package/dist/actions/service-account.js +373 -0
  18. package/dist/actions/service-account.js.map +1 -0
  19. package/dist/actions/support-bundles.d.mts +4 -0
  20. package/dist/actions/support-bundles.d.ts +4 -0
  21. package/dist/actions/support-bundles.js +659 -0
  22. package/dist/actions/support-bundles.js.map +1 -0
  23. package/dist/actions/team-settings.d.mts +4 -0
  24. package/dist/actions/team-settings.d.ts +4 -0
  25. package/dist/actions/team-settings.js +1040 -0
  26. package/dist/actions/team-settings.js.map +1 -0
  27. package/dist/actions/trial-signup.d.mts +24 -0
  28. package/dist/actions/trial-signup.d.ts +24 -0
  29. package/dist/actions/trial-signup.js +482 -0
  30. package/dist/actions/trial-signup.js.map +1 -0
  31. package/dist/actions/user-settings.d.mts +4 -0
  32. package/dist/actions/user-settings.d.ts +4 -0
  33. package/dist/actions/user-settings.js +621 -0
  34. package/dist/actions/user-settings.js.map +1 -0
  35. package/dist/airgap-instances.d.mts +4 -1
  36. package/dist/airgap-instances.d.ts +4 -1
  37. package/dist/airgap-instances.js +177 -32
  38. package/dist/airgap-instances.js.map +1 -1
  39. package/dist/branding-BsMSywts.d.mts +36 -0
  40. package/dist/branding-BsMSywts.d.ts +36 -0
  41. package/dist/error-page.js +10 -2
  42. package/dist/error-page.js.map +1 -1
  43. package/dist/error.js +10 -2
  44. package/dist/error.js.map +1 -1
  45. package/dist/esm/actions/change-team.js +455 -0
  46. package/dist/esm/actions/change-team.js.map +1 -0
  47. package/dist/esm/actions/index.js +1200 -428
  48. package/dist/esm/actions/index.js.map +1 -1
  49. package/dist/esm/actions/install-actions.js +673 -0
  50. package/dist/esm/actions/install-actions.js.map +1 -0
  51. package/dist/esm/actions/service-account.js +371 -0
  52. package/dist/esm/actions/service-account.js.map +1 -0
  53. package/dist/esm/actions/support-bundles.js +654 -0
  54. package/dist/esm/actions/support-bundles.js.map +1 -0
  55. package/dist/esm/actions/team-settings.js +1026 -0
  56. package/dist/esm/actions/team-settings.js.map +1 -0
  57. package/dist/esm/actions/trial-signup.js +478 -0
  58. package/dist/esm/actions/trial-signup.js.map +1 -0
  59. package/dist/esm/actions/user-settings.js +615 -0
  60. package/dist/esm/actions/user-settings.js.map +1 -0
  61. package/dist/esm/airgap-instances.js +176 -32
  62. package/dist/esm/airgap-instances.js.map +1 -1
  63. package/dist/esm/error-page.js +10 -2
  64. package/dist/esm/error-page.js.map +1 -1
  65. package/dist/esm/error.js +10 -2
  66. package/dist/esm/error.js.map +1 -1
  67. package/dist/esm/helm-install-wizard.js +127 -81
  68. package/dist/esm/helm-install-wizard.js.map +1 -1
  69. package/dist/esm/index.js +706 -438
  70. package/dist/esm/index.js.map +1 -1
  71. package/dist/esm/install-actions.js +40 -5
  72. package/dist/esm/install-actions.js.map +1 -1
  73. package/dist/esm/install-card.js +9 -6
  74. package/dist/esm/install-card.js.map +1 -1
  75. package/dist/esm/install-targets.js +9 -2
  76. package/dist/esm/install-targets.js.map +1 -1
  77. package/dist/esm/instance-card.js +175 -31
  78. package/dist/esm/instance-card.js.map +1 -1
  79. package/dist/esm/join-team.js +9 -3
  80. package/dist/esm/join-team.js.map +1 -1
  81. package/dist/esm/license-card.js +24 -22
  82. package/dist/esm/license-card.js.map +1 -1
  83. package/dist/esm/license-details.js +128 -334
  84. package/dist/esm/license-details.js.map +1 -1
  85. package/dist/esm/linux-install-wizard.js +219 -133
  86. package/dist/esm/linux-install-wizard.js.map +1 -1
  87. package/dist/esm/login.js +20 -4
  88. package/dist/esm/login.js.map +1 -1
  89. package/dist/esm/middleware.js +33 -0
  90. package/dist/esm/middleware.js.map +1 -0
  91. package/dist/esm/online-instance-list.js +176 -32
  92. package/dist/esm/online-instance-list.js.map +1 -1
  93. package/dist/esm/pending-installations.js +4 -3
  94. package/dist/esm/pending-installations.js.map +1 -1
  95. package/dist/esm/release-history-panel.js +27 -14
  96. package/dist/esm/release-history-panel.js.map +1 -1
  97. package/dist/esm/saml-callback-client.js +82 -0
  98. package/dist/esm/saml-callback-client.js.map +1 -0
  99. package/dist/esm/saml-handlers.js +138 -0
  100. package/dist/esm/saml-handlers.js.map +1 -0
  101. package/dist/esm/security-card.js +53 -38
  102. package/dist/esm/security-card.js.map +1 -1
  103. package/dist/esm/service-accounts-tab.js +800 -0
  104. package/dist/esm/service-accounts-tab.js.map +1 -0
  105. package/dist/esm/support-bundle-collection-card.js +55 -25
  106. package/dist/esm/support-bundle-collection-card.js.map +1 -1
  107. package/dist/esm/support-bundles-card.js +10 -5
  108. package/dist/esm/support-bundles-card.js.map +1 -1
  109. package/dist/esm/support-card.js +37 -5
  110. package/dist/esm/support-card.js.map +1 -1
  111. package/dist/esm/team-selection.js +5 -1
  112. package/dist/esm/team-selection.js.map +1 -1
  113. package/dist/esm/team-settings-card.js +5 -2
  114. package/dist/esm/team-settings-card.js.map +1 -1
  115. package/dist/esm/team-settings.js +7 -2
  116. package/dist/esm/team-settings.js.map +1 -1
  117. package/dist/esm/top-nav-user-menu.js +5 -1
  118. package/dist/esm/top-nav-user-menu.js.map +1 -1
  119. package/dist/esm/top-nav.js +175 -62
  120. package/dist/esm/top-nav.js.map +1 -1
  121. package/dist/esm/trial-signup.js +256 -0
  122. package/dist/esm/trial-signup.js.map +1 -0
  123. package/dist/esm/update-layout.js +175 -62
  124. package/dist/esm/update-layout.js.map +1 -1
  125. package/dist/esm/updates-card.js +15 -4
  126. package/dist/esm/updates-card.js.map +1 -1
  127. package/dist/esm/upload-support-bundle-modal.js +9 -4
  128. package/dist/esm/upload-support-bundle-modal.js.map +1 -1
  129. package/dist/esm/user-settings-card.js +5 -2
  130. package/dist/esm/user-settings-card.js.map +1 -1
  131. package/dist/esm/user-settings.js +12 -6
  132. package/dist/esm/user-settings.js.map +1 -1
  133. package/dist/esm/utils/index.js +204 -13
  134. package/dist/esm/utils/index.js.map +1 -1
  135. package/dist/fetch-license-iTyF7_GY.d.mts +81 -0
  136. package/dist/fetch-license-iTyF7_GY.d.ts +81 -0
  137. package/dist/helm-install-wizard.d.mts +12 -3
  138. package/dist/helm-install-wizard.d.ts +12 -3
  139. package/dist/helm-install-wizard.js +127 -81
  140. package/dist/helm-install-wizard.js.map +1 -1
  141. package/dist/{index-DkjaogsF.d.ts → index-DyzJ0yKD.d.mts} +194 -49
  142. package/dist/{index-DkjaogsF.d.mts → index-sMbq94M7.d.ts} +194 -49
  143. package/dist/index.d.mts +9 -2
  144. package/dist/index.d.ts +9 -2
  145. package/dist/index.js +726 -438
  146. package/dist/index.js.map +1 -1
  147. package/dist/install-actions.d.mts +5 -2
  148. package/dist/install-actions.d.ts +5 -2
  149. package/dist/install-actions.js +40 -5
  150. package/dist/install-actions.js.map +1 -1
  151. package/dist/install-card.d.mts +2 -2
  152. package/dist/install-card.d.ts +2 -2
  153. package/dist/install-card.js +9 -6
  154. package/dist/install-card.js.map +1 -1
  155. package/dist/install-targets.js +9 -2
  156. package/dist/install-targets.js.map +1 -1
  157. package/dist/instance-card.d.mts +4 -1
  158. package/dist/instance-card.d.ts +4 -1
  159. package/dist/instance-card.js +176 -31
  160. package/dist/instance-card.js.map +1 -1
  161. package/dist/join-team.js +9 -3
  162. package/dist/join-team.js.map +1 -1
  163. package/dist/license-card.d.mts +2 -2
  164. package/dist/license-card.d.ts +2 -2
  165. package/dist/license-card.js +24 -22
  166. package/dist/license-card.js.map +1 -1
  167. package/dist/license-details.js +128 -334
  168. package/dist/license-details.js.map +1 -1
  169. package/dist/linux-install-wizard.d.mts +12 -6
  170. package/dist/linux-install-wizard.d.ts +12 -6
  171. package/dist/linux-install-wizard.js +219 -133
  172. package/dist/linux-install-wizard.js.map +1 -1
  173. package/dist/login.d.mts +4 -0
  174. package/dist/login.d.ts +4 -0
  175. package/dist/login.js +20 -4
  176. package/dist/login.js.map +1 -1
  177. package/dist/middleware.d.mts +13 -0
  178. package/dist/middleware.d.ts +13 -0
  179. package/dist/middleware.js +35 -0
  180. package/dist/middleware.js.map +1 -0
  181. package/dist/online-instance-list.d.mts +4 -1
  182. package/dist/online-instance-list.d.ts +4 -1
  183. package/dist/online-instance-list.js +177 -32
  184. package/dist/online-instance-list.js.map +1 -1
  185. package/dist/pending-installations.d.mts +8 -3
  186. package/dist/pending-installations.d.ts +8 -3
  187. package/dist/pending-installations.js +4 -3
  188. package/dist/pending-installations.js.map +1 -1
  189. package/dist/release-history-panel.js +27 -14
  190. package/dist/release-history-panel.js.map +1 -1
  191. package/dist/saml-callback-client.d.mts +36 -0
  192. package/dist/saml-callback-client.d.ts +36 -0
  193. package/dist/saml-callback-client.js +88 -0
  194. package/dist/saml-callback-client.js.map +1 -0
  195. package/dist/saml-handlers.d.mts +50 -0
  196. package/dist/saml-handlers.d.ts +50 -0
  197. package/dist/saml-handlers.js +141 -0
  198. package/dist/saml-handlers.js.map +1 -0
  199. package/dist/security-card.d.mts +4 -1
  200. package/dist/security-card.d.ts +4 -1
  201. package/dist/security-card.js +53 -38
  202. package/dist/security-card.js.map +1 -1
  203. package/dist/service-accounts-tab.d.mts +51 -0
  204. package/dist/service-accounts-tab.d.ts +51 -0
  205. package/dist/service-accounts-tab.js +802 -0
  206. package/dist/service-accounts-tab.js.map +1 -0
  207. package/dist/styles.css +380 -143
  208. package/dist/support-bundle-collection-card.d.mts +1 -1
  209. package/dist/support-bundle-collection-card.d.ts +1 -1
  210. package/dist/support-bundle-collection-card.js +54 -24
  211. package/dist/support-bundle-collection-card.js.map +1 -1
  212. package/dist/support-bundles-card.d.mts +5 -2
  213. package/dist/support-bundles-card.d.ts +5 -2
  214. package/dist/support-bundles-card.js +10 -5
  215. package/dist/support-bundles-card.js.map +1 -1
  216. package/dist/support-card.js +37 -5
  217. package/dist/support-card.js.map +1 -1
  218. package/dist/team-selection.js +5 -1
  219. package/dist/team-selection.js.map +1 -1
  220. package/dist/team-settings-card.js +5 -2
  221. package/dist/team-settings-card.js.map +1 -1
  222. package/dist/team-settings.js +7 -2
  223. package/dist/team-settings.js.map +1 -1
  224. package/dist/{top-nav-IRIn66wS.d.ts → top-nav-BUQAGoG1.d.mts} +14 -2
  225. package/dist/{top-nav-IRIn66wS.d.mts → top-nav-CEqw0KpO.d.ts} +14 -2
  226. package/dist/top-nav-user-menu.js +5 -1
  227. package/dist/top-nav-user-menu.js.map +1 -1
  228. package/dist/top-nav.d.mts +2 -1
  229. package/dist/top-nav.d.ts +2 -1
  230. package/dist/top-nav.js +175 -62
  231. package/dist/top-nav.js.map +1 -1
  232. package/dist/trial-signup.d.mts +31 -0
  233. package/dist/trial-signup.d.ts +31 -0
  234. package/dist/trial-signup.js +258 -0
  235. package/dist/trial-signup.js.map +1 -0
  236. package/dist/update-layout.js +175 -62
  237. package/dist/update-layout.js.map +1 -1
  238. package/dist/updates-card.js +15 -4
  239. package/dist/updates-card.js.map +1 -1
  240. package/dist/upload-support-bundle-modal.js +9 -4
  241. package/dist/upload-support-bundle-modal.js.map +1 -1
  242. package/dist/user-settings-card.js +5 -2
  243. package/dist/user-settings-card.js.map +1 -1
  244. package/dist/user-settings.js +12 -6
  245. package/dist/user-settings.js.map +1 -1
  246. package/dist/utils/index.d.mts +74 -16
  247. package/dist/utils/index.d.ts +74 -16
  248. package/dist/utils/index.js +215 -12
  249. package/dist/utils/index.js.map +1 -1
  250. package/package.json +67 -1
@@ -7,6 +7,22 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
7
  * This file is generated by tsup. Do not edit manually.
8
8
  */
9
9
 
10
+
11
+ // src/utils/constants.ts
12
+ var DEFAULT_PRIMARY_COLOR = "#4f46e5";
13
+ async function copyToClipboard(text) {
14
+ if (!navigator.clipboard) {
15
+ console.warn("[copyToClipboard] Clipboard API not available");
16
+ return false;
17
+ }
18
+ try {
19
+ await navigator.clipboard.writeText(text);
20
+ return true;
21
+ } catch (error) {
22
+ console.error("[copyToClipboard] Failed to copy:", error);
23
+ return false;
24
+ }
25
+ }
10
26
  var DownloadIcon = ({ className }) => /* @__PURE__ */ jsxs(
11
27
  "svg",
12
28
  {
@@ -233,19 +249,10 @@ var FixedCount = ({ count, hasDiffData }) => {
233
249
  }
234
250
  return /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-green-600", children: count });
235
251
  };
236
- var ImageName = ({ imageString, compact }) => {
252
+ var ImageName = ({ imageString }) => {
237
253
  const parts = imageString.split("/");
238
254
  const namePart = parts[parts.length - 1] || imageString;
239
255
  const [name, tag] = namePart.split(":");
240
- if (compact && imageString.length > 50) {
241
- return /* @__PURE__ */ jsxs("div", { className: "truncate text-sm text-gray-700", title: imageString, children: [
242
- name,
243
- tag && /* @__PURE__ */ jsxs("span", { className: "text-gray-400", children: [
244
- ":",
245
- tag
246
- ] })
247
- ] });
248
- }
249
256
  return /* @__PURE__ */ jsxs("div", { className: "text-sm text-gray-700", title: imageString, children: [
250
257
  /* @__PURE__ */ jsxs("span", { className: "text-gray-400", children: [
251
258
  parts.slice(0, -1).join("/"),
@@ -300,7 +307,7 @@ function SecurityCard({
300
307
  channelReleases,
301
308
  showLinux,
302
309
  showHelm,
303
- primaryColor = "#326CE5",
310
+ primaryColor = DEFAULT_PRIMARY_COLOR,
304
311
  initialInstallType,
305
312
  initialChannelSequence,
306
313
  initialData,
@@ -333,6 +340,7 @@ function SecurityCard({
333
340
  const [isLoadingScans, setIsLoadingScans] = useState(false);
334
341
  const [isLoadingSbom, setIsLoadingSbom] = useState(false);
335
342
  const hasUsedInitialDataRef = useRef(!!initialData);
343
+ const [copiedDigest, setCopiedDigest] = useState(null);
336
344
  const [securityError, setSecurityError] = useState(null);
337
345
  const [sbomError, setSbomError] = useState(null);
338
346
  const [showAllContainersModal, setShowAllContainersModal] = useState(false);
@@ -591,36 +599,36 @@ function SecurityCard({
591
599
  ] })
592
600
  )
593
601
  ] }),
594
- (hasSecurityData || isLoadingScans || isLoadingSbom || securityError || sbomError) && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-2", children: [
602
+ (hasSecurityData || isLoadingScans || isLoadingSbom || securityError || sbomError) && /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
595
603
  /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-gray-200 bg-white", children: [
596
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between border-b border-gray-200 bg-gray-50 px-6 py-5", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-medium text-gray-900", children: "CVE Report" }) }),
597
- isLoadingScans ? /* @__PURE__ */ jsx("div", { className: "flex min-h-[200px] items-center justify-center p-6", children: /* @__PURE__ */ jsx(SpinnerIcon, { className: "h-8 w-8 text-gray-400" }) }) : securityError ? /* @__PURE__ */ jsx("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsxs("p", { className: "py-8 text-pink-500", children: [
604
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between rounded-t-lg border-b border-gray-200 bg-gray-50 px-6 py-5", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-medium text-gray-900", children: "CVE Report" }) }),
605
+ isLoadingScans ? /* @__PURE__ */ jsx("div", { className: "flex min-h-[200px] items-center justify-center p-8", children: /* @__PURE__ */ jsx(SpinnerIcon, { className: "h-8 w-8 text-gray-400" }) }) : securityError ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxs("p", { className: "py-8 text-pink-500", children: [
598
606
  "Error loading security data: ",
599
607
  securityError
600
- ] }) }) : !hasSecurityData ? /* @__PURE__ */ jsx("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx("p", { className: "py-8 text-gray-500", children: "No security report available for this release" }) }) : /* @__PURE__ */ jsxs("div", { className: "p-6", children: [
608
+ ] }) }) : !hasSecurityData ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx("p", { className: "py-8 text-gray-500", children: "No security report available for this release" }) }) : /* @__PURE__ */ jsxs("div", { className: "p-8", children: [
601
609
  /* @__PURE__ */ jsx("p", { className: "mb-6 text-gray-600", children: "Comprehensive vulnerability scanning using Trivy to identify and assess security risks in dependencies and container images." }),
602
- /* @__PURE__ */ jsx("div", { className: "mb-6 overflow-auto rounded-md bg-gray-50 p-2", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-sm", children: [
610
+ /* @__PURE__ */ jsx("div", { className: "mb-6 overflow-x-auto rounded-md bg-gray-50 p-4", children: /* @__PURE__ */ jsxs("table", { className: "w-full min-w-[400px] border-collapse text-sm", children: [
603
611
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
604
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase text-gray-500", children: "Severity" }),
605
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase text-gray-500", children: "Found" }),
606
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase text-gray-500", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
612
+ /* @__PURE__ */ jsx("th", { className: "px-6 py-3 text-left text-xs font-semibold uppercase text-gray-500", children: "Severity" }),
613
+ /* @__PURE__ */ jsx("th", { className: "px-6 py-3 text-left text-xs font-semibold uppercase text-gray-500", children: "Found" }),
614
+ /* @__PURE__ */ jsx("th", { className: "px-6 py-3 text-left text-xs font-semibold uppercase text-gray-500", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
607
615
  "Fixed",
608
616
  /* @__PURE__ */ jsx(Tooltip, { content: "CVEs fixed compared to the previous release version", children: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4 cursor-pointer text-blue-400" }) })
609
617
  ] }) })
610
618
  ] }) }),
611
619
  /* @__PURE__ */ jsx("tbody", { children: ["critical", "high", "medium", "low"].map((severity) => /* @__PURE__ */ jsxs("tr", { children: [
612
- /* @__PURE__ */ jsx("td", { className: "px-4 py-3 capitalize text-gray-700", children: severity }),
613
- /* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx("span", { className: `font-medium ${getSeverityColor(severity)}`, children: cveTotals[severity] }) }),
614
- /* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx(FixedCount, { count: fixedTotals[severity], hasDiffData: !!diffData }) })
620
+ /* @__PURE__ */ jsx("td", { className: "px-6 py-3 capitalize text-gray-700", children: severity }),
621
+ /* @__PURE__ */ jsx("td", { className: "px-6 py-3", children: /* @__PURE__ */ jsx("span", { className: `font-medium ${getSeverityColor(severity)}`, children: cveTotals[severity] }) }),
622
+ /* @__PURE__ */ jsx("td", { className: "px-6 py-3", children: /* @__PURE__ */ jsx(FixedCount, { count: fixedTotals[severity], hasDiffData: !!diffData }) })
615
623
  ] }, severity)) })
616
624
  ] }) }),
617
625
  /* @__PURE__ */ jsxs("div", { children: [
618
626
  /* @__PURE__ */ jsx("div", { className: "mb-3", children: /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-900", children: "Container Vulnerabilities" }) }),
619
- /* @__PURE__ */ jsx("div", { className: "overflow-auto rounded-lg border border-gray-200", children: /* @__PURE__ */ jsxs("table", { className: "w-full", children: [
627
+ /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-gray-200", children: /* @__PURE__ */ jsxs("table", { className: "w-full", children: [
620
628
  /* @__PURE__ */ jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxs("tr", { children: [
621
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Name" }),
622
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Found" }),
623
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
629
+ /* @__PURE__ */ jsx("th", { className: "px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Name" }),
630
+ /* @__PURE__ */ jsx("th", { className: "px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Found" }),
631
+ /* @__PURE__ */ jsx("th", { className: "px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
624
632
  "Fixed",
625
633
  /* @__PURE__ */ jsx(Tooltip, { content: "CVEs fixed compared to the previous release version", children: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4 cursor-pointer text-blue-400" }) })
626
634
  ] }) })
@@ -631,9 +639,9 @@ function SecurityCard({
631
639
  const fixedVulns = imageDiff?.removed;
632
640
  const totalFixed = fixedVulns ? Object.keys(fixedVulns.critical || {}).length + Object.keys(fixedVulns.high || {}).length + Object.keys(fixedVulns.medium || {}).length + Object.keys(fixedVulns.low || {}).length : void 0;
633
641
  return /* @__PURE__ */ jsxs("tr", { children: [
634
- /* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx("div", { className: "max-w-[300px]", children: /* @__PURE__ */ jsx(ImageName, { imageString: image.image, compact: true }) }) }),
635
- /* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx(VulnerabilityBadges, { summary: image.security?.result }) }),
636
- /* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx(FixedCount, { count: totalFixed, hasDiffData: !!imageDiff }) })
642
+ /* @__PURE__ */ jsx("td", { className: "px-6 py-3", children: /* @__PURE__ */ jsx(ImageName, { imageString: image.image }) }),
643
+ /* @__PURE__ */ jsx("td", { className: "px-6 py-3", children: /* @__PURE__ */ jsx(VulnerabilityBadges, { summary: image.security?.result }) }),
644
+ /* @__PURE__ */ jsx("td", { className: "px-6 py-3", children: /* @__PURE__ */ jsx(FixedCount, { count: totalFixed, hasDiffData: !!imageDiff }) })
637
645
  ] }, idx);
638
646
  }) })
639
647
  ] }) }),
@@ -650,7 +658,7 @@ function SecurityCard({
650
658
  ] })
651
659
  ] }),
652
660
  /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-gray-200 bg-white", children: [
653
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 bg-gray-50 px-6 py-5", children: [
661
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-t-lg border-b border-gray-200 bg-gray-50 px-6 py-5", children: [
654
662
  /* @__PURE__ */ jsx("h2", { className: "text-lg font-medium text-gray-900", children: "Software Bill of Materials" }),
655
663
  sbomMetadata && onDownloadSBOM && /* @__PURE__ */ jsxs(
656
664
  "button",
@@ -666,12 +674,12 @@ function SecurityCard({
666
674
  }
667
675
  )
668
676
  ] }),
669
- isLoadingSbom ? /* @__PURE__ */ jsx("div", { className: "flex min-h-[200px] items-center justify-center p-6", children: /* @__PURE__ */ jsx(SpinnerIcon, { className: "h-8 w-8 text-gray-400" }) }) : sbomError ? /* @__PURE__ */ jsx("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsxs("p", { className: "py-8 text-pink-500", children: [
677
+ isLoadingSbom ? /* @__PURE__ */ jsx("div", { className: "flex min-h-[200px] items-center justify-center p-8", children: /* @__PURE__ */ jsx(SpinnerIcon, { className: "h-8 w-8 text-gray-400" }) }) : sbomError ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxs("p", { className: "py-8 text-pink-500", children: [
670
678
  "Error loading SBOM data: ",
671
679
  sbomError
672
- ] }) }) : !sbomMetadata ? /* @__PURE__ */ jsx("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx("p", { className: "py-8 text-gray-500", children: "No SBOM available for this release" }) }) : /* @__PURE__ */ jsxs("div", { className: "p-6", children: [
680
+ ] }) }) : !sbomMetadata ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx("p", { className: "py-8 text-gray-500", children: "No SBOM available for this release" }) }) : /* @__PURE__ */ jsxs("div", { className: "p-8", children: [
673
681
  /* @__PURE__ */ jsx("p", { className: "mb-6 text-gray-600", children: "Comprehensive SBOM in SPDX format providing detailed software component inventory and licensing information." }),
674
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4 rounded-md bg-gray-50 p-4 text-sm text-gray-600", children: [
682
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-8 gap-y-4 rounded-md bg-gray-50 p-6 text-sm text-gray-600", children: [
675
683
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
676
684
  /* @__PURE__ */ jsx("span", { children: "Name:" }),
677
685
  /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: sbomMetadata.name || "Unknown" })
@@ -723,18 +731,25 @@ function SecurityCard({
723
731
  /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: "Digest:" }),
724
732
  hasDigest ? /* @__PURE__ */ jsxs(Fragment, { children: [
725
733
  /* @__PURE__ */ jsx("code", { className: "text-gray-700", children: digest }),
726
- /* @__PURE__ */ jsxs(
734
+ /* @__PURE__ */ jsx(
727
735
  "button",
728
736
  {
729
737
  type: "button",
730
- onClick: () => {
731
- navigator.clipboard.writeText(digest);
738
+ onClick: async () => {
739
+ const success = await copyToClipboard(digest);
740
+ if (success) {
741
+ setCopiedDigest(digest);
742
+ setTimeout(() => setCopiedDigest(null), 2e3);
743
+ }
732
744
  },
733
745
  className: "inline-flex items-center gap-1 text-blue-600 hover:text-blue-800",
734
- children: [
746
+ children: copiedDigest === digest ? /* @__PURE__ */ jsxs(Fragment, { children: [
747
+ /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
748
+ /* @__PURE__ */ jsx("span", { children: "Copied" })
749
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
735
750
  /* @__PURE__ */ jsx(CopyIcon, { className: "h-3.5 w-3.5" }),
736
751
  /* @__PURE__ */ jsx("span", { children: "Copy" })
737
- ]
752
+ ] })
738
753
  }
739
754
  )
740
755
  ] }) : /* @__PURE__ */ jsx("span", { className: "text-gray-400", children: "---" })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/security-card.tsx"],"names":[],"mappings":"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","file":"security-card.js","sourcesContent":["\"use client\";\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from \"react\";\nimport type {\n SecurityInstallType,\n SecurityReleaseImage,\n SecurityScanSummary,\n SecurityInfoDiff,\n SBOMMetadata\n} from \"../actions\";\nimport type { ChannelRelease } from \"../actions/install\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** Pre-fetched security data for SSR */\nexport interface InitialSecurityData {\n /** Security scan results */\n securityInfo?: { images: SecurityReleaseImage[]; activeInstancesByVersion?: Record<string, number> };\n /** CVE diff between releases */\n securityDiff?: { images: Record<string, SecurityInfoDiff> };\n /** SBOM metadata (lightweight, included in SSR. Full SBOM available via download) */\n sbom?: { sboms: { unified?: SBOMMetadata } };\n /** Install type the initial data was fetched for */\n installType: SecurityInstallType;\n /** Channel sequence the initial data was fetched for */\n channelSequence: number;\n /** Previous channel sequence for diff (if any) */\n previousChannelSequence?: number;\n}\n\nexport interface SecurityCardProps {\n /** Available channel releases */\n channelReleases: ChannelRelease[];\n /** Whether Linux install type is enabled */\n showLinux: boolean;\n /** Whether Helm install type is enabled */\n showHelm: boolean;\n /** Primary brand color. Defaults to \"#326CE5\" */\n primaryColor?: string;\n /** Initial install type selection */\n initialInstallType?: SecurityInstallType;\n /** Initial channel sequence selection */\n initialChannelSequence?: number;\n /** Pre-fetched security data for SSR (server-side rendering) */\n initialData?: InitialSecurityData;\n /** Callback to fetch security info when selection changes */\n onFetchSecurityInfo: (params: {\n installType: SecurityInstallType;\n channelSequence: number;\n }) => Promise<{ images: SecurityReleaseImage[]; activeInstancesByVersion?: Record<string, number> }>;\n /** Callback to fetch security diff */\n onFetchSecurityDiff?: (params: {\n installType: SecurityInstallType;\n fromChannelSequence: number;\n toChannelSequence: number;\n }) => Promise<{ images: Record<string, SecurityInfoDiff> }>;\n /** Callback to fetch SBOM */\n onFetchSBOM?: (params: {\n installType: SecurityInstallType;\n channelSequence: number;\n }) => Promise<{ sboms: { unified?: SBOMMetadata } }>;\n /** Callback to download full SBOM file - returns the file content as a string. Required for download functionality. */\n onDownloadSBOM?: (params: {\n installType: SecurityInstallType;\n channelSequence: number;\n }) => Promise<string>;\n}\n\n// =============================================================================\n// Icons\n// =============================================================================\n\nconst DownloadIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M12 3v14\" />\n <path d=\"M8 13l4 4 4-4\" />\n <path d=\"M5 21h14\" />\n </svg>\n);\n\nconst InfoIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={className}\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n </svg>\n);\n\nconst ChevronDownIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n);\n\nconst XIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M18 6L6 18\" />\n <path d=\"M6 6l12 12\" />\n </svg>\n);\n\nconst SpinnerIcon = ({ className }: { className?: string }) => (\n <svg\n className={`animate-spin ${className ?? \"\"}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\nconst CopyIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={className}\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\" />\n </svg>\n);\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\nconst countCVEs = (summary?: SecurityScanSummary): number => {\n if (!summary) return 0;\n return (\n Object.keys(summary.critical || {}).length +\n Object.keys(summary.high || {}).length +\n Object.keys(summary.medium || {}).length +\n Object.keys(summary.low || {}).length\n );\n};\n\nconst getSeverityColor = (severity: string): string => {\n switch (severity) {\n case \"critical\":\n return \"text-pink-600\";\n case \"high\":\n return \"text-yellow-600\";\n case \"medium\":\n return \"text-blue-400\";\n case \"low\":\n return \"text-green-500\";\n default:\n return \"text-gray-500\";\n }\n};\n\nconst formatLastScanned = (dateString?: string): string => {\n if (!dateString) return \"---\";\n try {\n const date = new Date(dateString);\n return date.toLocaleString(\"en-US\", {\n month: \"numeric\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n });\n } catch {\n return \"---\";\n }\n};\n\nconst getShortImageName = (imageString: string): string => {\n const parts = imageString.split(\"/\");\n return parts[parts.length - 1] || imageString;\n};\n\n// =============================================================================\n// Sub-Components\n// =============================================================================\n\ninterface DropdownProps {\n value: string;\n options: { value: string; label: string; sublabel?: string; badge?: string }[];\n onChange: (value: string) => void;\n disabled?: boolean;\n testId?: string;\n}\n\nconst Dropdown = ({ value, options, onChange, disabled, testId }: DropdownProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const selected = options.find((o) => o.value === value);\n\n return (\n <div className=\"relative w-full\">\n <button\n type=\"button\"\n onClick={() => !disabled && setIsOpen(!isOpen)}\n disabled={disabled}\n data-testid={testId}\n className=\"flex w-full items-center justify-between rounded-md border border-gray-200 bg-white px-4 py-2 text-left text-sm font-semibold text-gray-900 hover:bg-gray-50 disabled:opacity-50\"\n >\n <div className=\"flex items-center gap-2\">\n <span>{selected?.label || \"Select...\"}</span>\n {selected?.badge && (\n <span className=\"rounded bg-green-50 px-1.5 py-0.5 text-xs font-medium text-green-600\">\n {selected.badge}\n </span>\n )}\n {selected?.sublabel && (\n <span className=\"text-xs font-normal text-gray-500\">{selected.sublabel}</span>\n )}\n </div>\n <ChevronDownIcon className=\"h-4 w-4 text-gray-500\" />\n </button>\n {isOpen && (\n <>\n <div className=\"fixed inset-0 z-10\" onClick={() => setIsOpen(false)} />\n <div className=\"absolute z-20 mt-1 max-h-60 w-full overflow-auto rounded-md border border-gray-200 bg-white py-1 shadow-lg\">\n {options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value);\n setIsOpen(false);\n }}\n data-testid={`${testId}-option-${option.value}`}\n className=\"flex w-full items-center justify-between px-4 py-2 text-left text-sm hover:bg-gray-100\"\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"font-semibold text-gray-900\">{option.label}</span>\n {option.badge && (\n <span className=\"rounded bg-green-50 px-1.5 py-0.5 text-xs font-medium text-green-600\">\n {option.badge}\n </span>\n )}\n </div>\n {option.sublabel && (\n <span className=\"text-xs text-gray-500\">{option.sublabel}</span>\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n );\n};\n\ninterface VulnerabilityBadgesProps {\n summary?: SecurityScanSummary;\n}\n\nconst VulnerabilityBadges = ({ summary }: VulnerabilityBadgesProps) => {\n if (!summary) {\n return <span className=\"text-sm text-gray-400\">No scan data</span>;\n }\n\n const counts = [\n { severity: \"critical\", count: Object.keys(summary.critical || {}).length },\n { severity: \"high\", count: Object.keys(summary.high || {}).length },\n { severity: \"medium\", count: Object.keys(summary.medium || {}).length },\n { severity: \"low\", count: Object.keys(summary.low || {}).length }\n ].filter((c) => c.count > 0);\n\n if (counts.length === 0) {\n return <span className=\"text-sm text-green-600\">No vulnerabilities</span>;\n }\n\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {counts.map(({ severity, count }) => (\n <span\n key={severity}\n className={`inline-flex items-center rounded px-1.5 py-0.5 text-xs font-medium ${getSeverityColor(severity)} bg-gray-100`}\n >\n {count} {severity.charAt(0).toUpperCase()}\n </span>\n ))}\n </div>\n );\n};\n\ninterface FixedCountProps {\n count?: number;\n hasDiffData: boolean;\n}\n\nconst FixedCount = ({ count, hasDiffData }: FixedCountProps) => {\n if (!hasDiffData) {\n return <span className=\"text-sm text-gray-400\">None</span>;\n }\n if (count === undefined || count === 0) {\n return <span className=\"text-sm text-gray-400\">None</span>;\n }\n return <span className=\"text-sm font-medium text-green-600\">{count}</span>;\n};\n\ninterface ImageNameProps {\n imageString: string;\n compact?: boolean;\n}\n\nconst ImageName = ({ imageString, compact }: ImageNameProps) => {\n const parts = imageString.split(\"/\");\n const namePart = parts[parts.length - 1] || imageString;\n const [name, tag] = namePart.split(\":\");\n\n if (compact && imageString.length > 50) {\n return (\n <div className=\"truncate text-sm text-gray-700\" title={imageString}>\n {name}\n {tag && <span className=\"text-gray-400\">:{tag}</span>}\n </div>\n );\n }\n\n return (\n <div className=\"text-sm text-gray-700\" title={imageString}>\n <span className=\"text-gray-400\">{parts.slice(0, -1).join(\"/\")}/</span>\n {name}\n {tag && <span className=\"text-gray-400\">:{tag}</span>}\n </div>\n );\n};\n\ninterface ModalProps {\n isOpen: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n}\n\nconst Modal = ({ isOpen, onClose, title, children }: ModalProps) => {\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"fixed inset-0 bg-black/50\" onClick={onClose} />\n <div className=\"relative z-10 max-h-[90vh] w-full max-w-6xl overflow-auto rounded-lg bg-white shadow-xl\">\n <div className=\"flex items-center justify-between border-b border-gray-200 px-6 py-4\">\n <h3 className=\"text-lg font-semibold text-gray-900\">{title}</h3>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-full p-1 hover:bg-gray-100\"\n >\n <XIcon className=\"h-5 w-5 text-gray-500\" />\n </button>\n </div>\n {children}\n </div>\n </div>\n );\n};\n\ninterface TooltipProps {\n content: string;\n children: React.ReactNode;\n}\n\nconst Tooltip = ({ content, children }: TooltipProps) => {\n const [show, setShow] = useState(false);\n\n return (\n <div className=\"relative inline-flex items-center\">\n <div\n onMouseEnter={() => setShow(true)}\n onMouseLeave={() => setShow(false)}\n >\n {children}\n </div>\n {show && (\n <div className=\"absolute bottom-full left-1/2 z-50 mb-2 -translate-x-1/2 whitespace-nowrap rounded bg-gray-900 px-2 py-1 text-xs text-white\">\n {content}\n <div className=\"absolute left-1/2 top-full -translate-x-1/2 border-4 border-transparent border-t-gray-900\" />\n </div>\n )}\n </div>\n );\n};\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\nexport function SecurityCard({\n channelReleases,\n showLinux,\n showHelm,\n primaryColor = \"#326CE5\",\n initialInstallType,\n initialChannelSequence,\n initialData,\n onFetchSecurityInfo,\n onFetchSecurityDiff,\n onFetchSBOM,\n onDownloadSBOM\n}: SecurityCardProps) {\n // Determine available install types\n const availableInstallTypes = useMemo(() => {\n const types: SecurityInstallType[] = [];\n if (showLinux) types.push(\"linux\");\n if (showHelm) types.push(\"helm\");\n return types;\n }, [showLinux, showHelm]);\n\n // State - use initial data's install type/sequence if provided\n const [selectedInstallType, setSelectedInstallType] = useState<SecurityInstallType>(\n initialData?.installType ?? initialInstallType ?? availableInstallTypes[0] ?? \"linux\"\n );\n const [selectedSequence, setSelectedSequence] = useState<number | null>(\n initialData?.channelSequence ?? initialChannelSequence ?? null\n );\n\n // Data states - initialize with server-fetched data if available\n const [securityData, setSecurityData] = useState<{ images: SecurityReleaseImage[]; activeInstancesByVersion?: Record<string, number> } | null>(\n initialData?.securityInfo ?? null\n );\n const [diffData, setDiffData] = useState<{ images: Record<string, SecurityInfoDiff> } | null>(\n initialData?.securityDiff ?? null\n );\n const [sbomData, setSbomData] = useState<{ sboms: { unified?: SBOMMetadata } } | null>(\n initialData?.sbom ?? null\n );\n\n // Loading states - not loading if we have initial data\n const [isLoadingScans, setIsLoadingScans] = useState(false);\n const [isLoadingSbom, setIsLoadingSbom] = useState(false);\n \n // Track if this is the initial render with pre-fetched data (use ref to avoid re-render)\n const hasUsedInitialDataRef = useRef(!!initialData);\n\n // Error states\n const [securityError, setSecurityError] = useState<string | null>(null);\n const [sbomError, setSbomError] = useState<string | null>(null);\n\n // Modal state\n const [showAllContainersModal, setShowAllContainersModal] = useState(false);\n\n // Filter releases based on install type\n const filteredReleases = useMemo(() => {\n return channelReleases.filter((release) => {\n if (selectedInstallType === \"linux\") {\n return !!release.installationTypes?.embeddedCluster;\n }\n if (selectedInstallType === \"helm\") {\n return !!release.installationTypes?.helm;\n }\n return true;\n });\n }, [channelReleases, selectedInstallType]);\n\n // Get current and previous release\n const selectedRelease = useMemo(() => {\n if (!selectedSequence) return filteredReleases[0] || null;\n return filteredReleases.find((r) => r.channelSequence === selectedSequence) || null;\n }, [filteredReleases, selectedSequence]);\n\n // Latest release for comparison (first in filtered list)\n const latestRelease = useMemo(() => {\n return filteredReleases.length > 0 ? filteredReleases[0] : null;\n }, [filteredReleases]);\n\n // Check if selected release is the latest\n const isSelectedLatest = useMemo(() => {\n return selectedRelease?.channelSequence === latestRelease?.channelSequence;\n }, [selectedRelease, latestRelease]);\n\n // Set default sequence when releases change\n useEffect(() => {\n const firstRelease = filteredReleases[0];\n if (filteredReleases.length > 0 && !selectedSequence && firstRelease) {\n setSelectedSequence(firstRelease.channelSequence);\n } else if (filteredReleases.length > 0 && selectedSequence && firstRelease) {\n // If current selection is not valid for new install type, reset\n const isValid = filteredReleases.some((r) => r.channelSequence === selectedSequence);\n if (!isValid) {\n setSelectedSequence(firstRelease.channelSequence);\n }\n }\n }, [filteredReleases, selectedSequence]);\n\n // Fetch data when selection changes\n useEffect(() => {\n if (!selectedRelease) return;\n\n // Skip fetch if we have initial data matching current selection\n if (hasUsedInitialDataRef.current && initialData) {\n const isMatchingSelection = \n initialData.installType === selectedInstallType &&\n initialData.channelSequence === selectedRelease.channelSequence;\n \n if (isMatchingSelection) {\n // Mark that we've used the initial data, next selection change will fetch\n hasUsedInitialDataRef.current = false;\n return;\n }\n // Selection changed from initial, proceed with fetch\n hasUsedInitialDataRef.current = false;\n }\n\n const fetchData = async () => {\n setIsLoadingScans(true);\n setIsLoadingSbom(true);\n setSecurityError(null);\n setSbomError(null);\n\n // Fetch security info\n try {\n const result = await onFetchSecurityInfo({\n installType: selectedInstallType,\n channelSequence: selectedRelease.channelSequence\n });\n setSecurityData(result);\n } catch (err) {\n setSecurityError(err instanceof Error ? err.message : \"Failed to fetch security data\");\n setSecurityData(null);\n }\n\n // Fetch diff to latest if not on latest\n if (!isSelectedLatest && latestRelease && onFetchSecurityDiff) {\n try {\n const diffResult = await onFetchSecurityDiff({\n installType: selectedInstallType,\n fromChannelSequence: selectedRelease.channelSequence,\n toChannelSequence: latestRelease.channelSequence\n });\n setDiffData(diffResult);\n } catch (err) {\n console.error(\"Failed to fetch security diff:\", err);\n setDiffData(null);\n }\n } else {\n setDiffData(null);\n }\n\n setIsLoadingScans(false);\n\n // Fetch SBOM\n if (onFetchSBOM) {\n try {\n const sbomResult = await onFetchSBOM({\n installType: selectedInstallType,\n channelSequence: selectedRelease.channelSequence\n });\n setSbomData(sbomResult);\n } catch (err) {\n setSbomError(err instanceof Error ? err.message : \"Failed to fetch SBOM\");\n setSbomData(null);\n }\n }\n setIsLoadingSbom(false);\n };\n\n fetchData();\n }, [selectedRelease, selectedInstallType, latestRelease, isSelectedLatest, onFetchSecurityInfo, onFetchSecurityDiff, onFetchSBOM]);\n\n // Install type options\n const installTypeOptions = useMemo(() => {\n const options: { value: string; label: string }[] = [];\n if (showLinux) options.push({ value: \"linux\", label: \"Linux\" });\n if (showHelm) options.push({ value: \"helm\", label: \"Helm\" });\n return options;\n }, [showLinux, showHelm]);\n\n // Release options with \"Latest\" badge for the first release\n const releaseOptions = useMemo(() => {\n return filteredReleases.map((r, index) => ({\n value: r.channelSequence.toString(),\n label: `Version ${r.versionLabel}`,\n badge: index === 0 ? \"Latest\" : undefined,\n sublabel: `Sequence ${r.channelSequence}${r.isRequired ? \" (required)\" : \"\"}`\n }));\n }, [filteredReleases]);\n\n // Calculate CVE totals\n const cveTotals = useMemo(() => {\n if (!securityData?.images) {\n return { critical: 0, high: 0, medium: 0, low: 0 };\n }\n return securityData.images.reduce(\n (acc, image) => {\n if (!image.security?.result) return acc;\n const r = image.security.result;\n return {\n critical: acc.critical + Object.keys(r.critical || {}).length,\n high: acc.high + Object.keys(r.high || {}).length,\n medium: acc.medium + Object.keys(r.medium || {}).length,\n low: acc.low + Object.keys(r.low || {}).length\n };\n },\n { critical: 0, high: 0, medium: 0, low: 0 }\n );\n }, [securityData]);\n\n // Calculate fixed CVE totals\n const fixedTotals = useMemo(() => {\n if (!diffData?.images) {\n return { critical: 0, high: 0, medium: 0, low: 0 };\n }\n return Object.values(diffData.images).reduce(\n (acc, diff) => {\n if (!diff.removed) return acc;\n return {\n critical: acc.critical + Object.keys(diff.removed.critical || {}).length,\n high: acc.high + Object.keys(diff.removed.high || {}).length,\n medium: acc.medium + Object.keys(diff.removed.medium || {}).length,\n low: acc.low + Object.keys(diff.removed.low || {}).length\n };\n },\n { critical: 0, high: 0, medium: 0, low: 0 }\n );\n }, [diffData]);\n\n // SBOM metadata (no parsing needed - comes pre-parsed from API)\n const sbomMetadata = useMemo(() => {\n return sbomData?.sboms?.unified || null;\n }, [sbomData]);\n\n // Download SBOM handler\n const handleDownloadSBOM = useCallback(async () => {\n if (!selectedRelease) return;\n if (!onDownloadSBOM) {\n console.error(\"Download SBOM handler not provided\");\n return;\n }\n \n try {\n const fileContent = await onDownloadSBOM({\n installType: selectedInstallType,\n channelSequence: selectedRelease.channelSequence\n });\n \n // Create a blob and download URL from the file content\n const blob = new Blob([fileContent], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n \n // Trigger download\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `sbom-report-${selectedRelease.versionLabel || \"unknown\"}.json`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n } catch (error) {\n console.error(\"Failed to download SBOM:\", error);\n }\n }, [selectedRelease, selectedInstallType, onDownloadSBOM]);\n\n // Check if we have any security data\n const hasSecurityData = securityData?.images?.some((img) => img.security);\n\n // Calculate active instances for the selected version\n const activeInstancesOnVersion = useMemo(() => {\n if (!selectedRelease?.versionLabel || !securityData?.activeInstancesByVersion) {\n return 0;\n }\n return securityData.activeInstancesByVersion[selectedRelease.versionLabel] || 0;\n }, [selectedRelease, securityData]);\n\n // Calculate total fixed CVEs if updating to latest\n const fixedCVEsToLatest = useMemo(() => {\n if (!diffData?.images) return 0;\n\n return Object.values(diffData.images).reduce((total, imageDiff) => {\n if (!imageDiff.removed) return total;\n return (\n total +\n Object.keys(imageDiff.removed.critical || {}).length +\n Object.keys(imageDiff.removed.high || {}).length +\n Object.keys(imageDiff.removed.medium || {}).length +\n Object.keys(imageDiff.removed.low || {}).length\n );\n }, 0);\n }, [diffData]);\n\n // Check if critical CVEs would be fixed by updating to latest\n const hasCriticalFixed = useMemo(() => {\n if (!diffData?.images) return false;\n\n return Object.values(diffData.images).some(\n (imageDiff) =>\n imageDiff.removed?.critical &&\n Object.keys(imageDiff.removed.critical).length > 0\n );\n }, [diffData]);\n\n return (\n <div className=\"space-y-6\">\n {/* Header */}\n <div>\n <h1 className=\"text-3xl font-bold text-gray-900\">Security Center</h1>\n <p className=\"text-gray-600\">\n Security information and compliance reports for each release\n </p>\n </div>\n\n {/* Dropdowns - flex layout with inline active instances text */}\n <div className=\"flex items-end gap-6\">\n {/* Install Type */}\n <div className=\"w-72\">\n <span className=\"mb-2 block text-sm font-medium text-gray-700\">\n Install Type\n </span>\n {availableInstallTypes.length > 1 ? (\n <Dropdown\n value={selectedInstallType}\n options={installTypeOptions}\n onChange={(v) => setSelectedInstallType(v as SecurityInstallType)}\n testId=\"install-type-dropdown\"\n />\n ) : (\n <div className=\"rounded-md border border-gray-200 bg-gray-50 px-4 py-2 text-sm font-semibold text-gray-900\">\n {installTypeOptions[0]?.label || \"Linux\"}\n </div>\n )}\n </div>\n\n {/* Release Version */}\n <div className=\"w-80\">\n <span className=\"mb-2 block text-sm font-medium text-gray-700\">\n Release Version\n </span>\n <Dropdown\n value={selectedSequence?.toString() || \"\"}\n options={releaseOptions}\n onChange={(v) => setSelectedSequence(parseInt(v, 10))}\n disabled={releaseOptions.length === 0}\n testId=\"release-dropdown\"\n />\n </div>\n\n {/* Update Available / Active Instances */}\n {!isSelectedLatest ? (\n <div className=\"flex flex-col gap-1 self-start pt-7\">\n <div className=\"flex items-center gap-2\">\n {/* Update button */}\n <a\n href=\"/update\"\n className=\"rounded px-3 py-1 text-xs text-white no-underline\"\n style={{\n backgroundColor: hasCriticalFixed ? \"#dc2626\" : (primaryColor || \"#2563eb\"),\n borderColor: hasCriticalFixed ? \"#dc2626\" : (primaryColor || \"#2563eb\"),\n }}\n >\n {hasCriticalFixed ? \"Critical update available\" : \"Update available\"}\n </a>\n {/* Fixed CVEs count */}\n {fixedCVEsToLatest > 0 && (\n <span className=\"text-xs font-medium text-gray-600\">\n {fixedCVEsToLatest} Fixed CVEs\n </span>\n )}\n </div>\n {/* Active instances on this version */}\n {activeInstancesOnVersion > 0 && (\n <span className=\"text-sm text-gray-600\">\n {activeInstancesOnVersion} active instance{activeInstancesOnVersion !== 1 ? 's' : ''} on this version.{' '}\n <a href=\"/update\" className=\"font-semibold text-blue-500 hover:underline\">\n See more.\n </a>\n </span>\n )}\n </div>\n ) : (\n /* Show active instances inline when on latest */\n activeInstancesOnVersion > 0 && (\n <div className=\"pb-2 text-sm text-gray-600\">\n {activeInstancesOnVersion} active instance{activeInstancesOnVersion !== 1 ? 's' : ''} on this version.{' '}\n <a href=\"/update\" className=\"font-semibold text-blue-500 hover:underline\">\n See more.\n </a>\n </div>\n )\n )}\n </div>\n\n {/* Cards Grid */}\n {(hasSecurityData || isLoadingScans || isLoadingSbom || securityError || sbomError) && (\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n {/* CVE Report Card */}\n <div className=\"rounded-lg border border-gray-200 bg-white\">\n <div className=\"flex items-center justify-between border-b border-gray-200 bg-gray-50 px-6 py-5\">\n <h2 className=\"text-lg font-medium text-gray-900\">CVE Report</h2>\n </div>\n\n {isLoadingScans ? (\n <div className=\"flex min-h-[200px] items-center justify-center p-6\">\n <SpinnerIcon className=\"h-8 w-8 text-gray-400\" />\n </div>\n ) : securityError ? (\n <div className=\"p-6 text-center\">\n <p className=\"py-8 text-pink-500\">Error loading security data: {securityError}</p>\n </div>\n ) : !hasSecurityData ? (\n <div className=\"p-6 text-center\">\n <p className=\"py-8 text-gray-500\">No security report available for this release</p>\n </div>\n ) : (\n <div className=\"p-6\">\n <p className=\"mb-6 text-gray-600\">\n Comprehensive vulnerability scanning using Trivy to identify and assess security\n risks in dependencies and container images.\n </p>\n\n {/* Severity Summary Table */}\n <div className=\"mb-6 overflow-auto rounded-md bg-gray-50 p-2\">\n <table className=\"w-full border-collapse text-sm\">\n <thead>\n <tr>\n <th className=\"px-4 py-3 text-left text-xs font-semibold uppercase text-gray-500\">\n Severity\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-semibold uppercase text-gray-500\">\n Found\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-semibold uppercase text-gray-500\">\n <span className=\"inline-flex items-center gap-1\">\n Fixed\n <Tooltip content=\"CVEs fixed compared to the previous release version\">\n <InfoIcon className=\"h-4 w-4 cursor-pointer text-blue-400\" />\n </Tooltip>\n </span>\n </th>\n </tr>\n </thead>\n <tbody>\n {([\"critical\", \"high\", \"medium\", \"low\"] as const).map((severity) => (\n <tr key={severity}>\n <td className=\"px-4 py-3 capitalize text-gray-700\">{severity}</td>\n <td className=\"px-4 py-3\">\n <span className={`font-medium ${getSeverityColor(severity)}`}>\n {cveTotals[severity]}\n </span>\n </td>\n <td className=\"px-4 py-3\">\n <FixedCount count={fixedTotals[severity]} hasDiffData={!!diffData} />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {/* Container Vulnerabilities */}\n <div>\n <div className=\"mb-3\">\n <h3 className=\"text-sm font-medium text-gray-900\">Container Vulnerabilities</h3>\n </div>\n <div className=\"overflow-auto rounded-lg border border-gray-200\">\n <table className=\"w-full\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500\">\n Name\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500\">\n Found\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500\">\n <span className=\"inline-flex items-center gap-1\">\n Fixed\n <Tooltip content=\"CVEs fixed compared to the previous release version\">\n <InfoIcon className=\"h-4 w-4 cursor-pointer text-blue-400\" />\n </Tooltip>\n </span>\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-200 bg-white\">\n {securityData?.images?.slice(0, 4).map((image, idx) => {\n const imageWithoutTag = image.image.split(\":\")[0] || image.image;\n const imageDiff = diffData?.images?.[imageWithoutTag];\n const fixedVulns = imageDiff?.removed;\n const totalFixed = fixedVulns\n ? Object.keys(fixedVulns.critical || {}).length +\n Object.keys(fixedVulns.high || {}).length +\n Object.keys(fixedVulns.medium || {}).length +\n Object.keys(fixedVulns.low || {}).length\n : undefined;\n\n return (\n <tr key={idx}>\n <td className=\"px-4 py-3\">\n <div className=\"max-w-[300px]\">\n <ImageName imageString={image.image} compact />\n </div>\n </td>\n <td className=\"px-4 py-3\">\n <VulnerabilityBadges summary={image.security?.result} />\n </td>\n <td className=\"px-4 py-3\">\n <FixedCount count={totalFixed} hasDiffData={!!imageDiff} />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n {(securityData?.images?.length ?? 0) > 4 && (\n <div className=\"mt-2 text-right\">\n <button\n type=\"button\"\n onClick={() => setShowAllContainersModal(true)}\n className=\"text-sm font-medium text-blue-600 hover:underline\"\n >\n Show all containers\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* SBOM Card */}\n <div className=\"rounded-lg border border-gray-200 bg-white\">\n <div className=\"flex items-center justify-between border-b border-gray-200 bg-gray-50 px-6 py-5\">\n <h2 className=\"text-lg font-medium text-gray-900\">Software Bill of Materials</h2>\n {sbomMetadata && onDownloadSBOM && (\n <button\n type=\"button\"\n onClick={handleDownloadSBOM}\n style={{ backgroundColor: primaryColor, borderColor: primaryColor }}\n className=\"inline-flex items-center gap-2 rounded px-3 py-1.5 text-sm font-medium text-white hover:opacity-90\"\n >\n <DownloadIcon className=\"h-4 w-4\" />\n Download report\n </button>\n )}\n </div>\n\n {isLoadingSbom ? (\n <div className=\"flex min-h-[200px] items-center justify-center p-6\">\n <SpinnerIcon className=\"h-8 w-8 text-gray-400\" />\n </div>\n ) : sbomError ? (\n <div className=\"p-6 text-center\">\n <p className=\"py-8 text-pink-500\">Error loading SBOM data: {sbomError}</p>\n </div>\n ) : !sbomMetadata ? (\n <div className=\"p-6 text-center\">\n <p className=\"py-8 text-gray-500\">No SBOM available for this release</p>\n </div>\n ) : (\n <div className=\"p-6\">\n <p className=\"mb-6 text-gray-600\">\n Comprehensive SBOM in SPDX format providing detailed software component inventory\n and licensing information.\n </p>\n\n <div className=\"grid grid-cols-2 gap-4 rounded-md bg-gray-50 p-4 text-sm text-gray-600\">\n <div className=\"flex items-center justify-between\">\n <span>Name:</span>\n <span className=\"font-medium text-gray-900\">{sbomMetadata.name || \"Unknown\"}</span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span>SPDX Version:</span>\n <span className=\"font-medium text-gray-900\">\n {sbomMetadata.spdxVersion || \"Unknown\"}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span>Packages:</span>\n <span className=\"font-medium text-gray-900\">\n {sbomMetadata.packageCount ?? 0}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span>Files:</span>\n <span className=\"font-medium text-gray-900\">\n {sbomMetadata.fileCount ?? 0}\n </span>\n </div>\n {sbomMetadata.created && (\n <div className=\"flex items-center justify-between\">\n <span>Created:</span>\n <span className=\"font-medium text-gray-900\">\n {new Date(sbomMetadata.created).toLocaleDateString()}\n </span>\n </div>\n )}\n {sbomMetadata.creator && (\n <div className=\"flex items-center justify-between\">\n <span>Tool:</span>\n <span className=\"font-medium text-gray-900\">\n {sbomMetadata.creator.replace(\"Tool: \", \"\")}\n </span>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* No Data Message */}\n {!isLoadingScans && !isLoadingSbom && !hasSecurityData && !securityError && (\n <div className=\"flex w-full items-center justify-center pt-6 text-gray-600\">\n No security report available for this release\n </div>\n )}\n\n {/* All Containers Modal */}\n <Modal\n isOpen={showAllContainersModal}\n onClose={() => setShowAllContainersModal(false)}\n title={`Container Images (${securityData?.images?.length ?? 0})`}\n >\n <div className=\"max-h-[640px] space-y-4 overflow-auto px-6 pb-6\">\n {securityData?.images?.map((image, idx) => {\n const imageWithoutTag = image.image.split(\":\")[0] || image.image;\n const imageDiff = diffData?.images?.[imageWithoutTag];\n const fixedVulns = imageDiff?.removed;\n const totalFixed = fixedVulns\n ? Object.keys(fixedVulns.critical || {}).length +\n Object.keys(fixedVulns.high || {}).length +\n Object.keys(fixedVulns.medium || {}).length +\n Object.keys(fixedVulns.low || {}).length\n : undefined;\n const digest = image.security?.digest || image.sha;\n const lastScanned = image.security?.last_scanned_at;\n const hasDigest = digest && digest !== \"---\";\n\n return (\n <div key={idx} className=\"border-b border-gray-200 pb-4 last:border-b-0 last:pb-0\">\n {/* Image short name */}\n <h3 className=\"mb-1.5 text-sm font-semibold text-gray-900\">\n {getShortImageName(image.image)}\n </h3>\n\n {/* Full image path in gray box */}\n <div className=\"mb-2 rounded bg-gray-100 px-2.5 py-1.5\">\n <code className=\"text-xs text-gray-700\">{image.image}</code>\n </div>\n\n {/* Digest row */}\n <div className=\"mb-2 flex items-center justify-between text-xs\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-gray-500\">Digest:</span>\n {hasDigest ? (\n <>\n <code className=\"text-gray-700\">{digest}</code>\n <button\n type=\"button\"\n onClick={() => {\n navigator.clipboard.writeText(digest);\n }}\n className=\"inline-flex items-center gap-1 text-blue-600 hover:text-blue-800\"\n >\n <CopyIcon className=\"h-3.5 w-3.5\" />\n <span>Copy</span>\n </button>\n </>\n ) : (\n <span className=\"text-gray-400\">---</span>\n )}\n </div>\n <div className=\"text-gray-500\">\n Last Scanned: {formatLastScanned(lastScanned)}\n </div>\n </div>\n\n {/* Found and Fixed row */}\n <div className=\"flex items-center gap-4 text-xs\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-gray-500\">Found:</span>\n {image.security?.result ? (\n <VulnerabilityBadges summary={image.security.result} />\n ) : (\n <span className=\"text-gray-400\">Unavailable</span>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-gray-500\">Fixed:</span>\n <Tooltip content=\"CVEs fixed compared to the previous release version\">\n <InfoIcon className=\"h-3.5 w-3.5 cursor-pointer text-blue-400\" />\n </Tooltip>\n {imageDiff ? (\n totalFixed && totalFixed > 0 ? (\n <span className=\"font-medium text-green-600\">{totalFixed}</span>\n ) : (\n <span className=\"text-gray-400\">None</span>\n )\n ) : (\n <span className=\"text-gray-400\">Unavailable</span>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </Modal>\n </div>\n );\n}\n\nSecurityCard.displayName = \"SecurityCard\";\n\n"]}
1
+ {"version":3,"sources":["../../src/utils/constants.ts","../../src/utils/clipboard.ts","../../src/components/security-card.tsx"],"names":["useState","useCallback"],"mappings":"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","file":"security-card.js","sourcesContent":["/**\n * Default globe favicon matching the CiGlobe icon (Circum Icons)\n * Used as fallback when custom branding doesn't provide a favicon\n */\nexport const DEFAULT_FAVICON = \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='1.5'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cellipse cx='12' cy='12' rx='4' ry='10'/%3E%3Cpath d='M2 12h20'/%3E%3C/svg%3E\";\n\n/**\n * Default primary brand color\n */\nexport const DEFAULT_PRIMARY_COLOR = \"#4f46e5\";\n\n/**\n * Default secondary brand color\n */\nexport const DEFAULT_SECONDARY_COLOR = \"#6366f1\";\n\n/**\n * Check if the API origin is HTTP (used for repldev environments)\n * This determines cookie security settings for cross-origin iframes\n * @returns true if the API origin starts with http:// (not https://)\n */\nexport const isHttpApiOrigin = (): boolean => {\n return process.env.REPLICATED_APP_ORIGIN?.startsWith('http://') || false;\n};\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\n\n/**\n * Hook for copy-to-clipboard functionality with visual feedback\n * @param resetDelay - Time in milliseconds before resetting copied state (default: 2000)\n * @returns Object with copy function and copied state\n */\nexport function useCopyToClipboard(resetDelay = 2000) {\n const [copied, setCopied] = useState(false);\n\n const copy = useCallback(async (text: string): Promise<boolean> => {\n if (!navigator.clipboard) {\n console.warn(\"[useCopyToClipboard] Clipboard API not available\");\n return false;\n }\n\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), resetDelay);\n return true;\n } catch (error) {\n console.error(\"[useCopyToClipboard] Failed to copy:\", error);\n return false;\n }\n }, [resetDelay]);\n\n return { copy, copied };\n}\n\n/**\n * Simple utility function to copy text to clipboard\n * @param text - Text to copy\n * @returns Promise that resolves to true if successful, false otherwise\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n if (!navigator.clipboard) {\n console.warn(\"[copyToClipboard] Clipboard API not available\");\n return false;\n }\n\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch (error) {\n console.error(\"[copyToClipboard] Failed to copy:\", error);\n return false;\n }\n}\n","\"use client\";\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from \"react\";\nimport { DEFAULT_PRIMARY_COLOR } from \"../utils/constants\";\nimport { copyToClipboard } from \"../utils/clipboard\";\nimport type {\n SecurityInstallType,\n SecurityReleaseImage,\n SecurityScanSummary,\n SecurityInfoDiff,\n SBOMMetadata\n} from \"../actions\";\nimport type { ChannelRelease } from \"../actions/install\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** Pre-fetched security data for SSR */\nexport interface InitialSecurityData {\n /** Security scan results */\n securityInfo?: { images: SecurityReleaseImage[]; activeInstancesByVersion?: Record<string, number> };\n /** CVE diff between releases */\n securityDiff?: { images: Record<string, SecurityInfoDiff> };\n /** SBOM metadata (lightweight, included in SSR. Full SBOM available via download) */\n sbom?: { sboms: { unified?: SBOMMetadata } };\n /** Install type the initial data was fetched for */\n installType: SecurityInstallType;\n /** Channel sequence the initial data was fetched for */\n channelSequence: number;\n /** Previous channel sequence for diff (if any) */\n previousChannelSequence?: number;\n}\n\nexport interface SecurityCardProps {\n /** Available channel releases */\n channelReleases: ChannelRelease[];\n /** Whether Linux install type is enabled */\n showLinux: boolean;\n /** Whether Helm install type is enabled */\n showHelm: boolean;\n /** Primary brand color. Defaults to \"#326CE5\" */\n primaryColor?: string;\n /** Initial install type selection */\n initialInstallType?: SecurityInstallType;\n /** Initial channel sequence selection */\n initialChannelSequence?: number;\n /** Pre-fetched security data for SSR (server-side rendering) */\n initialData?: InitialSecurityData;\n /** Callback to fetch security info when selection changes */\n onFetchSecurityInfo: (params: {\n installType: SecurityInstallType;\n channelSequence: number;\n }) => Promise<{ images: SecurityReleaseImage[]; activeInstancesByVersion?: Record<string, number> }>;\n /** Callback to fetch security diff */\n onFetchSecurityDiff?: (params: {\n installType: SecurityInstallType;\n fromChannelSequence: number;\n toChannelSequence: number;\n }) => Promise<{ images: Record<string, SecurityInfoDiff> }>;\n /** Callback to fetch SBOM */\n onFetchSBOM?: (params: {\n installType: SecurityInstallType;\n channelSequence: number;\n }) => Promise<{ sboms: { unified?: SBOMMetadata } }>;\n /** Callback to download full SBOM file - returns the file content as a string. Required for download functionality. */\n onDownloadSBOM?: (params: {\n installType: SecurityInstallType;\n channelSequence: number;\n }) => Promise<string>;\n}\n\n// =============================================================================\n// Icons\n// =============================================================================\n\nconst DownloadIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M12 3v14\" />\n <path d=\"M8 13l4 4 4-4\" />\n <path d=\"M5 21h14\" />\n </svg>\n);\n\nconst InfoIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={className}\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n </svg>\n);\n\nconst ChevronDownIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n);\n\nconst XIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M18 6L6 18\" />\n <path d=\"M6 6l12 12\" />\n </svg>\n);\n\nconst SpinnerIcon = ({ className }: { className?: string }) => (\n <svg\n className={`animate-spin ${className ?? \"\"}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\nconst CopyIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={className}\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\" />\n </svg>\n);\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\nconst countCVEs = (summary?: SecurityScanSummary): number => {\n if (!summary) return 0;\n return (\n Object.keys(summary.critical || {}).length +\n Object.keys(summary.high || {}).length +\n Object.keys(summary.medium || {}).length +\n Object.keys(summary.low || {}).length\n );\n};\n\nconst getSeverityColor = (severity: string): string => {\n switch (severity) {\n case \"critical\":\n return \"text-pink-600\";\n case \"high\":\n return \"text-yellow-600\";\n case \"medium\":\n return \"text-blue-400\";\n case \"low\":\n return \"text-green-500\";\n default:\n return \"text-gray-500\";\n }\n};\n\nconst formatLastScanned = (dateString?: string): string => {\n if (!dateString) return \"---\";\n try {\n const date = new Date(dateString);\n return date.toLocaleString(\"en-US\", {\n month: \"numeric\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n });\n } catch {\n return \"---\";\n }\n};\n\nconst getShortImageName = (imageString: string): string => {\n const parts = imageString.split(\"/\");\n return parts[parts.length - 1] || imageString;\n};\n\n// =============================================================================\n// Sub-Components\n// =============================================================================\n\ninterface DropdownProps {\n value: string;\n options: { value: string; label: string; sublabel?: string; badge?: string }[];\n onChange: (value: string) => void;\n disabled?: boolean;\n testId?: string;\n}\n\nconst Dropdown = ({ value, options, onChange, disabled, testId }: DropdownProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const selected = options.find((o) => o.value === value);\n\n return (\n <div className=\"relative w-full\">\n <button\n type=\"button\"\n onClick={() => !disabled && setIsOpen(!isOpen)}\n disabled={disabled}\n data-testid={testId}\n className=\"flex w-full items-center justify-between rounded-md border border-gray-200 bg-white px-4 py-2 text-left text-sm font-semibold text-gray-900 hover:bg-gray-50 disabled:opacity-50\"\n >\n <div className=\"flex items-center gap-2\">\n <span>{selected?.label || \"Select...\"}</span>\n {selected?.badge && (\n <span className=\"rounded bg-green-50 px-1.5 py-0.5 text-xs font-medium text-green-600\">\n {selected.badge}\n </span>\n )}\n {selected?.sublabel && (\n <span className=\"text-xs font-normal text-gray-500\">{selected.sublabel}</span>\n )}\n </div>\n <ChevronDownIcon className=\"h-4 w-4 text-gray-500\" />\n </button>\n {isOpen && (\n <>\n <div className=\"fixed inset-0 z-10\" onClick={() => setIsOpen(false)} />\n <div className=\"absolute z-20 mt-1 max-h-60 w-full overflow-auto rounded-md border border-gray-200 bg-white py-1 shadow-lg\">\n {options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value);\n setIsOpen(false);\n }}\n data-testid={`${testId}-option-${option.value}`}\n className=\"flex w-full items-center justify-between px-4 py-2 text-left text-sm hover:bg-gray-100\"\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"font-semibold text-gray-900\">{option.label}</span>\n {option.badge && (\n <span className=\"rounded bg-green-50 px-1.5 py-0.5 text-xs font-medium text-green-600\">\n {option.badge}\n </span>\n )}\n </div>\n {option.sublabel && (\n <span className=\"text-xs text-gray-500\">{option.sublabel}</span>\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n );\n};\n\ninterface VulnerabilityBadgesProps {\n summary?: SecurityScanSummary;\n}\n\nconst VulnerabilityBadges = ({ summary }: VulnerabilityBadgesProps) => {\n if (!summary) {\n return <span className=\"text-sm text-gray-400\">No scan data</span>;\n }\n\n const counts = [\n { severity: \"critical\", count: Object.keys(summary.critical || {}).length },\n { severity: \"high\", count: Object.keys(summary.high || {}).length },\n { severity: \"medium\", count: Object.keys(summary.medium || {}).length },\n { severity: \"low\", count: Object.keys(summary.low || {}).length }\n ].filter((c) => c.count > 0);\n\n if (counts.length === 0) {\n return <span className=\"text-sm text-green-600\">No vulnerabilities</span>;\n }\n\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {counts.map(({ severity, count }) => (\n <span\n key={severity}\n className={`inline-flex items-center rounded px-1.5 py-0.5 text-xs font-medium ${getSeverityColor(severity)} bg-gray-100`}\n >\n {count} {severity.charAt(0).toUpperCase()}\n </span>\n ))}\n </div>\n );\n};\n\ninterface FixedCountProps {\n count?: number;\n hasDiffData: boolean;\n}\n\nconst FixedCount = ({ count, hasDiffData }: FixedCountProps) => {\n if (!hasDiffData) {\n return <span className=\"text-sm text-gray-400\">None</span>;\n }\n if (count === undefined || count === 0) {\n return <span className=\"text-sm text-gray-400\">None</span>;\n }\n return <span className=\"text-sm font-medium text-green-600\">{count}</span>;\n};\n\ninterface ImageNameProps {\n imageString: string;\n}\n\nconst ImageName = ({ imageString }: ImageNameProps) => {\n const parts = imageString.split(\"/\");\n const namePart = parts[parts.length - 1] || imageString;\n const [name, tag] = namePart.split(\":\");\n\n return (\n <div className=\"text-sm text-gray-700\" title={imageString}>\n <span className=\"text-gray-400\">{parts.slice(0, -1).join(\"/\")}/</span>\n {name}\n {tag && <span className=\"text-gray-400\">:{tag}</span>}\n </div>\n );\n};\n\ninterface ModalProps {\n isOpen: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n}\n\nconst Modal = ({ isOpen, onClose, title, children }: ModalProps) => {\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"fixed inset-0 bg-black/50\" onClick={onClose} />\n <div className=\"relative z-10 max-h-[90vh] w-full max-w-6xl overflow-auto rounded-lg bg-white shadow-xl\">\n <div className=\"flex items-center justify-between border-b border-gray-200 px-6 py-4\">\n <h3 className=\"text-lg font-semibold text-gray-900\">{title}</h3>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-full p-1 hover:bg-gray-100\"\n >\n <XIcon className=\"h-5 w-5 text-gray-500\" />\n </button>\n </div>\n {children}\n </div>\n </div>\n );\n};\n\ninterface TooltipProps {\n content: string;\n children: React.ReactNode;\n}\n\nconst Tooltip = ({ content, children }: TooltipProps) => {\n const [show, setShow] = useState(false);\n\n return (\n <div className=\"relative inline-flex items-center\">\n <div\n onMouseEnter={() => setShow(true)}\n onMouseLeave={() => setShow(false)}\n >\n {children}\n </div>\n {show && (\n <div className=\"absolute bottom-full left-1/2 z-50 mb-2 -translate-x-1/2 whitespace-nowrap rounded bg-gray-900 px-2 py-1 text-xs text-white\">\n {content}\n <div className=\"absolute left-1/2 top-full -translate-x-1/2 border-4 border-transparent border-t-gray-900\" />\n </div>\n )}\n </div>\n );\n};\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\nexport function SecurityCard({\n channelReleases,\n showLinux,\n showHelm,\n primaryColor = DEFAULT_PRIMARY_COLOR,\n initialInstallType,\n initialChannelSequence,\n initialData,\n onFetchSecurityInfo,\n onFetchSecurityDiff,\n onFetchSBOM,\n onDownloadSBOM\n}: SecurityCardProps) {\n // Determine available install types\n const availableInstallTypes = useMemo(() => {\n const types: SecurityInstallType[] = [];\n if (showLinux) types.push(\"linux\");\n if (showHelm) types.push(\"helm\");\n return types;\n }, [showLinux, showHelm]);\n\n // State - use initial data's install type/sequence if provided\n const [selectedInstallType, setSelectedInstallType] = useState<SecurityInstallType>(\n initialData?.installType ?? initialInstallType ?? availableInstallTypes[0] ?? \"linux\"\n );\n const [selectedSequence, setSelectedSequence] = useState<number | null>(\n initialData?.channelSequence ?? initialChannelSequence ?? null\n );\n\n // Data states - initialize with server-fetched data if available\n const [securityData, setSecurityData] = useState<{ images: SecurityReleaseImage[]; activeInstancesByVersion?: Record<string, number> } | null>(\n initialData?.securityInfo ?? null\n );\n const [diffData, setDiffData] = useState<{ images: Record<string, SecurityInfoDiff> } | null>(\n initialData?.securityDiff ?? null\n );\n const [sbomData, setSbomData] = useState<{ sboms: { unified?: SBOMMetadata } } | null>(\n initialData?.sbom ?? null\n );\n\n // Loading states - not loading if we have initial data\n const [isLoadingScans, setIsLoadingScans] = useState(false);\n const [isLoadingSbom, setIsLoadingSbom] = useState(false);\n \n // Track if this is the initial render with pre-fetched data (use ref to avoid re-render)\n const hasUsedInitialDataRef = useRef(!!initialData);\n\n // Track which digest was copied for visual feedback\n const [copiedDigest, setCopiedDigest] = useState<string | null>(null);\n\n // Error states\n const [securityError, setSecurityError] = useState<string | null>(null);\n const [sbomError, setSbomError] = useState<string | null>(null);\n\n // Modal state\n const [showAllContainersModal, setShowAllContainersModal] = useState(false);\n\n // Filter releases based on install type\n const filteredReleases = useMemo(() => {\n return channelReleases.filter((release) => {\n if (selectedInstallType === \"linux\") {\n return !!release.installationTypes?.embeddedCluster;\n }\n if (selectedInstallType === \"helm\") {\n return !!release.installationTypes?.helm;\n }\n return true;\n });\n }, [channelReleases, selectedInstallType]);\n\n // Get current and previous release\n const selectedRelease = useMemo(() => {\n if (!selectedSequence) return filteredReleases[0] || null;\n return filteredReleases.find((r) => r.channelSequence === selectedSequence) || null;\n }, [filteredReleases, selectedSequence]);\n\n // Latest release for comparison (first in filtered list)\n const latestRelease = useMemo(() => {\n return filteredReleases.length > 0 ? filteredReleases[0] : null;\n }, [filteredReleases]);\n\n // Check if selected release is the latest\n const isSelectedLatest = useMemo(() => {\n return selectedRelease?.channelSequence === latestRelease?.channelSequence;\n }, [selectedRelease, latestRelease]);\n\n // Set default sequence when releases change\n useEffect(() => {\n const firstRelease = filteredReleases[0];\n if (filteredReleases.length > 0 && !selectedSequence && firstRelease) {\n setSelectedSequence(firstRelease.channelSequence);\n } else if (filteredReleases.length > 0 && selectedSequence && firstRelease) {\n // If current selection is not valid for new install type, reset\n const isValid = filteredReleases.some((r) => r.channelSequence === selectedSequence);\n if (!isValid) {\n setSelectedSequence(firstRelease.channelSequence);\n }\n }\n }, [filteredReleases, selectedSequence]);\n\n // Fetch data when selection changes\n useEffect(() => {\n if (!selectedRelease) return;\n\n // Skip fetch if we have initial data matching current selection\n if (hasUsedInitialDataRef.current && initialData) {\n const isMatchingSelection = \n initialData.installType === selectedInstallType &&\n initialData.channelSequence === selectedRelease.channelSequence;\n \n if (isMatchingSelection) {\n // Mark that we've used the initial data, next selection change will fetch\n hasUsedInitialDataRef.current = false;\n return;\n }\n // Selection changed from initial, proceed with fetch\n hasUsedInitialDataRef.current = false;\n }\n\n const fetchData = async () => {\n setIsLoadingScans(true);\n setIsLoadingSbom(true);\n setSecurityError(null);\n setSbomError(null);\n\n // Fetch security info\n try {\n const result = await onFetchSecurityInfo({\n installType: selectedInstallType,\n channelSequence: selectedRelease.channelSequence\n });\n setSecurityData(result);\n } catch (err) {\n setSecurityError(err instanceof Error ? err.message : \"Failed to fetch security data\");\n setSecurityData(null);\n }\n\n // Fetch diff to latest if not on latest\n if (!isSelectedLatest && latestRelease && onFetchSecurityDiff) {\n try {\n const diffResult = await onFetchSecurityDiff({\n installType: selectedInstallType,\n fromChannelSequence: selectedRelease.channelSequence,\n toChannelSequence: latestRelease.channelSequence\n });\n setDiffData(diffResult);\n } catch (err) {\n console.error(\"Failed to fetch security diff:\", err);\n setDiffData(null);\n }\n } else {\n setDiffData(null);\n }\n\n setIsLoadingScans(false);\n\n // Fetch SBOM\n if (onFetchSBOM) {\n try {\n const sbomResult = await onFetchSBOM({\n installType: selectedInstallType,\n channelSequence: selectedRelease.channelSequence\n });\n setSbomData(sbomResult);\n } catch (err) {\n setSbomError(err instanceof Error ? err.message : \"Failed to fetch SBOM\");\n setSbomData(null);\n }\n }\n setIsLoadingSbom(false);\n };\n\n fetchData();\n }, [selectedRelease, selectedInstallType, latestRelease, isSelectedLatest, onFetchSecurityInfo, onFetchSecurityDiff, onFetchSBOM]);\n\n // Install type options\n const installTypeOptions = useMemo(() => {\n const options: { value: string; label: string }[] = [];\n if (showLinux) options.push({ value: \"linux\", label: \"Linux\" });\n if (showHelm) options.push({ value: \"helm\", label: \"Helm\" });\n return options;\n }, [showLinux, showHelm]);\n\n // Release options with \"Latest\" badge for the first release\n const releaseOptions = useMemo(() => {\n return filteredReleases.map((r, index) => ({\n value: r.channelSequence.toString(),\n label: `Version ${r.versionLabel}`,\n badge: index === 0 ? \"Latest\" : undefined,\n sublabel: `Sequence ${r.channelSequence}${r.isRequired ? \" (required)\" : \"\"}`\n }));\n }, [filteredReleases]);\n\n // Calculate CVE totals\n const cveTotals = useMemo(() => {\n if (!securityData?.images) {\n return { critical: 0, high: 0, medium: 0, low: 0 };\n }\n return securityData.images.reduce(\n (acc, image) => {\n if (!image.security?.result) return acc;\n const r = image.security.result;\n return {\n critical: acc.critical + Object.keys(r.critical || {}).length,\n high: acc.high + Object.keys(r.high || {}).length,\n medium: acc.medium + Object.keys(r.medium || {}).length,\n low: acc.low + Object.keys(r.low || {}).length\n };\n },\n { critical: 0, high: 0, medium: 0, low: 0 }\n );\n }, [securityData]);\n\n // Calculate fixed CVE totals\n const fixedTotals = useMemo(() => {\n if (!diffData?.images) {\n return { critical: 0, high: 0, medium: 0, low: 0 };\n }\n return Object.values(diffData.images).reduce(\n (acc, diff) => {\n if (!diff.removed) return acc;\n return {\n critical: acc.critical + Object.keys(diff.removed.critical || {}).length,\n high: acc.high + Object.keys(diff.removed.high || {}).length,\n medium: acc.medium + Object.keys(diff.removed.medium || {}).length,\n low: acc.low + Object.keys(diff.removed.low || {}).length\n };\n },\n { critical: 0, high: 0, medium: 0, low: 0 }\n );\n }, [diffData]);\n\n // SBOM metadata (no parsing needed - comes pre-parsed from API)\n const sbomMetadata = useMemo(() => {\n return sbomData?.sboms?.unified || null;\n }, [sbomData]);\n\n // Download SBOM handler\n const handleDownloadSBOM = useCallback(async () => {\n if (!selectedRelease) return;\n if (!onDownloadSBOM) {\n console.error(\"Download SBOM handler not provided\");\n return;\n }\n \n try {\n const fileContent = await onDownloadSBOM({\n installType: selectedInstallType,\n channelSequence: selectedRelease.channelSequence\n });\n \n // Create a blob and download URL from the file content\n const blob = new Blob([fileContent], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n \n // Trigger download\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `sbom-report-${selectedRelease.versionLabel || \"unknown\"}.json`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n } catch (error) {\n console.error(\"Failed to download SBOM:\", error);\n }\n }, [selectedRelease, selectedInstallType, onDownloadSBOM]);\n\n // Check if we have any security data\n const hasSecurityData = securityData?.images?.some((img) => img.security);\n\n // Calculate active instances for the selected version\n const activeInstancesOnVersion = useMemo(() => {\n if (!selectedRelease?.versionLabel || !securityData?.activeInstancesByVersion) {\n return 0;\n }\n return securityData.activeInstancesByVersion[selectedRelease.versionLabel] || 0;\n }, [selectedRelease, securityData]);\n\n // Calculate total fixed CVEs if updating to latest\n const fixedCVEsToLatest = useMemo(() => {\n if (!diffData?.images) return 0;\n\n return Object.values(diffData.images).reduce((total, imageDiff) => {\n if (!imageDiff.removed) return total;\n return (\n total +\n Object.keys(imageDiff.removed.critical || {}).length +\n Object.keys(imageDiff.removed.high || {}).length +\n Object.keys(imageDiff.removed.medium || {}).length +\n Object.keys(imageDiff.removed.low || {}).length\n );\n }, 0);\n }, [diffData]);\n\n // Check if critical CVEs would be fixed by updating to latest\n const hasCriticalFixed = useMemo(() => {\n if (!diffData?.images) return false;\n\n return Object.values(diffData.images).some(\n (imageDiff) =>\n imageDiff.removed?.critical &&\n Object.keys(imageDiff.removed.critical).length > 0\n );\n }, [diffData]);\n\n return (\n <div className=\"space-y-6\">\n {/* Header */}\n <div>\n <h1 className=\"text-3xl font-bold text-gray-900\">Security Center</h1>\n <p className=\"text-gray-600\">\n Security information and compliance reports for each release\n </p>\n </div>\n\n {/* Dropdowns - flex layout with inline active instances text */}\n <div className=\"flex items-end gap-6\">\n {/* Install Type */}\n <div className=\"w-72\">\n <span className=\"mb-2 block text-sm font-medium text-gray-700\">\n Install Type\n </span>\n {availableInstallTypes.length > 1 ? (\n <Dropdown\n value={selectedInstallType}\n options={installTypeOptions}\n onChange={(v) => setSelectedInstallType(v as SecurityInstallType)}\n testId=\"install-type-dropdown\"\n />\n ) : (\n <div className=\"rounded-md border border-gray-200 bg-gray-50 px-4 py-2 text-sm font-semibold text-gray-900\">\n {installTypeOptions[0]?.label || \"Linux\"}\n </div>\n )}\n </div>\n\n {/* Release Version */}\n <div className=\"w-80\">\n <span className=\"mb-2 block text-sm font-medium text-gray-700\">\n Release Version\n </span>\n <Dropdown\n value={selectedSequence?.toString() || \"\"}\n options={releaseOptions}\n onChange={(v) => setSelectedSequence(parseInt(v, 10))}\n disabled={releaseOptions.length === 0}\n testId=\"release-dropdown\"\n />\n </div>\n\n {/* Update Available / Active Instances */}\n {!isSelectedLatest ? (\n <div className=\"flex flex-col gap-1 self-start pt-7\">\n <div className=\"flex items-center gap-2\">\n {/* Update button */}\n <a\n href=\"/update\"\n className=\"rounded px-3 py-1 text-xs text-white no-underline\"\n style={{\n backgroundColor: hasCriticalFixed ? \"#dc2626\" : (primaryColor || \"#2563eb\"),\n borderColor: hasCriticalFixed ? \"#dc2626\" : (primaryColor || \"#2563eb\"),\n }}\n >\n {hasCriticalFixed ? \"Critical update available\" : \"Update available\"}\n </a>\n {/* Fixed CVEs count */}\n {fixedCVEsToLatest > 0 && (\n <span className=\"text-xs font-medium text-gray-600\">\n {fixedCVEsToLatest} Fixed CVEs\n </span>\n )}\n </div>\n {/* Active instances on this version */}\n {activeInstancesOnVersion > 0 && (\n <span className=\"text-sm text-gray-600\">\n {activeInstancesOnVersion} active instance{activeInstancesOnVersion !== 1 ? 's' : ''} on this version.{' '}\n <a href=\"/update\" className=\"font-semibold text-blue-500 hover:underline\">\n See more.\n </a>\n </span>\n )}\n </div>\n ) : (\n /* Show active instances inline when on latest */\n activeInstancesOnVersion > 0 && (\n <div className=\"pb-2 text-sm text-gray-600\">\n {activeInstancesOnVersion} active instance{activeInstancesOnVersion !== 1 ? 's' : ''} on this version.{' '}\n <a href=\"/update\" className=\"font-semibold text-blue-500 hover:underline\">\n See more.\n </a>\n </div>\n )\n )}\n </div>\n\n {/* Cards Grid */}\n {(hasSecurityData || isLoadingScans || isLoadingSbom || securityError || sbomError) && (\n <div className=\"space-y-8\">\n {/* CVE Report Card */}\n <div className=\"rounded-lg border border-gray-200 bg-white\">\n <div className=\"flex items-center justify-between rounded-t-lg border-b border-gray-200 bg-gray-50 px-6 py-5\">\n <h2 className=\"text-lg font-medium text-gray-900\">CVE Report</h2>\n </div>\n\n {isLoadingScans ? (\n <div className=\"flex min-h-[200px] items-center justify-center p-8\">\n <SpinnerIcon className=\"h-8 w-8 text-gray-400\" />\n </div>\n ) : securityError ? (\n <div className=\"p-8 text-center\">\n <p className=\"py-8 text-pink-500\">Error loading security data: {securityError}</p>\n </div>\n ) : !hasSecurityData ? (\n <div className=\"p-8 text-center\">\n <p className=\"py-8 text-gray-500\">No security report available for this release</p>\n </div>\n ) : (\n <div className=\"p-8\">\n <p className=\"mb-6 text-gray-600\">\n Comprehensive vulnerability scanning using Trivy to identify and assess security\n risks in dependencies and container images.\n </p>\n\n {/* Severity Summary Table */}\n <div className=\"mb-6 overflow-x-auto rounded-md bg-gray-50 p-4\">\n <table className=\"w-full min-w-[400px] border-collapse text-sm\">\n <thead>\n <tr>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase text-gray-500\">\n Severity\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase text-gray-500\">\n Found\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase text-gray-500\">\n <span className=\"inline-flex items-center gap-1\">\n Fixed\n <Tooltip content=\"CVEs fixed compared to the previous release version\">\n <InfoIcon className=\"h-4 w-4 cursor-pointer text-blue-400\" />\n </Tooltip>\n </span>\n </th>\n </tr>\n </thead>\n <tbody>\n {([\"critical\", \"high\", \"medium\", \"low\"] as const).map((severity) => (\n <tr key={severity}>\n <td className=\"px-6 py-3 capitalize text-gray-700\">{severity}</td>\n <td className=\"px-6 py-3\">\n <span className={`font-medium ${getSeverityColor(severity)}`}>\n {cveTotals[severity]}\n </span>\n </td>\n <td className=\"px-6 py-3\">\n <FixedCount count={fixedTotals[severity]} hasDiffData={!!diffData} />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {/* Container Vulnerabilities */}\n <div>\n <div className=\"mb-3\">\n <h3 className=\"text-sm font-medium text-gray-900\">Container Vulnerabilities</h3>\n </div>\n <div className=\"rounded-lg border border-gray-200\">\n <table className=\"w-full\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500\">\n Name\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500\">\n Found\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500\">\n <span className=\"inline-flex items-center gap-1\">\n Fixed\n <Tooltip content=\"CVEs fixed compared to the previous release version\">\n <InfoIcon className=\"h-4 w-4 cursor-pointer text-blue-400\" />\n </Tooltip>\n </span>\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-200 bg-white\">\n {securityData?.images?.slice(0, 4).map((image, idx) => {\n const imageWithoutTag = image.image.split(\":\")[0] || image.image;\n const imageDiff = diffData?.images?.[imageWithoutTag];\n const fixedVulns = imageDiff?.removed;\n const totalFixed = fixedVulns\n ? Object.keys(fixedVulns.critical || {}).length +\n Object.keys(fixedVulns.high || {}).length +\n Object.keys(fixedVulns.medium || {}).length +\n Object.keys(fixedVulns.low || {}).length\n : undefined;\n\n return (\n <tr key={idx}>\n <td className=\"px-6 py-3\">\n <ImageName imageString={image.image} />\n </td>\n <td className=\"px-6 py-3\">\n <VulnerabilityBadges summary={image.security?.result} />\n </td>\n <td className=\"px-6 py-3\">\n <FixedCount count={totalFixed} hasDiffData={!!imageDiff} />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n {(securityData?.images?.length ?? 0) > 4 && (\n <div className=\"mt-2 text-right\">\n <button\n type=\"button\"\n onClick={() => setShowAllContainersModal(true)}\n className=\"text-sm font-medium text-blue-600 hover:underline\"\n >\n Show all containers\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* SBOM Card */}\n <div className=\"rounded-lg border border-gray-200 bg-white\">\n <div className=\"flex items-center justify-between rounded-t-lg border-b border-gray-200 bg-gray-50 px-6 py-5\">\n <h2 className=\"text-lg font-medium text-gray-900\">Software Bill of Materials</h2>\n {sbomMetadata && onDownloadSBOM && (\n <button\n type=\"button\"\n onClick={handleDownloadSBOM}\n style={{ backgroundColor: primaryColor, borderColor: primaryColor }}\n className=\"inline-flex items-center gap-2 rounded px-3 py-1.5 text-sm font-medium text-white hover:opacity-90\"\n >\n <DownloadIcon className=\"h-4 w-4\" />\n Download report\n </button>\n )}\n </div>\n\n {isLoadingSbom ? (\n <div className=\"flex min-h-[200px] items-center justify-center p-8\">\n <SpinnerIcon className=\"h-8 w-8 text-gray-400\" />\n </div>\n ) : sbomError ? (\n <div className=\"p-8 text-center\">\n <p className=\"py-8 text-pink-500\">Error loading SBOM data: {sbomError}</p>\n </div>\n ) : !sbomMetadata ? (\n <div className=\"p-8 text-center\">\n <p className=\"py-8 text-gray-500\">No SBOM available for this release</p>\n </div>\n ) : (\n <div className=\"p-8\">\n <p className=\"mb-6 text-gray-600\">\n Comprehensive SBOM in SPDX format providing detailed software component inventory\n and licensing information.\n </p>\n\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-4 rounded-md bg-gray-50 p-6 text-sm text-gray-600\">\n <div className=\"flex items-center justify-between\">\n <span>Name:</span>\n <span className=\"font-medium text-gray-900\">{sbomMetadata.name || \"Unknown\"}</span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span>SPDX Version:</span>\n <span className=\"font-medium text-gray-900\">\n {sbomMetadata.spdxVersion || \"Unknown\"}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span>Packages:</span>\n <span className=\"font-medium text-gray-900\">\n {sbomMetadata.packageCount ?? 0}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span>Files:</span>\n <span className=\"font-medium text-gray-900\">\n {sbomMetadata.fileCount ?? 0}\n </span>\n </div>\n {sbomMetadata.created && (\n <div className=\"flex items-center justify-between\">\n <span>Created:</span>\n <span className=\"font-medium text-gray-900\">\n {new Date(sbomMetadata.created).toLocaleDateString()}\n </span>\n </div>\n )}\n {sbomMetadata.creator && (\n <div className=\"flex items-center justify-between\">\n <span>Tool:</span>\n <span className=\"font-medium text-gray-900\">\n {sbomMetadata.creator.replace(\"Tool: \", \"\")}\n </span>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* No Data Message */}\n {!isLoadingScans && !isLoadingSbom && !hasSecurityData && !securityError && (\n <div className=\"flex w-full items-center justify-center pt-6 text-gray-600\">\n No security report available for this release\n </div>\n )}\n\n {/* All Containers Modal */}\n <Modal\n isOpen={showAllContainersModal}\n onClose={() => setShowAllContainersModal(false)}\n title={`Container Images (${securityData?.images?.length ?? 0})`}\n >\n <div className=\"max-h-[640px] space-y-4 overflow-auto px-6 pb-6\">\n {securityData?.images?.map((image, idx) => {\n const imageWithoutTag = image.image.split(\":\")[0] || image.image;\n const imageDiff = diffData?.images?.[imageWithoutTag];\n const fixedVulns = imageDiff?.removed;\n const totalFixed = fixedVulns\n ? Object.keys(fixedVulns.critical || {}).length +\n Object.keys(fixedVulns.high || {}).length +\n Object.keys(fixedVulns.medium || {}).length +\n Object.keys(fixedVulns.low || {}).length\n : undefined;\n const digest = image.security?.digest || image.sha;\n const lastScanned = image.security?.last_scanned_at;\n const hasDigest = digest && digest !== \"---\";\n\n return (\n <div key={idx} className=\"border-b border-gray-200 pb-4 last:border-b-0 last:pb-0\">\n {/* Image short name */}\n <h3 className=\"mb-1.5 text-sm font-semibold text-gray-900\">\n {getShortImageName(image.image)}\n </h3>\n\n {/* Full image path in gray box */}\n <div className=\"mb-2 rounded bg-gray-100 px-2.5 py-1.5\">\n <code className=\"text-xs text-gray-700\">{image.image}</code>\n </div>\n\n {/* Digest row */}\n <div className=\"mb-2 flex items-center justify-between text-xs\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-gray-500\">Digest:</span>\n {hasDigest ? (\n <>\n <code className=\"text-gray-700\">{digest}</code>\n <button\n type=\"button\"\n onClick={async () => {\n const success = await copyToClipboard(digest);\n if (success) {\n setCopiedDigest(digest);\n setTimeout(() => setCopiedDigest(null), 2000);\n }\n }}\n className=\"inline-flex items-center gap-1 text-blue-600 hover:text-blue-800\"\n >\n {copiedDigest === digest ? (\n <>\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n <span>Copied</span>\n </>\n ) : (\n <>\n <CopyIcon className=\"h-3.5 w-3.5\" />\n <span>Copy</span>\n </>\n )}\n </button>\n </>\n ) : (\n <span className=\"text-gray-400\">---</span>\n )}\n </div>\n <div className=\"text-gray-500\">\n Last Scanned: {formatLastScanned(lastScanned)}\n </div>\n </div>\n\n {/* Found and Fixed row */}\n <div className=\"flex items-center gap-4 text-xs\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-gray-500\">Found:</span>\n {image.security?.result ? (\n <VulnerabilityBadges summary={image.security.result} />\n ) : (\n <span className=\"text-gray-400\">Unavailable</span>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-gray-500\">Fixed:</span>\n <Tooltip content=\"CVEs fixed compared to the previous release version\">\n <InfoIcon className=\"h-3.5 w-3.5 cursor-pointer text-blue-400\" />\n </Tooltip>\n {imageDiff ? (\n totalFixed && totalFixed > 0 ? (\n <span className=\"font-medium text-green-600\">{totalFixed}</span>\n ) : (\n <span className=\"text-gray-400\">None</span>\n )\n ) : (\n <span className=\"text-gray-400\">Unavailable</span>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </Modal>\n </div>\n );\n}\n\nSecurityCard.displayName = \"SecurityCard\";\n\n"]}