@replicated/portal-components 0.0.13 → 0.0.15

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 (37) hide show
  1. package/components/metadata/registry.json +2 -2
  2. package/components/metadata/registry.md +2 -2
  3. package/dist/actions/index.d.mts +20 -16
  4. package/dist/actions/index.d.ts +20 -16
  5. package/dist/actions/index.js +31 -0
  6. package/dist/actions/index.js.map +1 -1
  7. package/dist/esm/actions/index.js +31 -1
  8. package/dist/esm/actions/index.js.map +1 -1
  9. package/dist/esm/helm-install-wizard.js.map +1 -1
  10. package/dist/esm/index.js +32 -2
  11. package/dist/esm/index.js.map +1 -1
  12. package/dist/esm/install-actions.js.map +1 -1
  13. package/dist/esm/license-details.js.map +1 -1
  14. package/dist/esm/linux-install-wizard.js.map +1 -1
  15. package/dist/esm/security-card.js +38 -30
  16. package/dist/esm/security-card.js.map +1 -1
  17. package/dist/esm/support-card.js.map +1 -1
  18. package/dist/esm/top-nav.js.map +1 -1
  19. package/dist/esm/update-layout.js.map +1 -1
  20. package/dist/esm/utils/index.js.map +1 -1
  21. package/dist/helm-install-wizard.js.map +1 -1
  22. package/dist/index.d.mts +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +32 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/install-actions.js.map +1 -1
  27. package/dist/license-details.js.map +1 -1
  28. package/dist/linux-install-wizard.js.map +1 -1
  29. package/dist/security-card.d.mts +10 -5
  30. package/dist/security-card.d.ts +10 -5
  31. package/dist/security-card.js +38 -30
  32. package/dist/security-card.js.map +1 -1
  33. package/dist/support-card.js.map +1 -1
  34. package/dist/top-nav.js.map +1 -1
  35. package/dist/update-layout.js.map +1 -1
  36. package/dist/utils/index.js.map +1 -1
  37. package/package.json +1 -1
@@ -302,7 +302,8 @@ function SecurityCard({
302
302
  initialData,
303
303
  onFetchSecurityInfo,
304
304
  onFetchSecurityDiff,
305
- onFetchSBOM
305
+ onFetchSBOM,
306
+ onDownloadSBOM
306
307
  }) {
307
308
  const availableInstallTypes = useMemo(() => {
308
309
  const types = [];
@@ -421,7 +422,7 @@ function SecurityCard({
421
422
  setIsLoadingSbom(false);
422
423
  };
423
424
  fetchData();
424
- }, [selectedRelease, selectedInstallType, previousRelease, onFetchSecurityInfo, onFetchSecurityDiff, onFetchSBOM, initialData]);
425
+ }, [selectedRelease, selectedInstallType, previousRelease, onFetchSecurityInfo, onFetchSecurityDiff, onFetchSBOM]);
425
426
  const installTypeOptions = useMemo(() => {
426
427
  const options = [];
427
428
  if (showLinux) options.push({ value: "linux", label: "Linux" });
@@ -470,26 +471,33 @@ function SecurityCard({
470
471
  { critical: 0, high: 0, medium: 0, low: 0 }
471
472
  );
472
473
  }, [diffData]);
473
- const parsedSbom = useMemo(() => {
474
- if (!sbomData?.sboms?.unified?.sbom) return null;
474
+ const sbomMetadata = useMemo(() => {
475
+ return sbomData?.sboms?.unified || null;
476
+ }, [sbomData]);
477
+ const handleDownloadSBOM = useCallback(async () => {
478
+ if (!selectedRelease) return;
479
+ if (!onDownloadSBOM) {
480
+ console.error("Download SBOM handler not provided");
481
+ return;
482
+ }
475
483
  try {
476
- return JSON.parse(sbomData.sboms.unified.sbom);
477
- } catch {
478
- return null;
484
+ const fileContent = await onDownloadSBOM({
485
+ installType: selectedInstallType,
486
+ channelSequence: selectedRelease.channelSequence
487
+ });
488
+ const blob = new Blob([fileContent], { type: "application/json" });
489
+ const url = URL.createObjectURL(blob);
490
+ const a = document.createElement("a");
491
+ a.href = url;
492
+ a.download = `sbom-report-${selectedRelease.versionLabel || "unknown"}.json`;
493
+ document.body.appendChild(a);
494
+ a.click();
495
+ document.body.removeChild(a);
496
+ URL.revokeObjectURL(url);
497
+ } catch (error) {
498
+ console.error("Failed to download SBOM:", error);
479
499
  }
480
- }, [sbomData]);
481
- const handleDownloadSBOM = useCallback(() => {
482
- if (!sbomData?.sboms?.unified?.sbom) return;
483
- const blob = new Blob([sbomData.sboms.unified.sbom], { type: "application/json" });
484
- const url = URL.createObjectURL(blob);
485
- const a = document.createElement("a");
486
- a.href = url;
487
- a.download = `sbom-report-${selectedRelease?.versionLabel || "unknown"}.json`;
488
- document.body.appendChild(a);
489
- a.click();
490
- document.body.removeChild(a);
491
- URL.revokeObjectURL(url);
492
- }, [sbomData, selectedRelease]);
500
+ }, [selectedRelease, selectedInstallType, onDownloadSBOM]);
493
501
  const hasSecurityData = securityData?.images?.some((img) => img.security);
494
502
  return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
495
503
  /* @__PURE__ */ jsxs("div", { children: [
@@ -584,7 +592,7 @@ function SecurityCard({
584
592
  /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-gray-200 bg-white", children: [
585
593
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 bg-gray-50 px-6 py-5", children: [
586
594
  /* @__PURE__ */ jsx("h2", { className: "text-lg font-medium text-gray-900", children: "Software Bill of Materials" }),
587
- parsedSbom && /* @__PURE__ */ jsxs(
595
+ sbomMetadata && onDownloadSBOM && /* @__PURE__ */ jsxs(
588
596
  "button",
589
597
  {
590
598
  type: "button",
@@ -601,32 +609,32 @@ function SecurityCard({
601
609
  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: [
602
610
  "Error loading SBOM data: ",
603
611
  sbomError
604
- ] }) }) : !parsedSbom ? /* @__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: [
612
+ ] }) }) : !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: [
605
613
  /* @__PURE__ */ jsx("p", { className: "mb-6 text-gray-600", children: "Comprehensive SBOM in SPDX format providing detailed software component inventory and licensing information." }),
606
614
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4 rounded-md bg-gray-50 p-4 text-sm text-gray-600", children: [
607
615
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
608
616
  /* @__PURE__ */ jsx("span", { children: "Name:" }),
609
- /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: parsedSbom.name || "Unknown" })
617
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: sbomMetadata.name || "Unknown" })
610
618
  ] }),
611
619
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
612
620
  /* @__PURE__ */ jsx("span", { children: "SPDX Version:" }),
613
- /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: parsedSbom.spdxVersion || "Unknown" })
621
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: sbomMetadata.spdxVersion || "Unknown" })
614
622
  ] }),
615
623
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
616
624
  /* @__PURE__ */ jsx("span", { children: "Packages:" }),
617
- /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: parsedSbom.packages?.length ?? 0 })
625
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: sbomMetadata.packageCount ?? 0 })
618
626
  ] }),
619
627
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
620
628
  /* @__PURE__ */ jsx("span", { children: "Files:" }),
621
- /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: parsedSbom.files?.length ?? 0 })
629
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: sbomMetadata.fileCount ?? 0 })
622
630
  ] }),
623
- parsedSbom.creationInfo?.created && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
631
+ sbomMetadata.created && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
624
632
  /* @__PURE__ */ jsx("span", { children: "Created:" }),
625
- /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: new Date(parsedSbom.creationInfo.created).toLocaleDateString() })
633
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: new Date(sbomMetadata.created).toLocaleDateString() })
626
634
  ] }),
627
- parsedSbom.creationInfo?.creators?.[0] && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
635
+ sbomMetadata.creator && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
628
636
  /* @__PURE__ */ jsx("span", { children: "Tool:" }),
629
- /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: parsedSbom.creationInfo.creators[0].replace("Tool: ", "") })
637
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: sbomMetadata.creator.replace("Tool: ", "") })
630
638
  ] })
631
639
  ] })
632
640
  ] })
@@ -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 UnifiedSbom,\n SpdxDocument\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[] };\n /** CVE diff between releases */\n securityDiff?: { images: Record<string, SecurityInfoDiff> };\n /** SBOM data */\n sbom?: { sboms: { unified?: UnifiedSbom } };\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[] }>;\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?: UnifiedSbom } }>;\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 }[];\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?.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 <span className=\"font-semibold text-gray-900\">{option.label}</span>\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}: 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[] } | 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?: UnifiedSbom } } | 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 const previousRelease = useMemo(() => {\n if (!selectedRelease) return null;\n const idx = filteredReleases.findIndex(\n (r) => r.channelSequence === selectedRelease.channelSequence\n );\n if (idx === -1 || idx >= filteredReleases.length - 1) return null;\n return filteredReleases[idx + 1];\n }, [filteredReleases, selectedRelease]);\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 if previous release exists\n if (previousRelease && onFetchSecurityDiff) {\n try {\n const diffResult = await onFetchSecurityDiff({\n installType: selectedInstallType,\n fromChannelSequence: previousRelease.channelSequence,\n toChannelSequence: selectedRelease.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, previousRelease, onFetchSecurityInfo, onFetchSecurityDiff, onFetchSBOM, initialData]);\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\n const releaseOptions = useMemo(() => {\n return filteredReleases.map((r) => ({\n value: r.channelSequence.toString(),\n label: `Version ${r.versionLabel}`,\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 // Parse SBOM\n const parsedSbom = useMemo((): SpdxDocument | null => {\n if (!sbomData?.sboms?.unified?.sbom) return null;\n try {\n return JSON.parse(sbomData.sboms.unified.sbom) as SpdxDocument;\n } catch {\n return null;\n }\n }, [sbomData]);\n\n // Download SBOM handler\n const handleDownloadSBOM = useCallback(() => {\n if (!sbomData?.sboms?.unified?.sbom) return;\n const blob = new Blob([sbomData.sboms.unified.sbom], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\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 }, [sbomData, selectedRelease]);\n\n // Check if we have any security data\n const hasSecurityData = securityData?.images?.some((img) => img.security);\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 - grid layout to align with cards below */}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n {/* Install Type - aligns with CVE Report */}\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 - aligns with SBOM */}\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 </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 {parsedSbom && (\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 ) : !parsedSbom ? (\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\">{parsedSbom.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 {parsedSbom.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 {parsedSbom.packages?.length ?? 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 {parsedSbom.files?.length ?? 0}\n </span>\n </div>\n {parsedSbom.creationInfo?.created && (\n <div className=\"flex items-center justify-between\">\n <span>Created:</span>\n <span className=\"font-medium text-gray-900\">\n {new Date(parsedSbom.creationInfo.created).toLocaleDateString()}\n </span>\n </div>\n )}\n {parsedSbom.creationInfo?.creators?.[0] && (\n <div className=\"flex items-center justify-between\">\n <span>Tool:</span>\n <span className=\"font-medium text-gray-900\">\n {parsedSbom.creationInfo.creators[0].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/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[] };\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[] }>;\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 }[];\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?.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 <span className=\"font-semibold text-gray-900\">{option.label}</span>\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[] } | 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 const previousRelease = useMemo(() => {\n if (!selectedRelease) return null;\n const idx = filteredReleases.findIndex(\n (r) => r.channelSequence === selectedRelease.channelSequence\n );\n if (idx === -1 || idx >= filteredReleases.length - 1) return null;\n return filteredReleases[idx + 1];\n }, [filteredReleases, selectedRelease]);\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 if previous release exists\n if (previousRelease && onFetchSecurityDiff) {\n try {\n const diffResult = await onFetchSecurityDiff({\n installType: selectedInstallType,\n fromChannelSequence: previousRelease.channelSequence,\n toChannelSequence: selectedRelease.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, previousRelease, 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\n const releaseOptions = useMemo(() => {\n return filteredReleases.map((r) => ({\n value: r.channelSequence.toString(),\n label: `Version ${r.versionLabel}`,\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 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 - grid layout to align with cards below */}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n {/* Install Type - aligns with CVE Report */}\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 - aligns with SBOM */}\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 </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"]}