@replicated/portal-components 0.0.2 → 0.0.4

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 (216) hide show
  1. package/components/metadata/registry.json +83 -2
  2. package/components/metadata/registry.md +27 -2
  3. package/dist/actions/index.d.mts +566 -3
  4. package/dist/actions/index.d.ts +566 -3
  5. package/dist/actions/index.js +1853 -12
  6. package/dist/actions/index.js.map +1 -1
  7. package/dist/airgap-instances.d.mts +26 -0
  8. package/dist/airgap-instances.d.ts +26 -0
  9. package/dist/airgap-instances.js +354 -0
  10. package/dist/airgap-instances.js.map +1 -0
  11. package/dist/error-page.d.mts +14 -0
  12. package/dist/error-page.d.ts +14 -0
  13. package/dist/error-page.js +153 -0
  14. package/dist/error-page.js.map +1 -0
  15. package/dist/error.d.mts +15 -0
  16. package/dist/error.d.ts +15 -0
  17. package/dist/error.js +144 -0
  18. package/dist/error.js.map +1 -0
  19. package/dist/esm/actions/index.js +1816 -13
  20. package/dist/esm/actions/index.js.map +1 -1
  21. package/dist/esm/airgap-instances.js +352 -0
  22. package/dist/esm/airgap-instances.js.map +1 -0
  23. package/dist/esm/error-page.js +151 -0
  24. package/dist/esm/error-page.js.map +1 -0
  25. package/dist/esm/error.js +142 -0
  26. package/dist/esm/error.js.map +1 -0
  27. package/dist/esm/helm-install-wizard.js +1007 -0
  28. package/dist/esm/helm-install-wizard.js.map +1 -0
  29. package/dist/esm/index.js +2232 -155
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/install-actions.js +746 -0
  32. package/dist/esm/install-actions.js.map +1 -0
  33. package/dist/esm/install-card.js +115 -0
  34. package/dist/esm/install-card.js.map +1 -0
  35. package/dist/esm/install-targets.js +48 -0
  36. package/dist/esm/install-targets.js.map +1 -0
  37. package/dist/esm/instance-card.js +197 -0
  38. package/dist/esm/instance-card.js.map +1 -0
  39. package/dist/esm/join-team.js +218 -0
  40. package/dist/esm/join-team.js.map +1 -0
  41. package/dist/esm/license-card.js +131 -0
  42. package/dist/esm/license-card.js.map +1 -0
  43. package/dist/esm/license-details.js +667 -0
  44. package/dist/esm/license-details.js.map +1 -0
  45. package/dist/esm/linux-install-wizard.js +1083 -0
  46. package/dist/esm/linux-install-wizard.js.map +1 -0
  47. package/dist/esm/login.js +261 -0
  48. package/dist/esm/login.js.map +1 -0
  49. package/dist/esm/online-instance-list.js +287 -0
  50. package/dist/esm/online-instance-list.js.map +1 -0
  51. package/dist/esm/pending-installations.js +235 -0
  52. package/dist/esm/pending-installations.js.map +1 -0
  53. package/dist/esm/release-history-panel.js +100 -0
  54. package/dist/esm/release-history-panel.js.map +1 -0
  55. package/dist/esm/release-notes-card.js +23 -0
  56. package/dist/esm/release-notes-card.js.map +1 -0
  57. package/dist/esm/security-card.js +700 -0
  58. package/dist/esm/security-card.js.map +1 -0
  59. package/dist/esm/support-bundle-collection-card.js +170 -0
  60. package/dist/esm/support-bundle-collection-card.js.map +1 -0
  61. package/dist/esm/support-bundles-card.js +306 -0
  62. package/dist/esm/support-bundles-card.js.map +1 -0
  63. package/dist/esm/support-card.js +305 -0
  64. package/dist/esm/support-card.js.map +1 -0
  65. package/dist/esm/team-selection.js +117 -0
  66. package/dist/esm/team-selection.js.map +1 -0
  67. package/dist/esm/team-settings-card.js +78 -0
  68. package/dist/esm/team-settings-card.js.map +1 -0
  69. package/dist/esm/team-settings.js +136 -0
  70. package/dist/esm/team-settings.js.map +1 -0
  71. package/dist/esm/top-nav-user-menu.js +173 -0
  72. package/dist/esm/top-nav-user-menu.js.map +1 -0
  73. package/dist/esm/top-nav.js +398 -0
  74. package/dist/esm/top-nav.js.map +1 -0
  75. package/dist/esm/update-layout.js +405 -0
  76. package/dist/esm/update-layout.js.map +1 -0
  77. package/dist/esm/updates-card.js +85 -0
  78. package/dist/esm/updates-card.js.map +1 -0
  79. package/dist/esm/upload-support-bundle-modal.js +143 -0
  80. package/dist/esm/upload-support-bundle-modal.js.map +1 -0
  81. package/dist/esm/user-settings-card.js +21 -0
  82. package/dist/esm/user-settings-card.js.map +1 -0
  83. package/dist/esm/user-settings.js +368 -0
  84. package/dist/esm/user-settings.js.map +1 -0
  85. package/dist/esm/utils/index.js +170 -0
  86. package/dist/esm/utils/index.js.map +1 -0
  87. package/dist/helm-install-wizard.d.mts +38 -0
  88. package/dist/helm-install-wizard.d.ts +38 -0
  89. package/dist/helm-install-wizard.js +1011 -0
  90. package/dist/helm-install-wizard.js.map +1 -0
  91. package/dist/index.d.mts +11 -27
  92. package/dist/index.d.ts +11 -27
  93. package/dist/index.js +2258 -154
  94. package/dist/index.js.map +1 -1
  95. package/dist/install-B19AaKF_.d.mts +233 -0
  96. package/dist/install-Bi1qJ8Bu.d.ts +233 -0
  97. package/dist/install-actions.d.mts +141 -0
  98. package/dist/install-actions.d.ts +141 -0
  99. package/dist/install-actions.js +765 -0
  100. package/dist/install-actions.js.map +1 -0
  101. package/dist/install-card.d.mts +15 -0
  102. package/dist/install-card.d.ts +15 -0
  103. package/dist/install-card.js +117 -0
  104. package/dist/install-card.js.map +1 -0
  105. package/dist/install-targets.d.mts +19 -0
  106. package/dist/install-targets.d.ts +19 -0
  107. package/dist/install-targets.js +50 -0
  108. package/dist/install-targets.js.map +1 -0
  109. package/dist/instance-card.d.mts +22 -0
  110. package/dist/instance-card.d.ts +22 -0
  111. package/dist/instance-card.js +199 -0
  112. package/dist/instance-card.js.map +1 -0
  113. package/dist/join-team.d.mts +30 -0
  114. package/dist/join-team.d.ts +30 -0
  115. package/dist/join-team.js +220 -0
  116. package/dist/join-team.js.map +1 -0
  117. package/dist/license-card.d.mts +15 -0
  118. package/dist/license-card.d.ts +15 -0
  119. package/dist/license-card.js +133 -0
  120. package/dist/license-card.js.map +1 -0
  121. package/dist/license-details.d.mts +10 -0
  122. package/dist/license-details.d.ts +10 -0
  123. package/dist/license-details.js +669 -0
  124. package/dist/license-details.js.map +1 -0
  125. package/dist/linux-install-wizard.d.mts +66 -0
  126. package/dist/linux-install-wizard.d.ts +66 -0
  127. package/dist/linux-install-wizard.js +1093 -0
  128. package/dist/linux-install-wizard.js.map +1 -0
  129. package/dist/login.d.mts +37 -0
  130. package/dist/login.d.ts +37 -0
  131. package/dist/login.js +263 -0
  132. package/dist/login.js.map +1 -0
  133. package/dist/online-instance-list.d.mts +22 -0
  134. package/dist/online-instance-list.d.ts +22 -0
  135. package/dist/online-instance-list.js +289 -0
  136. package/dist/online-instance-list.js.map +1 -0
  137. package/dist/pending-installations.d.mts +15 -0
  138. package/dist/pending-installations.d.ts +15 -0
  139. package/dist/pending-installations.js +237 -0
  140. package/dist/pending-installations.js.map +1 -0
  141. package/dist/release-history-panel.d.mts +22 -0
  142. package/dist/release-history-panel.d.ts +22 -0
  143. package/dist/release-history-panel.js +102 -0
  144. package/dist/release-history-panel.js.map +1 -0
  145. package/dist/release-notes-card.d.mts +13 -0
  146. package/dist/release-notes-card.d.ts +13 -0
  147. package/dist/release-notes-card.js +25 -0
  148. package/dist/release-notes-card.js.map +1 -0
  149. package/dist/security-card.d.mts +73 -0
  150. package/dist/security-card.d.ts +73 -0
  151. package/dist/security-card.js +702 -0
  152. package/dist/security-card.js.map +1 -0
  153. package/dist/styles.css +1877 -194
  154. package/dist/support-bundle-collection-card.d.mts +20 -0
  155. package/dist/support-bundle-collection-card.d.ts +20 -0
  156. package/dist/support-bundle-collection-card.js +172 -0
  157. package/dist/support-bundle-collection-card.js.map +1 -0
  158. package/dist/support-bundles-card.d.mts +19 -0
  159. package/dist/support-bundles-card.d.ts +19 -0
  160. package/dist/support-bundles-card.js +308 -0
  161. package/dist/support-bundles-card.js.map +1 -0
  162. package/dist/support-card.d.mts +8 -0
  163. package/dist/support-card.d.ts +8 -0
  164. package/dist/support-card.js +307 -0
  165. package/dist/support-card.js.map +1 -0
  166. package/dist/team-selection.d.mts +23 -0
  167. package/dist/team-selection.d.ts +23 -0
  168. package/dist/team-selection.js +119 -0
  169. package/dist/team-selection.js.map +1 -0
  170. package/dist/team-settings-card-Dq1d9b5c.d.mts +14 -0
  171. package/dist/team-settings-card-Dq1d9b5c.d.ts +14 -0
  172. package/dist/team-settings-card.d.mts +2 -0
  173. package/dist/team-settings-card.d.ts +2 -0
  174. package/dist/team-settings-card.js +80 -0
  175. package/dist/team-settings-card.js.map +1 -0
  176. package/dist/team-settings.d.mts +25 -0
  177. package/dist/team-settings.d.ts +25 -0
  178. package/dist/team-settings.js +138 -0
  179. package/dist/team-settings.js.map +1 -0
  180. package/dist/top-nav-0mb1K_H0.d.mts +32 -0
  181. package/dist/top-nav-0mb1K_H0.d.ts +32 -0
  182. package/dist/top-nav-user-menu.d.mts +18 -0
  183. package/dist/top-nav-user-menu.d.ts +18 -0
  184. package/dist/top-nav-user-menu.js +175 -0
  185. package/dist/top-nav-user-menu.js.map +1 -0
  186. package/dist/top-nav.d.mts +3 -0
  187. package/dist/top-nav.d.ts +3 -0
  188. package/dist/top-nav.js +400 -0
  189. package/dist/top-nav.js.map +1 -0
  190. package/dist/update-layout.d.mts +12 -0
  191. package/dist/update-layout.d.ts +12 -0
  192. package/dist/update-layout.js +407 -0
  193. package/dist/update-layout.js.map +1 -0
  194. package/dist/updates-card-BbubBrVR.d.mts +18 -0
  195. package/dist/updates-card-BbubBrVR.d.ts +18 -0
  196. package/dist/updates-card.d.mts +2 -0
  197. package/dist/updates-card.d.ts +2 -0
  198. package/dist/updates-card.js +87 -0
  199. package/dist/updates-card.js.map +1 -0
  200. package/dist/upload-support-bundle-modal.d.mts +19 -0
  201. package/dist/upload-support-bundle-modal.d.ts +19 -0
  202. package/dist/upload-support-bundle-modal.js +145 -0
  203. package/dist/upload-support-bundle-modal.js.map +1 -0
  204. package/dist/user-settings-card.d.mts +8 -0
  205. package/dist/user-settings-card.d.ts +8 -0
  206. package/dist/user-settings-card.js +23 -0
  207. package/dist/user-settings-card.js.map +1 -0
  208. package/dist/user-settings.d.mts +47 -0
  209. package/dist/user-settings.d.ts +47 -0
  210. package/dist/user-settings.js +370 -0
  211. package/dist/user-settings.js.map +1 -0
  212. package/dist/utils/index.d.mts +70 -0
  213. package/dist/utils/index.d.ts +70 -0
  214. package/dist/utils/index.js +177 -0
  215. package/dist/utils/index.js.map +1 -0
  216. package/package.json +163 -3
@@ -0,0 +1,20 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface SupportBundleCollectionCardProps {
4
+ /** App slug used in the Linux CLI command. Defaults to "APP_SLUG" placeholder. */
5
+ appSlug?: string;
6
+ /** Whether to show the Linux tab. Defaults to true. */
7
+ showLinux?: boolean;
8
+ /** Whether to show the Helm tab. Defaults to true. */
9
+ showHelm?: boolean;
10
+ /** Callback when the upload button is clicked. If not provided, button is hidden. */
11
+ onUploadClick?: () => void;
12
+ /** Primary brand color for buttons. Defaults to "#6366f1". */
13
+ primaryColor?: string;
14
+ }
15
+ declare const SupportBundleCollectionCard: {
16
+ ({ appSlug, showLinux, showHelm, onUploadClick, primaryColor }: SupportBundleCollectionCardProps): react_jsx_runtime.JSX.Element | null;
17
+ displayName: string;
18
+ };
19
+
20
+ export { SupportBundleCollectionCard };
@@ -0,0 +1,20 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface SupportBundleCollectionCardProps {
4
+ /** App slug used in the Linux CLI command. Defaults to "APP_SLUG" placeholder. */
5
+ appSlug?: string;
6
+ /** Whether to show the Linux tab. Defaults to true. */
7
+ showLinux?: boolean;
8
+ /** Whether to show the Helm tab. Defaults to true. */
9
+ showHelm?: boolean;
10
+ /** Callback when the upload button is clicked. If not provided, button is hidden. */
11
+ onUploadClick?: () => void;
12
+ /** Primary brand color for buttons. Defaults to "#6366f1". */
13
+ primaryColor?: string;
14
+ }
15
+ declare const SupportBundleCollectionCard: {
16
+ ({ appSlug, showLinux, showHelm, onUploadClick, primaryColor }: SupportBundleCollectionCardProps): react_jsx_runtime.JSX.Element | null;
17
+ displayName: string;
18
+ };
19
+
20
+ export { SupportBundleCollectionCard };
@@ -0,0 +1,172 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('react');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ /**
8
+ * Enterprise Portal Components
9
+ * This file is generated by tsup. Do not edit manually.
10
+ */
11
+ var getInstructionsByTab = (appSlug) => ({
12
+ Linux: {
13
+ title: "UI based collection",
14
+ description: "Log in to the Admin Console and go to the Troubleshoot tab. Click Analyze to generate a support bundle. After the analysis completes, you can download the bundle or send it directly to the vendor if enabled.",
15
+ cli: `sudo ./${appSlug} support-bundle`,
16
+ footer: "The support bundle will be saved as a .tar.gz file in your current directory. While sensitive information is automatically redacted, we recommend reviewing the contents before uploading for analysis."
17
+ },
18
+ Helm: {
19
+ title: "CLI based collection",
20
+ description: "For Helm installations, you'll need to use the kubectl support-bundle plugin to collect diagnostics.",
21
+ steps: [
22
+ {
23
+ title: "Step 1: Install the support-bundle plugin",
24
+ description: "First, install the kubectl support-bundle plugin using krew:",
25
+ command: "kubectl krew install support-bundle",
26
+ notes: [
27
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
28
+ "If you don't have krew installed, follow the instructions at",
29
+ " ",
30
+ /* @__PURE__ */ jsxRuntime.jsx(
31
+ "a",
32
+ {
33
+ href: "https://krew.sigs.k8s.io/docs/user-guide/setup/install/",
34
+ className: "text-indigo-500 hover:text-indigo-400",
35
+ target: "_blank",
36
+ rel: "noreferrer",
37
+ children: "https://krew.sigs.k8s.io/docs/user-guide/setup/install/"
38
+ }
39
+ )
40
+ ] })
41
+ ]
42
+ },
43
+ {
44
+ title: "Step 2: Generate a support bundle",
45
+ description: "Run the following command to collect diagnostics from your Kubernetes cluster:",
46
+ command: "kubectl support-bundle --load-cluster-specs",
47
+ notes: [
48
+ "This command will automatically detect and collect diagnostics from your Kubernetes cluster.",
49
+ "The support bundle will be saved as a .tar.gz file in your current directory. While sensitive information is automatically redacted, we recommend reviewing the contents before uploading for analysis."
50
+ ]
51
+ }
52
+ ]
53
+ }
54
+ });
55
+ var tabButtonBase = "w-full rounded-lg px-4 py-2 text-left text-sm font-medium transition";
56
+ var cliWrapperClass = "mt-4 rounded-lg bg-slate-900 px-4 py-3 font-mono text-sm text-slate-100 shadow-inner flex items-center justify-between";
57
+ var CommandBlock = ({ command }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cliWrapperClass, role: "group", "aria-label": "Copy support bundle command", children: [
58
+ /* @__PURE__ */ jsxRuntime.jsx("code", { children: command }),
59
+ /* @__PURE__ */ jsxRuntime.jsx(
60
+ "button",
61
+ {
62
+ type: "button",
63
+ className: "rounded-md bg-slate-800 px-2 py-1 text-xs font-semibold text-white transition hover:bg-slate-700",
64
+ onClick: async () => {
65
+ try {
66
+ await navigator.clipboard?.writeText(command);
67
+ } catch (error) {
68
+ console.error("[SupportBundleCollection] copy failed", error);
69
+ }
70
+ },
71
+ children: "Copy"
72
+ }
73
+ )
74
+ ] });
75
+ var SupportBundleCollectionCard = ({
76
+ appSlug = "APP_SLUG",
77
+ showLinux = true,
78
+ showHelm = true,
79
+ onUploadClick,
80
+ primaryColor = "#6366f1"
81
+ }) => {
82
+ const availableTabs = react.useMemo(() => {
83
+ const tabs = [];
84
+ if (showLinux) tabs.push("Linux");
85
+ if (showHelm) tabs.push("Helm");
86
+ return tabs;
87
+ }, [showLinux, showHelm]);
88
+ const [activeTab, setActiveTab] = react.useState(() => availableTabs[0] ?? "Linux");
89
+ const instructionsByTab = react.useMemo(() => getInstructionsByTab(appSlug), [appSlug]);
90
+ const activeInstructions = instructionsByTab[activeTab];
91
+ if (availableTabs.length === 0) {
92
+ return null;
93
+ }
94
+ const showTabs = availableTabs.length > 1;
95
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "rounded-3xl border border-gray-100 bg-white p-8 shadow-[0_18px_45px_rgba(17,24,39,0.08)]", children: [
96
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-wrap items-center justify-between gap-4", children: [
97
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
98
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-semibold text-gray-900", children: "Support Bundle Collection" }),
99
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-gray-500", children: showTabs ? "Choose your deployment method to view the recommended collection steps." : "Follow these steps to collect a support bundle." })
100
+ ] }),
101
+ onUploadClick && /* @__PURE__ */ jsxRuntime.jsxs(
102
+ "button",
103
+ {
104
+ type: "button",
105
+ onClick: onUploadClick,
106
+ className: "inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-semibold text-white shadow-sm transition hover:opacity-90",
107
+ style: { backgroundColor: primaryColor },
108
+ children: [
109
+ /* @__PURE__ */ jsxRuntime.jsxs(
110
+ "svg",
111
+ {
112
+ xmlns: "http://www.w3.org/2000/svg",
113
+ viewBox: "0 0 24 24",
114
+ fill: "none",
115
+ stroke: "currentColor",
116
+ strokeWidth: "1.5",
117
+ className: "h-4 w-4",
118
+ "aria-hidden": "true",
119
+ children: [
120
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 16V3" }),
121
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 7l4-4 4 4" }),
122
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 21h14" })
123
+ ]
124
+ }
125
+ ),
126
+ "Upload a support bundle"
127
+ ]
128
+ }
129
+ )
130
+ ] }),
131
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex flex-col gap-6 lg:flex-row", children: [
132
+ showTabs && /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex w-full flex-col gap-2 rounded-2xl border border-gray-200 bg-gray-50 p-4 lg:w-52", children: availableTabs.map((tab) => {
133
+ const isActive = tab === activeTab;
134
+ return /* @__PURE__ */ jsxRuntime.jsx(
135
+ "button",
136
+ {
137
+ type: "button",
138
+ onClick: () => setActiveTab(tab),
139
+ className: `${tabButtonBase} ${isActive ? "text-white shadow" : "text-gray-600 hover:bg-white"}`,
140
+ style: isActive ? { backgroundColor: primaryColor } : void 0,
141
+ children: tab
142
+ },
143
+ tab
144
+ );
145
+ }) }),
146
+ /* @__PURE__ */ jsxRuntime.jsx("article", { className: "flex-1 rounded-2xl border border-gray-200 bg-white p-6 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-5", children: [
147
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
148
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900", children: activeInstructions.title }),
149
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-gray-600", children: activeInstructions.description })
150
+ ] }),
151
+ activeInstructions.steps?.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: activeInstructions.steps.map((step) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
152
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold text-gray-900", children: step.title }),
153
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600", children: step.description }),
154
+ step.command ? /* @__PURE__ */ jsxRuntime.jsx(CommandBlock, { command: step.command }) : null,
155
+ step.notes?.map((note, index) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600", children: note }, `${step.title}-note-${index}`))
156
+ ] }, step.title)) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
157
+ activeInstructions.cli ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
158
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold text-gray-900", children: "CLI based collection" }),
159
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-gray-600", children: "To collect diagnostics about your environment, SSH onto a controller node and run the following command:" }),
160
+ /* @__PURE__ */ jsxRuntime.jsx(CommandBlock, { command: activeInstructions.cli })
161
+ ] }) : null,
162
+ activeInstructions.footer ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 leading-relaxed", children: activeInstructions.footer }) : null
163
+ ] })
164
+ ] }) })
165
+ ] })
166
+ ] });
167
+ };
168
+ SupportBundleCollectionCard.displayName = "SupportBundleCollectionCard";
169
+
170
+ exports.SupportBundleCollectionCard = SupportBundleCollectionCard;
171
+ //# sourceMappingURL=support-bundle-collection-card.js.map
172
+ //# sourceMappingURL=support-bundle-collection-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/support-bundle-collection-card.tsx"],"names":["jsxs","Fragment","jsx","useMemo","useState"],"mappings":";;;;;;;;;AAkCA,IAAM,oBAAA,GAAuB,CAAC,OAAA,MAAoD;AAAA,EAChF,KAAA,EAAO;AAAA,IACL,KAAA,EAAO,qBAAA;AAAA,IACP,WAAA,EACE,iNAAA;AAAA,IACF,GAAA,EAAK,UAAU,OAAO,CAAA,eAAA,CAAA;AAAA,IACtB,MAAA,EACE;AAAA,GACJ;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,sBAAA;AAAA,IACP,WAAA,EACE,sGAAA;AAAA,IACF,KAAA,EAAO;AAAA,MACL;AAAA,QACE,KAAA,EAAO,2CAAA;AAAA,QACP,WAAA,EAAa,8DAAA;AAAA,QACb,OAAA,EAAS,qCAAA;AAAA,QACT,KAAA,EAAO;AAAA,0BACLA,eAAA,CAAAC,mBAAA,EAAA,EAAE,QAAA,EAAA;AAAA,YAAA,8DAAA;AAAA,YAC6D,GAAA;AAAA,4BAC7DC,cAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,yDAAA;AAAA,gBACL,SAAA,EAAU,uCAAA;AAAA,gBACV,MAAA,EAAO,QAAA;AAAA,gBACP,GAAA,EAAI,YAAA;AAAA,gBACL,QAAA,EAAA;AAAA;AAAA;AAED,WAAA,EACF;AAAA;AACF,OACF;AAAA,MACA;AAAA,QACE,KAAA,EAAO,mCAAA;AAAA,QACP,WAAA,EAAa,gFAAA;AAAA,QACb,OAAA,EAAS,6CAAA;AAAA,QACT,KAAA,EAAO;AAAA,UACL,8FAAA;AAAA,UACA;AAAA;AACF;AACF;AACF;AAEJ,CAAA,CAAA;AAEA,IAAM,aAAA,GACJ,sEAAA;AAEF,IAAM,eAAA,GACJ,wHAAA;AAEF,IAAM,YAAA,GAAe,CAAC,EAAE,OAAA,EAAQ,qBAC9BF,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,eAAA,EAAiB,IAAA,EAAK,OAAA,EAAQ,YAAA,EAAW,6BAAA,EACvD,QAAA,EAAA;AAAA,kBAAAE,cAAA,CAAC,UAAM,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,kBACfA,cAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,SAAA,EAAU,kGAAA;AAAA,MACV,SAAS,YAAY;AACnB,QAAA,IAAI;AACF,UAAA,MAAM,SAAA,CAAU,SAAA,EAAW,SAAA,CAAU,OAAO,CAAA;AAAA,QAC9C,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAAA,QAC9D;AAAA,MACF,CAAA;AAAA,MACD,QAAA,EAAA;AAAA;AAAA;AAED,CAAA,EACF,CAAA;AAGK,IAAM,8BAA8B,CAAC;AAAA,EAC1C,OAAA,GAAU,UAAA;AAAA,EACV,SAAA,GAAY,IAAA;AAAA,EACZ,QAAA,GAAW,IAAA;AAAA,EACX,aAAA;AAAA,EACA,YAAA,GAAe;AACjB,CAAA,KAAwC;AAEtC,EAAA,MAAM,aAAA,GAAgBC,cAAQ,MAAM;AAClC,IAAA,MAAM,OAAmB,EAAC;AAC1B,IAAA,IAAI,SAAA,EAAW,IAAA,CAAK,IAAA,CAAK,OAAO,CAAA;AAChC,IAAA,IAAI,QAAA,EAAU,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,EAAG,CAAC,SAAA,EAAW,QAAQ,CAAC,CAAA;AAGxB,EAAA,MAAM,CAAC,WAAW,YAAY,CAAA,GAAIC,eAAmB,MAAM,aAAA,CAAc,CAAC,CAAA,IAAK,OAAO,CAAA;AAGtF,EAAA,MAAM,iBAAA,GAAoBD,cAAQ,MAAM,oBAAA,CAAqB,OAAO,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAChF,EAAA,MAAM,kBAAA,GAAqB,kBAAkB,SAAS,CAAA;AAGtD,EAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAA,GAAW,cAAc,MAAA,GAAS,CAAA;AAExC,EAAA,uBACEH,eAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,0FAAA,EACjB,QAAA,EAAA;AAAA,oBAAAA,eAAA,CAAC,QAAA,EAAA,EAAO,WAAU,mDAAA,EAChB,QAAA,EAAA;AAAA,sBAAAA,eAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAE,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qCAAA,EAAsC,QAAA,EAAA,2BAAA,EAAyB,CAAA;AAAA,uCAC5E,GAAA,EAAA,EAAE,SAAA,EAAU,4BAAA,EACV,QAAA,EAAA,QAAA,GACG,4EACA,iDAAA,EACN;AAAA,OAAA,EACF,CAAA;AAAA,MACC,aAAA,oBACCF,eAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAS,aAAA;AAAA,UACT,SAAA,EAAU,8HAAA;AAAA,UACV,KAAA,EAAO,EAAE,eAAA,EAAiB,YAAA,EAAa;AAAA,UAEvC,QAAA,EAAA;AAAA,4BAAAA,eAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAM,4BAAA;AAAA,gBACN,OAAA,EAAQ,WAAA;AAAA,gBACR,IAAA,EAAK,MAAA;AAAA,gBACL,MAAA,EAAO,cAAA;AAAA,gBACP,WAAA,EAAY,KAAA;AAAA,gBACZ,SAAA,EAAU,SAAA;AAAA,gBACV,aAAA,EAAY,MAAA;AAAA,gBAEZ,QAAA,EAAA;AAAA,kCAAAE,cAAA,CAAC,MAAA,EAAA,EAAK,GAAE,UAAA,EAAW,CAAA;AAAA,kCACnBA,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,cAAA,EAAe,CAAA;AAAA,kCACvBA,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,UAAA,EAAW;AAAA;AAAA;AAAA,aACrB;AAAA,YAAM;AAAA;AAAA;AAAA;AAER,KAAA,EAEJ,CAAA;AAAA,oBACAF,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sCAAA,EACZ,QAAA,EAAA;AAAA,MAAA,QAAA,mCACE,KAAA,EAAA,EAAI,SAAA,EAAU,wFACZ,QAAA,EAAA,aAAA,CAAc,GAAA,CAAI,CAAC,GAAA,KAAQ;AAC1B,QAAA,MAAM,WAAW,GAAA,KAAQ,SAAA;AACzB,QAAA,uBACEE,cAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,YAAA,CAAa,GAAG,CAAA;AAAA,YAC/B,WAAW,CAAA,EAAG,aAAa,CAAA,CAAA,EACzB,QAAA,GACI,sBACA,8BACN,CAAA,CAAA;AAAA,YACA,KAAA,EAAO,QAAA,GAAW,EAAE,eAAA,EAAiB,cAAa,GAAI,MAAA;AAAA,YAErD,QAAA,EAAA;AAAA,WAAA;AAAA,UAVI;AAAA,SAWP;AAAA,MAEJ,CAAC,CAAA,EACH,CAAA;AAAA,qCAED,SAAA,EAAA,EAAQ,SAAA,EAAU,oEACjB,QAAA,kBAAAF,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,WAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,eAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAE,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qCAAA,EACX,QAAA,EAAA,kBAAA,CAAmB,KAAA,EACtB,CAAA;AAAA,0BACAA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,4BAAA,EACV,6BAAmB,WAAA,EACtB;AAAA,SAAA,EACF,CAAA;AAAA,QACC,kBAAA,CAAmB,KAAA,EAAO,MAAA,mBACzBA,cAAA,CAAC,SAAI,SAAA,EAAU,WAAA,EACZ,QAAA,EAAA,kBAAA,CAAmB,KAAA,CAAM,IAAI,CAAC,IAAA,qBAC7BF,eAAA,CAAC,KAAA,EAAA,EAAqB,WAAU,WAAA,EAC9B,QAAA,EAAA;AAAA,0BAAAE,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qCAAA,EAAuC,QAAA,EAAA,IAAA,CAAK,KAAA,EAAM,CAAA;AAAA,0BAChEA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uBAAA,EAAyB,eAAK,WAAA,EAAY,CAAA;AAAA,UACtD,KAAK,OAAA,mBAAUA,cAAA,CAAC,gBAAa,OAAA,EAAS,IAAA,CAAK,SAAS,CAAA,GAAK,IAAA;AAAA,UACzD,KAAK,KAAA,EAAO,GAAA,CAAI,CAAC,IAAA,EAAM,0BACtBA,cAAA,CAAC,GAAA,EAAA,EAAsC,SAAA,EAAU,uBAAA,EAC9C,kBADK,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,MAAA,EAAS,KAAK,EAEnC,CACD;AAAA,SAAA,EAAA,EARO,IAAA,CAAK,KASf,CACD,CAAA,EACH,oBAEAF,eAAA,CAAAC,mBAAA,EAAA,EACG,QAAA,EAAA;AAAA,UAAA,kBAAA,CAAmB,GAAA,mCACjB,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAAC,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qCAAA,EAAsC,QAAA,EAAA,sBAAA,EAAoB,CAAA;AAAA,4BACxEA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,4BAAA,EAA6B,QAAA,EAAA,0GAAA,EAE1C,CAAA;AAAA,4BACAA,cAAA,CAAC,YAAA,EAAA,EAAa,OAAA,EAAS,kBAAA,CAAmB,GAAA,EAAK;AAAA,WAAA,EACjD,CAAA,GACE,IAAA;AAAA,UACH,kBAAA,CAAmB,yBAClBA,cAAA,CAAC,GAAA,EAAA,EAAE,WAAU,uCAAA,EACV,QAAA,EAAA,kBAAA,CAAmB,QACtB,CAAA,GACE;AAAA,SAAA,EACN;AAAA,OAAA,EAEJ,CAAA,EACF;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AAEA,2BAAA,CAA4B,WAAA,GAAc,6BAAA","file":"support-bundle-collection-card.js","sourcesContent":["\"use client\";\n\nimport { type ReactNode, useState, useMemo } from \"react\";\n\ntype Platform = \"Linux\" | \"Helm\";\n\ntype StepInstruction = {\n title: string;\n description: ReactNode;\n command?: string;\n notes?: ReactNode[];\n};\n\ntype Instruction = {\n title: string;\n description: ReactNode;\n cli?: string;\n footer?: ReactNode;\n steps?: StepInstruction[];\n};\n\ninterface SupportBundleCollectionCardProps {\n /** App slug used in the Linux CLI command. Defaults to \"APP_SLUG\" placeholder. */\n appSlug?: string;\n /** Whether to show the Linux tab. Defaults to true. */\n showLinux?: boolean;\n /** Whether to show the Helm tab. Defaults to true. */\n showHelm?: boolean;\n /** Callback when the upload button is clicked. If not provided, button is hidden. */\n onUploadClick?: () => void;\n /** Primary brand color for buttons. Defaults to \"#6366f1\". */\n primaryColor?: string;\n}\n\nconst getInstructionsByTab = (appSlug: string): Record<Platform, Instruction> => ({\n Linux: {\n title: \"UI based collection\",\n description:\n \"Log in to the Admin Console and go to the Troubleshoot tab. Click Analyze to generate a support bundle. After the analysis completes, you can download the bundle or send it directly to the vendor if enabled.\",\n cli: `sudo ./${appSlug} support-bundle`,\n footer:\n \"The support bundle will be saved as a .tar.gz file in your current directory. While sensitive information is automatically redacted, we recommend reviewing the contents before uploading for analysis.\"\n },\n Helm: {\n title: \"CLI based collection\",\n description:\n \"For Helm installations, you'll need to use the kubectl support-bundle plugin to collect diagnostics.\",\n steps: [\n {\n title: \"Step 1: Install the support-bundle plugin\",\n description: \"First, install the kubectl support-bundle plugin using krew:\",\n command: \"kubectl krew install support-bundle\",\n notes: [\n <>\n If you don't have krew installed, follow the instructions at{\" \"}\n <a\n href=\"https://krew.sigs.k8s.io/docs/user-guide/setup/install/\"\n className=\"text-indigo-500 hover:text-indigo-400\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n https://krew.sigs.k8s.io/docs/user-guide/setup/install/\n </a>\n </>\n ]\n },\n {\n title: \"Step 2: Generate a support bundle\",\n description: \"Run the following command to collect diagnostics from your Kubernetes cluster:\",\n command: \"kubectl support-bundle --load-cluster-specs\",\n notes: [\n \"This command will automatically detect and collect diagnostics from your Kubernetes cluster.\",\n \"The support bundle will be saved as a .tar.gz file in your current directory. While sensitive information is automatically redacted, we recommend reviewing the contents before uploading for analysis.\"\n ]\n }\n ]\n }\n});\n\nconst tabButtonBase =\n \"w-full rounded-lg px-4 py-2 text-left text-sm font-medium transition\";\n\nconst cliWrapperClass =\n \"mt-4 rounded-lg bg-slate-900 px-4 py-3 font-mono text-sm text-slate-100 shadow-inner flex items-center justify-between\";\n\nconst CommandBlock = ({ command }: { command: string }) => (\n <div className={cliWrapperClass} role=\"group\" aria-label=\"Copy support bundle command\">\n <code>{command}</code>\n <button\n type=\"button\"\n className=\"rounded-md bg-slate-800 px-2 py-1 text-xs font-semibold text-white transition hover:bg-slate-700\"\n onClick={async () => {\n try {\n await navigator.clipboard?.writeText(command);\n } catch (error) {\n console.error(\"[SupportBundleCollection] copy failed\", error);\n }\n }}\n >\n Copy\n </button>\n </div>\n);\n\nexport const SupportBundleCollectionCard = ({\n appSlug = \"APP_SLUG\",\n showLinux = true,\n showHelm = true,\n onUploadClick,\n primaryColor = \"#6366f1\"\n}: SupportBundleCollectionCardProps) => {\n // Build available tabs based on props\n const availableTabs = useMemo(() => {\n const tabs: Platform[] = [];\n if (showLinux) tabs.push(\"Linux\");\n if (showHelm) tabs.push(\"Helm\");\n return tabs;\n }, [showLinux, showHelm]);\n\n // Default to first available tab\n const [activeTab, setActiveTab] = useState<Platform>(() => availableTabs[0] ?? \"Linux\");\n\n // Get instructions with dynamic app slug\n const instructionsByTab = useMemo(() => getInstructionsByTab(appSlug), [appSlug]);\n const activeInstructions = instructionsByTab[activeTab];\n\n // If no tabs available, don't render\n if (availableTabs.length === 0) {\n return null;\n }\n\n const showTabs = availableTabs.length > 1;\n\n return (\n <section className=\"rounded-3xl border border-gray-100 bg-white p-8 shadow-[0_18px_45px_rgba(17,24,39,0.08)]\">\n <header className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n <h2 className=\"text-xl font-semibold text-gray-900\">Support Bundle Collection</h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n {showTabs\n ? \"Choose your deployment method to view the recommended collection steps.\"\n : \"Follow these steps to collect a support bundle.\"}\n </p>\n </div>\n {onUploadClick && (\n <button\n type=\"button\"\n onClick={onUploadClick}\n className=\"inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-semibold text-white shadow-sm transition hover:opacity-90\"\n style={{ backgroundColor: primaryColor }}\n >\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=\"h-4 w-4\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 16V3\" />\n <path d=\"M8 7l4-4 4 4\" />\n <path d=\"M5 21h14\" />\n </svg>\n Upload a support bundle\n </button>\n )}\n </header>\n <div className=\"mt-6 flex flex-col gap-6 lg:flex-row\">\n {showTabs && (\n <nav className=\"flex w-full flex-col gap-2 rounded-2xl border border-gray-200 bg-gray-50 p-4 lg:w-52\">\n {availableTabs.map((tab) => {\n const isActive = tab === activeTab;\n return (\n <button\n key={tab}\n type=\"button\"\n onClick={() => setActiveTab(tab)}\n className={`${tabButtonBase} ${\n isActive\n ? \"text-white shadow\"\n : \"text-gray-600 hover:bg-white\"\n }`}\n style={isActive ? { backgroundColor: primaryColor } : undefined}\n >\n {tab}\n </button>\n );\n })}\n </nav>\n )}\n <article className=\"flex-1 rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <div className=\"space-y-5\">\n <div>\n <h3 className=\"text-lg font-semibold text-gray-900\">\n {activeInstructions.title}\n </h3>\n <p className=\"mt-2 text-sm text-gray-600\">\n {activeInstructions.description}\n </p>\n </div>\n {activeInstructions.steps?.length ? (\n <div className=\"space-y-6\">\n {activeInstructions.steps.map((step) => (\n <div key={step.title} className=\"space-y-3\">\n <h4 className=\"text-sm font-semibold text-gray-900\">{step.title}</h4>\n <p className=\"text-sm text-gray-600\">{step.description}</p>\n {step.command ? <CommandBlock command={step.command} /> : null}\n {step.notes?.map((note, index) => (\n <p key={`${step.title}-note-${index}`} className=\"text-sm text-gray-600\">\n {note}\n </p>\n ))}\n </div>\n ))}\n </div>\n ) : (\n <>\n {activeInstructions.cli ? (\n <div>\n <h4 className=\"text-sm font-semibold text-gray-900\">CLI based collection</h4>\n <p className=\"mt-2 text-sm text-gray-600\">\n To collect diagnostics about your environment, SSH onto a controller node and run the following command:\n </p>\n <CommandBlock command={activeInstructions.cli} />\n </div>\n ) : null}\n {activeInstructions.footer ? (\n <p className=\"text-xs text-gray-500 leading-relaxed\">\n {activeInstructions.footer}\n </p>\n ) : null}\n </>\n )}\n </div>\n </article>\n </div>\n </section>\n );\n};\n\nSupportBundleCollectionCard.displayName = \"SupportBundleCollectionCard\";\n"]}
@@ -0,0 +1,19 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SupportBundleSummary } from './actions/index.mjs';
3
+
4
+ interface SupportBundlesCardProps {
5
+ totalCount: number;
6
+ bundles: SupportBundleSummary[];
7
+ /** Callback to download a bundle. Returns a signed URL. */
8
+ onDownload?: (bundleId: string) => Promise<string>;
9
+ /** Callback to delete a bundle. */
10
+ onDelete?: (bundleId: string) => Promise<void>;
11
+ /** Primary brand color. Defaults to "#6366f1". */
12
+ primaryColor?: string;
13
+ }
14
+ declare const SupportBundlesCard: {
15
+ ({ totalCount, bundles, onDownload, onDelete, primaryColor }: SupportBundlesCardProps): react_jsx_runtime.JSX.Element;
16
+ displayName: string;
17
+ };
18
+
19
+ export { SupportBundlesCard };
@@ -0,0 +1,19 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SupportBundleSummary } from './actions/index.js';
3
+
4
+ interface SupportBundlesCardProps {
5
+ totalCount: number;
6
+ bundles: SupportBundleSummary[];
7
+ /** Callback to download a bundle. Returns a signed URL. */
8
+ onDownload?: (bundleId: string) => Promise<string>;
9
+ /** Callback to delete a bundle. */
10
+ onDelete?: (bundleId: string) => Promise<void>;
11
+ /** Primary brand color. Defaults to "#6366f1". */
12
+ primaryColor?: string;
13
+ }
14
+ declare const SupportBundlesCard: {
15
+ ({ totalCount, bundles, onDownload, onDelete, primaryColor }: SupportBundlesCardProps): react_jsx_runtime.JSX.Element;
16
+ displayName: string;
17
+ };
18
+
19
+ export { SupportBundlesCard };
@@ -0,0 +1,308 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('react');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ /**
8
+ * Enterprise Portal Components
9
+ * This file is generated by tsup. Do not edit manually.
10
+ */
11
+
12
+ var formatBytes = (bytes, decimals = 1) => {
13
+ if (bytes === 0) return "0 Bytes";
14
+ const k = 1024;
15
+ const dm = decimals < 0 ? 0 : decimals;
16
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
17
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
18
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
19
+ };
20
+ var DownloadIcon = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs(
21
+ "svg",
22
+ {
23
+ xmlns: "http://www.w3.org/2000/svg",
24
+ viewBox: "0 0 24 24",
25
+ fill: "none",
26
+ stroke: "currentColor",
27
+ strokeWidth: "1.5",
28
+ className,
29
+ "aria-hidden": "true",
30
+ children: [
31
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 3v14" }),
32
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 13l4 4 4-4" }),
33
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 21h14" })
34
+ ]
35
+ }
36
+ );
37
+ var TrashIcon = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs(
38
+ "svg",
39
+ {
40
+ xmlns: "http://www.w3.org/2000/svg",
41
+ viewBox: "0 0 24 24",
42
+ fill: "none",
43
+ stroke: "currentColor",
44
+ strokeWidth: "1.5",
45
+ className,
46
+ "aria-hidden": "true",
47
+ children: [
48
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 6h18" }),
49
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }),
50
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }),
51
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "11", x2: "10", y2: "17" }),
52
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "14", y1: "11", x2: "14", y2: "17" })
53
+ ]
54
+ }
55
+ );
56
+ var CheckIcon = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs(
57
+ "svg",
58
+ {
59
+ xmlns: "http://www.w3.org/2000/svg",
60
+ viewBox: "0 0 24 24",
61
+ fill: "none",
62
+ stroke: "currentColor",
63
+ strokeWidth: "2",
64
+ className,
65
+ "aria-hidden": "true",
66
+ children: [
67
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
68
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 12l2 2 4-4" })
69
+ ]
70
+ }
71
+ );
72
+ var PendingIcon = ({ className }) => /* @__PURE__ */ jsxRuntime.jsx(
73
+ "svg",
74
+ {
75
+ xmlns: "http://www.w3.org/2000/svg",
76
+ viewBox: "0 0 24 24",
77
+ fill: "none",
78
+ stroke: "currentColor",
79
+ strokeWidth: "2",
80
+ className,
81
+ "aria-hidden": "true",
82
+ children: /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10", strokeDasharray: "4 2" })
83
+ }
84
+ );
85
+ var AlertTriangleIcon = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs(
86
+ "svg",
87
+ {
88
+ xmlns: "http://www.w3.org/2000/svg",
89
+ viewBox: "0 0 24 24",
90
+ fill: "none",
91
+ stroke: "currentColor",
92
+ strokeWidth: "2",
93
+ className,
94
+ "aria-hidden": "true",
95
+ children: [
96
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
97
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
98
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
99
+ ]
100
+ }
101
+ );
102
+ var SupportBundlesCard = ({
103
+ totalCount,
104
+ bundles,
105
+ onDownload,
106
+ onDelete,
107
+ primaryColor = "#6366f1"
108
+ }) => {
109
+ const [downloadingId, setDownloadingId] = react.useState(null);
110
+ const [deletingId, setDeletingId] = react.useState(null);
111
+ const [bundleToDelete, setBundleToDelete] = react.useState(null);
112
+ const [error, setError] = react.useState(null);
113
+ const handleDownload = react.useCallback(async (bundleId) => {
114
+ if (!onDownload) return;
115
+ setError(null);
116
+ setDownloadingId(bundleId);
117
+ try {
118
+ const signedUrl = await onDownload(bundleId);
119
+ const link = document.createElement("a");
120
+ link.href = signedUrl;
121
+ link.setAttribute("download", "");
122
+ document.body.appendChild(link);
123
+ link.click();
124
+ document.body.removeChild(link);
125
+ } catch (err) {
126
+ setError(err instanceof Error ? err.message : "Failed to download bundle");
127
+ } finally {
128
+ setDownloadingId(null);
129
+ }
130
+ }, [onDownload]);
131
+ const handleDeleteClick = react.useCallback((bundle) => {
132
+ setBundleToDelete(bundle);
133
+ }, []);
134
+ const handleDeleteConfirm = react.useCallback(async () => {
135
+ if (!onDelete || !bundleToDelete) return;
136
+ setError(null);
137
+ setDeletingId(bundleToDelete.id);
138
+ try {
139
+ await onDelete(bundleToDelete.id);
140
+ setBundleToDelete(null);
141
+ } catch (err) {
142
+ setError(err instanceof Error ? err.message : "Failed to delete bundle");
143
+ setBundleToDelete(null);
144
+ } finally {
145
+ setDeletingId(null);
146
+ }
147
+ }, [onDelete, bundleToDelete]);
148
+ const handleDeleteCancel = react.useCallback(() => {
149
+ setBundleToDelete(null);
150
+ }, []);
151
+ const isActionDisabled = downloadingId !== null || deletingId !== null;
152
+ const renderIssues = (insights) => {
153
+ const errors = insights?.filter((i) => i.level === "error")?.length ?? 0;
154
+ const warnings = insights?.filter((i) => i.level === "warn")?.length ?? 0;
155
+ if (!errors && !warnings) {
156
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400", children: "No issues found" });
157
+ }
158
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
159
+ errors > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-red-600", children: [
160
+ /* @__PURE__ */ jsxRuntime.jsx(AlertTriangleIcon, { className: "h-4 w-4" }),
161
+ errors,
162
+ " ",
163
+ errors === 1 ? "error" : "errors"
164
+ ] }),
165
+ warnings > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-yellow-600", children: [
166
+ /* @__PURE__ */ jsxRuntime.jsx(AlertTriangleIcon, { className: "h-4 w-4" }),
167
+ warnings,
168
+ " ",
169
+ warnings === 1 ? "warning" : "warnings"
170
+ ] })
171
+ ] });
172
+ };
173
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
174
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "rounded-3xl border border-gray-100 bg-white p-8 shadow-[0_18px_45px_rgba(17,24,39,0.08)]", children: [
175
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex items-center justify-between", children: [
176
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-semibold text-gray-900", children: "Support Bundles" }),
177
+ totalCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-500", children: [
178
+ totalCount,
179
+ " total"
180
+ ] })
181
+ ] }),
182
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700", children: error }),
183
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: bundles.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "rounded-2xl border border-dashed border-gray-200 bg-gray-50 px-6 py-10 text-center text-sm text-gray-500", children: "No support bundles have been uploaded yet." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
184
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
185
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Instance" }),
186
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Date Collected" }),
187
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Status" }),
188
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Issues" }),
189
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500", children: "Size" }),
190
+ (onDownload || onDelete) && /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "relative px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Actions" }) })
191
+ ] }) }),
192
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-gray-200 bg-white", children: bundles.map((bundle) => {
193
+ const isDownloading = downloadingId === bundle.id;
194
+ const isDeleting = deletingId === bundle.id;
195
+ const status = bundle.status ?? "uploaded";
196
+ const isUploaded = status === "uploaded";
197
+ return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
198
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "whitespace-nowrap px-4 py-3 text-sm text-gray-900", children: (bundle.instanceId || bundle.id).slice(0, 7) }),
199
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "whitespace-nowrap px-4 py-3 text-sm text-gray-500", children: bundle.createdAt ? new Date(bundle.createdAt).toLocaleString() : "Unknown" }),
200
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "whitespace-nowrap px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
201
+ "span",
202
+ {
203
+ className: `inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium ${isUploaded ? "bg-green-50 text-green-700" : "bg-yellow-50 text-yellow-700"}`,
204
+ children: [
205
+ isUploaded ? /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "h-3 w-3" }) : /* @__PURE__ */ jsxRuntime.jsx(PendingIcon, { className: "h-3 w-3" }),
206
+ status.charAt(0).toUpperCase() + status.slice(1)
207
+ ]
208
+ }
209
+ ) }),
210
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "whitespace-nowrap px-4 py-3 text-sm", children: renderIssues(bundle.insights) }),
211
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "whitespace-nowrap px-4 py-3 text-sm text-gray-500", children: bundle.size ? formatBytes(bundle.size) : "\u2014" }),
212
+ (onDownload || onDelete) && /* @__PURE__ */ jsxRuntime.jsx("td", { className: "whitespace-nowrap px-4 py-3 text-right text-sm font-medium", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-3", children: [
213
+ onDownload && /* @__PURE__ */ jsxRuntime.jsxs(
214
+ "button",
215
+ {
216
+ type: "button",
217
+ onClick: () => handleDownload(bundle.id),
218
+ disabled: isActionDisabled,
219
+ className: "inline-flex items-center gap-1 text-gray-600 hover:text-gray-900 disabled:opacity-50",
220
+ children: [
221
+ /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, { className: "h-4 w-4" }),
222
+ isDownloading ? "Downloading..." : "Download"
223
+ ]
224
+ }
225
+ ),
226
+ onDelete && /* @__PURE__ */ jsxRuntime.jsxs(
227
+ "button",
228
+ {
229
+ type: "button",
230
+ onClick: () => handleDeleteClick(bundle),
231
+ disabled: isActionDisabled,
232
+ className: "inline-flex items-center gap-1 text-red-600 hover:text-red-700 disabled:opacity-50",
233
+ children: [
234
+ /* @__PURE__ */ jsxRuntime.jsx(TrashIcon, { className: "h-4 w-4" }),
235
+ isDeleting ? "Deleting..." : "Delete"
236
+ ]
237
+ }
238
+ )
239
+ ] }) })
240
+ ] }, bundle.id);
241
+ }) })
242
+ ] }) }) })
243
+ ] }),
244
+ bundleToDelete && /* @__PURE__ */ jsxRuntime.jsx(
245
+ "div",
246
+ {
247
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50",
248
+ role: "dialog",
249
+ "aria-modal": "true",
250
+ "aria-labelledby": "delete-modal-title",
251
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-md rounded-2xl bg-white p-6 shadow-xl", children: [
252
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { id: "delete-modal-title", className: "text-lg font-semibold text-gray-900", children: "Confirm Deletion" }),
253
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-gray-600", children: "Are you sure you want to delete this support bundle? This action cannot be undone." }),
254
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 rounded-lg bg-gray-50 p-3 text-sm text-gray-700", children: [
255
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1", children: [
256
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Instance ID:" }),
257
+ " ",
258
+ (bundleToDelete.instanceId || bundleToDelete.id).slice(0, 7)
259
+ ] }),
260
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1", children: [
261
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Date Collected:" }),
262
+ " ",
263
+ bundleToDelete.createdAt ? new Date(bundleToDelete.createdAt).toLocaleString() : "Unknown"
264
+ ] }),
265
+ bundleToDelete.size && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1", children: [
266
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Size:" }),
267
+ " ",
268
+ formatBytes(bundleToDelete.size)
269
+ ] }),
270
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
271
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Status:" }),
272
+ " ",
273
+ (bundleToDelete.status ?? "uploaded").charAt(0).toUpperCase() + (bundleToDelete.status ?? "uploaded").slice(1)
274
+ ] })
275
+ ] }),
276
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex justify-end gap-3", children: [
277
+ /* @__PURE__ */ jsxRuntime.jsx(
278
+ "button",
279
+ {
280
+ type: "button",
281
+ onClick: handleDeleteCancel,
282
+ disabled: deletingId !== null,
283
+ className: "rounded-lg bg-gray-100 px-4 py-2 text-sm font-medium text-gray-700 transition hover:bg-gray-200 disabled:opacity-50",
284
+ children: "Cancel"
285
+ }
286
+ ),
287
+ /* @__PURE__ */ jsxRuntime.jsx(
288
+ "button",
289
+ {
290
+ type: "button",
291
+ onClick: handleDeleteConfirm,
292
+ disabled: deletingId !== null,
293
+ className: "rounded-lg px-4 py-2 text-sm font-medium text-white transition hover:opacity-90 disabled:opacity-50",
294
+ style: { backgroundColor: primaryColor },
295
+ children: deletingId !== null ? "Deleting..." : "Delete"
296
+ }
297
+ )
298
+ ] })
299
+ ] })
300
+ }
301
+ )
302
+ ] });
303
+ };
304
+ SupportBundlesCard.displayName = "SupportBundlesCard";
305
+
306
+ exports.SupportBundlesCard = SupportBundlesCard;
307
+ //# sourceMappingURL=support-bundles-card.js.map
308
+ //# sourceMappingURL=support-bundles-card.js.map