@burdenoff/microfe-auth 2026.510.127
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/README.md +12 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/auth/AuthRoot.d.ts +30 -0
- package/dist/auth/AuthRoot.d.ts.map +1 -0
- package/dist/auth/AuthRoot.js +82 -0
- package/dist/auth/AuthRoot.js.map +1 -0
- package/dist/auth/AuthRoutes.d.ts +29 -0
- package/dist/auth/AuthRoutes.d.ts.map +1 -0
- package/dist/auth/AuthRoutes.js +271 -0
- package/dist/auth/AuthRoutes.js.map +1 -0
- package/dist/auth/components/AuthIcons.d.ts +17 -0
- package/dist/auth/components/AuthIcons.d.ts.map +1 -0
- package/dist/auth/components/AuthIcons.js +197 -0
- package/dist/auth/components/AuthIcons.js.map +1 -0
- package/dist/auth/components/AuthLayout.d.ts +17 -0
- package/dist/auth/components/AuthLayout.d.ts.map +1 -0
- package/dist/auth/components/AuthLayout.js +237 -0
- package/dist/auth/components/AuthLayout.js.map +1 -0
- package/dist/auth/components/CaptchaV2.d.ts +16 -0
- package/dist/auth/components/CaptchaV2.d.ts.map +1 -0
- package/dist/auth/components/CaptchaV2.js +47 -0
- package/dist/auth/components/CaptchaV2.js.map +1 -0
- package/dist/auth/components/ConfirmActionDialog.d.ts +16 -0
- package/dist/auth/components/ConfirmActionDialog.d.ts.map +1 -0
- package/dist/auth/components/ConfirmActionDialog.js +68 -0
- package/dist/auth/components/ConfirmActionDialog.js.map +1 -0
- package/dist/auth/components/index.d.ts +4 -0
- package/dist/auth/components/index.d.ts.map +1 -0
- package/dist/auth/components/profile/UserProfileMenu.d.ts +42 -0
- package/dist/auth/components/profile/UserProfileMenu.d.ts.map +1 -0
- package/dist/auth/components/profile/UserProfileMenu.js +91 -0
- package/dist/auth/components/profile/UserProfileMenu.js.map +1 -0
- package/dist/auth/components/workspace/WorkspaceSelector.d.ts +76 -0
- package/dist/auth/components/workspace/WorkspaceSelector.d.ts.map +1 -0
- package/dist/auth/components/workspace/WorkspaceSelector.js +240 -0
- package/dist/auth/components/workspace/WorkspaceSelector.js.map +1 -0
- package/dist/auth/constants/permissions.d.ts +30 -0
- package/dist/auth/constants/permissions.d.ts.map +1 -0
- package/dist/auth/constants/permissions.js +18 -0
- package/dist/auth/constants/permissions.js.map +1 -0
- package/dist/auth/constants/sessionKeys.d.ts +18 -0
- package/dist/auth/constants/sessionKeys.d.ts.map +1 -0
- package/dist/auth/constants/sessionKeys.js +6 -0
- package/dist/auth/constants/sessionKeys.js.map +1 -0
- package/dist/auth/hooks/index.d.ts +18 -0
- package/dist/auth/hooks/index.d.ts.map +1 -0
- package/dist/auth/hooks/index.js +16 -0
- package/dist/auth/hooks/useAccountOperations.d.ts +19 -0
- package/dist/auth/hooks/useAccountOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useAccountOperations.js +52 -0
- package/dist/auth/hooks/useAccountOperations.js.map +1 -0
- package/dist/auth/hooks/useApiKeyOperations.d.ts +22 -0
- package/dist/auth/hooks/useApiKeyOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useApiKeyOperations.js +4 -0
- package/dist/auth/hooks/useAppOperations.d.ts +26 -0
- package/dist/auth/hooks/useAppOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useAppOperations.js +4 -0
- package/dist/auth/hooks/useAuthOperations.d.ts +57 -0
- package/dist/auth/hooks/useAuthOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useAuthOperations.js +236 -0
- package/dist/auth/hooks/useAuthOperations.js.map +1 -0
- package/dist/auth/hooks/useAuthPermissions.d.ts +20 -0
- package/dist/auth/hooks/useAuthPermissions.d.ts.map +1 -0
- package/dist/auth/hooks/useAuthPermissions.js +22 -0
- package/dist/auth/hooks/useAuthPermissions.js.map +1 -0
- package/dist/auth/hooks/useCaptchaV3.d.ts +13 -0
- package/dist/auth/hooks/useCaptchaV3.d.ts.map +1 -0
- package/dist/auth/hooks/useCaptchaV3.js +19 -0
- package/dist/auth/hooks/useCaptchaV3.js.map +1 -0
- package/dist/auth/hooks/useContextSwitcherData.d.ts +106 -0
- package/dist/auth/hooks/useContextSwitcherData.d.ts.map +1 -0
- package/dist/auth/hooks/useContextSwitcherData.js +466 -0
- package/dist/auth/hooks/useContextSwitcherData.js.map +1 -0
- package/dist/auth/hooks/useDelegationOperations.d.ts +25 -0
- package/dist/auth/hooks/useDelegationOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useDelegationOperations.js +4 -0
- package/dist/auth/hooks/useMfaOperations.d.ts +18 -0
- package/dist/auth/hooks/useMfaOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useMfaOperations.js +103 -0
- package/dist/auth/hooks/useMfaOperations.js.map +1 -0
- package/dist/auth/hooks/useMyWorkspaces.d.ts +45 -0
- package/dist/auth/hooks/useMyWorkspaces.d.ts.map +1 -0
- package/dist/auth/hooks/useMyWorkspaces.js +140 -0
- package/dist/auth/hooks/useMyWorkspaces.js.map +1 -0
- package/dist/auth/hooks/useOAuthOperations.d.ts +19 -0
- package/dist/auth/hooks/useOAuthOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useOAuthOperations.js +103 -0
- package/dist/auth/hooks/useOAuthOperations.js.map +1 -0
- package/dist/auth/hooks/usePasswordOperations.d.ts +13 -0
- package/dist/auth/hooks/usePasswordOperations.d.ts.map +1 -0
- package/dist/auth/hooks/usePasswordOperations.js +56 -0
- package/dist/auth/hooks/usePasswordOperations.js.map +1 -0
- package/dist/auth/hooks/useSessionOperations.d.ts +41 -0
- package/dist/auth/hooks/useSessionOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useSessionOperations.js +59 -0
- package/dist/auth/hooks/useSessionOperations.js.map +1 -0
- package/dist/auth/hooks/useSsoOperations.d.ts +65 -0
- package/dist/auth/hooks/useSsoOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useSsoOperations.js +236 -0
- package/dist/auth/hooks/useSsoOperations.js.map +1 -0
- package/dist/auth/hooks/useTokenRefresh.d.ts +56 -0
- package/dist/auth/hooks/useTokenRefresh.d.ts.map +1 -0
- package/dist/auth/hooks/useTokenRefresh.js +53 -0
- package/dist/auth/hooks/useTokenRefresh.js.map +1 -0
- package/dist/auth/hooks/useUserOperations.d.ts +32 -0
- package/dist/auth/hooks/useUserOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useUserOperations.js +100 -0
- package/dist/auth/hooks/useUserOperations.js.map +1 -0
- package/dist/auth/hooks/useWorkspaceOperations.d.ts +35 -0
- package/dist/auth/hooks/useWorkspaceOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useWorkspaceOperations.js +35 -0
- package/dist/auth/hooks/useWorkspaceOperations.js.map +1 -0
- package/dist/auth/hooks/useWorkspaceToken.d.ts +56 -0
- package/dist/auth/hooks/useWorkspaceToken.d.ts.map +1 -0
- package/dist/auth/hooks/useWorkspaceToken.js +94 -0
- package/dist/auth/hooks/useWorkspaceToken.js.map +1 -0
- package/dist/auth/index.d.ts +63 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +18 -0
- package/dist/auth/pages/ApiKeysPage.d.ts +5 -0
- package/dist/auth/pages/ApiKeysPage.d.ts.map +1 -0
- package/dist/auth/pages/AppsPage.d.ts +5 -0
- package/dist/auth/pages/AppsPage.d.ts.map +1 -0
- package/dist/auth/pages/AuditLogPage.d.ts +5 -0
- package/dist/auth/pages/AuditLogPage.d.ts.map +1 -0
- package/dist/auth/pages/AuditLogPage.js +129 -0
- package/dist/auth/pages/AuditLogPage.js.map +1 -0
- package/dist/auth/pages/DelegationsPage.d.ts +5 -0
- package/dist/auth/pages/DelegationsPage.d.ts.map +1 -0
- package/dist/auth/pages/EmailVerifyPage.d.ts +5 -0
- package/dist/auth/pages/EmailVerifyPage.d.ts.map +1 -0
- package/dist/auth/pages/EmailVerifyPage.js +166 -0
- package/dist/auth/pages/EmailVerifyPage.js.map +1 -0
- package/dist/auth/pages/LoginPage.d.ts +6 -0
- package/dist/auth/pages/LoginPage.d.ts.map +1 -0
- package/dist/auth/pages/LoginPage.js +575 -0
- package/dist/auth/pages/LoginPage.js.map +1 -0
- package/dist/auth/pages/MagicLinkPage.d.ts +6 -0
- package/dist/auth/pages/MagicLinkPage.d.ts.map +1 -0
- package/dist/auth/pages/MagicLinkPage.js +219 -0
- package/dist/auth/pages/MagicLinkPage.js.map +1 -0
- package/dist/auth/pages/MfaSetupPage.d.ts +5 -0
- package/dist/auth/pages/MfaSetupPage.d.ts.map +1 -0
- package/dist/auth/pages/MfaSetupPage.js +341 -0
- package/dist/auth/pages/MfaSetupPage.js.map +1 -0
- package/dist/auth/pages/MfaVerifyPage.d.ts +7 -0
- package/dist/auth/pages/MfaVerifyPage.d.ts.map +1 -0
- package/dist/auth/pages/MfaVerifyPage.js +189 -0
- package/dist/auth/pages/MfaVerifyPage.js.map +1 -0
- package/dist/auth/pages/OAuthCallbackPage.d.ts +7 -0
- package/dist/auth/pages/OAuthCallbackPage.d.ts.map +1 -0
- package/dist/auth/pages/OAuthCallbackPage.js +100 -0
- package/dist/auth/pages/OAuthCallbackPage.js.map +1 -0
- package/dist/auth/pages/PasswordResetPage.d.ts +6 -0
- package/dist/auth/pages/PasswordResetPage.d.ts.map +1 -0
- package/dist/auth/pages/PasswordResetPage.js +352 -0
- package/dist/auth/pages/PasswordResetPage.js.map +1 -0
- package/dist/auth/pages/ReactivatePage.d.ts +6 -0
- package/dist/auth/pages/ReactivatePage.d.ts.map +1 -0
- package/dist/auth/pages/ReactivatePage.js +217 -0
- package/dist/auth/pages/ReactivatePage.js.map +1 -0
- package/dist/auth/pages/RegisterPage.d.ts +5 -0
- package/dist/auth/pages/RegisterPage.d.ts.map +1 -0
- package/dist/auth/pages/RegisterPage.js +439 -0
- package/dist/auth/pages/RegisterPage.js.map +1 -0
- package/dist/auth/pages/SSORelayCallbackPage.d.ts +8 -0
- package/dist/auth/pages/SSORelayCallbackPage.d.ts.map +1 -0
- package/dist/auth/pages/SSORelayCallbackPage.js +48 -0
- package/dist/auth/pages/SSORelayCallbackPage.js.map +1 -0
- package/dist/auth/pages/SSORelayPage.d.ts +18 -0
- package/dist/auth/pages/SSORelayPage.d.ts.map +1 -0
- package/dist/auth/pages/SSORelayPage.js +134 -0
- package/dist/auth/pages/SSORelayPage.js.map +1 -0
- package/dist/auth/pages/SecurityPage.d.ts +5 -0
- package/dist/auth/pages/SecurityPage.d.ts.map +1 -0
- package/dist/auth/pages/SecurityPage.js +587 -0
- package/dist/auth/pages/SecurityPage.js.map +1 -0
- package/dist/auth/pages/SessionBridgePage.d.ts +14 -0
- package/dist/auth/pages/SessionBridgePage.d.ts.map +1 -0
- package/dist/auth/pages/SessionBridgePage.js +231 -0
- package/dist/auth/pages/SessionBridgePage.js.map +1 -0
- package/dist/auth/pages/SessionsPage.d.ts +5 -0
- package/dist/auth/pages/SessionsPage.d.ts.map +1 -0
- package/dist/auth/pages/SessionsPage.js +258 -0
- package/dist/auth/pages/SessionsPage.js.map +1 -0
- package/dist/auth/pages/SsoCallbackPage.d.ts +8 -0
- package/dist/auth/pages/SsoCallbackPage.d.ts.map +1 -0
- package/dist/auth/pages/SsoCallbackPage.js +188 -0
- package/dist/auth/pages/SsoCallbackPage.js.map +1 -0
- package/dist/auth/pages/SsoConfigPage.d.ts +6 -0
- package/dist/auth/pages/SsoConfigPage.d.ts.map +1 -0
- package/dist/auth/pages/SsoConfigPage.js +1144 -0
- package/dist/auth/pages/SsoConfigPage.js.map +1 -0
- package/dist/auth/pages/SsoLoginPage.d.ts +7 -0
- package/dist/auth/pages/SsoLoginPage.d.ts.map +1 -0
- package/dist/auth/pages/SsoLoginPage.js +236 -0
- package/dist/auth/pages/SsoLoginPage.js.map +1 -0
- package/dist/auth/pages/UserDetailsPage.d.ts +11 -0
- package/dist/auth/pages/UserDetailsPage.d.ts.map +1 -0
- package/dist/auth/pages/UserDetailsPage.js +338 -0
- package/dist/auth/pages/UserDetailsPage.js.map +1 -0
- package/dist/auth/pages/UserProfilePage.d.ts +5 -0
- package/dist/auth/pages/UserProfilePage.d.ts.map +1 -0
- package/dist/auth/pages/UserProfilePage.js +445 -0
- package/dist/auth/pages/UserProfilePage.js.map +1 -0
- package/dist/auth/pages/UsersPage.d.ts +5 -0
- package/dist/auth/pages/UsersPage.d.ts.map +1 -0
- package/dist/auth/pages/UsersPage.js +899 -0
- package/dist/auth/pages/UsersPage.js.map +1 -0
- package/dist/auth/providers/AuthProvider.d.ts +18 -0
- package/dist/auth/providers/AuthProvider.d.ts.map +1 -0
- package/dist/auth/providers/AuthProvider.js +36 -0
- package/dist/auth/providers/AuthProvider.js.map +1 -0
- package/dist/auth/providers/CaptchaProvider.d.ts +13 -0
- package/dist/auth/providers/CaptchaProvider.d.ts.map +1 -0
- package/dist/auth/providers/CaptchaProvider.js +21 -0
- package/dist/auth/providers/CaptchaProvider.js.map +1 -0
- package/dist/auth/store/authStore.d.ts +91 -0
- package/dist/auth/store/authStore.d.ts.map +1 -0
- package/dist/auth/store/authStore.js +314 -0
- package/dist/auth/store/authStore.js.map +1 -0
- package/dist/auth/types/index.d.ts +636 -0
- package/dist/auth/types/index.d.ts.map +1 -0
- package/dist/auth/utils/captchaConfig.d.ts +4 -0
- package/dist/auth/utils/captchaConfig.d.ts.map +1 -0
- package/dist/auth/utils/captchaConfig.js +13 -0
- package/dist/auth/utils/captchaConfig.js.map +1 -0
- package/dist/auth/utils/formatters.d.ts +37 -0
- package/dist/auth/utils/formatters.d.ts.map +1 -0
- package/dist/auth/utils/formatters.js +48 -0
- package/dist/auth/utils/formatters.js.map +1 -0
- package/dist/auth/utils/gatewayBaseUrls.d.ts +6 -0
- package/dist/auth/utils/gatewayBaseUrls.d.ts.map +1 -0
- package/dist/auth/utils/gatewayBaseUrls.js +18 -0
- package/dist/auth/utils/gatewayBaseUrls.js.map +1 -0
- package/dist/auth/utils/index.d.ts +3 -0
- package/dist/auth/utils/index.d.ts.map +1 -0
- package/dist/auth/utils/validation.d.ts +30 -0
- package/dist/auth/utils/validation.d.ts.map +1 -0
- package/dist/auth/utils/validation.js +15 -0
- package/dist/auth/utils/validation.js.map +1 -0
- package/dist/dev/main.d.ts +2 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/generated/global-operations.d.ts +2978 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-operations.js +944 -0
- package/dist/generated/global-operations.js.map +1 -0
- package/dist/generated/global-types.d.ts +21253 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +2 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-types.d.ts +55214 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/microfe-auth.css +3 -0
- package/dist/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js +70 -0
- package/dist/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js.map +1 -0
- package/dist/node_modules/object-assign/index.js +41 -0
- package/dist/node_modules/object-assign/index.js.map +1 -0
- package/dist/node_modules/prop-types/checkPropTypes.js +46 -0
- package/dist/node_modules/prop-types/checkPropTypes.js.map +1 -0
- package/dist/node_modules/prop-types/factoryWithThrowingShims.js +49 -0
- package/dist/node_modules/prop-types/factoryWithThrowingShims.js.map +1 -0
- package/dist/node_modules/prop-types/factoryWithTypeCheckers.js +272 -0
- package/dist/node_modules/prop-types/factoryWithTypeCheckers.js.map +1 -0
- package/dist/node_modules/prop-types/index.js +16 -0
- package/dist/node_modules/prop-types/index.js.map +1 -0
- package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js +10 -0
- package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js.map +1 -0
- package/dist/node_modules/prop-types/lib/has.js +10 -0
- package/dist/node_modules/prop-types/lib/has.js.map +1 -0
- package/dist/node_modules/qrcode.react/lib/esm/index.js +959 -0
- package/dist/node_modules/qrcode.react/lib/esm/index.js.map +1 -0
- package/dist/node_modules/react-async-script/lib/esm/async-script-loader.js +114 -0
- package/dist/node_modules/react-async-script/lib/esm/async-script-loader.js.map +1 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/index.js +8 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/index.js.map +1 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha-wrapper.js +20 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha-wrapper.js.map +1 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha.js +148 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha.js.map +1 -0
- package/dist/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js +445 -0
- package/dist/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js.map +1 -0
- package/dist/node_modules/react-is/cjs/react-is.development.js +84 -0
- package/dist/node_modules/react-is/cjs/react-is.development.js.map +1 -0
- package/dist/node_modules/react-is/cjs/react-is.production.min.js +64 -0
- package/dist/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
- package/dist/node_modules/react-is/index.js +12 -0
- package/dist/node_modules/react-is/index.js.map +1 -0
- package/dist/shared/hooks/index.d.ts +7 -0
- package/dist/shared/hooks/index.d.ts.map +1 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/types/index.d.ts +109 -0
- package/dist/shared/types/index.d.ts.map +1 -0
- package/dist/utils/nativeBridge.d.ts +3 -0
- package/dist/utils/nativeBridge.d.ts.map +1 -0
- package/dist/utils/nativeBridge.js +2 -0
- package/package.json +114 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { AlertCircle as e, AlertTriangle as t, Info as n, Loader2 as r } from "lucide-react";
|
|
2
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
3
|
+
import { AlertDialog as o, AlertDialogAction as s, AlertDialogCancel as c, AlertDialogContent as l, AlertDialogDescription as u, AlertDialogFooter as d, AlertDialogHeader as f, AlertDialogTitle as p } from "@burdenoff/fe-libs/ui";
|
|
4
|
+
//#region src/auth/components/ConfirmActionDialog.tsx
|
|
5
|
+
var m = {
|
|
6
|
+
default: {
|
|
7
|
+
icon: n,
|
|
8
|
+
iconContainerClassName: "bg-[var(--color-status-info-bg-subtle)]",
|
|
9
|
+
iconClassName: "text-[var(--color-status-info-text)]",
|
|
10
|
+
actionClassName: "bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)] hover:opacity-90"
|
|
11
|
+
},
|
|
12
|
+
warning: {
|
|
13
|
+
icon: t,
|
|
14
|
+
iconContainerClassName: "bg-[var(--color-status-warning-bg-subtle)]",
|
|
15
|
+
iconClassName: "text-[var(--color-status-warning-text)]",
|
|
16
|
+
actionClassName: "bg-[var(--color-status-warning-bg)] text-[var(--color-text-inverse)] hover:opacity-90"
|
|
17
|
+
},
|
|
18
|
+
danger: {
|
|
19
|
+
icon: e,
|
|
20
|
+
iconContainerClassName: "bg-[var(--color-status-error-bg-subtle)]",
|
|
21
|
+
iconClassName: "text-[var(--color-status-error-text)]",
|
|
22
|
+
actionClassName: "bg-[var(--color-status-error-bg)] text-[var(--color-text-inverse)] hover:opacity-90"
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
function h({ open: e, onOpenChange: t, title: n, description: h, confirmText: g = "Confirm", cancelText: _ = "Cancel", variant: v = "default", isPending: y = !1, disabled: b = !1, onConfirm: x }) {
|
|
26
|
+
let S = m[v], C = S.icon;
|
|
27
|
+
return /* @__PURE__ */ i(o, {
|
|
28
|
+
open: e,
|
|
29
|
+
onOpenChange: t,
|
|
30
|
+
children: /* @__PURE__ */ a(l, {
|
|
31
|
+
className: "max-w-md border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)]",
|
|
32
|
+
children: [/* @__PURE__ */ i(f, { children: /* @__PURE__ */ a("div", {
|
|
33
|
+
className: "flex items-start gap-4",
|
|
34
|
+
children: [/* @__PURE__ */ i("div", {
|
|
35
|
+
className: `flex h-10 w-10 shrink-0 items-center justify-center rounded-full ${S.iconContainerClassName}`,
|
|
36
|
+
children: /* @__PURE__ */ i(C, { className: `h-5 w-5 ${S.iconClassName}` })
|
|
37
|
+
}), /* @__PURE__ */ a("div", {
|
|
38
|
+
className: "flex-1",
|
|
39
|
+
children: [/* @__PURE__ */ i(p, {
|
|
40
|
+
className: "text-lg text-[var(--color-text-primary)]",
|
|
41
|
+
children: n
|
|
42
|
+
}), /* @__PURE__ */ i(u, {
|
|
43
|
+
className: "mt-2 text-sm text-[var(--color-text-secondary)]",
|
|
44
|
+
children: h
|
|
45
|
+
})]
|
|
46
|
+
})]
|
|
47
|
+
}) }), /* @__PURE__ */ a(d, {
|
|
48
|
+
className: "mt-6",
|
|
49
|
+
children: [/* @__PURE__ */ i(c, {
|
|
50
|
+
disabled: y,
|
|
51
|
+
className: "border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] hover:bg-[var(--color-bg-subtle)]",
|
|
52
|
+
children: _
|
|
53
|
+
}), /* @__PURE__ */ a(s, {
|
|
54
|
+
disabled: b || y,
|
|
55
|
+
onClick: (e) => {
|
|
56
|
+
e.preventDefault(), x();
|
|
57
|
+
},
|
|
58
|
+
className: S.actionClassName,
|
|
59
|
+
children: [y ? /* @__PURE__ */ i(r, { className: "h-4 w-4 animate-spin" }) : null, g]
|
|
60
|
+
})]
|
|
61
|
+
})]
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { h as ConfirmActionDialog };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=ConfirmActionDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmActionDialog.js","names":[],"sources":["../../../src/auth/components/ConfirmActionDialog.tsx"],"sourcesContent":["import { AlertCircle, AlertTriangle, Info, Loader2 } from \"lucide-react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@burdenoff/fe-libs/ui\";\n\ntype ConfirmActionDialogVariant = \"default\" | \"warning\" | \"danger\";\n\ninterface ConfirmActionDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description: string;\n confirmText?: string;\n cancelText?: string;\n variant?: ConfirmActionDialogVariant;\n isPending?: boolean;\n disabled?: boolean;\n onConfirm: () => void | Promise<void>;\n}\n\nconst VARIANT_STYLES: Record<\n ConfirmActionDialogVariant,\n {\n icon: typeof Info;\n iconContainerClassName: string;\n iconClassName: string;\n actionClassName: string;\n }\n> = {\n default: {\n icon: Info,\n iconContainerClassName: \"bg-[var(--color-status-info-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-info-text)]\",\n actionClassName:\n \"bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)] hover:opacity-90\",\n },\n warning: {\n icon: AlertTriangle,\n iconContainerClassName: \"bg-[var(--color-status-warning-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-warning-text)]\",\n actionClassName:\n \"bg-[var(--color-status-warning-bg)] text-[var(--color-text-inverse)] hover:opacity-90\",\n },\n danger: {\n icon: AlertCircle,\n iconContainerClassName: \"bg-[var(--color-status-error-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-error-text)]\",\n actionClassName:\n \"bg-[var(--color-status-error-bg)] text-[var(--color-text-inverse)] hover:opacity-90\",\n },\n};\n\nexport function ConfirmActionDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmText = \"Confirm\",\n cancelText = \"Cancel\",\n variant = \"default\",\n isPending = false,\n disabled = false,\n onConfirm,\n}: ConfirmActionDialogProps) {\n const styles = VARIANT_STYLES[variant];\n const Icon = styles.icon;\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"max-w-md border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)]\">\n <AlertDialogHeader>\n <div className=\"flex items-start gap-4\">\n <div\n className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-full ${styles.iconContainerClassName}`}\n >\n <Icon className={`h-5 w-5 ${styles.iconClassName}`} />\n </div>\n <div className=\"flex-1\">\n <AlertDialogTitle className=\"text-lg text-[var(--color-text-primary)]\">\n {title}\n </AlertDialogTitle>\n <AlertDialogDescription className=\"mt-2 text-sm text-[var(--color-text-secondary)]\">\n {description}\n </AlertDialogDescription>\n </div>\n </div>\n </AlertDialogHeader>\n\n <AlertDialogFooter className=\"mt-6\">\n <AlertDialogCancel\n disabled={isPending}\n className=\"border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] hover:bg-[var(--color-bg-subtle)]\"\n >\n {cancelText}\n </AlertDialogCancel>\n <AlertDialogAction\n disabled={disabled || isPending}\n onClick={(event) => {\n event.preventDefault();\n void onConfirm();\n }}\n className={styles.actionClassName}\n >\n {isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : null}\n {confirmText}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n"],"mappings":";;;;AA2BA,IAAM,IAQF;CACF,SAAS;EACP,MAAM;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;EACH;CACD,SAAS;EACP,MAAM;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;EACH;CACD,QAAQ;EACN,MAAM;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;EACH;CACF;AAED,SAAgB,EAAoB,EAClC,SACA,iBACA,UACA,gBACA,iBAAc,WACd,gBAAa,UACb,aAAU,WACV,eAAY,IACZ,cAAW,IACX,gBAC2B;CAC3B,IAAM,IAAS,EAAe,IACxB,IAAO,EAAO;AAEpB,QACE,kBAAC,GAAD;EAAmB;EAAoB;YACrC,kBAAC,GAAD;GAAoB,WAAU;aAA9B,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KACE,WAAW,oEAAoE,EAAO;eAEtF,kBAAC,GAAD,EAAM,WAAW,WAAW,EAAO,iBAAmB,CAAA;KAClD,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAkB,WAAU;gBACzB;MACgB,CAAA,EACnB,kBAAC,GAAD;MAAwB,WAAU;gBAC/B;MACsB,CAAA,CACrB;OACF;OACY,CAAA,EAEpB,kBAAC,GAAD;IAAmB,WAAU;cAA7B,CACE,kBAAC,GAAD;KACE,UAAU;KACV,WAAU;eAET;KACiB,CAAA,EACpB,kBAAC,GAAD;KACE,UAAU,KAAY;KACtB,UAAU,MAAU;AAEb,MADL,EAAM,gBAAgB,EACjB,GAAW;;KAElB,WAAW,EAAO;eANpB,CAQG,IAAY,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAAG,MAC3D,EACiB;OACF;MACD;;EACT,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface UserProfileMenuProps {
|
|
2
|
+
/**
|
|
3
|
+
* Callback when workspace switcher should be shown
|
|
4
|
+
*/
|
|
5
|
+
onSwitchWorkspace?: () => void;
|
|
6
|
+
/**
|
|
7
|
+
* Logout handler (REQUIRED)
|
|
8
|
+
* Should clear auth state and redirect to login
|
|
9
|
+
*/
|
|
10
|
+
onLogout: () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Position of the dropdown menu
|
|
13
|
+
* @default 'right'
|
|
14
|
+
*/
|
|
15
|
+
position?: "left" | "right";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* User Profile Menu Component
|
|
19
|
+
*
|
|
20
|
+
* Displays user avatar/icon with dropdown menu containing:
|
|
21
|
+
* - User information
|
|
22
|
+
* - Switch Workspace option
|
|
23
|
+
* - Logout button
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* import { UserProfileMenu } from '@burdenoff/microfe-auth';
|
|
28
|
+
*
|
|
29
|
+
* function AppHeader() {
|
|
30
|
+
* return (
|
|
31
|
+
* <div className="header">
|
|
32
|
+
* <UserProfileMenu
|
|
33
|
+
* onSwitchWorkspace={() => setShowWorkspaceSwitcher(true)}
|
|
34
|
+
* position="right"
|
|
35
|
+
* />
|
|
36
|
+
* </div>
|
|
37
|
+
* );
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function UserProfileMenu({ onSwitchWorkspace, onLogout, position, }: UserProfileMenuProps): import("react/jsx-runtime").JSX.Element | null;
|
|
42
|
+
//# sourceMappingURL=UserProfileMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserProfileMenu.d.ts","sourceRoot":"","sources":["../../../../src/auth/components/profile/UserProfileMenu.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE/B;;;OAGG;IACH,QAAQ,EAAE,MAAM,IAAI,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,iBAAiB,EACjB,QAAQ,EACR,QAAkB,GACnB,EAAE,oBAAoB,kDA2ItB"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { useAuthStore as e } from "../../store/authStore.js";
|
|
2
|
+
import { useEffect as t, useRef as n, useState as r } from "react";
|
|
3
|
+
import { Building2 as i, ChevronDown as a, LogOut as o } from "lucide-react";
|
|
4
|
+
import { useI18n as s } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
5
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
6
|
+
//#region src/auth/components/profile/UserProfileMenu.tsx
|
|
7
|
+
function u({ onSwitchWorkspace: u, onLogout: d, position: f = "right" }) {
|
|
8
|
+
let { t: p } = s(), m = (e, t) => {
|
|
9
|
+
let n = p(e);
|
|
10
|
+
return n === e ? t : n;
|
|
11
|
+
}, [h, g] = r(!1), _ = n(null), v = e((e) => e.user), y = e((e) => e.currentWorkspaceId);
|
|
12
|
+
t(() => {
|
|
13
|
+
function e(e) {
|
|
14
|
+
_.current && !_.current.contains(e.target) && g(!1);
|
|
15
|
+
}
|
|
16
|
+
if (h) return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
17
|
+
}, [h]);
|
|
18
|
+
let b = () => {
|
|
19
|
+
g(!1), d();
|
|
20
|
+
}, x = () => {
|
|
21
|
+
g(!1), u?.();
|
|
22
|
+
};
|
|
23
|
+
if (!v) return null;
|
|
24
|
+
let S = () => {
|
|
25
|
+
if (v.firstName && v.lastName) return `${v.firstName[0]}${v.lastName[0]}`.toUpperCase();
|
|
26
|
+
if (v.name) {
|
|
27
|
+
let e = v.name.split(" ");
|
|
28
|
+
return e.length >= 2 ? `${e[0][0]}${e[1][0]}`.toUpperCase() : v.name.substring(0, 2).toUpperCase();
|
|
29
|
+
}
|
|
30
|
+
return v.username ? v.username.substring(0, 2).toUpperCase() : v.email.substring(0, 2).toUpperCase();
|
|
31
|
+
}, C = v.name || `${v.firstName || ""} ${v.lastName || ""}`.trim() || v.username;
|
|
32
|
+
return /* @__PURE__ */ l("div", {
|
|
33
|
+
className: "relative",
|
|
34
|
+
ref: _,
|
|
35
|
+
children: [/* @__PURE__ */ l("button", {
|
|
36
|
+
onClick: () => g(!h),
|
|
37
|
+
className: "flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-bg-sunken transition-colors",
|
|
38
|
+
"aria-label": "User menu",
|
|
39
|
+
"aria-expanded": h,
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ c("div", {
|
|
42
|
+
className: "w-8 h-8 rounded-full bg-accent-blue flex items-center justify-center text-white text-sm font-medium",
|
|
43
|
+
children: S()
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ c("span", {
|
|
46
|
+
className: "hidden sm:block text-sm font-medium text-text-secondary",
|
|
47
|
+
children: C
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ c(a, { className: `w-4 h-4 text-text-secondary transition-transform ${h ? "rotate-180" : ""}` })
|
|
50
|
+
]
|
|
51
|
+
}), h && /* @__PURE__ */ l("div", {
|
|
52
|
+
className: `absolute top-full mt-2 w-64 bg-bg-surface rounded-lg shadow-lg border border-border-subtle py-2 z-50 ${f === "right" ? "right-0" : "left-0"}`,
|
|
53
|
+
children: [/* @__PURE__ */ l("div", {
|
|
54
|
+
className: "px-4 py-3 border-b border-border-subtle",
|
|
55
|
+
children: [
|
|
56
|
+
/* @__PURE__ */ c("p", {
|
|
57
|
+
className: "text-sm font-medium text-foreground truncate",
|
|
58
|
+
children: C
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ c("p", {
|
|
61
|
+
className: "text-xs text-text-secondary truncate",
|
|
62
|
+
children: v.email
|
|
63
|
+
}),
|
|
64
|
+
y && /* @__PURE__ */ l("p", {
|
|
65
|
+
className: "text-xs text-text-tertiary mt-1 truncate",
|
|
66
|
+
children: [
|
|
67
|
+
"Workspace: ",
|
|
68
|
+
y.substring(0, 8),
|
|
69
|
+
"..."
|
|
70
|
+
]
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
}), /* @__PURE__ */ l("div", {
|
|
74
|
+
className: "py-1",
|
|
75
|
+
children: [u && /* @__PURE__ */ l("button", {
|
|
76
|
+
onClick: x,
|
|
77
|
+
className: "w-full flex items-center gap-3 px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken transition-colors",
|
|
78
|
+
children: [/* @__PURE__ */ c(i, { className: "w-4 h-4" }), /* @__PURE__ */ c("span", { children: m("auth.profileMenu.switchWorkspace", "Switch Workspace") })]
|
|
79
|
+
}), /* @__PURE__ */ l("button", {
|
|
80
|
+
onClick: b,
|
|
81
|
+
className: "w-full flex items-center gap-3 px-4 py-2 text-sm text-status-error-text hover:bg-status-error-bg-subtle transition-colors",
|
|
82
|
+
children: [/* @__PURE__ */ c(o, { className: "w-4 h-4" }), /* @__PURE__ */ c("span", { children: m("auth.profileMenu.logout", "Logout") })]
|
|
83
|
+
})]
|
|
84
|
+
})]
|
|
85
|
+
})]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { u as UserProfileMenu };
|
|
90
|
+
|
|
91
|
+
//# sourceMappingURL=UserProfileMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserProfileMenu.js","names":[],"sources":["../../../../src/auth/components/profile/UserProfileMenu.tsx"],"sourcesContent":["import { useState, useRef, useEffect } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { LogOut, ChevronDown, Building2 } from \"lucide-react\";\nimport { useAuthStore } from \"../../store/authStore\";\n\nexport interface UserProfileMenuProps {\n /**\n * Callback when workspace switcher should be shown\n */\n onSwitchWorkspace?: () => void;\n\n /**\n * Logout handler (REQUIRED)\n * Should clear auth state and redirect to login\n */\n onLogout: () => void;\n\n /**\n * Position of the dropdown menu\n * @default 'right'\n */\n position?: \"left\" | \"right\";\n}\n\n/**\n * User Profile Menu Component\n *\n * Displays user avatar/icon with dropdown menu containing:\n * - User information\n * - Switch Workspace option\n * - Logout button\n *\n * @example\n * ```tsx\n * import { UserProfileMenu } from '@burdenoff/microfe-auth';\n *\n * function AppHeader() {\n * return (\n * <div className=\"header\">\n * <UserProfileMenu\n * onSwitchWorkspace={() => setShowWorkspaceSwitcher(true)}\n * position=\"right\"\n * />\n * </div>\n * );\n * }\n * ```\n */\nexport function UserProfileMenu({\n onSwitchWorkspace,\n onLogout,\n position = \"right\",\n}: UserProfileMenuProps) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const [isOpen, setIsOpen] = useState(false);\n const menuRef = useRef<HTMLDivElement>(null);\n\n const user = useAuthStore((state) => state.user);\n const currentWorkspaceId = useAuthStore((state) => state.currentWorkspaceId);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (menuRef.current && !menuRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n }\n\n if (isOpen) {\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () =>\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n }, [isOpen]);\n\n const handleLogout = () => {\n setIsOpen(false);\n onLogout();\n };\n\n const handleSwitchWorkspace = () => {\n setIsOpen(false);\n onSwitchWorkspace?.();\n };\n\n if (!user) {\n return null;\n }\n\n // Get user initials for avatar\n const getInitials = () => {\n if (user.firstName && user.lastName) {\n return `${user.firstName[0]}${user.lastName[0]}`.toUpperCase();\n }\n if (user.name) {\n const parts = user.name.split(\" \");\n if (parts.length >= 2) {\n return `${parts[0][0]}${parts[1][0]}`.toUpperCase();\n }\n return user.name.substring(0, 2).toUpperCase();\n }\n if (user.username) {\n return user.username.substring(0, 2).toUpperCase();\n }\n return user.email.substring(0, 2).toUpperCase();\n };\n\n const displayName =\n user.name ||\n `${user.firstName || \"\"} ${user.lastName || \"\"}`.trim() ||\n user.username;\n\n return (\n <div className=\"relative\" ref={menuRef}>\n {/* Profile Button */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n className=\"flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-bg-sunken transition-colors\"\n aria-label=\"User menu\"\n aria-expanded={isOpen}\n >\n {/* Avatar */}\n <div className=\"w-8 h-8 rounded-full bg-accent-blue flex items-center justify-center text-white text-sm font-medium\">\n {getInitials()}\n </div>\n\n {/* User Name (optional, hide on small screens) */}\n <span className=\"hidden sm:block text-sm font-medium text-text-secondary\">\n {displayName}\n </span>\n\n {/* Chevron */}\n <ChevronDown\n className={`w-4 h-4 text-text-secondary transition-transform ${\n isOpen ? \"rotate-180\" : \"\"\n }`}\n />\n </button>\n\n {/* Dropdown Menu */}\n {isOpen && (\n <div\n className={`absolute top-full mt-2 w-64 bg-bg-surface rounded-lg shadow-lg border border-border-subtle py-2 z-50 ${\n position === \"right\" ? \"right-0\" : \"left-0\"\n }`}\n >\n {/* User Info Section */}\n <div className=\"px-4 py-3 border-b border-border-subtle\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {displayName}\n </p>\n <p className=\"text-xs text-text-secondary truncate\">{user.email}</p>\n {currentWorkspaceId && (\n <p className=\"text-xs text-text-tertiary mt-1 truncate\">\n Workspace: {currentWorkspaceId.substring(0, 8)}...\n </p>\n )}\n </div>\n\n {/* Menu Items */}\n <div className=\"py-1\">\n {/* Switch Workspace */}\n {onSwitchWorkspace && (\n <button\n onClick={handleSwitchWorkspace}\n className=\"w-full flex items-center gap-3 px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken transition-colors\"\n >\n <Building2 className=\"w-4 h-4\" />\n <span>\n {tr(\"auth.profileMenu.switchWorkspace\", \"Switch Workspace\")}\n </span>\n </button>\n )}\n\n {/* Logout */}\n <button\n onClick={handleLogout}\n className=\"w-full flex items-center gap-3 px-4 py-2 text-sm text-status-error-text hover:bg-status-error-bg-subtle transition-colors\"\n >\n <LogOut className=\"w-4 h-4\" />\n <span>{tr(\"auth.profileMenu.logout\", \"Logout\")}</span>\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AAgDA,SAAgB,EAAgB,EAC9B,sBACA,aACA,cAAW,WACY;CACvB,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAEnC,CAAC,GAAQ,KAAa,EAAS,GAAM,EACrC,IAAU,EAAuB,KAAK,EAEtC,IAAO,GAAc,MAAU,EAAM,KAAK,EAC1C,IAAqB,GAAc,MAAU,EAAM,mBAAmB;AAG5E,SAAgB;EACd,SAAS,EAAmB,GAAmB;AAC7C,GAAI,EAAQ,WAAW,CAAC,EAAQ,QAAQ,SAAS,EAAM,OAAe,IACpE,EAAU,GAAM;;AAIpB,MAAI,EAEF,QADA,SAAS,iBAAiB,aAAa,EAAmB,QAExD,SAAS,oBAAoB,aAAa,EAAmB;IAEhE,CAAC,EAAO,CAAC;CAEZ,IAAM,UAAqB;AAEzB,EADA,EAAU,GAAM,EAChB,GAAU;IAGN,UAA8B;AAElC,EADA,EAAU,GAAM,EAChB,KAAqB;;AAGvB,KAAI,CAAC,EACH,QAAO;CAIT,IAAM,UAAoB;AACxB,MAAI,EAAK,aAAa,EAAK,SACzB,QAAO,GAAG,EAAK,UAAU,KAAK,EAAK,SAAS,KAAK,aAAa;AAEhE,MAAI,EAAK,MAAM;GACb,IAAM,IAAQ,EAAK,KAAK,MAAM,IAAI;AAIlC,UAHI,EAAM,UAAU,IACX,GAAG,EAAM,GAAG,KAAK,EAAM,GAAG,KAAK,aAAa,GAE9C,EAAK,KAAK,UAAU,GAAG,EAAE,CAAC,aAAa;;AAKhD,SAHI,EAAK,WACA,EAAK,SAAS,UAAU,GAAG,EAAE,CAAC,aAAa,GAE7C,EAAK,MAAM,UAAU,GAAG,EAAE,CAAC,aAAa;IAG3C,IACJ,EAAK,QACL,GAAG,EAAK,aAAa,GAAG,GAAG,EAAK,YAAY,KAAK,MAAM,IACvD,EAAK;AAEP,QACE,kBAAC,OAAD;EAAK,WAAU;EAAW,KAAK;YAA/B,CAEE,kBAAC,UAAD;GACE,eAAe,EAAU,CAAC,EAAO;GACjC,WAAU;GACV,cAAW;GACX,iBAAe;aAJjB;IAOE,kBAAC,OAAD;KAAK,WAAU;eACZ,GAAa;KACV,CAAA;IAGN,kBAAC,QAAD;KAAM,WAAU;eACb;KACI,CAAA;IAGP,kBAAC,GAAD,EACE,WAAW,oDACT,IAAS,eAAe,MAE1B,CAAA;IACK;MAGR,KACC,kBAAC,OAAD;GACE,WAAW,wGACT,MAAa,UAAU,YAAY;aAFvC,CAME,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,KAAD;MAAG,WAAU;gBACV;MACC,CAAA;KACJ,kBAAC,KAAD;MAAG,WAAU;gBAAwC,EAAK;MAAU,CAAA;KACnE,KACC,kBAAC,KAAD;MAAG,WAAU;gBAAb;OAAwD;OAC1C,EAAmB,UAAU,GAAG,EAAE;OAAC;OAC7C;;KAEF;OAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEG,KACC,kBAAC,UAAD;KACE,SAAS;KACT,WAAU;eAFZ,CAIE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EACjC,kBAAC,QAAD,EAAA,UACG,EAAG,oCAAoC,mBAAmB,EACtD,CAAA,CACA;QAIX,kBAAC,UAAD;KACE,SAAS;KACT,WAAU;eAFZ,CAIE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAC9B,kBAAC,QAAD,EAAA,UAAO,EAAG,2BAA2B,SAAS,EAAQ,CAAA,CAC/C;OACL;MACF;KAEJ"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Workspace } from '../../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Organization interface (grouped from workspaces)
|
|
5
|
+
*/
|
|
6
|
+
export interface Organization {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
workspaceCount: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Project interface (optional, for future use)
|
|
13
|
+
*/
|
|
14
|
+
export interface Project {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
workspaceId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface WorkspaceSelectorProps {
|
|
20
|
+
/**
|
|
21
|
+
* Control modal visibility
|
|
22
|
+
*/
|
|
23
|
+
isOpen: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Callback when modal is closed without selection
|
|
26
|
+
*/
|
|
27
|
+
onClose: () => void;
|
|
28
|
+
/**
|
|
29
|
+
* List of workspaces to choose from
|
|
30
|
+
*/
|
|
31
|
+
workspaces: Workspace[];
|
|
32
|
+
/**
|
|
33
|
+
* Optional list of projects (filtered by workspace)
|
|
34
|
+
*/
|
|
35
|
+
projects?: Project[];
|
|
36
|
+
/**
|
|
37
|
+
* Callback when workspace is selected and confirmed
|
|
38
|
+
*/
|
|
39
|
+
onSelect: (workspace: Workspace, project?: Project) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Loading state while issuing workspace token
|
|
42
|
+
*/
|
|
43
|
+
isLoading?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Error message to display
|
|
46
|
+
*/
|
|
47
|
+
error?: string | null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* WorkspaceSelector Component
|
|
51
|
+
*
|
|
52
|
+
* Multi-level workspace selection modal for use across all Burdenoff products.
|
|
53
|
+
*
|
|
54
|
+
* Features:
|
|
55
|
+
* - Three-tier selection: Organization → Workspace → Project (optional)
|
|
56
|
+
* - Auto-select if only one option at each level
|
|
57
|
+
* - Loading and error states
|
|
58
|
+
* - Clean, accessible UI
|
|
59
|
+
*
|
|
60
|
+
* Usage:
|
|
61
|
+
* ```tsx
|
|
62
|
+
* import { WorkspaceSelector } from '@burdenoff/microfe-auth';
|
|
63
|
+
*
|
|
64
|
+
* <WorkspaceSelector
|
|
65
|
+
* isOpen={showSelector}
|
|
66
|
+
* onClose={() => setShowSelector(false)}
|
|
67
|
+
* workspaces={workspaces}
|
|
68
|
+
* onSelect={async (workspace) => {
|
|
69
|
+
* await issueWorkspaceToken(workspace.id);
|
|
70
|
+
* navigate('/');
|
|
71
|
+
* }}
|
|
72
|
+
* />
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function WorkspaceSelector({ isOpen, onClose, workspaces, projects, onSelect, isLoading, error, }: WorkspaceSelectorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
76
|
+
//# sourceMappingURL=WorkspaceSelector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceSelector.d.ts","sourceRoot":"","sources":["../../../../src/auth/components/workspace/WorkspaceSelector.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,SAAS,EAAE,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAE5D;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,OAAO,EACP,UAAU,EACV,QAAa,EACb,QAAQ,EACR,SAAiB,EACjB,KAAY,GACb,EAAE,sBAAsB,kDAyVxB"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { useEffect as e, useMemo as t, useState as n } from "react";
|
|
2
|
+
import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
3
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
|
+
//#region src/auth/components/workspace/WorkspaceSelector.tsx
|
|
5
|
+
function o({ isOpen: o, onClose: s, workspaces: c, projects: l = [], onSelect: u, isLoading: d = !1, error: f = null }) {
|
|
6
|
+
let { t: p } = r(), m = (e, t) => {
|
|
7
|
+
let n = p(e);
|
|
8
|
+
return n === e ? t : n;
|
|
9
|
+
}, [h, g] = n(null), [_, v] = n(null), [y, b] = n(null), x = t(() => {
|
|
10
|
+
let e = /* @__PURE__ */ new Map();
|
|
11
|
+
return c.forEach((t) => {
|
|
12
|
+
let n = t.organizationId || "default";
|
|
13
|
+
e.has(n) || e.set(n, {
|
|
14
|
+
name: n === "default" ? "Default" : `Organization ${n.slice(0, 8)}`,
|
|
15
|
+
count: 0
|
|
16
|
+
}), e.get(n).count++;
|
|
17
|
+
}), Array.from(e.entries()).map(([e, { name: t, count: n }]) => ({
|
|
18
|
+
id: e,
|
|
19
|
+
name: t,
|
|
20
|
+
workspaceCount: n
|
|
21
|
+
}));
|
|
22
|
+
}, [c]), S = t(() => h ? c.filter((e) => (e.organizationId || "default") === h) : c, [c, h]), C = t(() => _ ? l.filter((e) => e.workspaceId === _) : [], [l, _]), w = t(() => c.find((e) => e.id === _), [c, _]), T = t(() => l.find((e) => e.id === y), [l, y]);
|
|
23
|
+
e(() => {
|
|
24
|
+
x.length === 1 && !h && g(x[0].id);
|
|
25
|
+
}, [x, h]), e(() => {
|
|
26
|
+
S.length === 1 && !_ && v(S[0].id);
|
|
27
|
+
}, [S, _]);
|
|
28
|
+
let E = (e) => {
|
|
29
|
+
g(e), v(null), b(null);
|
|
30
|
+
}, D = (e) => {
|
|
31
|
+
v(e), b(null);
|
|
32
|
+
}, O = (e) => {
|
|
33
|
+
b(e);
|
|
34
|
+
}, k = () => {
|
|
35
|
+
w && u(w, T);
|
|
36
|
+
}, A = () => {
|
|
37
|
+
g(null), v(null), b(null), s();
|
|
38
|
+
}, j = _ !== null;
|
|
39
|
+
return o ? /* @__PURE__ */ a("div", {
|
|
40
|
+
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
41
|
+
children: [/* @__PURE__ */ i("div", {
|
|
42
|
+
className: "absolute inset-0 bg-black/50",
|
|
43
|
+
onClick: A,
|
|
44
|
+
"aria-hidden": "true"
|
|
45
|
+
}), /* @__PURE__ */ a("div", {
|
|
46
|
+
className: "relative bg-bg-surface rounded-2xl shadow-xl max-w-2xl w-full mx-4 p-6 space-y-6",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ a("div", {
|
|
49
|
+
className: "space-y-2",
|
|
50
|
+
children: [/* @__PURE__ */ i("h2", {
|
|
51
|
+
className: "text-2xl font-semibold text-foreground",
|
|
52
|
+
children: m("auth.workspaceSelector.title", "Select Your Workspace")
|
|
53
|
+
}), /* @__PURE__ */ i("p", {
|
|
54
|
+
className: "text-sm text-text-secondary",
|
|
55
|
+
children: m("auth.workspaceSelector.subtitle", "Choose the workspace you want to work in. You can switch workspaces later from the header.")
|
|
56
|
+
})]
|
|
57
|
+
}),
|
|
58
|
+
f && /* @__PURE__ */ a("div", {
|
|
59
|
+
className: "rounded-lg bg-status-error-bg-subtle p-4 text-sm text-status-error-text",
|
|
60
|
+
children: [/* @__PURE__ */ i("p", {
|
|
61
|
+
className: "font-medium",
|
|
62
|
+
children: m("auth.workspaceSelector.error", "Error")
|
|
63
|
+
}), /* @__PURE__ */ i("p", { children: f })]
|
|
64
|
+
}),
|
|
65
|
+
/* @__PURE__ */ a("div", {
|
|
66
|
+
className: "space-y-4",
|
|
67
|
+
children: [
|
|
68
|
+
x.length > 1 && /* @__PURE__ */ a("div", {
|
|
69
|
+
className: "space-y-2",
|
|
70
|
+
children: [/* @__PURE__ */ i("label", {
|
|
71
|
+
className: "block text-sm font-medium text-text-secondary",
|
|
72
|
+
children: /* @__PURE__ */ a("span", {
|
|
73
|
+
className: "flex items-center gap-2",
|
|
74
|
+
children: [/* @__PURE__ */ i("svg", {
|
|
75
|
+
className: "h-4 w-4",
|
|
76
|
+
fill: "none",
|
|
77
|
+
stroke: "currentColor",
|
|
78
|
+
viewBox: "0 0 24 24",
|
|
79
|
+
children: /* @__PURE__ */ i("path", {
|
|
80
|
+
strokeLinecap: "round",
|
|
81
|
+
strokeLinejoin: "round",
|
|
82
|
+
strokeWidth: 2,
|
|
83
|
+
d: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"
|
|
84
|
+
})
|
|
85
|
+
}), "Organization"]
|
|
86
|
+
})
|
|
87
|
+
}), /* @__PURE__ */ a("select", {
|
|
88
|
+
value: h || "",
|
|
89
|
+
onChange: (e) => E(e.target.value),
|
|
90
|
+
className: "w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-foreground focus:border-primary focus:ring-2 focus:ring-primary/20",
|
|
91
|
+
children: [/* @__PURE__ */ i("option", {
|
|
92
|
+
value: "",
|
|
93
|
+
children: m("auth.workspaceSelector.selectOrg", "Select organization...")
|
|
94
|
+
}), x.map((e) => /* @__PURE__ */ a("option", {
|
|
95
|
+
value: e.id,
|
|
96
|
+
children: [
|
|
97
|
+
e.name,
|
|
98
|
+
" (",
|
|
99
|
+
e.workspaceCount,
|
|
100
|
+
" workspace",
|
|
101
|
+
e.workspaceCount === 1 ? "" : "s",
|
|
102
|
+
")"
|
|
103
|
+
]
|
|
104
|
+
}, e.id))]
|
|
105
|
+
})]
|
|
106
|
+
}),
|
|
107
|
+
/* @__PURE__ */ a("div", {
|
|
108
|
+
className: "space-y-2",
|
|
109
|
+
children: [/* @__PURE__ */ i("label", {
|
|
110
|
+
className: "block text-sm font-medium text-text-secondary",
|
|
111
|
+
children: /* @__PURE__ */ a("span", {
|
|
112
|
+
className: "flex items-center gap-2",
|
|
113
|
+
children: [/* @__PURE__ */ i("svg", {
|
|
114
|
+
className: "h-4 w-4",
|
|
115
|
+
fill: "none",
|
|
116
|
+
stroke: "currentColor",
|
|
117
|
+
viewBox: "0 0 24 24",
|
|
118
|
+
children: /* @__PURE__ */ i("path", {
|
|
119
|
+
strokeLinecap: "round",
|
|
120
|
+
strokeLinejoin: "round",
|
|
121
|
+
strokeWidth: 2,
|
|
122
|
+
d: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"
|
|
123
|
+
})
|
|
124
|
+
}), "Workspace"]
|
|
125
|
+
})
|
|
126
|
+
}), /* @__PURE__ */ a("select", {
|
|
127
|
+
value: _ || "",
|
|
128
|
+
onChange: (e) => D(e.target.value),
|
|
129
|
+
disabled: !h && x.length > 1,
|
|
130
|
+
className: "w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-foreground focus:border-primary focus:ring-2 focus:ring-primary/20 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
131
|
+
children: [/* @__PURE__ */ i("option", {
|
|
132
|
+
value: "",
|
|
133
|
+
children: m("auth.workspaceSelector.selectWorkspace", "Select workspace...")
|
|
134
|
+
}), S.map((e) => /* @__PURE__ */ a("option", {
|
|
135
|
+
value: e.id,
|
|
136
|
+
children: [
|
|
137
|
+
e.name,
|
|
138
|
+
" (",
|
|
139
|
+
e.slug,
|
|
140
|
+
")"
|
|
141
|
+
]
|
|
142
|
+
}, e.id))]
|
|
143
|
+
})]
|
|
144
|
+
}),
|
|
145
|
+
C.length > 0 && /* @__PURE__ */ a("div", {
|
|
146
|
+
className: "space-y-2",
|
|
147
|
+
children: [/* @__PURE__ */ i("label", {
|
|
148
|
+
className: "block text-sm font-medium text-text-secondary",
|
|
149
|
+
children: /* @__PURE__ */ a("span", {
|
|
150
|
+
className: "flex items-center gap-2",
|
|
151
|
+
children: [/* @__PURE__ */ i("svg", {
|
|
152
|
+
className: "h-4 w-4",
|
|
153
|
+
fill: "none",
|
|
154
|
+
stroke: "currentColor",
|
|
155
|
+
viewBox: "0 0 24 24",
|
|
156
|
+
children: /* @__PURE__ */ i("path", {
|
|
157
|
+
strokeLinecap: "round",
|
|
158
|
+
strokeLinejoin: "round",
|
|
159
|
+
strokeWidth: 2,
|
|
160
|
+
d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
161
|
+
})
|
|
162
|
+
}), "Project (Optional)"]
|
|
163
|
+
})
|
|
164
|
+
}), /* @__PURE__ */ a("select", {
|
|
165
|
+
value: y || "",
|
|
166
|
+
onChange: (e) => O(e.target.value),
|
|
167
|
+
className: "w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-foreground focus:border-primary focus:ring-2 focus:ring-primary/20",
|
|
168
|
+
children: [/* @__PURE__ */ i("option", {
|
|
169
|
+
value: "",
|
|
170
|
+
children: m("auth.workspaceSelector.noProject", "No project selected")
|
|
171
|
+
}), C.map((e) => /* @__PURE__ */ i("option", {
|
|
172
|
+
value: e.id,
|
|
173
|
+
children: e.name
|
|
174
|
+
}, e.id))]
|
|
175
|
+
})]
|
|
176
|
+
}),
|
|
177
|
+
w && /* @__PURE__ */ a("div", {
|
|
178
|
+
className: "rounded-lg bg-bg-sunken p-4 space-y-2",
|
|
179
|
+
children: [/* @__PURE__ */ i("p", {
|
|
180
|
+
className: "text-sm font-medium text-foreground",
|
|
181
|
+
children: m("auth.workspaceSelector.selected", "Selected:")
|
|
182
|
+
}), /* @__PURE__ */ a("div", {
|
|
183
|
+
className: "text-sm text-text-secondary space-y-1",
|
|
184
|
+
children: [/* @__PURE__ */ a("div", {
|
|
185
|
+
className: "flex items-center gap-2",
|
|
186
|
+
children: [/* @__PURE__ */ i("svg", {
|
|
187
|
+
className: "h-3 w-3",
|
|
188
|
+
fill: "none",
|
|
189
|
+
stroke: "currentColor",
|
|
190
|
+
viewBox: "0 0 24 24",
|
|
191
|
+
children: /* @__PURE__ */ i("path", {
|
|
192
|
+
strokeLinecap: "round",
|
|
193
|
+
strokeLinejoin: "round",
|
|
194
|
+
strokeWidth: 2,
|
|
195
|
+
d: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"
|
|
196
|
+
})
|
|
197
|
+
}), /* @__PURE__ */ i("span", { children: w.name })]
|
|
198
|
+
}), T && /* @__PURE__ */ a("div", {
|
|
199
|
+
className: "flex items-center gap-2",
|
|
200
|
+
children: [/* @__PURE__ */ i("svg", {
|
|
201
|
+
className: "h-3 w-3",
|
|
202
|
+
fill: "none",
|
|
203
|
+
stroke: "currentColor",
|
|
204
|
+
viewBox: "0 0 24 24",
|
|
205
|
+
children: /* @__PURE__ */ i("path", {
|
|
206
|
+
strokeLinecap: "round",
|
|
207
|
+
strokeLinejoin: "round",
|
|
208
|
+
strokeWidth: 2,
|
|
209
|
+
d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
210
|
+
})
|
|
211
|
+
}), /* @__PURE__ */ i("span", { children: T.name })]
|
|
212
|
+
})]
|
|
213
|
+
})]
|
|
214
|
+
})
|
|
215
|
+
]
|
|
216
|
+
}),
|
|
217
|
+
/* @__PURE__ */ a("div", {
|
|
218
|
+
className: "flex items-center justify-end gap-3 pt-4 border-t border-border-subtle",
|
|
219
|
+
children: [/* @__PURE__ */ i("button", {
|
|
220
|
+
type: "button",
|
|
221
|
+
onClick: A,
|
|
222
|
+
disabled: d,
|
|
223
|
+
className: "px-4 py-2 text-sm font-medium text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
224
|
+
children: "Cancel"
|
|
225
|
+
}), /* @__PURE__ */ i("button", {
|
|
226
|
+
type: "button",
|
|
227
|
+
onClick: k,
|
|
228
|
+
disabled: !j || d,
|
|
229
|
+
className: "px-4 py-2 text-sm font-medium text-primary-foreground bg-primary hover:bg-primary/90 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
230
|
+
children: d ? m("auth.workspaceSelector.loading", "Loading...") : m("auth.workspaceSelector.continue", "Continue")
|
|
231
|
+
})]
|
|
232
|
+
})
|
|
233
|
+
]
|
|
234
|
+
})]
|
|
235
|
+
}) : null;
|
|
236
|
+
}
|
|
237
|
+
//#endregion
|
|
238
|
+
export { o as WorkspaceSelector };
|
|
239
|
+
|
|
240
|
+
//# sourceMappingURL=WorkspaceSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceSelector.js","names":[],"sources":["../../../../src/auth/components/workspace/WorkspaceSelector.tsx"],"sourcesContent":["import { useState, useMemo, useEffect } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport type { Workspace } from \"../../types\";\n\n/**\n * Organization interface (grouped from workspaces)\n */\nexport interface Organization {\n id: string;\n name: string;\n workspaceCount: number;\n}\n\n/**\n * Project interface (optional, for future use)\n */\nexport interface Project {\n id: string;\n name: string;\n workspaceId: string;\n}\n\nexport interface WorkspaceSelectorProps {\n /**\n * Control modal visibility\n */\n isOpen: boolean;\n\n /**\n * Callback when modal is closed without selection\n */\n onClose: () => void;\n\n /**\n * List of workspaces to choose from\n */\n workspaces: Workspace[];\n\n /**\n * Optional list of projects (filtered by workspace)\n */\n projects?: Project[];\n\n /**\n * Callback when workspace is selected and confirmed\n */\n onSelect: (workspace: Workspace, project?: Project) => void;\n\n /**\n * Loading state while issuing workspace token\n */\n isLoading?: boolean;\n\n /**\n * Error message to display\n */\n error?: string | null;\n}\n\n/**\n * WorkspaceSelector Component\n *\n * Multi-level workspace selection modal for use across all Burdenoff products.\n *\n * Features:\n * - Three-tier selection: Organization → Workspace → Project (optional)\n * - Auto-select if only one option at each level\n * - Loading and error states\n * - Clean, accessible UI\n *\n * Usage:\n * ```tsx\n * import { WorkspaceSelector } from '@burdenoff/microfe-auth';\n *\n * <WorkspaceSelector\n * isOpen={showSelector}\n * onClose={() => setShowSelector(false)}\n * workspaces={workspaces}\n * onSelect={async (workspace) => {\n * await issueWorkspaceToken(workspace.id);\n * navigate('/');\n * }}\n * />\n * ```\n */\nexport function WorkspaceSelector({\n isOpen,\n onClose,\n workspaces,\n projects = [],\n onSelect,\n isLoading = false,\n error = null,\n}: WorkspaceSelectorProps) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n // Selection state\n const [selectedOrgId, setSelectedOrgId] = useState<string | null>(null);\n const [selectedWorkspaceId, setSelectedWorkspaceId] = useState<string | null>(\n null,\n );\n const [selectedProjectId, setSelectedProjectId] = useState<string | null>(\n null,\n );\n\n // Group workspaces by organization\n const organizations = useMemo<Organization[]>(() => {\n const orgMap = new Map<string, { name: string; count: number }>();\n\n workspaces.forEach((workspace) => {\n const orgId = workspace.organizationId || \"default\";\n if (!orgMap.has(orgId)) {\n // Use org ID for name since workspace doesn't have organizationName\n orgMap.set(orgId, {\n name:\n orgId === \"default\"\n ? \"Default\"\n : `Organization ${orgId.slice(0, 8)}`,\n count: 0,\n });\n }\n orgMap.get(orgId)!.count++;\n });\n\n return Array.from(orgMap.entries()).map(([id, { name, count }]) => ({\n id,\n name,\n workspaceCount: count,\n }));\n }, [workspaces]);\n\n // Filter workspaces by selected organization\n const filteredWorkspaces = useMemo(() => {\n if (!selectedOrgId) return workspaces;\n return workspaces.filter(\n (w) => (w.organizationId || \"default\") === selectedOrgId,\n );\n }, [workspaces, selectedOrgId]);\n\n // Filter projects by selected workspace\n const filteredProjects = useMemo(() => {\n if (!selectedWorkspaceId) return [];\n return projects.filter((p) => p.workspaceId === selectedWorkspaceId);\n }, [projects, selectedWorkspaceId]);\n\n // Get selected workspace object\n const selectedWorkspace = useMemo(() => {\n return workspaces.find((w) => w.id === selectedWorkspaceId);\n }, [workspaces, selectedWorkspaceId]);\n\n // Get selected project object\n const selectedProject = useMemo(() => {\n return projects.find((p) => p.id === selectedProjectId);\n }, [projects, selectedProjectId]);\n\n // Auto-select if only one organization\n useEffect(() => {\n if (organizations.length === 1 && !selectedOrgId) {\n setSelectedOrgId(organizations[0].id);\n }\n }, [organizations, selectedOrgId]);\n\n // Auto-select if only one workspace\n useEffect(() => {\n if (filteredWorkspaces.length === 1 && !selectedWorkspaceId) {\n setSelectedWorkspaceId(filteredWorkspaces[0].id);\n }\n }, [filteredWorkspaces, selectedWorkspaceId]);\n\n // Handle organization selection\n const handleOrgChange = (orgId: string) => {\n setSelectedOrgId(orgId);\n setSelectedWorkspaceId(null);\n setSelectedProjectId(null);\n };\n\n // Handle workspace selection\n const handleWorkspaceChange = (workspaceId: string) => {\n setSelectedWorkspaceId(workspaceId);\n setSelectedProjectId(null);\n };\n\n // Handle project selection\n const handleProjectChange = (projectId: string) => {\n setSelectedProjectId(projectId);\n };\n\n // Handle continue button\n const handleContinue = () => {\n if (!selectedWorkspace) return;\n onSelect(selectedWorkspace, selectedProject);\n };\n\n // Handle cancel\n const handleCancel = () => {\n setSelectedOrgId(null);\n setSelectedWorkspaceId(null);\n setSelectedProjectId(null);\n onClose();\n };\n\n // Check if continue button should be enabled\n const canContinue = selectedWorkspaceId !== null;\n\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <div\n className=\"absolute inset-0 bg-black/50\"\n onClick={handleCancel}\n aria-hidden=\"true\"\n />\n\n {/* Modal */}\n <div className=\"relative bg-bg-surface rounded-2xl shadow-xl max-w-2xl w-full mx-4 p-6 space-y-6\">\n {/* Header */}\n <div className=\"space-y-2\">\n <h2 className=\"text-2xl font-semibold text-foreground\">\n {tr(\"auth.workspaceSelector.title\", \"Select Your Workspace\")}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"auth.workspaceSelector.subtitle\",\n \"Choose the workspace you want to work in. You can switch workspaces later from the header.\",\n )}\n </p>\n </div>\n\n {/* Error display */}\n {error && (\n <div className=\"rounded-lg bg-status-error-bg-subtle p-4 text-sm text-status-error-text\">\n <p className=\"font-medium\">\n {tr(\"auth.workspaceSelector.error\", \"Error\")}\n </p>\n <p>{error}</p>\n </div>\n )}\n\n {/* Form */}\n <div className=\"space-y-4\">\n {/* Organization selection */}\n {organizations.length > 1 && (\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium text-text-secondary\">\n <span className=\"flex items-center gap-2\">\n <svg\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4\"\n />\n </svg>\n Organization\n </span>\n </label>\n <select\n value={selectedOrgId || \"\"}\n onChange={(e) => handleOrgChange(e.target.value)}\n className=\"w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-foreground focus:border-primary focus:ring-2 focus:ring-primary/20\"\n >\n <option value=\"\">\n {tr(\n \"auth.workspaceSelector.selectOrg\",\n \"Select organization...\",\n )}\n </option>\n {organizations.map((org) => (\n <option key={org.id} value={org.id}>\n {org.name} ({org.workspaceCount} workspace\n {org.workspaceCount !== 1 ? \"s\" : \"\"})\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Workspace selection */}\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium text-text-secondary\">\n <span className=\"flex items-center gap-2\">\n <svg\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z\"\n />\n </svg>\n Workspace\n </span>\n </label>\n <select\n value={selectedWorkspaceId || \"\"}\n onChange={(e) => handleWorkspaceChange(e.target.value)}\n disabled={!selectedOrgId && organizations.length > 1}\n className=\"w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-foreground focus:border-primary focus:ring-2 focus:ring-primary/20 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <option value=\"\">\n {tr(\n \"auth.workspaceSelector.selectWorkspace\",\n \"Select workspace...\",\n )}\n </option>\n {filteredWorkspaces.map((workspace) => (\n <option key={workspace.id} value={workspace.id}>\n {workspace.name} ({workspace.slug})\n </option>\n ))}\n </select>\n </div>\n\n {/* Project selection (optional) */}\n {filteredProjects.length > 0 && (\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium text-text-secondary\">\n <span className=\"flex items-center gap-2\">\n <svg\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n Project (Optional)\n </span>\n </label>\n <select\n value={selectedProjectId || \"\"}\n onChange={(e) => handleProjectChange(e.target.value)}\n className=\"w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-foreground focus:border-primary focus:ring-2 focus:ring-primary/20\"\n >\n <option value=\"\">\n {tr(\n \"auth.workspaceSelector.noProject\",\n \"No project selected\",\n )}\n </option>\n {filteredProjects.map((project) => (\n <option key={project.id} value={project.id}>\n {project.name}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Selection summary */}\n {selectedWorkspace && (\n <div className=\"rounded-lg bg-bg-sunken p-4 space-y-2\">\n <p className=\"text-sm font-medium text-foreground\">\n {tr(\"auth.workspaceSelector.selected\", \"Selected:\")}\n </p>\n <div className=\"text-sm text-text-secondary space-y-1\">\n <div className=\"flex items-center gap-2\">\n <svg\n className=\"h-3 w-3\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z\"\n />\n </svg>\n <span>{selectedWorkspace.name}</span>\n </div>\n {selectedProject && (\n <div className=\"flex items-center gap-2\">\n <svg\n className=\"h-3 w-3\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n <span>{selectedProject.name}</span>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-end gap-3 pt-4 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={isLoading}\n className=\"px-4 py-2 text-sm font-medium text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleContinue}\n disabled={!canContinue || isLoading}\n className=\"px-4 py-2 text-sm font-medium text-primary-foreground bg-primary hover:bg-primary/90 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isLoading\n ? tr(\"auth.workspaceSelector.loading\", \"Loading...\")\n : tr(\"auth.workspaceSelector.continue\", \"Continue\")}\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Permission Constants
|
|
3
|
+
*
|
|
4
|
+
* Permission strings matching the @rbac directives on global-auth-svc.
|
|
5
|
+
* Only covers admin-facing operations — public auth flows (login, signup,
|
|
6
|
+
* password reset, MFA verify, OAuth, SSO) don't need RBAC.
|
|
7
|
+
* Self-service operations (own profile, sessions, API keys) are identity-scoped.
|
|
8
|
+
*
|
|
9
|
+
* Resource types and actions from global-rbac-svc seed:
|
|
10
|
+
* user: read, update, delete
|
|
11
|
+
* app: read, create, update
|
|
12
|
+
* sso-config: manage, delete
|
|
13
|
+
* oidc-config: manage, delete
|
|
14
|
+
* auth-method: update
|
|
15
|
+
*/
|
|
16
|
+
export declare const AUTH_PERMISSIONS: {
|
|
17
|
+
readonly USER_READ: "user:read";
|
|
18
|
+
readonly USER_UPDATE: "user:update";
|
|
19
|
+
readonly USER_DELETE: "user:delete";
|
|
20
|
+
readonly APP_READ: "app:read";
|
|
21
|
+
readonly APP_CREATE: "app:create";
|
|
22
|
+
readonly APP_UPDATE: "app:update";
|
|
23
|
+
readonly SSO_CONFIG_MANAGE: "sso-config:manage";
|
|
24
|
+
readonly SSO_CONFIG_DELETE: "sso-config:delete";
|
|
25
|
+
readonly OIDC_CONFIG_MANAGE: "oidc-config:manage";
|
|
26
|
+
readonly OIDC_CONFIG_DELETE: "oidc-config:delete";
|
|
27
|
+
readonly AUTH_METHOD_UPDATE: "auth-method:update";
|
|
28
|
+
};
|
|
29
|
+
export type AuthPermission = (typeof AUTH_PERMISSIONS)[keyof typeof AUTH_PERMISSIONS];
|
|
30
|
+
//# sourceMappingURL=permissions.d.ts.map
|