@replicated/portal-components 0.0.19 → 0.0.21

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 (244) hide show
  1. package/components/metadata/registry.json +2 -2
  2. package/components/metadata/registry.md +2 -2
  3. package/dist/actions/change-team.js +66 -7
  4. package/dist/actions/change-team.js.map +1 -1
  5. package/dist/actions/index.d.mts +3 -1
  6. package/dist/actions/index.d.ts +3 -1
  7. package/dist/actions/index.js +182 -465
  8. package/dist/actions/index.js.map +1 -1
  9. package/dist/actions/install-actions.d.mts +3 -1
  10. package/dist/actions/install-actions.d.ts +3 -1
  11. package/dist/actions/install-actions.js +58 -5
  12. package/dist/actions/install-actions.js.map +1 -1
  13. package/dist/actions/service-account.d.mts +3 -1
  14. package/dist/actions/service-account.d.ts +3 -1
  15. package/dist/actions/service-account.js +58 -5
  16. package/dist/actions/service-account.js.map +1 -1
  17. package/dist/actions/support-bundles.d.mts +3 -1
  18. package/dist/actions/support-bundles.d.ts +3 -1
  19. package/dist/actions/support-bundles.js +58 -5
  20. package/dist/actions/support-bundles.js.map +1 -1
  21. package/dist/actions/team-settings.d.mts +3 -1
  22. package/dist/actions/team-settings.d.ts +3 -1
  23. package/dist/actions/team-settings.js +91 -27
  24. package/dist/actions/team-settings.js.map +1 -1
  25. package/dist/actions/trial-signup.d.mts +24 -0
  26. package/dist/actions/trial-signup.d.ts +24 -0
  27. package/dist/actions/trial-signup.js +482 -0
  28. package/dist/actions/trial-signup.js.map +1 -0
  29. package/dist/actions/user-settings.d.mts +3 -1
  30. package/dist/actions/user-settings.d.ts +3 -1
  31. package/dist/actions/user-settings.js +58 -5
  32. package/dist/actions/user-settings.js.map +1 -1
  33. package/dist/airgap-instances.d.mts +3 -1
  34. package/dist/airgap-instances.d.ts +3 -1
  35. package/dist/airgap-instances.js +41 -112
  36. package/dist/airgap-instances.js.map +1 -1
  37. package/dist/branding-BsMSywts.d.mts +36 -0
  38. package/dist/branding-BsMSywts.d.ts +36 -0
  39. package/dist/error-page.js +10 -2
  40. package/dist/error-page.js.map +1 -1
  41. package/dist/error.js +10 -2
  42. package/dist/error.js.map +1 -1
  43. package/dist/esm/actions/change-team.js +66 -7
  44. package/dist/esm/actions/change-team.js.map +1 -1
  45. package/dist/esm/actions/index.js +181 -462
  46. package/dist/esm/actions/index.js.map +1 -1
  47. package/dist/esm/actions/install-actions.js +58 -5
  48. package/dist/esm/actions/install-actions.js.map +1 -1
  49. package/dist/esm/actions/service-account.js +58 -5
  50. package/dist/esm/actions/service-account.js.map +1 -1
  51. package/dist/esm/actions/support-bundles.js +58 -5
  52. package/dist/esm/actions/support-bundles.js.map +1 -1
  53. package/dist/esm/actions/team-settings.js +91 -27
  54. package/dist/esm/actions/team-settings.js.map +1 -1
  55. package/dist/esm/actions/trial-signup.js +478 -0
  56. package/dist/esm/actions/trial-signup.js.map +1 -0
  57. package/dist/esm/actions/user-settings.js +58 -5
  58. package/dist/esm/actions/user-settings.js.map +1 -1
  59. package/dist/esm/airgap-instances.js +40 -112
  60. package/dist/esm/airgap-instances.js.map +1 -1
  61. package/dist/esm/error-page.js +10 -2
  62. package/dist/esm/error-page.js.map +1 -1
  63. package/dist/esm/error.js +10 -2
  64. package/dist/esm/error.js.map +1 -1
  65. package/dist/esm/helm-install-wizard.js +118 -79
  66. package/dist/esm/helm-install-wizard.js.map +1 -1
  67. package/dist/esm/index.js +706 -438
  68. package/dist/esm/index.js.map +1 -1
  69. package/dist/esm/install-actions.js +40 -5
  70. package/dist/esm/install-actions.js.map +1 -1
  71. package/dist/esm/install-card.js +9 -6
  72. package/dist/esm/install-card.js.map +1 -1
  73. package/dist/esm/install-targets.js +9 -2
  74. package/dist/esm/install-targets.js.map +1 -1
  75. package/dist/esm/instance-card.js +39 -111
  76. package/dist/esm/instance-card.js.map +1 -1
  77. package/dist/esm/join-team.js +9 -3
  78. package/dist/esm/join-team.js.map +1 -1
  79. package/dist/esm/license-card.js +24 -22
  80. package/dist/esm/license-card.js.map +1 -1
  81. package/dist/esm/license-details.js +128 -334
  82. package/dist/esm/license-details.js.map +1 -1
  83. package/dist/esm/linux-install-wizard.js +95 -41
  84. package/dist/esm/linux-install-wizard.js.map +1 -1
  85. package/dist/esm/login.js +20 -4
  86. package/dist/esm/login.js.map +1 -1
  87. package/dist/esm/middleware.js +33 -0
  88. package/dist/esm/middleware.js.map +1 -0
  89. package/dist/esm/online-instance-list.js +40 -112
  90. package/dist/esm/online-instance-list.js.map +1 -1
  91. package/dist/esm/release-history-panel.js +27 -14
  92. package/dist/esm/release-history-panel.js.map +1 -1
  93. package/dist/esm/saml-callback-client.js +82 -0
  94. package/dist/esm/saml-callback-client.js.map +1 -0
  95. package/dist/esm/saml-handlers.js +138 -0
  96. package/dist/esm/saml-handlers.js.map +1 -0
  97. package/dist/esm/security-card.js +53 -38
  98. package/dist/esm/security-card.js.map +1 -1
  99. package/dist/esm/service-accounts-tab.js +800 -0
  100. package/dist/esm/service-accounts-tab.js.map +1 -0
  101. package/dist/esm/support-bundle-collection-card.js +48 -24
  102. package/dist/esm/support-bundle-collection-card.js.map +1 -1
  103. package/dist/esm/support-bundles-card.js +10 -5
  104. package/dist/esm/support-bundles-card.js.map +1 -1
  105. package/dist/esm/support-card.js +37 -5
  106. package/dist/esm/support-card.js.map +1 -1
  107. package/dist/esm/team-selection.js +5 -1
  108. package/dist/esm/team-selection.js.map +1 -1
  109. package/dist/esm/team-settings-card.js +5 -2
  110. package/dist/esm/team-settings-card.js.map +1 -1
  111. package/dist/esm/team-settings.js +7 -2
  112. package/dist/esm/team-settings.js.map +1 -1
  113. package/dist/esm/top-nav-user-menu.js +5 -1
  114. package/dist/esm/top-nav-user-menu.js.map +1 -1
  115. package/dist/esm/top-nav.js +175 -62
  116. package/dist/esm/top-nav.js.map +1 -1
  117. package/dist/esm/trial-signup.js +256 -0
  118. package/dist/esm/trial-signup.js.map +1 -0
  119. package/dist/esm/update-layout.js +175 -62
  120. package/dist/esm/update-layout.js.map +1 -1
  121. package/dist/esm/updates-card.js +15 -4
  122. package/dist/esm/updates-card.js.map +1 -1
  123. package/dist/esm/upload-support-bundle-modal.js +9 -4
  124. package/dist/esm/upload-support-bundle-modal.js.map +1 -1
  125. package/dist/esm/user-settings-card.js +5 -2
  126. package/dist/esm/user-settings-card.js.map +1 -1
  127. package/dist/esm/user-settings.js +12 -6
  128. package/dist/esm/user-settings.js.map +1 -1
  129. package/dist/esm/utils/index.js +204 -13
  130. package/dist/esm/utils/index.js.map +1 -1
  131. package/dist/fetch-license-iTyF7_GY.d.mts +81 -0
  132. package/dist/fetch-license-iTyF7_GY.d.ts +81 -0
  133. package/dist/helm-install-wizard.d.mts +11 -3
  134. package/dist/helm-install-wizard.d.ts +11 -3
  135. package/dist/helm-install-wizard.js +118 -79
  136. package/dist/helm-install-wizard.js.map +1 -1
  137. package/dist/{index-BAiVrSSR.d.mts → index-DyzJ0yKD.d.mts} +48 -50
  138. package/dist/{index-DWt-N5od.d.ts → index-sMbq94M7.d.ts} +48 -50
  139. package/dist/index.d.mts +8 -2
  140. package/dist/index.d.ts +8 -2
  141. package/dist/index.js +726 -438
  142. package/dist/index.js.map +1 -1
  143. package/dist/install-actions.d.mts +4 -2
  144. package/dist/install-actions.d.ts +4 -2
  145. package/dist/install-actions.js +40 -5
  146. package/dist/install-actions.js.map +1 -1
  147. package/dist/install-card.d.mts +2 -3
  148. package/dist/install-card.d.ts +2 -3
  149. package/dist/install-card.js +9 -6
  150. package/dist/install-card.js.map +1 -1
  151. package/dist/install-targets.js +9 -2
  152. package/dist/install-targets.js.map +1 -1
  153. package/dist/instance-card.d.mts +3 -1
  154. package/dist/instance-card.d.ts +3 -1
  155. package/dist/instance-card.js +40 -111
  156. package/dist/instance-card.js.map +1 -1
  157. package/dist/join-team.js +9 -3
  158. package/dist/join-team.js.map +1 -1
  159. package/dist/license-card.d.mts +2 -3
  160. package/dist/license-card.d.ts +2 -3
  161. package/dist/license-card.js +24 -22
  162. package/dist/license-card.js.map +1 -1
  163. package/dist/license-details.js +128 -334
  164. package/dist/license-details.js.map +1 -1
  165. package/dist/linux-install-wizard.d.mts +9 -3
  166. package/dist/linux-install-wizard.d.ts +9 -3
  167. package/dist/linux-install-wizard.js +95 -41
  168. package/dist/linux-install-wizard.js.map +1 -1
  169. package/dist/login.d.mts +4 -0
  170. package/dist/login.d.ts +4 -0
  171. package/dist/login.js +20 -4
  172. package/dist/login.js.map +1 -1
  173. package/dist/middleware.d.mts +13 -0
  174. package/dist/middleware.d.ts +13 -0
  175. package/dist/middleware.js +35 -0
  176. package/dist/middleware.js.map +1 -0
  177. package/dist/online-instance-list.d.mts +3 -1
  178. package/dist/online-instance-list.d.ts +3 -1
  179. package/dist/online-instance-list.js +41 -112
  180. package/dist/online-instance-list.js.map +1 -1
  181. package/dist/pending-installations.d.mts +3 -1
  182. package/dist/pending-installations.d.ts +3 -1
  183. package/dist/release-history-panel.js +27 -14
  184. package/dist/release-history-panel.js.map +1 -1
  185. package/dist/saml-callback-client.d.mts +36 -0
  186. package/dist/saml-callback-client.d.ts +36 -0
  187. package/dist/saml-callback-client.js +88 -0
  188. package/dist/saml-callback-client.js.map +1 -0
  189. package/dist/saml-handlers.d.mts +50 -0
  190. package/dist/saml-handlers.d.ts +50 -0
  191. package/dist/saml-handlers.js +141 -0
  192. package/dist/saml-handlers.js.map +1 -0
  193. package/dist/security-card.d.mts +3 -1
  194. package/dist/security-card.d.ts +3 -1
  195. package/dist/security-card.js +53 -38
  196. package/dist/security-card.js.map +1 -1
  197. package/dist/service-accounts-tab.d.mts +51 -0
  198. package/dist/service-accounts-tab.d.ts +51 -0
  199. package/dist/service-accounts-tab.js +802 -0
  200. package/dist/service-accounts-tab.js.map +1 -0
  201. package/dist/styles.css +375 -127
  202. package/dist/support-bundle-collection-card.d.mts +1 -1
  203. package/dist/support-bundle-collection-card.d.ts +1 -1
  204. package/dist/support-bundle-collection-card.js +47 -23
  205. package/dist/support-bundle-collection-card.js.map +1 -1
  206. package/dist/support-bundles-card.d.mts +4 -2
  207. package/dist/support-bundles-card.d.ts +4 -2
  208. package/dist/support-bundles-card.js +10 -5
  209. package/dist/support-bundles-card.js.map +1 -1
  210. package/dist/support-card.js +37 -5
  211. package/dist/support-card.js.map +1 -1
  212. package/dist/team-selection.js +5 -1
  213. package/dist/team-selection.js.map +1 -1
  214. package/dist/team-settings-card.js +5 -2
  215. package/dist/team-settings-card.js.map +1 -1
  216. package/dist/team-settings.js +7 -2
  217. package/dist/team-settings.js.map +1 -1
  218. package/dist/{top-nav-IRIn66wS.d.ts → top-nav-BUQAGoG1.d.mts} +14 -2
  219. package/dist/{top-nav-IRIn66wS.d.mts → top-nav-CEqw0KpO.d.ts} +14 -2
  220. package/dist/top-nav-user-menu.js +5 -1
  221. package/dist/top-nav-user-menu.js.map +1 -1
  222. package/dist/top-nav.d.mts +2 -1
  223. package/dist/top-nav.d.ts +2 -1
  224. package/dist/top-nav.js +175 -62
  225. package/dist/top-nav.js.map +1 -1
  226. package/dist/trial-signup.d.mts +31 -0
  227. package/dist/trial-signup.d.ts +31 -0
  228. package/dist/trial-signup.js +258 -0
  229. package/dist/trial-signup.js.map +1 -0
  230. package/dist/update-layout.js +175 -62
  231. package/dist/update-layout.js.map +1 -1
  232. package/dist/updates-card.js +15 -4
  233. package/dist/updates-card.js.map +1 -1
  234. package/dist/upload-support-bundle-modal.js +9 -4
  235. package/dist/upload-support-bundle-modal.js.map +1 -1
  236. package/dist/user-settings-card.js +5 -2
  237. package/dist/user-settings-card.js.map +1 -1
  238. package/dist/user-settings.js +12 -6
  239. package/dist/user-settings.js.map +1 -1
  240. package/dist/utils/index.d.mts +74 -16
  241. package/dist/utils/index.d.ts +74 -16
  242. package/dist/utils/index.js +215 -12
  243. package/dist/utils/index.js.map +1 -1
  244. package/package.json +37 -2
@@ -1,12 +1,24 @@
1
1
  import { Buffer } from 'buffer';
2
2
  import { cache } from 'react';
3
+ import { cookies } from 'next/headers';
3
4
  import { jsxs, jsx } from 'react/jsx-runtime';
4
5
 
5
6
  /**
6
7
  * Enterprise Portal Components
7
8
  * This file is generated by tsup. Do not edit manually.
8
9
  */
10
+ var __defProp = Object.defineProperty;
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
9
15
 
16
+ // datadog/tracer.ts
17
+ var tracer_exports = {};
18
+ __export(tracer_exports, {
19
+ default: () => tracer_default
20
+ });
21
+ var tracer_default;
10
22
 
11
23
  // src/utils/api-client.ts
12
24
  async function authenticatedFetch(url, options = {}) {
@@ -31,8 +43,17 @@ async function handle401() {
31
43
  const { redirect } = await import('next/navigation');
32
44
  return redirect("/?expired=1");
33
45
  }
46
+ function isErrorPage(url) {
47
+ try {
48
+ const urlObj = new URL(url);
49
+ return urlObj.pathname === "/error";
50
+ } catch {
51
+ return url === "/error" || url.startsWith("/error?");
52
+ }
53
+ }
34
54
  async function handleServerError(statusCode) {
35
55
  const { redirect } = await import('next/navigation');
56
+ const { cookies: cookies2 } = await import('next/headers');
36
57
  let sourceUrl;
37
58
  try {
38
59
  const { headers } = await import('next/headers');
@@ -40,12 +61,20 @@ async function handleServerError(statusCode) {
40
61
  const referer = headersList.get("referer");
41
62
  const host = headersList.get("host");
42
63
  const pathname = headersList.get("x-invoke-path") || headersList.get("x-forwarded-path");
43
- if (referer) {
64
+ if (referer && !isErrorPage(referer)) {
44
65
  sourceUrl = referer;
45
66
  } else if (host && pathname) {
46
67
  const protocol = headersList.get("x-forwarded-proto") || "https";
47
68
  sourceUrl = `${protocol}://${host}${pathname}`;
48
69
  }
70
+ if (!sourceUrl || isErrorPage(sourceUrl)) {
71
+ const cookieStore = await cookies2();
72
+ const preservedSource = cookieStore.get("portal_error_source");
73
+ if (preservedSource?.value) {
74
+ sourceUrl = decodeURIComponent(preservedSource.value);
75
+ cookieStore.delete("portal_error_source");
76
+ }
77
+ }
49
78
  } catch (error) {
50
79
  console.debug("[portal-components] Could not determine source URL", error);
51
80
  }
@@ -55,12 +84,86 @@ async function handleServerError(statusCode) {
55
84
  }
56
85
  return redirect(`/error?${params.toString()}`);
57
86
  }
87
+ var deriveInstallMethods = (licenseData) => {
88
+ const methods = [];
89
+ if (licenseData.isKotsInstallEnabled) {
90
+ methods.push("Replicated KOTS");
91
+ }
92
+ if (licenseData.isHelmInstallEnabled) {
93
+ methods.push("Helm");
94
+ }
95
+ if (licenseData.isHelmAirgapEnabled) {
96
+ methods.push("Helm Airgap");
97
+ }
98
+ if (licenseData.isEmbeddedClusterDownloadEnabled || licenseData.isEmbeddedClusterMultiNodeEnabled) {
99
+ methods.push("Embedded Cluster");
100
+ }
101
+ if (licenseData.isKurlInstallEnabled) {
102
+ methods.push("kURL");
103
+ }
104
+ if (licenseData.isGitopsSupported) {
105
+ methods.push("GitOps");
106
+ }
107
+ return Array.from(new Set(methods));
108
+ };
109
+ var convertEntitlementsToFields = (entitlementFields, entitlementValues) => {
110
+ const valuesMap = /* @__PURE__ */ new Map();
111
+ entitlementValues.forEach((ev) => {
112
+ valuesMap.set(ev.name, ev.value);
113
+ });
114
+ return entitlementFields.filter((field) => field.hidden === 0).map((field) => ({
115
+ key: field.name,
116
+ label: field.title || field.name,
117
+ value: valuesMap.get(field.name) || field.defaultVal || null,
118
+ isSecret: field.type === "Password"
119
+ }));
120
+ };
121
+ async function fetchLicenseCore() {
122
+ const sessionStore = await cookies();
123
+ const session = sessionStore.get("portal_session");
124
+ const token = session?.value;
125
+ if (!token) {
126
+ throw new Error("No session found - user must be authenticated");
127
+ }
128
+ const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
129
+ if (process.env.NODE_ENV !== "production") {
130
+ console.debug("[portal-components] fetching license via %s (Enterprise Portal API)", endpoint);
131
+ }
132
+ const response = await authenticatedFetch(endpoint, {
133
+ method: "GET",
134
+ token,
135
+ headers: {
136
+ Accept: "application/json"
137
+ }
138
+ });
139
+ if (!response.ok) {
140
+ throw new Error(
141
+ `License request failed (${response.status} ${response.statusText})`
142
+ );
143
+ }
144
+ const envelope = await response.json();
145
+ const licenseData = envelope.data;
146
+ const license = {
147
+ ...licenseData,
148
+ // Alias fields for backward compatibility
149
+ expiresAt: licenseData.expireAt,
150
+ environment: licenseData.licenseType,
151
+ // Extract channel names from channels array
152
+ releaseChannels: (licenseData.channels || []).map((ch) => ch.channelName),
153
+ // Derive install methods from feature flags
154
+ installMethods: deriveInstallMethods(licenseData),
155
+ // Convert entitlements to fields format
156
+ fields: convertEntitlementsToFields(licenseData.entitlementFields || [], licenseData.entitlementValues || [])
157
+ };
158
+ return license;
159
+ }
160
+ var fetchLicenseImpl = cache(fetchLicenseCore);
161
+ var fetchLicense = fetchLicenseImpl;
58
162
 
59
163
  // src/actions/index.ts
60
164
  var getApiOrigin = () => {
61
165
  return (process.env.REPLICATED_APP_ORIGIN || "https://replicated.app").replace(/\/+$/, "");
62
166
  };
63
- var defineServerAction = (definition) => definition;
64
167
  var fetchCustomBrandingImpl = async () => {
65
168
  const appSlug = process.env.PORTAL_APP_SLUG;
66
169
  if (!appSlug) {
@@ -88,11 +191,15 @@ var fetchCustomBrandingImpl = async () => {
88
191
  const payload = await response.json();
89
192
  const brandingObject = {
90
193
  logo: payload.logoUrl,
91
- title: payload.appName,
92
- customColor1: payload.primaryColor,
93
- customColor2: payload.secondaryColor,
194
+ title: payload.title,
195
+ primaryColor: payload.primaryColor,
196
+ secondaryColor: payload.secondaryColor,
94
197
  favicon: payload.faviconUrl,
95
- supportPortalLink: payload.supportPortalLink || ""
198
+ supportPortalLink: payload.supportPortalLink || "",
199
+ background: payload.background,
200
+ backgroundImage: payload.backgroundImage,
201
+ customColor1: payload.customColor1,
202
+ customColor2: payload.customColor2
96
203
  };
97
204
  const brandingData = Buffer.from(JSON.stringify(brandingObject)).toString("base64");
98
205
  return {
@@ -102,317 +209,6 @@ var fetchCustomBrandingImpl = async () => {
102
209
  };
103
210
  };
104
211
  cache(fetchCustomBrandingImpl);
105
- var asRecord = (value) => {
106
- if (value && typeof value === "object") {
107
- return value;
108
- }
109
- return void 0;
110
- };
111
- var getValue = (record, key) => record ? record[key] : void 0;
112
- var getString = (record, key) => {
113
- const value = getValue(record, key);
114
- return typeof value === "string" ? value : void 0;
115
- };
116
- var getBoolean = (record, key) => {
117
- const value = getValue(record, key);
118
- if (typeof value === "boolean") {
119
- return value;
120
- }
121
- if (typeof value === "number") {
122
- return value === 1;
123
- }
124
- if (typeof value === "string") {
125
- const normalized = value.trim().toLowerCase();
126
- if (["true", "1", "yes"].includes(normalized)) {
127
- return true;
128
- }
129
- if (["false", "0", "no"].includes(normalized)) {
130
- return false;
131
- }
132
- }
133
- return void 0;
134
- };
135
- var toDisplayValue = (value) => {
136
- if (value === null || value === void 0) {
137
- return null;
138
- }
139
- if (typeof value === "string") {
140
- return value;
141
- }
142
- if (typeof value === "number" || typeof value === "boolean") {
143
- return String(value);
144
- }
145
- try {
146
- return JSON.stringify(value);
147
- } catch {
148
- return String(value);
149
- }
150
- };
151
- var normalizeStringArray = (value) => {
152
- if (Array.isArray(value)) {
153
- const normalized = value.map(
154
- (item) => typeof item === "string" ? item.trim() : ""
155
- ).filter((item) => item.length > 0);
156
- return normalized.length ? normalized : void 0;
157
- }
158
- if (typeof value === "string") {
159
- const normalized = value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
160
- return normalized.length ? normalized : void 0;
161
- }
162
- return void 0;
163
- };
164
- var normalizeLicenseFields = (input) => {
165
- if (!input) {
166
- return [];
167
- }
168
- if (Array.isArray(input)) {
169
- return input.map((field, index) => {
170
- if (!field || typeof field !== "object") {
171
- return null;
172
- }
173
- const candidate = field;
174
- const key = typeof candidate.key === "string" && candidate.key.trim().length ? candidate.key.trim() : typeof candidate.name === "string" && candidate.name.trim().length ? candidate.name.trim() : typeof candidate.label === "string" && candidate.label.trim().length ? candidate.label.trim() : `field-${index}`;
175
- const label = typeof candidate.label === "string" && candidate.label.trim().length ? candidate.label.trim() : typeof candidate.name === "string" && candidate.name.trim().length ? candidate.name.trim() : key;
176
- let value = candidate.value ?? candidate.data ?? candidate.content;
177
- if ((value === void 0 || value === null) && typeof candidate.text === "string") {
178
- value = candidate.text;
179
- }
180
- if ((value === void 0 || value === null) && typeof candidate.defaultValue === "string") {
181
- value = candidate.defaultValue;
182
- }
183
- const isSecret = Boolean(
184
- candidate.isSecret ?? candidate.secret ?? candidate.masked
185
- );
186
- const resolved = toDisplayValue(value);
187
- return {
188
- key,
189
- label,
190
- value: resolved,
191
- isSecret
192
- };
193
- }).filter((field) => Boolean(field));
194
- }
195
- if (typeof input === "object") {
196
- return Object.entries(input).map(
197
- ([key, value]) => {
198
- let resolvedValue = value;
199
- let isSecret = false;
200
- if (value && typeof value === "object") {
201
- const obj = value;
202
- if ("value" in obj) {
203
- resolvedValue = obj.value;
204
- }
205
- isSecret = Boolean(obj.isSecret ?? obj.secret ?? obj.masked);
206
- }
207
- const normalized = toDisplayValue(resolvedValue);
208
- return {
209
- key,
210
- label: key,
211
- value: normalized,
212
- isSecret
213
- };
214
- }
215
- );
216
- }
217
- return [];
218
- };
219
- var extractChannelNames = (input) => {
220
- if (!Array.isArray(input)) {
221
- return void 0;
222
- }
223
- const names = input.map((item) => {
224
- if (typeof item === "string") {
225
- return item.trim();
226
- }
227
- const record = asRecord(item);
228
- if (!record) {
229
- return null;
230
- }
231
- return getString(record, "name") ?? getString(record, "channelName") ?? getString(record, "channel") ?? getString(record, "channelSlug") ?? getString(record, "slug") ?? void 0;
232
- }).filter((name) => Boolean(name && name.length));
233
- return names.length ? names : void 0;
234
- };
235
- var normalizeEntitlementFields = (fieldsInput, valuesInput) => {
236
- const valuesMap = /* @__PURE__ */ new Map();
237
- const assignValue = (key, value) => {
238
- if (!key) {
239
- return;
240
- }
241
- valuesMap.set(key, toDisplayValue(value));
242
- };
243
- if (Array.isArray(valuesInput)) {
244
- valuesInput.forEach((item) => {
245
- const record = asRecord(item);
246
- if (!record) {
247
- if (typeof item === "string") {
248
- assignValue(item, item);
249
- }
250
- return;
251
- }
252
- const key = getString(record, "name") ?? getString(record, "field") ?? getString(record, "title") ?? getString(record, "label") ?? getString(record, "slug") ?? (() => {
253
- const idValue = getValue(record, "id");
254
- if (typeof idValue === "string" || typeof idValue === "number") {
255
- return String(idValue);
256
- }
257
- return void 0;
258
- })();
259
- const value = getValue(record, "value") ?? getValue(record, "currentValue") ?? getValue(record, "entitlementValue") ?? getValue(record, "content") ?? getValue(record, "data") ?? getValue(record, "defaultVal") ?? getValue(record, "defaultValue");
260
- assignValue(key, value);
261
- });
262
- } else if (valuesInput && typeof valuesInput === "object") {
263
- Object.entries(valuesInput).forEach(
264
- ([key, value]) => assignValue(key, value)
265
- );
266
- }
267
- const normalized = [];
268
- if (Array.isArray(fieldsInput)) {
269
- fieldsInput.forEach((item, index) => {
270
- const record = asRecord(item);
271
- if (!record) {
272
- return;
273
- }
274
- const baseKey = getString(record, "name") ?? getString(record, "field") ?? getString(record, "slug") ?? `entitlement-${index}`;
275
- const key = `entitlement-${baseKey}`;
276
- const label = getString(record, "title") ?? getString(record, "label") ?? baseKey;
277
- const defaultValue = getString(record, "defaultVal") ?? getString(record, "default") ?? getString(record, "defaultValue");
278
- const value = valuesMap.get(baseKey) ?? valuesMap.get(label) ?? defaultValue ?? null;
279
- const isSecret = Boolean(
280
- getBoolean(record, "secret") ?? getBoolean(record, "isSecret") ?? getBoolean(record, "masked")
281
- );
282
- normalized.push({
283
- key,
284
- label,
285
- value,
286
- isSecret
287
- });
288
- });
289
- }
290
- valuesMap.forEach((value, key) => {
291
- const normalizedKey = `entitlement-${key}`;
292
- if (!normalized.some((field) => field.key === normalizedKey)) {
293
- normalized.push({
294
- key: normalizedKey,
295
- label: key,
296
- value
297
- });
298
- }
299
- });
300
- return normalized;
301
- };
302
- var normalizeLicensePayload = (payload) => {
303
- const payloadRecord = asRecord(payload);
304
- const rootRecord = asRecord(getValue(payloadRecord, "license")) ?? asRecord(getValue(payloadRecord, "data")) ?? payloadRecord ?? {};
305
- const sourceRecord = asRecord(getValue(rootRecord, "metadata")) ?? rootRecord;
306
- const customer = asRecord(getValue(rootRecord, "customer")) ?? asRecord(getValue(sourceRecord, "customer")) ?? asRecord(getValue(payloadRecord, "customer")) ?? {};
307
- let releaseChannels = normalizeStringArray(
308
- getValue(rootRecord, "releaseChannels") ?? getValue(sourceRecord, "releaseChannels") ?? getValue(sourceRecord, "channels") ?? getValue(rootRecord, "channels") ?? getValue(sourceRecord, "channel") ?? getValue(rootRecord, "channel")
309
- ) ?? void 0;
310
- if (!releaseChannels) {
311
- releaseChannels = extractChannelNames(getValue(rootRecord, "channels")) ?? extractChannelNames(getValue(sourceRecord, "channels")) ?? void 0;
312
- }
313
- let installMethods = normalizeStringArray(
314
- getValue(rootRecord, "installMethods") ?? getValue(sourceRecord, "installMethods") ?? getValue(sourceRecord, "install_options") ?? getValue(rootRecord, "install_options") ?? getValue(sourceRecord, "installOptions")
315
- ) ?? void 0;
316
- if (!installMethods || installMethods.length === 0) {
317
- const resolved = [];
318
- const flag = (key) => getBoolean(rootRecord, key) ?? getBoolean(sourceRecord, key) ?? false;
319
- if (flag("isKotsInstallEnabled")) {
320
- resolved.push("Replicated KOTS");
321
- }
322
- if (flag("isHelmInstallEnabled")) {
323
- resolved.push("Helm");
324
- }
325
- if (flag("isHelmAirgapEnabled")) {
326
- resolved.push("Helm Airgap");
327
- }
328
- if (flag("isEmbeddedClusterDownloadEnabled") || flag("isEmbeddedClusterMultiNodeEnabled")) {
329
- resolved.push("Embedded Cluster");
330
- }
331
- if (flag("isKurlInstallEnabled")) {
332
- resolved.push("kURL");
333
- }
334
- if (flag("isGitopsSupported")) {
335
- resolved.push("GitOps");
336
- }
337
- if (resolved.length) {
338
- installMethods = Array.from(new Set(resolved));
339
- }
340
- }
341
- const expiresAtSource = getValue(sourceRecord, "expiresAt") ?? getValue(sourceRecord, "expireAt") ?? getValue(sourceRecord, "expire_at") ?? getValue(sourceRecord, "expiration") ?? getValue(sourceRecord, "expirationDate") ?? getValue(sourceRecord, "expires_on") ?? getValue(rootRecord, "expiresAt") ?? getValue(rootRecord, "expireAt") ?? getValue(rootRecord, "expire_at") ?? getValue(rootRecord, "expiration");
342
- const expiresAt = typeof expiresAtSource === "string" && expiresAtSource.trim().length ? expiresAtSource : expiresAtSource === null ? null : void 0;
343
- const baseFields = normalizeLicenseFields(
344
- getValue(rootRecord, "additionalFields") ?? getValue(sourceRecord, "additionalFields") ?? getValue(sourceRecord, "fields") ?? getValue(rootRecord, "fields") ?? getValue(payloadRecord, "fields") ?? getValue(payloadRecord, "additional_fields")
345
- );
346
- const entitlementFields = normalizeEntitlementFields(
347
- getValue(rootRecord, "entitlementFields") ?? getValue(sourceRecord, "entitlementFields"),
348
- getValue(rootRecord, "entitlementValues") ?? getValue(sourceRecord, "entitlementValues")
349
- );
350
- const fields = [
351
- ...baseFields,
352
- ...entitlementFields.filter(
353
- (field) => !baseFields.some((existing) => existing.key === field.key)
354
- )
355
- ];
356
- const statusFromSource = getString(sourceRecord, "status") ?? getString(sourceRecord, "state");
357
- const statusLabelFromSource = getString(sourceRecord, "statusLabel") ?? getString(sourceRecord, "stateLabel");
358
- const expiredFlag = getBoolean(sourceRecord, "isExpired") ?? getBoolean(rootRecord, "isExpired");
359
- const derivedStatus = statusFromSource ?? (typeof expiredFlag === "boolean" ? expiredFlag ? "expired" : "active" : void 0);
360
- const statusLabel = statusLabelFromSource ?? (derivedStatus ? derivedStatus.charAt(0).toUpperCase() + derivedStatus.slice(1) : void 0);
361
- const licenseType = getString(sourceRecord, "licenseType") ?? getString(rootRecord, "licenseType");
362
- const status = derivedStatus;
363
- const license = {
364
- id: getString(rootRecord, "id") ?? getString(sourceRecord, "id") ?? getString(sourceRecord, "licenseId") ?? getString(customer, "licenseId") ?? void 0,
365
- status,
366
- statusLabel,
367
- environment: getString(sourceRecord, "environment") ?? getString(sourceRecord, "tier") ?? licenseType ?? void 0,
368
- expiresAt: expiresAt ?? null,
369
- releaseChannels: releaseChannels ?? [
370
- getString(rootRecord, "channelName") ?? getString(rootRecord, "channel") ?? void 0
371
- ].filter((value) => Boolean(value)),
372
- installMethods,
373
- installNotes: getString(sourceRecord, "installNotes"),
374
- customerName: getString(sourceRecord, "customerName") ?? getString(customer, "name") ?? void 0,
375
- customerId: getString(sourceRecord, "customerId") ?? getString(customer, "id") ?? getString(rootRecord, "customerId") ?? void 0,
376
- customerOrganization: getString(customer, "organization") ?? getString(sourceRecord, "customerOrganization") ?? getString(rootRecord, "customerOrganization") ?? void 0,
377
- fields
378
- };
379
- return license;
380
- };
381
- var fetchLicenseDetails = defineServerAction({
382
- id: "license/fetch-details",
383
- description: "Fetches the authenticated user's enterprise license details.",
384
- visibility: "customer",
385
- tags: ["license", "entitlements"],
386
- async run({ token }, context) {
387
- if (typeof token !== "string" || token.trim().length === 0) {
388
- throw new Error("fetchLicenseDetails requires a non-empty token");
389
- }
390
- const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
391
- if (process.env.NODE_ENV !== "production") {
392
- console.debug("[portal-components] fetching license via %s (Enterprise Portal API)", endpoint);
393
- }
394
- const response = await authenticatedFetch(endpoint, {
395
- method: "GET",
396
- token,
397
- headers: {
398
- accept: "application/json"
399
- },
400
- signal: context?.signal
401
- });
402
- if (!response.ok) {
403
- throw new Error(
404
- `License request failed (${response.status} ${response.statusText})`
405
- );
406
- }
407
- const payload = await response.json();
408
- const licenseData = payload.data;
409
- const license = normalizeLicensePayload(licenseData);
410
- return {
411
- license,
412
- raw: licenseData ?? null
413
- };
414
- }
415
- });
416
212
  var ShieldIcon = (props) => /* @__PURE__ */ jsx(
417
213
  "svg",
418
214
  {
@@ -545,12 +341,12 @@ var InfoRow = ({
545
341
  icon,
546
342
  title,
547
343
  children
548
- }) => /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3", children: [
549
- /* @__PURE__ */ jsx("div", { className: "mt-1 text-gray-900", children: icon }),
550
- /* @__PURE__ */ jsxs("div", { children: [
551
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-900", children: title }),
552
- children
553
- ] })
344
+ }) => /* @__PURE__ */ jsxs("div", { children: [
345
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
346
+ /* @__PURE__ */ jsx("div", { className: "flex h-4 w-4 flex-shrink-0 items-center justify-center text-gray-900", children: icon }),
347
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium leading-4 text-gray-900", children: title })
348
+ ] }),
349
+ /* @__PURE__ */ jsx("div", { className: "pl-6", children })
554
350
  ] });
555
351
  var renderInstallOrChannel = (values) => {
556
352
  if (!values || values.length === 0) {
@@ -565,12 +361,12 @@ var buildPrimaryRows = (license) => {
565
361
  node: /* @__PURE__ */ jsxs(
566
362
  InfoRow,
567
363
  {
568
- icon: /* @__PURE__ */ jsx(ShieldIcon, { className: "h-5 w-5" }),
364
+ icon: /* @__PURE__ */ jsx(ShieldIcon, { className: "h-4 w-4" }),
569
365
  title: "License Status",
570
366
  children: [
571
367
  /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center text-sm text-gray-600", children: [
572
368
  /* @__PURE__ */ jsx(CheckIcon, { className: "mr-1.5 h-4 w-4 text-green-500" }),
573
- /* @__PURE__ */ jsx("span", { children: license.statusLabel ?? (license.status ? license.status.charAt(0).toUpperCase() + license.status.slice(1) : "Unknown") })
369
+ /* @__PURE__ */ jsx("span", { children: license.isExpired ? "Expired" : "Active" })
574
370
  ] }),
575
371
  license.environment ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: license.environment }) : null
576
372
  ]
@@ -582,7 +378,7 @@ var buildPrimaryRows = (license) => {
582
378
  node: /* @__PURE__ */ jsx(
583
379
  InfoRow,
584
380
  {
585
- icon: /* @__PURE__ */ jsx(CalendarIcon, { className: "h-5 w-5" }),
381
+ icon: /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4" }),
586
382
  title: "Expiration Date",
587
383
  children: /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: formatExpiration(license.expiresAt) })
588
384
  }
@@ -593,7 +389,7 @@ var buildPrimaryRows = (license) => {
593
389
  node: /* @__PURE__ */ jsx(
594
390
  InfoRow,
595
391
  {
596
- icon: /* @__PURE__ */ jsx(ShieldIcon, { className: "h-5 w-5" }),
392
+ icon: /* @__PURE__ */ jsx(ShieldIcon, { className: "h-4 w-4" }),
597
393
  title: "Release Channel(s)",
598
394
  children: renderInstallOrChannel(license.releaseChannels)
599
395
  }
@@ -604,7 +400,7 @@ var buildPrimaryRows = (license) => {
604
400
  node: /* @__PURE__ */ jsx(
605
401
  InfoRow,
606
402
  {
607
- icon: /* @__PURE__ */ jsx(DownloadIcon, { className: "h-5 w-5" }),
403
+ icon: /* @__PURE__ */ jsx(DownloadIcon, { className: "h-4 w-4" }),
608
404
  title: "Install Options",
609
405
  children: renderInstallOrChannel(license.installMethods)
610
406
  }
@@ -615,7 +411,7 @@ var buildPrimaryRows = (license) => {
615
411
  node: /* @__PURE__ */ jsxs(
616
412
  InfoRow,
617
413
  {
618
- icon: /* @__PURE__ */ jsx(BuildingIcon, { className: "h-5 w-5" }),
414
+ icon: /* @__PURE__ */ jsx(BuildingIcon, { className: "h-4 w-4" }),
619
415
  title: "Customer Name",
620
416
  children: [
621
417
  /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: license.customerName ?? "Unknown customer" }),
@@ -633,7 +429,7 @@ var renderFields = (fields) => {
633
429
  if (!fields.length) {
634
430
  return /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No additional fields available." });
635
431
  }
636
- return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3", children: fields.map((field) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
432
+ return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3", children: fields.map((field) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
637
433
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900", children: field.label }),
638
434
  /* @__PURE__ */ jsx(
639
435
  "p",
@@ -654,9 +450,7 @@ var LicenseDetails = async ({
654
450
  if (typeof token !== "string" || token.trim().length === 0) {
655
451
  throw new Error("LicenseDetails component requires a non-empty token");
656
452
  }
657
- const response = await fetchLicenseDetails.run({ token });
658
- console.debug("[portal-components] license response", response.raw);
659
- const { license } = response;
453
+ const license = await fetchLicense();
660
454
  const rows = buildPrimaryRows(license);
661
455
  return /* @__PURE__ */ jsxs("div", { className: "rounded border border-gray-100 bg-white p-8 shadow-[0_18px_45px_rgba(17,24,39,0.08)]", children: [
662
456
  /* @__PURE__ */ jsxs("header", { className: "flex flex-col border-b border-gray-100 pb-6", children: [
@@ -664,7 +458,7 @@ var LicenseDetails = async ({
664
458
  description ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-600", children: description }) : null
665
459
  ] }),
666
460
  /* @__PURE__ */ jsxs("div", { className: "mt-6 space-y-6", children: [
667
- /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-gray-100 bg-white p-6 sm:p-8", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3", children: rows.map((row) => /* @__PURE__ */ jsx("div", { children: row.node }, row.key)) }) }),
461
+ /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-gray-100 bg-white p-6 sm:p-8", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 items-start gap-6 md:grid-cols-2 xl:grid-cols-3", children: rows.map((row) => /* @__PURE__ */ jsx("div", { children: row.node }, row.key)) }) }),
668
462
  /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-gray-100 bg-white p-6 sm:p-8", children: [
669
463
  /* @__PURE__ */ jsx("h2", { className: "mb-4 text-lg font-medium text-gray-900", children: "Additional License Fields" }),
670
464
  /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: renderFields(license.fields ?? []) })