@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.
- package/components/metadata/registry.json +2 -2
- package/components/metadata/registry.md +2 -2
- package/dist/actions/change-team.js +66 -7
- package/dist/actions/change-team.js.map +1 -1
- package/dist/actions/index.d.mts +3 -1
- package/dist/actions/index.d.ts +3 -1
- package/dist/actions/index.js +182 -465
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/install-actions.d.mts +3 -1
- package/dist/actions/install-actions.d.ts +3 -1
- package/dist/actions/install-actions.js +58 -5
- package/dist/actions/install-actions.js.map +1 -1
- package/dist/actions/service-account.d.mts +3 -1
- package/dist/actions/service-account.d.ts +3 -1
- package/dist/actions/service-account.js +58 -5
- package/dist/actions/service-account.js.map +1 -1
- package/dist/actions/support-bundles.d.mts +3 -1
- package/dist/actions/support-bundles.d.ts +3 -1
- package/dist/actions/support-bundles.js +58 -5
- package/dist/actions/support-bundles.js.map +1 -1
- package/dist/actions/team-settings.d.mts +3 -1
- package/dist/actions/team-settings.d.ts +3 -1
- package/dist/actions/team-settings.js +91 -27
- package/dist/actions/team-settings.js.map +1 -1
- package/dist/actions/trial-signup.d.mts +24 -0
- package/dist/actions/trial-signup.d.ts +24 -0
- package/dist/actions/trial-signup.js +482 -0
- package/dist/actions/trial-signup.js.map +1 -0
- package/dist/actions/user-settings.d.mts +3 -1
- package/dist/actions/user-settings.d.ts +3 -1
- package/dist/actions/user-settings.js +58 -5
- package/dist/actions/user-settings.js.map +1 -1
- package/dist/airgap-instances.d.mts +3 -1
- package/dist/airgap-instances.d.ts +3 -1
- package/dist/airgap-instances.js +41 -112
- package/dist/airgap-instances.js.map +1 -1
- package/dist/branding-BsMSywts.d.mts +36 -0
- package/dist/branding-BsMSywts.d.ts +36 -0
- package/dist/error-page.js +10 -2
- package/dist/error-page.js.map +1 -1
- package/dist/error.js +10 -2
- package/dist/error.js.map +1 -1
- package/dist/esm/actions/change-team.js +66 -7
- package/dist/esm/actions/change-team.js.map +1 -1
- package/dist/esm/actions/index.js +181 -462
- package/dist/esm/actions/index.js.map +1 -1
- package/dist/esm/actions/install-actions.js +58 -5
- package/dist/esm/actions/install-actions.js.map +1 -1
- package/dist/esm/actions/service-account.js +58 -5
- package/dist/esm/actions/service-account.js.map +1 -1
- package/dist/esm/actions/support-bundles.js +58 -5
- package/dist/esm/actions/support-bundles.js.map +1 -1
- package/dist/esm/actions/team-settings.js +91 -27
- package/dist/esm/actions/team-settings.js.map +1 -1
- package/dist/esm/actions/trial-signup.js +478 -0
- package/dist/esm/actions/trial-signup.js.map +1 -0
- package/dist/esm/actions/user-settings.js +58 -5
- package/dist/esm/actions/user-settings.js.map +1 -1
- package/dist/esm/airgap-instances.js +40 -112
- package/dist/esm/airgap-instances.js.map +1 -1
- package/dist/esm/error-page.js +10 -2
- package/dist/esm/error-page.js.map +1 -1
- package/dist/esm/error.js +10 -2
- package/dist/esm/error.js.map +1 -1
- package/dist/esm/helm-install-wizard.js +118 -79
- package/dist/esm/helm-install-wizard.js.map +1 -1
- package/dist/esm/index.js +706 -438
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/install-actions.js +40 -5
- package/dist/esm/install-actions.js.map +1 -1
- package/dist/esm/install-card.js +9 -6
- package/dist/esm/install-card.js.map +1 -1
- package/dist/esm/install-targets.js +9 -2
- package/dist/esm/install-targets.js.map +1 -1
- package/dist/esm/instance-card.js +39 -111
- package/dist/esm/instance-card.js.map +1 -1
- package/dist/esm/join-team.js +9 -3
- package/dist/esm/join-team.js.map +1 -1
- package/dist/esm/license-card.js +24 -22
- package/dist/esm/license-card.js.map +1 -1
- package/dist/esm/license-details.js +128 -334
- package/dist/esm/license-details.js.map +1 -1
- package/dist/esm/linux-install-wizard.js +95 -41
- package/dist/esm/linux-install-wizard.js.map +1 -1
- package/dist/esm/login.js +20 -4
- package/dist/esm/login.js.map +1 -1
- package/dist/esm/middleware.js +33 -0
- package/dist/esm/middleware.js.map +1 -0
- package/dist/esm/online-instance-list.js +40 -112
- package/dist/esm/online-instance-list.js.map +1 -1
- package/dist/esm/release-history-panel.js +27 -14
- package/dist/esm/release-history-panel.js.map +1 -1
- package/dist/esm/saml-callback-client.js +82 -0
- package/dist/esm/saml-callback-client.js.map +1 -0
- package/dist/esm/saml-handlers.js +138 -0
- package/dist/esm/saml-handlers.js.map +1 -0
- package/dist/esm/security-card.js +53 -38
- package/dist/esm/security-card.js.map +1 -1
- package/dist/esm/service-accounts-tab.js +800 -0
- package/dist/esm/service-accounts-tab.js.map +1 -0
- package/dist/esm/support-bundle-collection-card.js +48 -24
- package/dist/esm/support-bundle-collection-card.js.map +1 -1
- package/dist/esm/support-bundles-card.js +10 -5
- package/dist/esm/support-bundles-card.js.map +1 -1
- package/dist/esm/support-card.js +37 -5
- package/dist/esm/support-card.js.map +1 -1
- package/dist/esm/team-selection.js +5 -1
- package/dist/esm/team-selection.js.map +1 -1
- package/dist/esm/team-settings-card.js +5 -2
- package/dist/esm/team-settings-card.js.map +1 -1
- package/dist/esm/team-settings.js +7 -2
- package/dist/esm/team-settings.js.map +1 -1
- package/dist/esm/top-nav-user-menu.js +5 -1
- package/dist/esm/top-nav-user-menu.js.map +1 -1
- package/dist/esm/top-nav.js +175 -62
- package/dist/esm/top-nav.js.map +1 -1
- package/dist/esm/trial-signup.js +256 -0
- package/dist/esm/trial-signup.js.map +1 -0
- package/dist/esm/update-layout.js +175 -62
- package/dist/esm/update-layout.js.map +1 -1
- package/dist/esm/updates-card.js +15 -4
- package/dist/esm/updates-card.js.map +1 -1
- package/dist/esm/upload-support-bundle-modal.js +9 -4
- package/dist/esm/upload-support-bundle-modal.js.map +1 -1
- package/dist/esm/user-settings-card.js +5 -2
- package/dist/esm/user-settings-card.js.map +1 -1
- package/dist/esm/user-settings.js +12 -6
- package/dist/esm/user-settings.js.map +1 -1
- package/dist/esm/utils/index.js +204 -13
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/fetch-license-iTyF7_GY.d.mts +81 -0
- package/dist/fetch-license-iTyF7_GY.d.ts +81 -0
- package/dist/helm-install-wizard.d.mts +11 -3
- package/dist/helm-install-wizard.d.ts +11 -3
- package/dist/helm-install-wizard.js +118 -79
- package/dist/helm-install-wizard.js.map +1 -1
- package/dist/{index-BAiVrSSR.d.mts → index-DyzJ0yKD.d.mts} +48 -50
- package/dist/{index-DWt-N5od.d.ts → index-sMbq94M7.d.ts} +48 -50
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +726 -438
- package/dist/index.js.map +1 -1
- package/dist/install-actions.d.mts +4 -2
- package/dist/install-actions.d.ts +4 -2
- package/dist/install-actions.js +40 -5
- package/dist/install-actions.js.map +1 -1
- package/dist/install-card.d.mts +2 -3
- package/dist/install-card.d.ts +2 -3
- package/dist/install-card.js +9 -6
- package/dist/install-card.js.map +1 -1
- package/dist/install-targets.js +9 -2
- package/dist/install-targets.js.map +1 -1
- package/dist/instance-card.d.mts +3 -1
- package/dist/instance-card.d.ts +3 -1
- package/dist/instance-card.js +40 -111
- package/dist/instance-card.js.map +1 -1
- package/dist/join-team.js +9 -3
- package/dist/join-team.js.map +1 -1
- package/dist/license-card.d.mts +2 -3
- package/dist/license-card.d.ts +2 -3
- package/dist/license-card.js +24 -22
- package/dist/license-card.js.map +1 -1
- package/dist/license-details.js +128 -334
- package/dist/license-details.js.map +1 -1
- package/dist/linux-install-wizard.d.mts +9 -3
- package/dist/linux-install-wizard.d.ts +9 -3
- package/dist/linux-install-wizard.js +95 -41
- package/dist/linux-install-wizard.js.map +1 -1
- package/dist/login.d.mts +4 -0
- package/dist/login.d.ts +4 -0
- package/dist/login.js +20 -4
- package/dist/login.js.map +1 -1
- package/dist/middleware.d.mts +13 -0
- package/dist/middleware.d.ts +13 -0
- package/dist/middleware.js +35 -0
- package/dist/middleware.js.map +1 -0
- package/dist/online-instance-list.d.mts +3 -1
- package/dist/online-instance-list.d.ts +3 -1
- package/dist/online-instance-list.js +41 -112
- package/dist/online-instance-list.js.map +1 -1
- package/dist/pending-installations.d.mts +3 -1
- package/dist/pending-installations.d.ts +3 -1
- package/dist/release-history-panel.js +27 -14
- package/dist/release-history-panel.js.map +1 -1
- package/dist/saml-callback-client.d.mts +36 -0
- package/dist/saml-callback-client.d.ts +36 -0
- package/dist/saml-callback-client.js +88 -0
- package/dist/saml-callback-client.js.map +1 -0
- package/dist/saml-handlers.d.mts +50 -0
- package/dist/saml-handlers.d.ts +50 -0
- package/dist/saml-handlers.js +141 -0
- package/dist/saml-handlers.js.map +1 -0
- package/dist/security-card.d.mts +3 -1
- package/dist/security-card.d.ts +3 -1
- package/dist/security-card.js +53 -38
- package/dist/security-card.js.map +1 -1
- package/dist/service-accounts-tab.d.mts +51 -0
- package/dist/service-accounts-tab.d.ts +51 -0
- package/dist/service-accounts-tab.js +802 -0
- package/dist/service-accounts-tab.js.map +1 -0
- package/dist/styles.css +375 -127
- package/dist/support-bundle-collection-card.d.mts +1 -1
- package/dist/support-bundle-collection-card.d.ts +1 -1
- package/dist/support-bundle-collection-card.js +47 -23
- package/dist/support-bundle-collection-card.js.map +1 -1
- package/dist/support-bundles-card.d.mts +4 -2
- package/dist/support-bundles-card.d.ts +4 -2
- package/dist/support-bundles-card.js +10 -5
- package/dist/support-bundles-card.js.map +1 -1
- package/dist/support-card.js +37 -5
- package/dist/support-card.js.map +1 -1
- package/dist/team-selection.js +5 -1
- package/dist/team-selection.js.map +1 -1
- package/dist/team-settings-card.js +5 -2
- package/dist/team-settings-card.js.map +1 -1
- package/dist/team-settings.js +7 -2
- package/dist/team-settings.js.map +1 -1
- package/dist/{top-nav-IRIn66wS.d.ts → top-nav-BUQAGoG1.d.mts} +14 -2
- package/dist/{top-nav-IRIn66wS.d.mts → top-nav-CEqw0KpO.d.ts} +14 -2
- package/dist/top-nav-user-menu.js +5 -1
- package/dist/top-nav-user-menu.js.map +1 -1
- package/dist/top-nav.d.mts +2 -1
- package/dist/top-nav.d.ts +2 -1
- package/dist/top-nav.js +175 -62
- package/dist/top-nav.js.map +1 -1
- package/dist/trial-signup.d.mts +31 -0
- package/dist/trial-signup.d.ts +31 -0
- package/dist/trial-signup.js +258 -0
- package/dist/trial-signup.js.map +1 -0
- package/dist/update-layout.js +175 -62
- package/dist/update-layout.js.map +1 -1
- package/dist/updates-card.js +15 -4
- package/dist/updates-card.js.map +1 -1
- package/dist/upload-support-bundle-modal.js +9 -4
- package/dist/upload-support-bundle-modal.js.map +1 -1
- package/dist/user-settings-card.js +5 -2
- package/dist/user-settings-card.js.map +1 -1
- package/dist/user-settings.js +12 -6
- package/dist/user-settings.js.map +1 -1
- package/dist/utils/index.d.mts +74 -16
- package/dist/utils/index.d.ts +74 -16
- package/dist/utils/index.js +215 -12
- package/dist/utils/index.js.map +1 -1
- package/package.json +37 -2
package/dist/esm/login.js
CHANGED
|
@@ -60,6 +60,9 @@ var Button = forwardRef(
|
|
|
60
60
|
}
|
|
61
61
|
);
|
|
62
62
|
Button.displayName = "Button";
|
|
63
|
+
|
|
64
|
+
// src/utils/constants.ts
|
|
65
|
+
var DEFAULT_PRIMARY_COLOR = "#4f46e5";
|
|
63
66
|
var Login = forwardRef(
|
|
64
67
|
({
|
|
65
68
|
logo,
|
|
@@ -70,6 +73,8 @@ var Login = forwardRef(
|
|
|
70
73
|
ctaLabel = "Continue with email \u2192",
|
|
71
74
|
initialEmail = "",
|
|
72
75
|
isSubmitting = false,
|
|
76
|
+
primaryColor,
|
|
77
|
+
secondaryColor,
|
|
73
78
|
onContinue,
|
|
74
79
|
onVerifyCode,
|
|
75
80
|
redirectPath = "/",
|
|
@@ -140,15 +145,18 @@ var Login = forwardRef(
|
|
|
140
145
|
{
|
|
141
146
|
ref,
|
|
142
147
|
className: [
|
|
143
|
-
"w-full max-w-xl rounded-3xl border-2
|
|
148
|
+
"w-full max-w-xl rounded-3xl border-2 bg-white p-12 shadow-xl",
|
|
144
149
|
"text-gray-900 transition-shadow",
|
|
145
150
|
className
|
|
146
151
|
].filter(Boolean).join(" "),
|
|
152
|
+
style: {
|
|
153
|
+
borderColor: secondaryColor || "#111827"
|
|
154
|
+
},
|
|
147
155
|
onSubmit: handleSubmit,
|
|
148
156
|
...props,
|
|
149
157
|
children: [
|
|
150
158
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-6 text-center", children: [
|
|
151
|
-
logo
|
|
159
|
+
logo,
|
|
152
160
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
153
161
|
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold tracking-tight text-gray-900", children: title }),
|
|
154
162
|
/* @__PURE__ */ jsx("p", { className: "mt-3 text-base text-gray-600", children: description })
|
|
@@ -204,7 +212,11 @@ var Login = forwardRef(
|
|
|
204
212
|
{
|
|
205
213
|
type: "submit",
|
|
206
214
|
size: "lg",
|
|
207
|
-
className: "w-full justify-center rounded-xl
|
|
215
|
+
className: "w-full justify-center rounded-xl text-white transition-[filter] hover:brightness-90",
|
|
216
|
+
style: {
|
|
217
|
+
backgroundColor: primaryColor || DEFAULT_PRIMARY_COLOR,
|
|
218
|
+
borderColor: primaryColor || DEFAULT_PRIMARY_COLOR
|
|
219
|
+
},
|
|
208
220
|
disabled,
|
|
209
221
|
isLoading: disabled,
|
|
210
222
|
children: ctaLabel
|
|
@@ -241,7 +253,11 @@ var Login = forwardRef(
|
|
|
241
253
|
{
|
|
242
254
|
type: "button",
|
|
243
255
|
size: "lg",
|
|
244
|
-
className: "w-full justify-center rounded-xl
|
|
256
|
+
className: "w-full justify-center rounded-xl text-white transition-[filter] hover:brightness-90",
|
|
257
|
+
style: {
|
|
258
|
+
backgroundColor: primaryColor || DEFAULT_PRIMARY_COLOR,
|
|
259
|
+
borderColor: primaryColor || DEFAULT_PRIMARY_COLOR
|
|
260
|
+
},
|
|
245
261
|
disabled: verificationCode.length !== 12 || verifying,
|
|
246
262
|
isLoading: verifying,
|
|
247
263
|
onClick: handleVerify,
|
package/dist/esm/login.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/button.tsx","../../src/components/login.tsx"],"names":["forwardRef","jsxs","jsx"],"mappings":"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","file":"login.js","sourcesContent":["import {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ReactNode\n} from \"react\";\n\nconst buttonVariants = [\"primary\", \"secondary\", \"ghost\", \"destructive\"] as const;\nconst buttonSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nconst variantStyles: Record<ButtonVariant, string> = {\n primary:\n \"bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-primary\",\n secondary:\n \"bg-secondary/20 text-secondary-foreground hover:bg-secondary/30 focus-visible:ring-secondary\",\n ghost:\n \"bg-transparent text-primary hover:bg-primary/10 focus-visible:ring-primary/60\",\n destructive:\n \"bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger\"\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n sm: \"h-8 px-3 text-sm\",\n md: \"h-10 px-4 text-sm\",\n lg: \"h-12 px-6 text-base\"\n};\n\nconst inlineFlexBase =\n \"inline-flex items-center justify-center gap-2 rounded-md font-medium tracking-tight transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-60\";\n\nconst Spinner = () => (\n <span className=\"inline-flex h-3.5 w-3.5 animate-spin items-center justify-center\">\n <span className=\"h-3 w-3 rounded-full border-2 border-transparent border-t-current\" />\n </span>\n);\n\nexport type ButtonVariant = (typeof buttonVariants)[number];\nexport type ButtonSize = (typeof buttonSizes)[number];\n\nexport interface ButtonProps extends ComponentPropsWithoutRef<\"button\"> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n isLoading?: boolean;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n}\n\nconst composeClassName = (\n ...values: Array<string | undefined | false>\n): string => values.filter(Boolean).join(\" \");\n\n/**\n * Button is the primary interactive primitive for triggering portal actions.\n * It is theme aware via CSS variables generated from portal tokens.\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = \"primary\",\n size = \"md\",\n type = \"button\",\n isLoading = false,\n leadingIcon,\n trailingIcon,\n disabled,\n className,\n children,\n ...props\n },\n ref\n ) => {\n const computedLeading = isLoading ? <Spinner /> : leadingIcon;\n const computedDisabled = disabled ?? isLoading;\n\n return (\n <button\n ref={ref}\n type={type}\n className={composeClassName(\n inlineFlexBase,\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n aria-busy={isLoading || undefined}\n disabled={computedDisabled}\n {...props}\n >\n {computedLeading ? (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {computedLeading}\n </span>\n ) : null}\n <span className=\"flex-1 whitespace-nowrap\">{children}</span>\n {trailingIcon ? (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {trailingIcon}\n </span>\n ) : null}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n","'use client';\n\nimport {\n forwardRef,\n useMemo,\n useState,\n type ComponentPropsWithoutRef,\n type FormEvent,\n type ReactNode\n} from \"react\";\n\nimport { Button } from \"./button\";\n\nexport interface LoginProps\n extends Omit<ComponentPropsWithoutRef<\"form\">, \"onSubmit\" | \"children\"> {\n logo?: ReactNode;\n title?: string;\n description?: string;\n label?: string;\n placeholder?: string;\n ctaLabel?: string;\n initialEmail?: string;\n isSubmitting?: boolean;\n /** \n * Called when user submits email. Return { showVerification: false } to prevent\n * showing the verification code form (e.g., for SAML redirect).\n */\n onContinue?: (email: string) => Promise<void | { showVerification: boolean }> | void | { showVerification: boolean };\n onVerifyCode?: (\n code: string,\n redirectPath: string\n ) => Promise<\n | void\n | { success: true }\n | { success: false; message?: string }\n >;\n redirectPath?: string;\n}\n\n/**\n * Login renders a compact form card tailored for portal authentication flows.\n * The component keeps styling self-contained so it can be dropped into the\n * local Next.js template without additional wrappers.\n */\nexport const Login = forwardRef<HTMLFormElement, LoginProps>(\n (\n {\n logo,\n title = \"Enterprise Factory Installation Portal\",\n description = \"Sign in to manage your enterprise installation\",\n label = \"Work email address\",\n placeholder = \"you@company.com\",\n ctaLabel = \"Continue with email →\",\n initialEmail = \"\",\n isSubmitting = false,\n onContinue,\n onVerifyCode,\n redirectPath = \"/\",\n className,\n ...props\n },\n ref\n ) => {\n const [mode, setMode] = useState<\"email\" | \"verify\">(\"email\");\n const [email, setEmail] = useState(initialEmail);\n const [submittedEmail, setSubmittedEmail] = useState(initialEmail);\n const [verificationCode, setVerificationCode] = useState(\"\");\n const [verifying, setVerifying] = useState(false);\n const [pending, setPending] = useState(false);\n const [verificationError, setVerificationError] = useState<string | null>(\n null\n );\n\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (!onContinue || mode !== \"email\") {\n return;\n }\n\n try {\n setPending(true);\n const result = await onContinue(email);\n \n // Check if we should show verification form\n // If result is { showVerification: false }, don't show it (e.g., SAML redirect)\n if (result && typeof result === \"object\" && \"showVerification\" in result && result.showVerification === false) {\n // Don't transition to verify mode - caller is handling redirect\n return;\n }\n \n // Show verification code form\n setSubmittedEmail(email);\n setVerificationCode(\"\");\n setVerificationError(null);\n setMode(\"verify\");\n } finally {\n setPending(false);\n }\n };\n\n const disabled = mode === \"email\" && (isSubmitting || pending);\n const verificationMessage = useMemo(() => {\n if (!submittedEmail) {\n return null;\n }\n return `If there is an account for ${submittedEmail}, an email will be sent with a login code.`;\n }, [submittedEmail]);\n\n const handleVerify = async () => {\n if (!onVerifyCode || !verificationCode) {\n return;\n }\n try {\n setVerificationError(null);\n setVerifying(true);\n const result = await onVerifyCode(verificationCode, redirectPath);\n if (\n result &&\n typeof result === \"object\" &&\n \"success\" in result &&\n (result as { success?: unknown }).success === false\n ) {\n const message =\n (result as { message?: string }).message ??\n \"Unable to verify code. Try again.\";\n setVerificationError(message);\n return;\n }\n setVerificationCode(\"\");\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof (error as { message?: unknown }).message === \"string\"\n ) {\n setVerificationError((error as { message: string }).message);\n } else {\n setVerificationError(\"Unable to verify code. Try again.\");\n }\n } finally {\n setVerifying(false);\n }\n };\n\n return (\n <form\n ref={ref}\n className={[\n \"w-full max-w-xl rounded-3xl border-2 border-gray-900 bg-white p-12 shadow-xl\",\n \"text-gray-900 transition-shadow\",\n className\n ]\n .filter(Boolean)\n .join(\" \")}\n onSubmit={handleSubmit}\n {...props}\n >\n <div className=\"flex flex-col items-center gap-6 text-center\">\n {logo ?? (\n <div className=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-gradient-to-br from-blue-500 to-violet-500 text-lg font-semibold leading-tight text-white\">\n EP\n </div>\n )}\n <div>\n <h1 className=\"text-3xl font-bold tracking-tight text-gray-900\">\n {title}\n </h1>\n <p className=\"mt-3 text-base text-gray-600\">{description}</p>\n </div>\n </div>\n {mode === \"email\" ? (\n <div className=\"mt-10 space-y-4\">\n <label\n htmlFor=\"login-email\"\n className=\"block text-sm font-medium text-gray-700\"\n >\n {label}\n </label>\n <div className=\"relative\">\n <div className=\"pointer-events-none absolute inset-y-0 left-0 flex items-center pl-4\">\n <svg\n className=\"h-5 w-5 text-gray-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n </div>\n <input\n id=\"login-email\"\n type=\"email\"\n inputMode=\"email\"\n autoComplete=\"email\"\n placeholder={placeholder}\n value={email}\n onChange={(event) => setEmail(event.target.value)}\n className=\"portal-input w-full py-4 pr-4 text-base\"\n style={{ paddingLeft: '3rem' }}\n disabled={disabled}\n required\n />\n </div>\n <Button\n type=\"submit\"\n size=\"lg\"\n className=\"w-full justify-center rounded-xl bg-indigo-600 text-white hover:bg-indigo-700\"\n disabled={disabled}\n isLoading={disabled}\n >\n {ctaLabel}\n </Button>\n </div>\n ) : (\n <div className=\"mt-10 space-y-4\">\n <div>\n <p className=\"text-sm font-semibold text-gray-900\">\n Verification Code\n </p>\n {verificationMessage ? (\n <p className=\"mt-2 text-sm text-gray-600\">{verificationMessage}</p>\n ) : null}\n {verificationError ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {verificationError}\n </p>\n ) : null}\n </div>\n <label\n htmlFor=\"login-code\"\n className=\"block text-sm font-medium text-gray-700\"\n >\n One-time code\n </label>\n <input\n id=\"login-code\"\n inputMode=\"numeric\"\n maxLength={12}\n placeholder=\"Enter 12 digit code\"\n className=\"portal-input w-full px-5 py-4 text-base\"\n value={verificationCode}\n onChange={(event) => setVerificationCode(event.target.value)}\n />\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"w-full justify-center rounded-xl bg-indigo-600 text-white hover:bg-indigo-700\"\n disabled={verificationCode.length !== 12 || verifying}\n isLoading={verifying}\n onClick={handleVerify}\n >\n Verify code\n </Button>\n </div>\n )}\n </form>\n );\n }\n);\n\nLogin.displayName = \"Login\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/button.tsx","../../src/utils/constants.ts","../../src/components/login.tsx"],"names":["forwardRef","jsxs","jsx"],"mappings":"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","file":"login.js","sourcesContent":["import {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ReactNode\n} from \"react\";\n\nconst buttonVariants = [\"primary\", \"secondary\", \"ghost\", \"destructive\"] as const;\nconst buttonSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nconst variantStyles: Record<ButtonVariant, string> = {\n primary:\n \"bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-primary\",\n secondary:\n \"bg-secondary/20 text-secondary-foreground hover:bg-secondary/30 focus-visible:ring-secondary\",\n ghost:\n \"bg-transparent text-primary hover:bg-primary/10 focus-visible:ring-primary/60\",\n destructive:\n \"bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger\"\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n sm: \"h-8 px-3 text-sm\",\n md: \"h-10 px-4 text-sm\",\n lg: \"h-12 px-6 text-base\"\n};\n\nconst inlineFlexBase =\n \"inline-flex items-center justify-center gap-2 rounded-md font-medium tracking-tight transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-60\";\n\nconst Spinner = () => (\n <span className=\"inline-flex h-3.5 w-3.5 animate-spin items-center justify-center\">\n <span className=\"h-3 w-3 rounded-full border-2 border-transparent border-t-current\" />\n </span>\n);\n\nexport type ButtonVariant = (typeof buttonVariants)[number];\nexport type ButtonSize = (typeof buttonSizes)[number];\n\nexport interface ButtonProps extends ComponentPropsWithoutRef<\"button\"> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n isLoading?: boolean;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n}\n\nconst composeClassName = (\n ...values: Array<string | undefined | false>\n): string => values.filter(Boolean).join(\" \");\n\n/**\n * Button is the primary interactive primitive for triggering portal actions.\n * It is theme aware via CSS variables generated from portal tokens.\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = \"primary\",\n size = \"md\",\n type = \"button\",\n isLoading = false,\n leadingIcon,\n trailingIcon,\n disabled,\n className,\n children,\n ...props\n },\n ref\n ) => {\n const computedLeading = isLoading ? <Spinner /> : leadingIcon;\n const computedDisabled = disabled ?? isLoading;\n\n return (\n <button\n ref={ref}\n type={type}\n className={composeClassName(\n inlineFlexBase,\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n aria-busy={isLoading || undefined}\n disabled={computedDisabled}\n {...props}\n >\n {computedLeading ? (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {computedLeading}\n </span>\n ) : null}\n <span className=\"flex-1 whitespace-nowrap\">{children}</span>\n {trailingIcon ? (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {trailingIcon}\n </span>\n ) : null}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n","/**\n * Default globe favicon matching the CiGlobe icon (Circum Icons)\n * Used as fallback when custom branding doesn't provide a favicon\n */\nexport const DEFAULT_FAVICON = \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='1.5'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cellipse cx='12' cy='12' rx='4' ry='10'/%3E%3Cpath d='M2 12h20'/%3E%3C/svg%3E\";\n\n/**\n * Default primary brand color\n */\nexport const DEFAULT_PRIMARY_COLOR = \"#4f46e5\";\n\n/**\n * Default secondary brand color\n */\nexport const DEFAULT_SECONDARY_COLOR = \"#6366f1\";\n\n/**\n * Check if the API origin is HTTP (used for repldev environments)\n * This determines cookie security settings for cross-origin iframes\n * @returns true if the API origin starts with http:// (not https://)\n */\nexport const isHttpApiOrigin = (): boolean => {\n return process.env.REPLICATED_APP_ORIGIN?.startsWith('http://') || false;\n};\n","'use client';\n\nimport {\n forwardRef,\n useMemo,\n useState,\n type ComponentPropsWithoutRef,\n type FormEvent,\n type ReactNode\n} from \"react\";\n\nimport { Button } from \"./button\";\nimport { DEFAULT_PRIMARY_COLOR } from \"../utils/constants\";\n\nexport interface LoginProps\n extends Omit<ComponentPropsWithoutRef<\"form\">, \"onSubmit\" | \"children\"> {\n logo?: ReactNode;\n title?: string;\n description?: string;\n label?: string;\n placeholder?: string;\n ctaLabel?: string;\n initialEmail?: string;\n isSubmitting?: boolean;\n /** Primary color for buttons */\n primaryColor?: string;\n /** Secondary color for borders/accents */\n secondaryColor?: string;\n /** \n * Called when user submits email. Return { showVerification: false } to prevent\n * showing the verification code form (e.g., for SAML redirect).\n */\n onContinue?: (email: string) => Promise<void | { showVerification: boolean }> | void | { showVerification: boolean };\n onVerifyCode?: (\n code: string,\n redirectPath: string\n ) => Promise<\n | void\n | { success: true }\n | { success: false; message?: string }\n >;\n redirectPath?: string;\n}\n\n/**\n * Login renders a compact form card tailored for portal authentication flows.\n * The component keeps styling self-contained so it can be dropped into the\n * local Next.js template without additional wrappers.\n */\nexport const Login = forwardRef<HTMLFormElement, LoginProps>(\n (\n {\n logo,\n title = \"Enterprise Factory Installation Portal\",\n description = \"Sign in to manage your enterprise installation\",\n label = \"Work email address\",\n placeholder = \"you@company.com\",\n ctaLabel = \"Continue with email →\",\n initialEmail = \"\",\n isSubmitting = false,\n primaryColor,\n secondaryColor,\n onContinue,\n onVerifyCode,\n redirectPath = \"/\",\n className,\n ...props\n },\n ref\n ) => {\n const [mode, setMode] = useState<\"email\" | \"verify\">(\"email\");\n const [email, setEmail] = useState(initialEmail);\n const [submittedEmail, setSubmittedEmail] = useState(initialEmail);\n const [verificationCode, setVerificationCode] = useState(\"\");\n const [verifying, setVerifying] = useState(false);\n const [pending, setPending] = useState(false);\n const [verificationError, setVerificationError] = useState<string | null>(\n null\n );\n\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (!onContinue || mode !== \"email\") {\n return;\n }\n\n try {\n setPending(true);\n const result = await onContinue(email);\n \n // Check if we should show verification form\n // If result is { showVerification: false }, don't show it (e.g., SAML redirect)\n if (result && typeof result === \"object\" && \"showVerification\" in result && result.showVerification === false) {\n // Don't transition to verify mode - caller is handling redirect\n return;\n }\n \n // Show verification code form\n setSubmittedEmail(email);\n setVerificationCode(\"\");\n setVerificationError(null);\n setMode(\"verify\");\n } finally {\n setPending(false);\n }\n };\n\n const disabled = mode === \"email\" && (isSubmitting || pending);\n const verificationMessage = useMemo(() => {\n if (!submittedEmail) {\n return null;\n }\n return `If there is an account for ${submittedEmail}, an email will be sent with a login code.`;\n }, [submittedEmail]);\n\n const handleVerify = async () => {\n if (!onVerifyCode || !verificationCode) {\n return;\n }\n try {\n setVerificationError(null);\n setVerifying(true);\n const result = await onVerifyCode(verificationCode, redirectPath);\n if (\n result &&\n typeof result === \"object\" &&\n \"success\" in result &&\n (result as { success?: unknown }).success === false\n ) {\n const message =\n (result as { message?: string }).message ??\n \"Unable to verify code. Try again.\";\n setVerificationError(message);\n return;\n }\n setVerificationCode(\"\");\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof (error as { message?: unknown }).message === \"string\"\n ) {\n setVerificationError((error as { message: string }).message);\n } else {\n setVerificationError(\"Unable to verify code. Try again.\");\n }\n } finally {\n setVerifying(false);\n }\n };\n\n return (\n <form\n ref={ref}\n className={[\n \"w-full max-w-xl rounded-3xl border-2 bg-white p-12 shadow-xl\",\n \"text-gray-900 transition-shadow\",\n className\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{\n borderColor: secondaryColor || '#111827',\n }}\n onSubmit={handleSubmit}\n {...props}\n >\n <div className=\"flex flex-col items-center gap-6 text-center\">\n {logo}\n <div>\n <h1 className=\"text-3xl font-bold tracking-tight text-gray-900\">\n {title}\n </h1>\n <p className=\"mt-3 text-base text-gray-600\">{description}</p>\n </div>\n </div>\n {mode === \"email\" ? (\n <div className=\"mt-10 space-y-4\">\n <label\n htmlFor=\"login-email\"\n className=\"block text-sm font-medium text-gray-700\"\n >\n {label}\n </label>\n <div className=\"relative\">\n <div className=\"pointer-events-none absolute inset-y-0 left-0 flex items-center pl-4\">\n <svg\n className=\"h-5 w-5 text-gray-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n </div>\n <input\n id=\"login-email\"\n type=\"email\"\n inputMode=\"email\"\n autoComplete=\"email\"\n placeholder={placeholder}\n value={email}\n onChange={(event) => setEmail(event.target.value)}\n className=\"portal-input w-full py-4 pr-4 text-base\"\n style={{ paddingLeft: '3rem' }}\n disabled={disabled}\n required\n />\n </div>\n <Button\n type=\"submit\"\n size=\"lg\"\n className=\"w-full justify-center rounded-xl text-white transition-[filter] hover:brightness-90\"\n style={{\n backgroundColor: primaryColor || DEFAULT_PRIMARY_COLOR,\n borderColor: primaryColor || DEFAULT_PRIMARY_COLOR,\n }}\n disabled={disabled}\n isLoading={disabled}\n >\n {ctaLabel}\n </Button>\n </div>\n ) : (\n <div className=\"mt-10 space-y-4\">\n <div>\n <p className=\"text-sm font-semibold text-gray-900\">\n Verification Code\n </p>\n {verificationMessage ? (\n <p className=\"mt-2 text-sm text-gray-600\">{verificationMessage}</p>\n ) : null}\n {verificationError ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {verificationError}\n </p>\n ) : null}\n </div>\n <label\n htmlFor=\"login-code\"\n className=\"block text-sm font-medium text-gray-700\"\n >\n One-time code\n </label>\n <input\n id=\"login-code\"\n inputMode=\"numeric\"\n maxLength={12}\n placeholder=\"Enter 12 digit code\"\n className=\"portal-input w-full px-5 py-4 text-base\"\n value={verificationCode}\n onChange={(event) => setVerificationCode(event.target.value)}\n />\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"w-full justify-center rounded-xl text-white transition-[filter] hover:brightness-90\"\n style={{\n backgroundColor: primaryColor || DEFAULT_PRIMARY_COLOR,\n borderColor: primaryColor || DEFAULT_PRIMARY_COLOR,\n }}\n disabled={verificationCode.length !== 12 || verifying}\n isLoading={verifying}\n onClick={handleVerify}\n >\n Verify code\n </Button>\n </div>\n )}\n </form>\n );\n }\n);\n\nLogin.displayName = \"Login\";\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enterprise Portal Components
|
|
5
|
+
* This file is generated by tsup. Do not edit manually.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
function portalMiddleware(request) {
|
|
9
|
+
const url = request.nextUrl;
|
|
10
|
+
const pathname = url.pathname;
|
|
11
|
+
if (pathname === "/" && url.searchParams.get("expired") === "1") {
|
|
12
|
+
const basePath = process.env.NEXT_PUBLIC_BASE_PATH;
|
|
13
|
+
const redirectUrl = new URL(basePath || "/", request.url);
|
|
14
|
+
const response = NextResponse.redirect(redirectUrl);
|
|
15
|
+
response.cookies.delete("portal_session");
|
|
16
|
+
return response;
|
|
17
|
+
}
|
|
18
|
+
const appSlug = process.env.PORTAL_APP_SLUG;
|
|
19
|
+
if (appSlug && (pathname === `/${appSlug}` || pathname.startsWith(`/${appSlug}/`))) {
|
|
20
|
+
const basePath = process.env.NEXT_PUBLIC_BASE_PATH;
|
|
21
|
+
const newPathname = pathname.slice(appSlug.length + 1) || "/";
|
|
22
|
+
const fullPath = basePath ? `${basePath}${newPathname}` : newPathname;
|
|
23
|
+
const normalizedPath = fullPath.length > 1 ? fullPath.replace(/\/$/, "") : fullPath;
|
|
24
|
+
const newUrl = new URL(normalizedPath, request.url);
|
|
25
|
+
newUrl.search = url.search;
|
|
26
|
+
return NextResponse.redirect(newUrl);
|
|
27
|
+
}
|
|
28
|
+
return NextResponse.next();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { portalMiddleware };
|
|
32
|
+
//# sourceMappingURL=middleware.js.map
|
|
33
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/middleware.ts"],"names":[],"mappings":";;;;;;;AAWO,SAAS,iBAAiB,OAAA,EAAsB;AACrD,EAAA,MAAM,MAAM,OAAA,CAAQ,OAAA;AACpB,EAAA,MAAM,WAAW,GAAA,CAAI,QAAA;AAGrB,EAAA,IAAI,aAAa,GAAA,IAAO,GAAA,CAAI,aAAa,GAAA,CAAI,SAAS,MAAM,GAAA,EAAK;AAE/D,IAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,qBAAA;AAC7B,IAAA,MAAM,cAAc,IAAI,GAAA,CAAI,QAAA,IAAY,GAAA,EAAK,QAAQ,GAAG,CAAA;AACxD,IAAA,MAAM,QAAA,GAAW,YAAA,CAAa,QAAA,CAAS,WAAW,CAAA;AAGlD,IAAA,QAAA,CAAS,OAAA,CAAQ,OAAO,gBAAgB,CAAA;AAExC,IAAA,OAAO,QAAA;AAAA,EACT;AAIA,EAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,eAAA;AAC5B,EAAA,IAAI,OAAA,KAAY,QAAA,KAAa,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,IAAM,SAAS,UAAA,CAAW,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,CAAG,CAAA,CAAA,EAAI;AAElF,IAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,qBAAA;AAC7B,IAAA,MAAM,cAAc,QAAA,CAAS,KAAA,CAAM,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,IAAK,GAAA;AAC1D,IAAA,MAAM,WAAW,QAAA,GAAW,CAAA,EAAG,QAAQ,CAAA,EAAG,WAAW,CAAA,CAAA,GAAK,WAAA;AAE1D,IAAA,MAAM,cAAA,GAAiB,SAAS,MAAA,GAAS,CAAA,GAAI,SAAS,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GAAI,QAAA;AAC3E,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,cAAA,EAAgB,QAAQ,GAAG,CAAA;AAClD,IAAA,MAAA,CAAO,SAAS,GAAA,CAAI,MAAA;AACpB,IAAA,OAAO,YAAA,CAAa,SAAS,MAAM,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO,aAAa,IAAA,EAAK;AAC3B","file":"middleware.js","sourcesContent":["import { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\n\n/**\n * Shared middleware for enterprise portal applications.\n * \n * Handles:\n * - Expired session redirects (deletes cookie and redirects to root)\n * - App slug prefix redirects (/{appSlug}/path → /path)\n * - Respects NEXT_PUBLIC_BASE_PATH for reverse proxy scenarios\n */\nexport function portalMiddleware(request: NextRequest) {\n const url = request.nextUrl;\n const pathname = url.pathname;\n\n // Check if this is a logout/expired session redirect\n if (pathname === \"/\" && url.searchParams.get(\"expired\") === \"1\") {\n // Redirect to the app's root (respecting basePath for proxied scenarios)\n const basePath = process.env.NEXT_PUBLIC_BASE_PATH;\n const redirectUrl = new URL(basePath || \"/\", request.url);\n const response = NextResponse.redirect(redirectUrl);\n \n // Delete the expired session cookie\n response.cookies.delete(\"portal_session\");\n \n return response;\n }\n\n // Handle app slug prefix: /{appSlug}/... → /...\n // Redirect to remove the app slug prefix from the URL (respecting basePath for proxied scenarios)\n const appSlug = process.env.PORTAL_APP_SLUG;\n if (appSlug && (pathname === `/${appSlug}` || pathname.startsWith(`/${appSlug}/`))) {\n // Redirect /{appSlug} → /, /{appSlug}/invite → /invite, etc.\n const basePath = process.env.NEXT_PUBLIC_BASE_PATH;\n const newPathname = pathname.slice(appSlug.length + 1) || \"/\";\n const fullPath = basePath ? `${basePath}${newPathname}` : newPathname;\n // Remove trailing slash unless it's the root path\n const normalizedPath = fullPath.length > 1 ? fullPath.replace(/\\/$/, '') : fullPath;\n const newUrl = new URL(normalizedPath, request.url);\n newUrl.search = url.search;\n return NextResponse.redirect(newUrl);\n }\n\n return NextResponse.next();\n}\n\n/**\n * Note: The middleware config matcher cannot be exported from this module.\n * Next.js requires it to be defined as a static object literal in each\n * template's middleware.ts file for build-time analysis.\n * \n * Recommended config for templates:\n * \n * export const config = {\n * matcher: [\n * \"/((?!api|_next/static|_next/image|favicon.ico).*)\",\n * ],\n * };\n */\n"]}
|
|
@@ -1,96 +1,38 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import Link from 'next/link';
|
|
4
|
+
import cx from 'classnames';
|
|
4
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Enterprise Portal Components
|
|
8
9
|
* This file is generated by tsup. Do not edit manually.
|
|
9
10
|
*/
|
|
10
|
-
var __create = Object.create;
|
|
11
|
-
var __defProp = Object.defineProperty;
|
|
12
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
17
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
-
};
|
|
19
|
-
var __copyProps = (to, from, except, desc) => {
|
|
20
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
-
for (let key of __getOwnPropNames(from))
|
|
22
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
-
}
|
|
25
|
-
return to;
|
|
26
|
-
};
|
|
27
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
28
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
29
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
30
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
31
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
32
|
-
!mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
33
|
-
mod
|
|
34
|
-
));
|
|
35
11
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (Array.isArray(arg)) {
|
|
59
|
-
return classNames.apply(null, arg);
|
|
60
|
-
}
|
|
61
|
-
if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]")) {
|
|
62
|
-
return arg.toString();
|
|
63
|
-
}
|
|
64
|
-
var classes = "";
|
|
65
|
-
for (var key in arg) {
|
|
66
|
-
if (hasOwn.call(arg, key) && arg[key]) {
|
|
67
|
-
classes = appendClass(classes, key);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return classes;
|
|
71
|
-
}
|
|
72
|
-
function appendClass(value, newClass) {
|
|
73
|
-
if (!newClass) {
|
|
74
|
-
return value;
|
|
75
|
-
}
|
|
76
|
-
if (value) {
|
|
77
|
-
return value + " " + newClass;
|
|
78
|
-
}
|
|
79
|
-
return value + newClass;
|
|
80
|
-
}
|
|
81
|
-
if (typeof module !== "undefined" && module.exports) {
|
|
82
|
-
classNames.default = classNames;
|
|
83
|
-
module.exports = classNames;
|
|
84
|
-
} else if (typeof define === "function" && typeof define.amd === "object" && define.amd) {
|
|
85
|
-
define("classnames", [], function() {
|
|
86
|
-
return classNames;
|
|
87
|
-
});
|
|
88
|
-
} else {
|
|
89
|
-
window.classNames = classNames;
|
|
90
|
-
}
|
|
91
|
-
})();
|
|
12
|
+
|
|
13
|
+
// src/utils/constants.ts
|
|
14
|
+
var DEFAULT_SECONDARY_COLOR = "#6366f1";
|
|
15
|
+
|
|
16
|
+
// src/utils/format.ts
|
|
17
|
+
function formatDateTimeLocal(dateString) {
|
|
18
|
+
if (!dateString) return "N/A";
|
|
19
|
+
try {
|
|
20
|
+
const date = new Date(dateString);
|
|
21
|
+
if (isNaN(date.getTime())) {
|
|
22
|
+
return dateString;
|
|
23
|
+
}
|
|
24
|
+
return date.toLocaleDateString("en-US", {
|
|
25
|
+
month: "numeric",
|
|
26
|
+
day: "numeric",
|
|
27
|
+
year: "numeric",
|
|
28
|
+
hour: "numeric",
|
|
29
|
+
minute: "2-digit",
|
|
30
|
+
hour12: true
|
|
31
|
+
});
|
|
32
|
+
} catch {
|
|
33
|
+
return "N/A";
|
|
92
34
|
}
|
|
93
|
-
}
|
|
35
|
+
}
|
|
94
36
|
|
|
95
37
|
// src/actions/instances.ts
|
|
96
38
|
var ACTIVE_INSTANCE_THRESHOLD_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -150,9 +92,6 @@ function getInstanceName(instance) {
|
|
|
150
92
|
const nameTag = instance.tags?.find((tag) => tag.key === "name");
|
|
151
93
|
return nameTag?.value || instance.id.slice(0, 7);
|
|
152
94
|
}
|
|
153
|
-
|
|
154
|
-
// src/components/app-status-badge.tsx
|
|
155
|
-
var import_classnames = __toESM(require_classnames());
|
|
156
95
|
var toTitle = (value) => {
|
|
157
96
|
const s = value.trim();
|
|
158
97
|
if (!s) return s;
|
|
@@ -276,7 +215,7 @@ function AppStatusBadge({
|
|
|
276
215
|
return /* @__PURE__ */ jsxs(
|
|
277
216
|
"span",
|
|
278
217
|
{
|
|
279
|
-
className: (
|
|
218
|
+
className: cx(
|
|
280
219
|
"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium",
|
|
281
220
|
getClassNameForType(type),
|
|
282
221
|
className
|
|
@@ -288,18 +227,6 @@ function AppStatusBadge({
|
|
|
288
227
|
}
|
|
289
228
|
);
|
|
290
229
|
}
|
|
291
|
-
function formatDateTime(dateString) {
|
|
292
|
-
if (!dateString) return "N/A";
|
|
293
|
-
const date = new Date(dateString);
|
|
294
|
-
return date.toLocaleDateString("en-US", {
|
|
295
|
-
month: "numeric",
|
|
296
|
-
day: "numeric",
|
|
297
|
-
year: "numeric",
|
|
298
|
-
hour: "numeric",
|
|
299
|
-
minute: "2-digit",
|
|
300
|
-
hour12: true
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
230
|
function UpdateBadge({ count }) {
|
|
304
231
|
if (count <= 0) return null;
|
|
305
232
|
return /* @__PURE__ */ jsx("span", { className: "ml-1.5 inline-flex h-5 w-5 items-center justify-center rounded-full bg-rose-500 text-xs font-medium text-white", children: count });
|
|
@@ -337,7 +264,7 @@ function InstanceCard({
|
|
|
337
264
|
channelReleases = [],
|
|
338
265
|
installOptions = [],
|
|
339
266
|
onUpdateClick,
|
|
340
|
-
primaryColor =
|
|
267
|
+
primaryColor = DEFAULT_SECONDARY_COLOR,
|
|
341
268
|
securityData = {},
|
|
342
269
|
securityDiffData = {},
|
|
343
270
|
securityEnabled = false
|
|
@@ -437,18 +364,28 @@ function InstanceCard({
|
|
|
437
364
|
instance.versionLabel || "Unknown",
|
|
438
365
|
/* @__PURE__ */ jsx(UpdateBadge, { count: availableUpdates })
|
|
439
366
|
] }),
|
|
440
|
-
instance.isAirgap && /* @__PURE__ */ jsx(
|
|
367
|
+
instance.isAirgap && /* @__PURE__ */ jsx(
|
|
368
|
+
"span",
|
|
369
|
+
{
|
|
370
|
+
className: "rounded-full px-2 py-0.5 text-xs font-medium",
|
|
371
|
+
style: {
|
|
372
|
+
backgroundColor: `var(--portal-branding-primary-light, ${DEFAULT_SECONDARY_COLOR}20)`,
|
|
373
|
+
color: `var(--portal-branding-primary, ${DEFAULT_SECONDARY_COLOR})`
|
|
374
|
+
},
|
|
375
|
+
children: "air gap"
|
|
376
|
+
}
|
|
377
|
+
),
|
|
441
378
|
installType && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600", children: installType }),
|
|
442
379
|
(instance.appStatus || instance.resourceStates && instance.resourceStates.length > 0) && /* @__PURE__ */ jsx(AppStatusBadge, { status: statusForBadge })
|
|
443
380
|
] }),
|
|
444
381
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-4", children: [
|
|
445
382
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
446
383
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500", children: "First check-in:" }),
|
|
447
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-600", children:
|
|
384
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-600", children: formatDateTimeLocal(instance.firstCheckin) })
|
|
448
385
|
] }),
|
|
449
386
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
450
387
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500", children: "Last check-in:" }),
|
|
451
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-600", children:
|
|
388
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-600", children: formatDateTimeLocal(instance.lastCheckin) })
|
|
452
389
|
] })
|
|
453
390
|
] }),
|
|
454
391
|
securityEnabled && hasSecurityInfo && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -495,7 +432,7 @@ var OnlineInstanceList = ({
|
|
|
495
432
|
channelReleases = [],
|
|
496
433
|
installOptions = [],
|
|
497
434
|
onUpdateClick,
|
|
498
|
-
primaryColor =
|
|
435
|
+
primaryColor = DEFAULT_SECONDARY_COLOR,
|
|
499
436
|
securityData = {},
|
|
500
437
|
securityDiffData = {},
|
|
501
438
|
securityEnabled = false,
|
|
@@ -573,15 +510,6 @@ var OnlineInstanceList = ({
|
|
|
573
510
|
] });
|
|
574
511
|
};
|
|
575
512
|
OnlineInstanceList.displayName = "OnlineInstanceList";
|
|
576
|
-
/*! Bundled license information:
|
|
577
|
-
|
|
578
|
-
classnames/index.js:
|
|
579
|
-
(*!
|
|
580
|
-
Copyright (c) 2018 Jed Watson.
|
|
581
|
-
Licensed under the MIT License (MIT), see
|
|
582
|
-
http://jedwatson.github.io/classnames
|
|
583
|
-
*)
|
|
584
|
-
*/
|
|
585
513
|
|
|
586
514
|
export { OnlineInstanceList };
|
|
587
515
|
//# sourceMappingURL=online-instance-list.js.map
|