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