@workos-inc/widgets 1.5.1 → 1.6.1
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/CHANGELOG.md +15 -0
- package/dist/cjs/admin-portal-domain-verification.client.cjs +32 -17
- package/dist/cjs/admin-portal-domain-verification.client.cjs.map +1 -1
- package/dist/cjs/admin-portal-domain-verification.client.d.cts +3 -2
- package/dist/cjs/{admin-portal-sso-connection-client.cjs → admin-portal-sso-connection.client.cjs} +58 -31
- package/dist/cjs/admin-portal-sso-connection.client.cjs.map +1 -0
- package/dist/cjs/admin-portal-sso-connection.client.d.cts +16 -0
- package/dist/cjs/api/api-provider.cjs +1 -1
- package/dist/cjs/api/api-provider.cjs.map +1 -1
- package/dist/cjs/api/api-provider.d.cts +1 -1
- package/dist/cjs/api/endpoint.cjs +62 -2
- package/dist/cjs/api/endpoint.cjs.map +1 -1
- package/dist/cjs/api/endpoint.d.cts +62 -1
- package/dist/cjs/{api-keys-client.cjs → api-keys.client.cjs} +42 -25
- package/dist/cjs/api-keys.client.cjs.map +1 -0
- package/dist/cjs/api-keys.client.d.cts +15 -0
- package/dist/cjs/index.cjs +9 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +6 -2
- package/dist/cjs/lib/admin-portal-domain-verification.cjs +33 -34
- package/dist/cjs/lib/admin-portal-domain-verification.cjs.map +1 -1
- package/dist/cjs/lib/admin-portal-domain-verification.d.cts +10 -6
- package/dist/cjs/lib/admin-portal-sso-connection.cjs +79 -79
- package/dist/cjs/lib/admin-portal-sso-connection.cjs.map +1 -1
- package/dist/cjs/lib/admin-portal-sso-connection.d.cts +13 -6
- package/dist/cjs/lib/api-keys/api-keys.cjs +70 -66
- package/dist/cjs/lib/api-keys/api-keys.cjs.map +1 -1
- package/dist/cjs/lib/api-keys/api-keys.d.cts +16 -8
- package/dist/cjs/lib/constants.cjs +5 -2
- package/dist/cjs/lib/constants.cjs.map +1 -1
- package/dist/cjs/lib/constants.d.cts +2 -1
- package/dist/cjs/lib/elevated-access.cjs.map +1 -1
- package/dist/cjs/lib/empty-state.cjs +24 -8
- package/dist/cjs/lib/empty-state.cjs.map +1 -1
- package/dist/cjs/lib/empty-state.d.cts +6 -2
- package/dist/cjs/lib/generic-error.cjs +33 -24
- package/dist/cjs/lib/generic-error.cjs.map +1 -1
- package/dist/cjs/lib/generic-error.d.cts +5 -2
- package/dist/cjs/lib/identity-providers.cjs +2 -1
- package/dist/cjs/lib/identity-providers.cjs.map +1 -1
- package/dist/cjs/lib/identity-providers.d.cts +2 -2
- package/dist/cjs/lib/oauth-icons.cjs +12 -7
- package/dist/cjs/lib/oauth-icons.cjs.map +1 -1
- package/dist/cjs/lib/oauth-icons.d.cts +7 -3
- package/dist/cjs/lib/organization-switcher.cjs +62 -9
- package/dist/cjs/lib/organization-switcher.cjs.map +1 -1
- package/dist/cjs/lib/organization-switcher.d.cts +12 -9
- package/dist/cjs/lib/otp-input.cjs +1 -1
- package/dist/cjs/lib/otp-input.cjs.map +1 -1
- package/dist/cjs/lib/pipes.cjs +345 -0
- package/dist/cjs/lib/pipes.cjs.map +1 -0
- package/dist/cjs/lib/pipes.d.cts +19 -0
- package/dist/cjs/lib/provider-icon.cjs +0 -6
- package/dist/cjs/lib/provider-icon.cjs.map +1 -1
- package/dist/cjs/lib/provider-icon.d.cts +4 -1
- package/dist/cjs/lib/save-button.cjs.map +1 -1
- package/dist/cjs/lib/user-profile.cjs +77 -83
- package/dist/cjs/lib/user-profile.cjs.map +1 -1
- package/dist/cjs/lib/user-profile.d.cts +11 -7
- package/dist/cjs/lib/user-security.cjs +30 -24
- package/dist/cjs/lib/user-security.cjs.map +1 -1
- package/dist/cjs/lib/user-security.d.cts +10 -7
- package/dist/cjs/lib/user-sessions.cjs +19 -9
- package/dist/cjs/lib/user-sessions.cjs.map +1 -1
- package/dist/cjs/lib/user-sessions.d.cts +10 -6
- package/dist/cjs/lib/users-management.cjs +224 -216
- package/dist/cjs/lib/users-management.cjs.map +1 -1
- package/dist/cjs/lib/users-management.d.cts +10 -7
- package/dist/cjs/lib/utils.cjs +43 -0
- package/dist/cjs/lib/utils.cjs.map +1 -1
- package/dist/cjs/lib/utils.d.cts +29 -2
- package/dist/cjs/organization-switcher.client.cjs +45 -16
- package/dist/cjs/organization-switcher.client.cjs.map +1 -1
- package/dist/cjs/organization-switcher.client.d.cts +2 -1
- package/dist/cjs/pipes.client.cjs +64 -0
- package/dist/cjs/pipes.client.cjs.map +1 -0
- package/dist/cjs/pipes.client.d.cts +15 -0
- package/dist/cjs/user-profile.client.cjs +27 -10
- package/dist/cjs/user-profile.client.cjs.map +1 -1
- package/dist/cjs/user-profile.client.d.cts +4 -3
- package/dist/cjs/user-security.client.cjs +27 -10
- package/dist/cjs/user-security.client.cjs.map +1 -1
- package/dist/cjs/user-security.client.d.cts +3 -2
- package/dist/cjs/user-sessions.client.cjs +34 -16
- package/dist/cjs/user-sessions.client.cjs.map +1 -1
- package/dist/cjs/user-sessions.client.d.cts +4 -2
- package/dist/cjs/users-management.client.cjs +35 -18
- package/dist/cjs/users-management.client.cjs.map +1 -1
- package/dist/cjs/users-management.client.d.cts +3 -2
- package/dist/cjs/workos-widgets.client.cjs +7 -12
- package/dist/cjs/workos-widgets.client.cjs.map +1 -1
- package/dist/css/lib/provider-icon.css +16 -11
- package/dist/esm/admin-portal-domain-verification.client.d.ts +3 -2
- package/dist/esm/admin-portal-domain-verification.client.js +31 -17
- package/dist/esm/admin-portal-domain-verification.client.js.map +1 -1
- package/dist/esm/admin-portal-sso-connection.client.d.ts +16 -0
- package/dist/esm/{admin-portal-sso-connection-client.js → admin-portal-sso-connection.client.js} +57 -31
- package/dist/esm/admin-portal-sso-connection.client.js.map +1 -0
- package/dist/esm/api/api-provider.d.ts +1 -1
- package/dist/esm/api/api-provider.js +1 -1
- package/dist/esm/api/api-provider.js.map +1 -1
- package/dist/esm/api/endpoint.d.ts +62 -1
- package/dist/esm/api/endpoint.js +56 -2
- package/dist/esm/api/endpoint.js.map +1 -1
- package/dist/esm/api-keys.client.d.ts +15 -0
- package/dist/esm/api-keys.client.js +75 -0
- package/dist/esm/api-keys.client.js.map +1 -0
- package/dist/esm/index.d.ts +6 -2
- package/dist/esm/index.js +9 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/admin-portal-domain-verification.d.ts +10 -6
- package/dist/esm/lib/admin-portal-domain-verification.js +33 -34
- package/dist/esm/lib/admin-portal-domain-verification.js.map +1 -1
- package/dist/esm/lib/admin-portal-sso-connection.d.ts +13 -6
- package/dist/esm/lib/admin-portal-sso-connection.js +83 -80
- package/dist/esm/lib/admin-portal-sso-connection.js.map +1 -1
- package/dist/esm/lib/api-keys/api-keys.d.ts +16 -8
- package/dist/esm/lib/api-keys/api-keys.js +69 -54
- package/dist/esm/lib/api-keys/api-keys.js.map +1 -1
- package/dist/esm/lib/constants.d.ts +2 -1
- package/dist/esm/lib/constants.js +3 -1
- package/dist/esm/lib/constants.js.map +1 -1
- package/dist/esm/lib/elevated-access.js.map +1 -1
- package/dist/esm/lib/empty-state.d.ts +6 -2
- package/dist/esm/lib/empty-state.js +24 -8
- package/dist/esm/lib/empty-state.js.map +1 -1
- package/dist/esm/lib/generic-error.d.ts +5 -2
- package/dist/esm/lib/generic-error.js +33 -24
- package/dist/esm/lib/generic-error.js.map +1 -1
- package/dist/esm/lib/identity-providers.d.ts +2 -2
- package/dist/esm/lib/identity-providers.js +2 -1
- package/dist/esm/lib/identity-providers.js.map +1 -1
- package/dist/esm/lib/oauth-icons.d.ts +7 -3
- package/dist/esm/lib/oauth-icons.js +11 -6
- package/dist/esm/lib/oauth-icons.js.map +1 -1
- package/dist/esm/lib/organization-switcher.d.ts +12 -9
- package/dist/esm/lib/organization-switcher.js +54 -9
- package/dist/esm/lib/organization-switcher.js.map +1 -1
- package/dist/esm/lib/otp-input.js +1 -1
- package/dist/esm/lib/otp-input.js.map +1 -1
- package/dist/esm/lib/pipes.d.ts +19 -0
- package/dist/esm/lib/pipes.js +336 -0
- package/dist/esm/lib/pipes.js.map +1 -0
- package/dist/esm/lib/provider-icon.d.ts +4 -1
- package/dist/esm/lib/provider-icon.js +0 -8
- package/dist/esm/lib/provider-icon.js.map +1 -1
- package/dist/esm/lib/save-button.js.map +1 -1
- package/dist/esm/lib/user-profile.d.ts +11 -7
- package/dist/esm/lib/user-profile.js +82 -75
- package/dist/esm/lib/user-profile.js.map +1 -1
- package/dist/esm/lib/user-security.d.ts +10 -7
- package/dist/esm/lib/user-security.js +34 -25
- package/dist/esm/lib/user-security.js.map +1 -1
- package/dist/esm/lib/user-sessions.d.ts +10 -6
- package/dist/esm/lib/user-sessions.js +20 -9
- package/dist/esm/lib/user-sessions.js.map +1 -1
- package/dist/esm/lib/users-management.d.ts +10 -7
- package/dist/esm/lib/users-management.js +230 -217
- package/dist/esm/lib/users-management.js.map +1 -1
- package/dist/esm/lib/utils.d.ts +29 -2
- package/dist/esm/lib/utils.js +46 -1
- package/dist/esm/lib/utils.js.map +1 -1
- package/dist/esm/organization-switcher.client.d.ts +2 -1
- package/dist/esm/organization-switcher.client.js +44 -16
- package/dist/esm/organization-switcher.client.js.map +1 -1
- package/dist/esm/pipes.client.d.ts +15 -0
- package/dist/esm/pipes.client.js +42 -0
- package/dist/esm/pipes.client.js.map +1 -0
- package/dist/esm/user-profile.client.d.ts +4 -3
- package/dist/esm/user-profile.client.js +26 -10
- package/dist/esm/user-profile.client.js.map +1 -1
- package/dist/esm/user-security.client.d.ts +3 -2
- package/dist/esm/user-security.client.js +26 -10
- package/dist/esm/user-security.client.js.map +1 -1
- package/dist/esm/user-sessions.client.d.ts +4 -2
- package/dist/esm/user-sessions.client.js +33 -16
- package/dist/esm/user-sessions.client.js.map +1 -1
- package/dist/esm/users-management.client.d.ts +3 -2
- package/dist/esm/users-management.client.js +34 -18
- package/dist/esm/users-management.client.js.map +1 -1
- package/dist/esm/workos-widgets.client.js +7 -12
- package/dist/esm/workos-widgets.client.js.map +1 -1
- package/package.json +17 -10
- package/dist/cjs/admin-portal-sso-connection-client.cjs.map +0 -1
- package/dist/cjs/admin-portal-sso-connection-client.d.cts +0 -12
- package/dist/cjs/api-keys-client.cjs.map +0 -1
- package/dist/cjs/api-keys-client.d.cts +0 -10
- package/dist/esm/admin-portal-sso-connection-client.d.ts +0 -12
- package/dist/esm/admin-portal-sso-connection-client.js.map +0 -1
- package/dist/esm/api-keys-client.d.ts +0 -10
- package/dist/esm/api-keys-client.js +0 -60
- package/dist/esm/api-keys-client.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/admin-portal-sso-connection.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Box, Button, Card, Flex, Text } from \"@radix-ui/themes\";\nimport { Skeleton } from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport {\n ExternalLinkIcon,\n InfoCircledIcon,\n Cross2Icon,\n} from \"@radix-ui/react-icons\";\nimport * as CardList from \"./card-list.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport {\n getIdentityProviderName,\n type IdentityProvider,\n} from \"./identity-providers.js\";\nimport { Status } from \"./status.js\";\nimport { unreachable } from \"./utils.js\";\nimport clsx from \"clsx\";\nimport { getErrorMessage } from \"./generic-error.js\";\n\ninterface NotConfiguredProps {\n connectionStatus: \"NotConfigured\";\n identityProvider?: never;\n expiryDate?: never;\n}\n\ninterface InactiveProps {\n connectionStatus: \"Inactive\";\n identityProvider: IdentityProvider;\n expiryDate?: never;\n}\n\ninterface ActiveProps {\n connectionStatus: \"Active\";\n identityProvider: IdentityProvider;\n expiryDate?: never;\n}\n\ninterface RequiresActionProps {\n connectionStatus: \"Expired\" | \"Expiring\";\n identityProvider: IdentityProvider;\n expiryDate: Date | null;\n}\n\nexport type AdminPortalSsoConnectionStatusProps =\n | NotConfiguredProps\n | InactiveProps\n | ActiveProps\n | RequiresActionProps;\n\nexport type AdminPortalSsoConnectionProps =\n AdminPortalSsoConnectionStatusProps & {\n currentDate: Date | null;\n\n lastSession: Date | null;\n adminPortalOpenButton: React.ReactNode;\n };\n\ninterface AdminPortalSsoConnectionContextValue {\n connectionStatus: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}\n\nconst AdminPortalSsoConnectionContext =\n React.createContext<AdminPortalSsoConnectionContextValue | null>(null);\nAdminPortalSsoConnectionContext.displayName = \"AdminPortalSsoConnectionContext\";\n\nfunction useAdminPortalSsoConnectionContext() {\n const context = React.useContext(AdminPortalSsoConnectionContext);\n if (!context) {\n throw new Error(\n \"useAdminPortalSsoConnectionContext must be used within a AdminPortalSsoConnectionContext provider\",\n );\n }\n return context;\n}\n\nexport const AdminPortalSsoConnection = ({\n currentDate,\n connectionStatus,\n identityProvider,\n expiryDate,\n lastSession,\n adminPortalOpenButton,\n}: AdminPortalSsoConnectionProps) => {\n return (\n <CardList.Root\n size=\"2\"\n className={clsx(\"woswidgets-widget\")}\n data-woswidgets-widget-id=\"admin-portal-sso-connection\"\n >\n <AdminPortalSsoConnectionContext.Provider value={{ connectionStatus }}>\n <CardList.Item>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n {(() => {\n if (connectionStatus === \"NotConfigured\") {\n return (\n <>\n <Text size=\"2\" color=\"gray\" ml=\"2\">\n You haven’t set up Single Sign-On yet.\n </Text>\n {adminPortalOpenButton}\n </>\n );\n }\n\n return (\n <>\n <SessionInfo\n connectionStatus={connectionStatus}\n identityProvider={identityProvider}\n lastSession={lastSession}\n currentDate={currentDate}\n />\n <Flex gap=\"5\" align=\"center\">\n <SsoStatus status={connectionStatus} />\n {adminPortalOpenButton}\n </Flex>\n </>\n );\n })()}\n </Flex>\n </CardList.Item>\n {connectionStatus === \"Expired\" && (\n <CardList.Item>\n <Flex align=\"start\" gap=\"2\">\n <Box asChild mt=\"2px\" flexShrink=\"0\">\n <InfoCircledIcon color=\"gray\" />\n </Box>\n {(() => {\n if (connectionStatus === \"Expired\") {\n return (\n <Text size=\"2\" color=\"gray\">\n {(() => {\n if (!expiryDate) {\n return \"The SAML response signing certificate has expired\";\n }\n\n return (\n <>\n The SAML response signing certificate expired on{\" \"}\n <Text weight=\"bold\" as=\"span\">\n {expiryDate?.toLocaleString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </Text>\n </>\n );\n })()}\n . Users won’t be able to sign-in to the application until\n the certificate is renewed.\n </Text>\n );\n }\n\n if (connectionStatus === \"Expiring\") {\n return (\n <Text size=\"2\" color=\"gray\">\n {(() => {\n if (!expiryDate) {\n return \"The SAML response signing certificate is expiring soon\";\n }\n\n return (\n <>\n The SAML response signing certificate will expire on{\" \"}\n <Text weight=\"bold\" as=\"span\">\n {expiryDate?.toLocaleString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </Text>\n </>\n );\n })()}\n . When expired, users won’t be able to sign-in.\n </Text>\n );\n }\n })()}\n </Flex>\n </CardList.Item>\n )}\n </AdminPortalSsoConnectionContext.Provider>\n </CardList.Root>\n );\n};\n\nfunction SsoStatus({\n status,\n}: {\n status: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}) {\n if (status === \"NotConfigured\") {\n return null;\n }\n\n if (status === \"Inactive\") {\n return <Status state=\"waiting\">Setup in progress</Status>;\n }\n\n if (status === \"Expired\") {\n return <Status state=\"error\">Requires action</Status>;\n }\n\n if (status === \"Active\" || status === \"Expiring\") {\n return <Status state=\"success\">Connected</Status>;\n }\n\n return unreachable(status);\n}\n\nfunction SessionInfo({\n currentDate,\n identityProvider,\n lastSession,\n connectionStatus,\n}: {\n identityProvider: IdentityProvider;\n lastSession: Date | null;\n currentDate: Date | null;\n connectionStatus: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}) {\n const relativeTimeString = React.useMemo(() => {\n if (\n !lastSession ||\n !currentDate ||\n connectionStatus === \"NotConfigured\" ||\n connectionStatus === \"Inactive\"\n ) {\n return null;\n }\n\n return getRelativeTimeString(currentDate, lastSession);\n }, [lastSession, currentDate, connectionStatus]);\n\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color=\"panel\">\n <ProviderIcon provider={identityProvider} size=\"2\" />\n </IconPanel>\n {lastSession ? (\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {getIdentityProviderName(identityProvider)}\n </Text>\n {relativeTimeString ? (\n <Text color=\"gray\" size=\"2\">\n Last session {relativeTimeString}\n </Text>\n ) : null}\n </Flex>\n ) : (\n <Text size=\"2\" weight=\"bold\">\n {getIdentityProviderName(identityProvider)}\n </Text>\n )}\n </Flex>\n );\n}\n\nexport function AdminPortalOpenButton({\n isPending,\n href,\n initConfig,\n}: {\n isPending: boolean;\n href: string | null;\n initConfig: () => void;\n}) {\n const { connectionStatus } = useAdminPortalSsoConnectionContext();\n const label = (() => {\n switch (connectionStatus) {\n case \"NotConfigured\":\n return \"Set up SSO\";\n case \"Inactive\":\n return \"Continue setup\";\n case \"Active\":\n case \"Expiring\":\n case \"Expired\":\n return \"Manage\";\n default:\n return unreachable(connectionStatus);\n }\n })();\n\n if (href) {\n return (\n <Button variant=\"outline\" color=\"gray\" asChild>\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {label} <ExternalLinkIcon />\n </a>\n </Button>\n );\n }\n\n return (\n <Button\n variant=\"outline\"\n color=\"gray\"\n loading={isPending}\n disabled={isPending}\n onClick={initConfig}\n >\n {label} <ExternalLinkIcon />\n </Button>\n );\n}\n\nexport const AdminPortalSsoConnectionLoading: React.FC = () => {\n return (\n <Card size=\"2\">\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel color=\"panel\">\n <ProviderIcon provider=\"okta\" size=\"2\" />\n </IconPanel>\n </Skeleton>\n <Flex direction=\"column\" gap=\"1\" my=\"-4px\">\n <Skeleton>\n <Text size=\"1\">Okta</Text>\n </Skeleton>\n <Skeleton>\n <Text size=\"1\">Last session 10 minutes ago</Text>\n </Skeleton>\n </Flex>\n </Flex>\n <Flex gap=\"5\" align=\"center\">\n <Skeleton>\n <Status state=\"error\">Requires action</Status>\n </Skeleton>\n <Skeleton>\n <Button variant=\"outline\" color=\"gray\">\n Manage <ExternalLinkIcon />\n </Button>\n </Skeleton>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\nexport function AdminPortalSsoConnectionError({ error }: { error: unknown }) {\n React.useEffect(() => {\n console.error(error);\n }, [error]);\n\n const { heading, message } = getErrorMessage(error);\n\n return (\n <Card size=\"2\">\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Flex\n align=\"center\"\n justify=\"center\"\n width=\"24px\"\n height=\"24px\"\n style={{\n borderRadius: \"9999px\",\n backgroundColor: \"var(--red-a4)\",\n color: \"var(--red-a11)\",\n flexShrink: 0,\n }}\n >\n <Cross2Icon width=\"18px\" height=\"18px\" />\n </Flex>\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {heading}\n </Text>\n <Text size=\"2\" color=\"gray\">\n {message}\n </Text>\n </Flex>\n </Flex>\n </Flex>\n </Card>\n );\n}\n\nfunction getRelativeTimeString(\n currentDate: Date | null,\n lastSession: Date | null,\n) {\n if (!currentDate || !lastSession) {\n return null;\n }\n\n const rtf = new Intl.RelativeTimeFormat(\"en\", { numeric: \"auto\" });\n const diff = lastSession.getTime() - currentDate.getTime();\n\n const diffSeconds = Math.round(diff / 1000);\n const diffMinutes = Math.round(diffSeconds / 60);\n const diffHours = Math.round(diffMinutes / 60);\n const diffDays = Math.round(diffHours / 24);\n const diffMonths = Math.round(diffDays / 30);\n const diffYears = Math.round(diffMonths / 12);\n\n if (Math.abs(diffSeconds) < 60) {\n return \"now\";\n }\n\n if (Math.abs(diffMinutes) < 60) {\n return rtf.format(diffMinutes, \"minute\");\n }\n\n if (Math.abs(diffHours) < 24) {\n return rtf.format(diffHours, \"hour\");\n }\n\n if (Math.abs(diffDays) < 30) {\n return rtf.format(diffDays, \"day\");\n }\n\n if (Math.abs(diffMonths) < 12) {\n return rtf.format(diffMonths, \"month\");\n }\n\n return rtf.format(diffYears, \"year\");\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/admin-portal-sso-connection.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Box, Button, Card, Flex, Text } from \"@radix-ui/themes\";\nimport { Skeleton } from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport {\n ExternalLinkIcon,\n InfoCircledIcon,\n Cross2Icon,\n} from \"@radix-ui/react-icons\";\nimport * as CardList from \"./card-list.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport {\n getIdentityProviderName,\n type IdentityProvider,\n} from \"./identity-providers.js\";\nimport { Status } from \"./status.js\";\nimport {\n getDomProps,\n unreachable,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\nimport { getErrorMessage } from \"./generic-error.js\";\n\ninterface NotConfiguredProps {\n connectionStatus: \"NotConfigured\";\n identityProvider?: never;\n expiryDate?: never;\n}\n\ninterface InactiveProps {\n connectionStatus: \"Inactive\";\n identityProvider: IdentityProvider;\n expiryDate?: never;\n}\n\ninterface ActiveProps {\n connectionStatus: \"Active\";\n identityProvider: IdentityProvider;\n expiryDate?: never;\n}\n\ninterface RequiresActionProps {\n connectionStatus: \"Expired\" | \"Expiring\";\n identityProvider: IdentityProvider;\n expiryDate: Date | null;\n}\n\nexport type AdminPortalSsoConnectionStatusProps =\n | NotConfiguredProps\n | InactiveProps\n | ActiveProps\n | RequiresActionProps;\n\ntype AdminPortalSsoConnectionProps = WidgetRootDomProps &\n AdminPortalSsoConnectionStatusProps & {\n currentDate: Date | null;\n lastSession: Date | null;\n adminPortalOpenButton: React.ReactNode;\n };\n\ninterface AdminPortalSsoConnectionContextValue {\n connectionStatus: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}\n\nconst AdminPortalSsoConnectionContext =\n React.createContext<AdminPortalSsoConnectionContextValue | null>(null);\nAdminPortalSsoConnectionContext.displayName = \"AdminPortalSsoConnectionContext\";\n\nfunction useAdminPortalSsoConnectionContext() {\n const context = React.useContext(AdminPortalSsoConnectionContext);\n if (!context) {\n throw new Error(\n \"useAdminPortalSsoConnectionContext must be used within a AdminPortalSsoConnectionContext provider\",\n );\n }\n return context;\n}\n\nconst AdminPortalSsoConnection: React.FC<AdminPortalSsoConnectionProps> = ({\n currentDate,\n connectionStatus,\n identityProvider,\n expiryDate,\n lastSession,\n adminPortalOpenButton,\n ...domProps\n}) => {\n return (\n <CardList.Root size=\"2\" {...getWidgetRootDomProps(\"resolved\", domProps)}>\n <AdminPortalSsoConnectionContext.Provider value={{ connectionStatus }}>\n <CardList.Item>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n {(() => {\n if (connectionStatus === \"NotConfigured\") {\n return (\n <>\n <Text size=\"2\" color=\"gray\">\n You haven’t set up Single Sign-On yet.\n </Text>\n {adminPortalOpenButton}\n </>\n );\n }\n\n return (\n <>\n <SessionInfo\n connectionStatus={connectionStatus}\n identityProvider={identityProvider}\n lastSession={lastSession}\n currentDate={currentDate}\n />\n <Flex gap=\"5\" align=\"center\">\n <SsoStatus status={connectionStatus} />\n {adminPortalOpenButton}\n </Flex>\n </>\n );\n })()}\n </Flex>\n </CardList.Item>\n {connectionStatus === \"Expired\" && (\n <CardList.Item>\n <Flex align=\"start\" gap=\"2\">\n <Box asChild mt=\"2px\" flexShrink=\"0\">\n <InfoCircledIcon color=\"gray\" />\n </Box>\n {(() => {\n if (connectionStatus === \"Expired\") {\n return (\n <Text size=\"2\" color=\"gray\">\n {(() => {\n if (!expiryDate) {\n return \"The SAML response signing certificate has expired\";\n }\n\n return (\n <>\n The SAML response signing certificate expired on{\" \"}\n <Text weight=\"bold\" as=\"span\">\n {expiryDate?.toLocaleString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </Text>\n </>\n );\n })()}\n . Users won’t be able to sign-in to the application until\n the certificate is renewed.\n </Text>\n );\n }\n\n if (connectionStatus === \"Expiring\") {\n return (\n <Text size=\"2\" color=\"gray\">\n {(() => {\n if (!expiryDate) {\n return \"The SAML response signing certificate is expiring soon\";\n }\n\n return (\n <>\n The SAML response signing certificate will expire on{\" \"}\n <Text weight=\"bold\" as=\"span\">\n {expiryDate?.toLocaleString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </Text>\n </>\n );\n })()}\n . When expired, users won’t be able to sign-in.\n </Text>\n );\n }\n })()}\n </Flex>\n </CardList.Item>\n )}\n </AdminPortalSsoConnectionContext.Provider>\n </CardList.Root>\n );\n};\n\nfunction SsoStatus({\n status,\n}: {\n status: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}) {\n if (status === \"NotConfigured\") {\n return null;\n }\n\n if (status === \"Inactive\") {\n return <Status state=\"waiting\">Setup in progress</Status>;\n }\n\n if (status === \"Expired\") {\n return <Status state=\"error\">Requires action</Status>;\n }\n\n if (status === \"Active\" || status === \"Expiring\") {\n return <Status state=\"success\">Connected</Status>;\n }\n\n return unreachable(status);\n}\n\nfunction SessionInfo({\n currentDate,\n identityProvider,\n lastSession,\n connectionStatus,\n}: {\n identityProvider: IdentityProvider;\n lastSession: Date | null;\n currentDate: Date | null;\n connectionStatus: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}) {\n const relativeTimeString = React.useMemo(() => {\n if (\n !lastSession ||\n !currentDate ||\n connectionStatus === \"NotConfigured\" ||\n connectionStatus === \"Inactive\"\n ) {\n return null;\n }\n\n return getRelativeTimeString(currentDate, lastSession);\n }, [lastSession, currentDate, connectionStatus]);\n\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color=\"panel\">\n <ProviderIcon provider={identityProvider} size=\"2\" />\n </IconPanel>\n {lastSession ? (\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {getIdentityProviderName(identityProvider)}\n </Text>\n {relativeTimeString ? (\n <Text color=\"gray\" size=\"2\">\n Last session {relativeTimeString}\n </Text>\n ) : null}\n </Flex>\n ) : (\n <Text size=\"2\" weight=\"bold\">\n {getIdentityProviderName(identityProvider)}\n </Text>\n )}\n </Flex>\n );\n}\n\nfunction AdminPortalOpenButton({\n isPending,\n href,\n initConfig,\n}: {\n isPending: boolean;\n href: string | null;\n initConfig: () => void;\n}) {\n const { connectionStatus } = useAdminPortalSsoConnectionContext();\n const label = (() => {\n switch (connectionStatus) {\n case \"NotConfigured\":\n return \"Set up SSO\";\n case \"Inactive\":\n return \"Continue setup\";\n case \"Active\":\n case \"Expiring\":\n case \"Expired\":\n return \"Manage\";\n default:\n return unreachable(connectionStatus);\n }\n })();\n\n if (href) {\n return (\n <Button variant=\"outline\" color=\"gray\" asChild>\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {label} <ExternalLinkIcon />\n </a>\n </Button>\n );\n }\n\n return (\n <Button\n variant=\"outline\"\n color=\"gray\"\n loading={isPending}\n disabled={isPending}\n onClick={initConfig}\n >\n {label} <ExternalLinkIcon />\n </Button>\n );\n}\n\ninterface AdminPortalSsoConnectionLoadingProps extends WidgetRootDomProps {}\n\nconst AdminPortalSsoConnectionLoading: React.FC<\n AdminPortalSsoConnectionLoadingProps\n> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel color=\"panel\">\n <ProviderIcon provider=\"okta\" size=\"2\" />\n </IconPanel>\n </Skeleton>\n <Flex direction=\"column\" gap=\"1\" my=\"-4px\">\n <Skeleton>\n <Text size=\"1\">Okta</Text>\n </Skeleton>\n <Skeleton>\n <Text size=\"1\">Last session 10 minutes ago</Text>\n </Skeleton>\n </Flex>\n </Flex>\n <Flex gap=\"5\" align=\"center\">\n <Skeleton>\n <Status state=\"error\">Requires action</Status>\n </Skeleton>\n <Skeleton>\n <Button variant=\"outline\" color=\"gray\">\n Manage <ExternalLinkIcon />\n </Button>\n </Skeleton>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\ninterface AdminPortalSsoConnectionErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst AdminPortalSsoConnectionError: React.FC<\n AdminPortalSsoConnectionErrorProps\n> = ({ error, ...domProps }) => {\n React.useEffect(() => {\n console.error(error);\n }, [error]);\n\n const { heading, message } = getErrorMessage(error);\n\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Flex\n align=\"center\"\n justify=\"center\"\n width=\"24px\"\n height=\"24px\"\n style={{\n borderRadius: \"9999px\",\n backgroundColor: \"var(--red-a4)\",\n color: \"var(--red-a11)\",\n flexShrink: 0,\n }}\n >\n <Cross2Icon width=\"18px\" height=\"18px\" />\n </Flex>\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {heading}\n </Text>\n <Text size=\"2\" color=\"gray\">\n {message}\n </Text>\n </Flex>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\nfunction getRelativeTimeString(\n currentDate: Date | null,\n lastSession: Date | null,\n) {\n if (!currentDate || !lastSession) {\n return null;\n }\n\n const rtf = new Intl.RelativeTimeFormat(\"en\", { numeric: \"auto\" });\n const diff = lastSession.getTime() - currentDate.getTime();\n\n const diffSeconds = Math.round(diff / 1000);\n const diffMinutes = Math.round(diffSeconds / 60);\n const diffHours = Math.round(diffMinutes / 60);\n const diffDays = Math.round(diffHours / 24);\n const diffMonths = Math.round(diffDays / 30);\n const diffYears = Math.round(diffMonths / 12);\n\n if (Math.abs(diffSeconds) < 60) {\n return \"now\";\n }\n\n if (Math.abs(diffMinutes) < 60) {\n return rtf.format(diffMinutes, \"minute\");\n }\n\n if (Math.abs(diffHours) < 24) {\n return rtf.format(diffHours, \"hour\");\n }\n\n if (Math.abs(diffDays) < 30) {\n return rtf.format(diffDays, \"day\");\n }\n\n if (Math.abs(diffMonths) < 12) {\n return rtf.format(diffMonths, \"month\");\n }\n\n return rtf.format(diffYears, \"year\");\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"admin-portal-sso-connection\",\n widgetState: state,\n });\n}\n\nexport type {\n AdminPortalSsoConnectionProps,\n AdminPortalSsoConnectionLoadingProps,\n AdminPortalSsoConnectionErrorProps,\n};\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n AdminPortalSsoConnectionError,\n /** @internal */\n AdminPortalOpenButton,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { WidgetRootDomProps } from '../utils.js';
|
|
2
|
+
import { ListOrganizationApiKeysResponse } from '../../api/endpoint.js';
|
|
3
|
+
import '@tanstack/react-query';
|
|
4
|
+
import '../../api/widgets-api-client.js';
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
interface ApiKeysProps extends WidgetRootDomProps {
|
|
7
|
+
apiKeys: ListOrganizationApiKeysResponse;
|
|
8
|
+
searchQuery: string | null;
|
|
9
|
+
}
|
|
10
|
+
declare const ApiKeys: React.FC<ApiKeysProps>;
|
|
11
|
+
interface ApiKeysLoadingProps extends WidgetRootDomProps {
|
|
12
|
+
}
|
|
13
|
+
declare const ApiKeysLoading: React.FC<ApiKeysLoadingProps>;
|
|
14
|
+
interface ApiKeysErrorProps extends WidgetRootDomProps {
|
|
5
15
|
error: unknown;
|
|
6
|
-
}
|
|
7
|
-
declare
|
|
8
|
-
declare function ApiKeysLoading(): react_jsx_runtime.JSX.Element;
|
|
9
|
-
declare function ApiKeysRoot({ className, children, ...props }: React.ComponentProps<typeof Flex>): react_jsx_runtime.JSX.Element;
|
|
16
|
+
}
|
|
17
|
+
declare const ApiKeysError: React.FC<ApiKeysErrorProps>;
|
|
10
18
|
|
|
11
|
-
export {
|
|
19
|
+
export { ApiKeys, ApiKeysError, type ApiKeysErrorProps, ApiKeysLoading, type ApiKeysLoadingProps, type ApiKeysProps };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button, Flex, Skeleton } from "@radix-ui/themes";
|
|
3
3
|
import { TextField, TextFieldSlot } from "../elements.js";
|
|
4
4
|
import { GenericError } from "../generic-error.js";
|
|
@@ -6,69 +6,84 @@ import { EmptyState } from "../empty-state.js";
|
|
|
6
6
|
import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
|
|
7
7
|
import { SkeletonTable } from "./skeleton-table.js";
|
|
8
8
|
import { CreateApiKeyButton } from "./create-api-key.js";
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
import { getDomProps } from "../utils.js";
|
|
10
|
+
import { ApiKeysSearchProvider } from "./api-keys-search-provider.js";
|
|
11
|
+
import { ApiKeysTable } from "./api-keys-table.js";
|
|
12
|
+
const ApiKeys = ({
|
|
13
|
+
apiKeys,
|
|
14
|
+
searchQuery,
|
|
15
|
+
...domProps
|
|
16
|
+
}) => {
|
|
17
|
+
return apiKeys.data.length === 0 && !searchQuery ? /* @__PURE__ */ jsx(ApiKeysEmptyState, { ...getWidgetRootDomProps("resolved", domProps) }) : /* @__PURE__ */ jsx(ApiKeysSearchProvider, { children: /* @__PURE__ */ jsx(
|
|
18
|
+
ApiKeysTable,
|
|
16
19
|
{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
action: /* @__PURE__ */ jsx(CreateApiKeyButton, {})
|
|
20
|
+
apiKeys,
|
|
21
|
+
...getWidgetRootDomProps("resolved", domProps)
|
|
20
22
|
}
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return /* @__PURE__ */ jsxs(
|
|
25
|
-
/* @__PURE__ */ jsxs(Flex, { justify: "between", align: "center", children: [
|
|
26
|
-
/* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(
|
|
27
|
-
TextField,
|
|
28
|
-
{
|
|
29
|
-
name: "api-keys-widget-search",
|
|
30
|
-
style: { width: "390px" },
|
|
31
|
-
placeholder: "Search by name",
|
|
32
|
-
children: /* @__PURE__ */ jsx(TextFieldSlot, { side: "left", children: /* @__PURE__ */ jsx(MagnifyingGlassIcon, { "aria-hidden": "true", height: "16", width: "16" }) })
|
|
33
|
-
}
|
|
34
|
-
) }),
|
|
35
|
-
/* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(Button, { children: "Create API key" }) })
|
|
36
|
-
] }),
|
|
37
|
-
/* @__PURE__ */ jsx(
|
|
38
|
-
SkeletonTable,
|
|
39
|
-
{
|
|
40
|
-
numRows: 5,
|
|
41
|
-
columns: [
|
|
42
|
-
{ children: "Name", width: "25%" },
|
|
43
|
-
{ children: "Secret key", width: "25%" },
|
|
44
|
-
{ children: "Last used", width: "25%" },
|
|
45
|
-
{ children: "Created", width: "25%" }
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
)
|
|
49
|
-
] });
|
|
50
|
-
}
|
|
51
|
-
function ApiKeysRoot({
|
|
52
|
-
className,
|
|
53
|
-
children,
|
|
54
|
-
...props
|
|
55
|
-
}) {
|
|
56
|
-
return /* @__PURE__ */ jsx(
|
|
23
|
+
) });
|
|
24
|
+
};
|
|
25
|
+
const ApiKeysLoading = (props) => {
|
|
26
|
+
return /* @__PURE__ */ jsxs(
|
|
57
27
|
Flex,
|
|
58
28
|
{
|
|
59
|
-
className: clsx("woswidgets-widget", className),
|
|
60
|
-
"data-woswidgets-widget-id": "api-keys",
|
|
61
29
|
direction: "column",
|
|
30
|
+
align: "stretch",
|
|
62
31
|
gap: "3",
|
|
63
|
-
...props,
|
|
64
|
-
children
|
|
32
|
+
...getWidgetRootDomProps("loading", props),
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ jsxs(Flex, { justify: "between", align: "center", children: [
|
|
35
|
+
/* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(
|
|
36
|
+
TextField,
|
|
37
|
+
{
|
|
38
|
+
name: "api-keys-widget-search",
|
|
39
|
+
style: { width: "390px" },
|
|
40
|
+
placeholder: "Search by name",
|
|
41
|
+
children: /* @__PURE__ */ jsx(TextFieldSlot, { side: "left", children: /* @__PURE__ */ jsx(MagnifyingGlassIcon, { "aria-hidden": "true", height: "16", width: "16" }) })
|
|
42
|
+
}
|
|
43
|
+
) }),
|
|
44
|
+
/* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(Button, { children: "Create API key" }) })
|
|
45
|
+
] }),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
SkeletonTable,
|
|
48
|
+
{
|
|
49
|
+
numRows: 5,
|
|
50
|
+
columns: [
|
|
51
|
+
{ children: "Name", width: "25%" },
|
|
52
|
+
{ children: "Secret key", width: "25%" },
|
|
53
|
+
{ children: "Last used", width: "25%" },
|
|
54
|
+
{ children: "Created", width: "25%" }
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
]
|
|
65
59
|
}
|
|
66
60
|
);
|
|
61
|
+
};
|
|
62
|
+
const ApiKeysError = ({ error, ...domProps }) => {
|
|
63
|
+
return /* @__PURE__ */ jsx(GenericError, { error, ...getWidgetRootDomProps("error", domProps) });
|
|
64
|
+
};
|
|
65
|
+
function ApiKeysEmptyState(props) {
|
|
66
|
+
return /* @__PURE__ */ jsx(
|
|
67
|
+
EmptyState,
|
|
68
|
+
{
|
|
69
|
+
heading: "No API keys yet",
|
|
70
|
+
message: "Generate an API key to authenticate and interact with our API.",
|
|
71
|
+
action: /* @__PURE__ */ jsx(CreateApiKeyButton, {}),
|
|
72
|
+
...props
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
function getWidgetRootDomProps(state, domProps) {
|
|
77
|
+
return getDomProps({
|
|
78
|
+
...domProps,
|
|
79
|
+
isWidgetRoot: true,
|
|
80
|
+
widgetId: "api-keys",
|
|
81
|
+
widgetState: state
|
|
82
|
+
});
|
|
67
83
|
}
|
|
68
84
|
export {
|
|
69
|
-
|
|
85
|
+
ApiKeys,
|
|
70
86
|
ApiKeysError,
|
|
71
|
-
ApiKeysLoading
|
|
72
|
-
ApiKeysRoot
|
|
87
|
+
ApiKeysLoading
|
|
73
88
|
};
|
|
74
89
|
//# sourceMappingURL=api-keys.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/api-keys/api-keys.tsx"],"sourcesContent":["import { Button, Flex, Skeleton } from \"@radix-ui/themes\";\nimport { TextField, TextFieldSlot } from \"../elements.js\";\nimport { GenericError } from \"../generic-error.js\";\nimport { EmptyState } from \"../empty-state.js\";\nimport { MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { SkeletonTable } from \"./skeleton-table.js\";\nimport { CreateApiKeyButton } from \"./create-api-key.js\";\nimport
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/api-keys/api-keys.tsx"],"sourcesContent":["import { Button, Flex, Skeleton } from \"@radix-ui/themes\";\nimport { TextField, TextFieldSlot } from \"../elements.js\";\nimport { GenericError } from \"../generic-error.js\";\nimport { EmptyState } from \"../empty-state.js\";\nimport { MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { SkeletonTable } from \"./skeleton-table.js\";\nimport { CreateApiKeyButton } from \"./create-api-key.js\";\nimport { getDomProps, WidgetRootDomProps, WidgetRootState } from \"../utils.js\";\nimport { ListOrganizationApiKeysResponse } from \"../../api/endpoint.js\";\nimport { ApiKeysSearchProvider } from \"./api-keys-search-provider.js\";\nimport { ApiKeysTable } from \"./api-keys-table.js\";\n\ninterface ApiKeysProps extends WidgetRootDomProps {\n apiKeys: ListOrganizationApiKeysResponse;\n searchQuery: string | null;\n}\n\nconst ApiKeys: React.FC<ApiKeysProps> = ({\n apiKeys,\n searchQuery,\n ...domProps\n}) => {\n return apiKeys.data.length === 0 && !searchQuery ? (\n <ApiKeysEmptyState {...getWidgetRootDomProps(\"resolved\", domProps)} />\n ) : (\n <ApiKeysSearchProvider>\n <ApiKeysTable\n apiKeys={apiKeys}\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n />\n </ApiKeysSearchProvider>\n );\n};\n\ninterface ApiKeysLoadingProps extends WidgetRootDomProps {}\n\nconst ApiKeysLoading: React.FC<ApiKeysLoadingProps> = (props) => {\n return (\n <Flex\n direction=\"column\"\n align=\"stretch\"\n gap=\"3\"\n {...getWidgetRootDomProps(\"loading\", props)}\n >\n <Flex justify=\"between\" align=\"center\">\n <Skeleton>\n <TextField\n name=\"api-keys-widget-search\"\n style={{ width: \"390px\" }}\n placeholder=\"Search by name\"\n >\n <TextFieldSlot side=\"left\">\n <MagnifyingGlassIcon aria-hidden=\"true\" height=\"16\" width=\"16\" />\n </TextFieldSlot>\n </TextField>\n </Skeleton>\n <Skeleton>\n <Button>Create API key</Button>\n </Skeleton>\n </Flex>\n <SkeletonTable\n numRows={5}\n columns={[\n { children: \"Name\", width: \"25%\" },\n { children: \"Secret key\", width: \"25%\" },\n { children: \"Last used\", width: \"25%\" },\n { children: \"Created\", width: \"25%\" },\n ]}\n />\n </Flex>\n );\n};\n\ninterface ApiKeysErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst ApiKeysError: React.FC<ApiKeysErrorProps> = ({ error, ...domProps }) => {\n return (\n <GenericError error={error} {...getWidgetRootDomProps(\"error\", domProps)} />\n );\n};\n\nfunction ApiKeysEmptyState(props: WidgetRootDomProps) {\n return (\n <EmptyState\n heading=\"No API keys yet\"\n message=\"Generate an API key to authenticate and interact with our API.\"\n action={<CreateApiKeyButton />}\n {...props}\n />\n );\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"api-keys\",\n widgetState: state,\n });\n}\n\nexport type { ApiKeysProps, ApiKeysLoadingProps, ApiKeysErrorProps };\nexport { ApiKeys, ApiKeysLoading, ApiKeysError };\n"],"mappings":"AAuBI,cAqBE,YArBF;AAvBJ,SAAS,QAAQ,MAAM,gBAAgB;AACvC,SAAS,WAAW,qBAAqB;AACzC,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,0BAA0B;AACnC,SAAS,mBAAwD;AAEjE,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAO7B,MAAM,UAAkC,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,SAAO,QAAQ,KAAK,WAAW,KAAK,CAAC,cACnC,oBAAC,qBAAmB,GAAG,sBAAsB,YAAY,QAAQ,GAAG,IAEpE,oBAAC,yBACC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACC,GAAG,sBAAsB,YAAY,QAAQ;AAAA;AAAA,EAChD,GACF;AAEJ;AAIA,MAAM,iBAAgD,CAAC,UAAU;AAC/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAM;AAAA,MACN,KAAI;AAAA,MACH,GAAG,sBAAsB,WAAW,KAAK;AAAA,MAE1C;AAAA,6BAAC,QAAK,SAAQ,WAAU,OAAM,UAC5B;AAAA,8BAAC,YACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,EAAE,OAAO,QAAQ;AAAA,cACxB,aAAY;AAAA,cAEZ,8BAAC,iBAAc,MAAK,QAClB,8BAAC,uBAAoB,eAAY,QAAO,QAAO,MAAK,OAAM,MAAK,GACjE;AAAA;AAAA,UACF,GACF;AAAA,UACA,oBAAC,YACC,8BAAC,UAAO,4BAAc,GACxB;AAAA,WACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,SAAS;AAAA,cACP,EAAE,UAAU,QAAQ,OAAO,MAAM;AAAA,cACjC,EAAE,UAAU,cAAc,OAAO,MAAM;AAAA,cACvC,EAAE,UAAU,aAAa,OAAO,MAAM;AAAA,cACtC,EAAE,UAAU,WAAW,OAAO,MAAM;AAAA,YACtC;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAMA,MAAM,eAA4C,CAAC,EAAE,OAAO,GAAG,SAAS,MAAM;AAC5E,SACE,oBAAC,gBAAa,OAAe,GAAG,sBAAsB,SAAS,QAAQ,GAAG;AAE9E;AAEA,SAAS,kBAAkB,OAA2B;AACpD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,SAAQ;AAAA,MACR,QAAQ,oBAAC,sBAAmB;AAAA,MAC3B,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,sBACP,OACA,UACA;AACA,SAAO,YAAY;AAAA,IACjB,GAAG;AAAA,IACH,cAAc;AAAA,IACd,UAAU;AAAA,IACV,aAAa;AAAA,EACf,CAAC;AACH;","names":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
declare const USER_ROW_LIMIT = 10;
|
|
2
2
|
declare const WIDGETS_API_VERSION = "1";
|
|
3
3
|
declare const WIDGETS_CLASS_NAMESPACE = "woswidgets";
|
|
4
|
+
declare const WIDGETS_DATA_ATTRIBUTE_NAMESPACE = "woswidgets";
|
|
4
5
|
|
|
5
|
-
export { USER_ROW_LIMIT, WIDGETS_API_VERSION, WIDGETS_CLASS_NAMESPACE };
|
|
6
|
+
export { USER_ROW_LIMIT, WIDGETS_API_VERSION, WIDGETS_CLASS_NAMESPACE, WIDGETS_DATA_ATTRIBUTE_NAMESPACE };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
const USER_ROW_LIMIT = 10;
|
|
2
2
|
const WIDGETS_API_VERSION = "1";
|
|
3
3
|
const WIDGETS_CLASS_NAMESPACE = "woswidgets";
|
|
4
|
+
const WIDGETS_DATA_ATTRIBUTE_NAMESPACE = "woswidgets";
|
|
4
5
|
export {
|
|
5
6
|
USER_ROW_LIMIT,
|
|
6
7
|
WIDGETS_API_VERSION,
|
|
7
|
-
WIDGETS_CLASS_NAMESPACE
|
|
8
|
+
WIDGETS_CLASS_NAMESPACE,
|
|
9
|
+
WIDGETS_DATA_ATTRIBUTE_NAMESPACE
|
|
8
10
|
};
|
|
9
11
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/constants.ts"],"sourcesContent":["export const USER_ROW_LIMIT = 10;\nexport const WIDGETS_API_VERSION = \"1\";\nexport const WIDGETS_CLASS_NAMESPACE = \"woswidgets\";\n"],"mappings":"AAAO,MAAM,iBAAiB;AACvB,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/constants.ts"],"sourcesContent":["export const USER_ROW_LIMIT = 10;\nexport const WIDGETS_API_VERSION = \"1\";\nexport const WIDGETS_CLASS_NAMESPACE = \"woswidgets\";\nexport const WIDGETS_DATA_ATTRIBUTE_NAMESPACE = \"woswidgets\";\n"],"mappings":"AAAO,MAAM,iBAAiB;AACvB,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAChC,MAAM,mCAAmC;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/elevated-access.tsx"],"sourcesContent":["import * as Form from \"@radix-ui/react-form\";\nimport { AlertDialog, Callout, Dialog, Flex, Text } from \"@radix-ui/themes\";\nimport { useMe, useSendVerification, useVerify } from \"../api/endpoint.js\";\nimport { useElevatedAccessToken } from \"../api/api-provider.js\";\nimport { PropsWithChildren, useEffect, useRef, useState } from \"react\";\nimport { PrimaryButton, SecondaryButton } from \"./elements.js\";\nimport * as Otp from \"./otp-input.js\";\n\ninterface ElevatedAccessProps extends PropsWithChildren {\n onVerified?: () => Promise<unknown>;\n type?: \"dialog\" | \"alert\";\n}\n\nexport function ElevatedAccess({\n type = \"dialog\",\n children,\n onVerified,\n}: ElevatedAccessProps) {\n const { elevatedAccess } = useElevatedAccessToken();\n const [authenticationChallengeId, setAuthenticationChallengeId] =\n useState<string>();\n\n const prevAccessToken = useRef(elevatedAccess);\n\n useEffect(() => {\n prevAccessToken.current = elevatedAccess;\n }, [elevatedAccess]);\n\n if (elevatedAccess) {\n return <>{children}</>;\n }\n\n if (!authenticationChallengeId) {\n const hasTokenExpired = !!prevAccessToken.current;\n\n return (\n <SendVerificationEmailForm\n type={type}\n hasTokenExpired={hasTokenExpired}\n onSuccess={(challengeId) => {\n setAuthenticationChallengeId(challengeId);\n }}\n />\n );\n }\n\n if (authenticationChallengeId) {\n return (\n <VerificationIdentityForm\n type={type}\n authenticationChallengeId={authenticationChallengeId}\n onSuccess={() => {\n // Reset the challenge id\n setAuthenticationChallengeId(undefined);\n\n return onVerified?.();\n }}\n />\n );\n }\n\n return null;\n}\n\ninterface SendVerificationEmailFormProps {\n onSuccess: (challengeId: string) => unknown | Promise<unknown>;\n type: \"dialog\" | \"alert\";\n hasTokenExpired: boolean;\n}\n\nfunction SendVerificationEmailForm({\n onSuccess,\n type,\n hasTokenExpired,\n}: SendVerificationEmailFormProps) {\n const { data: me } = useMe();\n const sendVerification = useSendVerification({\n mutation: { onSuccess: (data) => onSuccess(data.authenticationChallenge) },\n });\n\n const Title = type === \"dialog\" ? Dialog.Title : AlertDialog.Title;\n const Description =\n type === \"dialog\" ? Dialog.Description : AlertDialog.Description;\n const Close = type === \"dialog\" ? Dialog.Close : AlertDialog.Cancel;\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n sendVerification.mutate();\n };\n\n return (\n <form onSubmit={handleSubmit}>\n <Title>\n {hasTokenExpired\n ? \"Your verification token has expired\"\n : \"Verify your identity\"}\n </Title>\n\n <Description color=\"gray\" mb=\"5\">\n To continue, we need to confirm your identity. We'll send a temporary\n verification code to{\" \"}\n <Text weight=\"bold\" highContrast>\n {me?.email}\n </Text>\n .\n </Description>\n\n {sendVerification.error && (\n <Callout.Root color=\"red\" mt=\"-2\" mb=\"0\">\n <Callout.Text>\n {getMutationErrorMessage(sendVerification.error)}\n </Callout.Text>\n </Callout.Root>\n )}\n\n <Flex justify=\"end\" align=\"center\" gap=\"3\" mt=\"5\">\n <Close>\n <SecondaryButton type=\"button\" disabled={sendVerification.isPending}>\n Cancel\n </SecondaryButton>\n </Close>\n <PrimaryButton type=\"submit\" loading={sendVerification.isPending}>\n Send verification code\n </PrimaryButton>\n </Flex>\n </form>\n );\n}\n\ninterface VerificationIdentityFormProps {\n onSuccess?: () => unknown | Promise<unknown>;\n authenticationChallengeId: string;\n type: \"dialog\" | \"alert\";\n}\n\nfunction VerificationIdentityForm({\n onSuccess,\n authenticationChallengeId,\n type,\n}: VerificationIdentityFormProps) {\n const { data: me } = useMe();\n const { setElevatedAccess } = useElevatedAccessToken();\n const verifyIdentity = useVerify();\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const Title = type === \"dialog\" ? Dialog.Title : AlertDialog.Title;\n const Description =\n type === \"dialog\" ? Dialog.Description : AlertDialog.Description;\n const Close = type === \"dialog\" ? Dialog.Close : AlertDialog.Cancel;\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n const formData = new FormData(event.currentTarget);\n const code = formData.get(\"otp-code\")?.toString() ?? \"\";\n\n setIsSubmitting(true);\n\n try {\n // Mutate async so we can wait for the onSuccess callback as well\n const newAuthState = await verifyIdentity.mutateAsync({\n data: {\n code,\n authenticationChallengeId,\n },\n });\n\n const in10Seconds = new Date(Date.now() + 5 * 1000);\n\n setElevatedAccess({\n token: newAuthState.elevatedAccessToken,\n // expiresAt: newAuthState.expiresAt,\n expiresAt: in10Seconds.toISOString(),\n });\n\n if (onSuccess) {\n await new Promise((resolve) => setTimeout(resolve, 200));\n await onSuccess();\n }\n } catch (error) {\n console.error(error);\n }\n\n setIsSubmitting(false);\n };\n\n return (\n <Form.Root onSubmit={handleSubmit}>\n <Title>Verify your identity</Title>\n\n <Description color=\"gray\">\n A verification code was sent to{\" \"}\n <Text weight=\"bold\" highContrast>\n {me?.email}\n </Text>\n . Please enter it below.\n </Description>\n\n <Flex direction=\"column\" gap=\"2\" mt=\"5\" mx=\"auto\" width=\"fit-content\">\n <Otp.Root\n autoSubmit\n gap=\"2\"\n justify=\"center\"\n columns=\"repeat(6, 48px)\"\n width=\"fit-content\"\n rows=\"48px\"\n name=\"otp-code\"\n readOnly={isSubmitting}\n >\n <Otp.Input required autoFocus autoComplete=\"off\" />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n </Otp.Root>\n\n {verifyIdentity.error && (\n <Text color=\"red\" size=\"2\" as=\"p\">\n {getMutationErrorMessage(verifyIdentity.error)}\n </Text>\n )}\n </Flex>\n\n <Flex justify=\"end\" align=\"center\" gap=\"3\" mt=\"5\">\n <Close>\n <SecondaryButton type=\"button\">Cancel</SecondaryButton>\n </Close>\n\n <PrimaryButton type=\"submit\" loading={isSubmitting}>\n Confirm\n </PrimaryButton>\n </Flex>\n </Form.Root>\n );\n}\n\nfunction getMutationErrorMessage(error: unknown) {\n let message = typeof error === \"string\" ? error : \"\";\n\n if (error instanceof Error) {\n message = error.message;\n } else if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n message = error.message;\n }\n\n if (!message || message === \"Bad Request\") {\n message = \"Invalid code, please try again.\";\n }\n\n return message;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/elevated-access.tsx"],"sourcesContent":["import * as Form from \"@radix-ui/react-form\";\nimport { AlertDialog, Callout, Dialog, Flex, Text } from \"@radix-ui/themes\";\nimport { useMe, useSendVerification, useVerify } from \"../api/endpoint.js\";\nimport { useElevatedAccessToken } from \"../api/api-provider.js\";\nimport { PropsWithChildren, useEffect, useRef, useState } from \"react\";\nimport { PrimaryButton, SecondaryButton } from \"./elements.js\";\nimport * as Otp from \"./otp-input.js\";\n\ninterface ElevatedAccessProps extends PropsWithChildren {\n onVerified?: () => Promise<unknown>;\n type?: \"dialog\" | \"alert\";\n}\n\nexport function ElevatedAccess({\n type = \"dialog\",\n children,\n onVerified,\n}: ElevatedAccessProps) {\n const { elevatedAccess } = useElevatedAccessToken();\n const [authenticationChallengeId, setAuthenticationChallengeId] =\n useState<string>();\n\n const prevAccessToken = useRef(elevatedAccess);\n\n useEffect(() => {\n prevAccessToken.current = elevatedAccess;\n }, [elevatedAccess]);\n\n if (elevatedAccess) {\n return <>{children}</>;\n }\n\n if (!authenticationChallengeId) {\n // FIXME: This should be refactored\n // eslint-disable-next-line react-hooks/refs\n const hasTokenExpired = !!prevAccessToken.current;\n\n return (\n <SendVerificationEmailForm\n type={type}\n hasTokenExpired={hasTokenExpired}\n onSuccess={(challengeId) => {\n setAuthenticationChallengeId(challengeId);\n }}\n />\n );\n }\n\n if (authenticationChallengeId) {\n return (\n <VerificationIdentityForm\n type={type}\n authenticationChallengeId={authenticationChallengeId}\n onSuccess={() => {\n // Reset the challenge id\n setAuthenticationChallengeId(undefined);\n\n return onVerified?.();\n }}\n />\n );\n }\n\n return null;\n}\n\ninterface SendVerificationEmailFormProps {\n onSuccess: (challengeId: string) => unknown | Promise<unknown>;\n type: \"dialog\" | \"alert\";\n hasTokenExpired: boolean;\n}\n\nfunction SendVerificationEmailForm({\n onSuccess,\n type,\n hasTokenExpired,\n}: SendVerificationEmailFormProps) {\n const { data: me } = useMe();\n const sendVerification = useSendVerification({\n mutation: { onSuccess: (data) => onSuccess(data.authenticationChallenge) },\n });\n\n const Title = type === \"dialog\" ? Dialog.Title : AlertDialog.Title;\n const Description =\n type === \"dialog\" ? Dialog.Description : AlertDialog.Description;\n const Close = type === \"dialog\" ? Dialog.Close : AlertDialog.Cancel;\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n sendVerification.mutate();\n };\n\n return (\n <form onSubmit={handleSubmit}>\n <Title>\n {hasTokenExpired\n ? \"Your verification token has expired\"\n : \"Verify your identity\"}\n </Title>\n\n <Description color=\"gray\" mb=\"5\">\n To continue, we need to confirm your identity. We'll send a temporary\n verification code to{\" \"}\n <Text weight=\"bold\" highContrast>\n {me?.email}\n </Text>\n .\n </Description>\n\n {sendVerification.error && (\n <Callout.Root color=\"red\" mt=\"-2\" mb=\"0\">\n <Callout.Text>\n {getMutationErrorMessage(sendVerification.error)}\n </Callout.Text>\n </Callout.Root>\n )}\n\n <Flex justify=\"end\" align=\"center\" gap=\"3\" mt=\"5\">\n <Close>\n <SecondaryButton type=\"button\" disabled={sendVerification.isPending}>\n Cancel\n </SecondaryButton>\n </Close>\n <PrimaryButton type=\"submit\" loading={sendVerification.isPending}>\n Send verification code\n </PrimaryButton>\n </Flex>\n </form>\n );\n}\n\ninterface VerificationIdentityFormProps {\n onSuccess?: () => unknown | Promise<unknown>;\n authenticationChallengeId: string;\n type: \"dialog\" | \"alert\";\n}\n\nfunction VerificationIdentityForm({\n onSuccess,\n authenticationChallengeId,\n type,\n}: VerificationIdentityFormProps) {\n const { data: me } = useMe();\n const { setElevatedAccess } = useElevatedAccessToken();\n const verifyIdentity = useVerify();\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const Title = type === \"dialog\" ? Dialog.Title : AlertDialog.Title;\n const Description =\n type === \"dialog\" ? Dialog.Description : AlertDialog.Description;\n const Close = type === \"dialog\" ? Dialog.Close : AlertDialog.Cancel;\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n const formData = new FormData(event.currentTarget);\n const code = formData.get(\"otp-code\")?.toString() ?? \"\";\n\n setIsSubmitting(true);\n\n try {\n // Mutate async so we can wait for the onSuccess callback as well\n const newAuthState = await verifyIdentity.mutateAsync({\n data: {\n code,\n authenticationChallengeId,\n },\n });\n\n const in10Seconds = new Date(Date.now() + 5 * 1000);\n\n setElevatedAccess({\n token: newAuthState.elevatedAccessToken,\n // expiresAt: newAuthState.expiresAt,\n expiresAt: in10Seconds.toISOString(),\n });\n\n if (onSuccess) {\n await new Promise((resolve) => setTimeout(resolve, 200));\n await onSuccess();\n }\n } catch (error) {\n console.error(error);\n }\n\n setIsSubmitting(false);\n };\n\n return (\n <Form.Root onSubmit={handleSubmit}>\n <Title>Verify your identity</Title>\n\n <Description color=\"gray\">\n A verification code was sent to{\" \"}\n <Text weight=\"bold\" highContrast>\n {me?.email}\n </Text>\n . Please enter it below.\n </Description>\n\n <Flex direction=\"column\" gap=\"2\" mt=\"5\" mx=\"auto\" width=\"fit-content\">\n <Otp.Root\n autoSubmit\n gap=\"2\"\n justify=\"center\"\n columns=\"repeat(6, 48px)\"\n width=\"fit-content\"\n rows=\"48px\"\n name=\"otp-code\"\n readOnly={isSubmitting}\n >\n <Otp.Input required autoFocus autoComplete=\"off\" />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n </Otp.Root>\n\n {verifyIdentity.error && (\n <Text color=\"red\" size=\"2\" as=\"p\">\n {getMutationErrorMessage(verifyIdentity.error)}\n </Text>\n )}\n </Flex>\n\n <Flex justify=\"end\" align=\"center\" gap=\"3\" mt=\"5\">\n <Close>\n <SecondaryButton type=\"button\">Cancel</SecondaryButton>\n </Close>\n\n <PrimaryButton type=\"submit\" loading={isSubmitting}>\n Confirm\n </PrimaryButton>\n </Flex>\n </Form.Root>\n );\n}\n\nfunction getMutationErrorMessage(error: unknown) {\n let message = typeof error === \"string\" ? error : \"\";\n\n if (error instanceof Error) {\n message = error.message;\n } else if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n message = error.message;\n }\n\n if (!message || message === \"Bad Request\") {\n message = \"Invalid code, please try again.\";\n }\n\n return message;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { WidgetRootDomProps } from './utils.js';
|
|
3
|
+
import '../api/endpoint.js';
|
|
4
|
+
import '@tanstack/react-query';
|
|
5
|
+
import '../api/widgets-api-client.js';
|
|
2
6
|
|
|
3
|
-
interface EmptyStateProps {
|
|
7
|
+
interface EmptyStateProps extends WidgetRootDomProps {
|
|
4
8
|
heading: string;
|
|
5
9
|
message: string;
|
|
6
10
|
action?: React.ReactNode;
|
|
7
11
|
}
|
|
8
|
-
declare function EmptyState({ heading, message, action }: EmptyStateProps): react_jsx_runtime.JSX.Element;
|
|
12
|
+
declare function EmptyState({ heading, message, action, ...domProps }: EmptyStateProps): react_jsx_runtime.JSX.Element;
|
|
9
13
|
|
|
10
14
|
export { EmptyState };
|
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Flex, Heading, Text } from "@radix-ui/themes";
|
|
3
|
-
function EmptyState({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
function EmptyState({
|
|
4
|
+
heading,
|
|
5
|
+
message,
|
|
6
|
+
action,
|
|
7
|
+
...domProps
|
|
8
|
+
}) {
|
|
9
|
+
return /* @__PURE__ */ jsxs(
|
|
10
|
+
Flex,
|
|
11
|
+
{
|
|
12
|
+
p: "6",
|
|
13
|
+
gap: "4",
|
|
14
|
+
justify: "center",
|
|
15
|
+
align: "center",
|
|
16
|
+
direction: "column",
|
|
17
|
+
...domProps,
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "1", maxWidth: "420px", children: [
|
|
20
|
+
/* @__PURE__ */ jsx(Heading, { size: "5", align: "center", mb: "1", wrap: "balance", as: "h3", children: heading }),
|
|
21
|
+
/* @__PURE__ */ jsx(Text, { as: "p", align: "center", wrap: "balance", color: "gray", children: message })
|
|
22
|
+
] }),
|
|
23
|
+
action
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
);
|
|
11
27
|
}
|
|
12
28
|
export {
|
|
13
29
|
EmptyState
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/empty-state.tsx"],"sourcesContent":["import { Flex, Heading, Text } from \"@radix-ui/themes\";\n\ninterface EmptyStateProps {\n heading: string;\n message: string;\n action?: React.ReactNode;\n}\n\nexport function EmptyState({
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/empty-state.tsx"],"sourcesContent":["import { Flex, Heading, Text } from \"@radix-ui/themes\";\nimport { WidgetRootDomProps } from \"./utils.js\";\n\ninterface EmptyStateProps extends WidgetRootDomProps {\n heading: string;\n message: string;\n action?: React.ReactNode;\n}\n\nexport function EmptyState({\n heading,\n message,\n action,\n ...domProps\n}: EmptyStateProps) {\n return (\n <Flex\n p=\"6\"\n gap=\"4\"\n justify=\"center\"\n align=\"center\"\n direction=\"column\"\n {...domProps}\n >\n <Flex direction=\"column\" gap=\"1\" maxWidth=\"420px\">\n <Heading size=\"5\" align=\"center\" mb=\"1\" wrap=\"balance\" as=\"h3\">\n {heading}\n </Heading>\n\n <Text as=\"p\" align=\"center\" wrap=\"balance\" color=\"gray\">\n {message}\n </Text>\n </Flex>\n\n {action}\n </Flex>\n );\n}\n"],"mappings":"AAwBM,SACE,KADF;AAxBN,SAAS,MAAM,SAAS,YAAY;AAS7B,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,KAAI;AAAA,MACJ,SAAQ;AAAA,MACR,OAAM;AAAA,MACN,WAAU;AAAA,MACT,GAAG;AAAA,MAEJ;AAAA,6BAAC,QAAK,WAAU,UAAS,KAAI,KAAI,UAAS,SACxC;AAAA,8BAAC,WAAQ,MAAK,KAAI,OAAM,UAAS,IAAG,KAAI,MAAK,WAAU,IAAG,MACvD,mBACH;AAAA,UAEA,oBAAC,QAAK,IAAG,KAAI,OAAM,UAAS,MAAK,WAAU,OAAM,QAC9C,mBACH;AAAA,WACF;AAAA,QAEC;AAAA;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Flex } from '@radix-ui/themes';
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
type GenericErrorProps = React.ComponentProps<typeof Flex> & {
|
|
4
6
|
error: unknown;
|
|
5
|
-
}
|
|
7
|
+
};
|
|
8
|
+
declare function GenericError({ error, ...domProps }: GenericErrorProps): react_jsx_runtime.JSX.Element;
|
|
6
9
|
declare function getErrorMessage(error: unknown): {
|
|
7
10
|
heading: string;
|
|
8
11
|
message: string;
|
|
@@ -7,34 +7,43 @@ import {
|
|
|
7
7
|
NoAuthTokenError
|
|
8
8
|
} from "./errors.js";
|
|
9
9
|
import { Cross2Icon } from "@radix-ui/react-icons";
|
|
10
|
-
function GenericError({ error }) {
|
|
10
|
+
function GenericError({ error, ...domProps }) {
|
|
11
11
|
React.useEffect(() => {
|
|
12
12
|
console.error(error);
|
|
13
13
|
}, [error]);
|
|
14
|
-
const render = (heading2, message2) => /* @__PURE__ */ jsxs(Flex, { p: "6", justify: "center", align: "center", direction: "column", children: [
|
|
15
|
-
/* @__PURE__ */ jsx(
|
|
16
|
-
Flex,
|
|
17
|
-
{
|
|
18
|
-
align: "center",
|
|
19
|
-
justify: "center",
|
|
20
|
-
width: "32px",
|
|
21
|
-
height: "32px",
|
|
22
|
-
mb: "2",
|
|
23
|
-
style: {
|
|
24
|
-
borderRadius: "9999px",
|
|
25
|
-
backgroundColor: "var(--red-a4)",
|
|
26
|
-
color: "var(--red-a11)"
|
|
27
|
-
},
|
|
28
|
-
children: /* @__PURE__ */ jsx(Cross2Icon, { width: "24px", height: "24px" })
|
|
29
|
-
}
|
|
30
|
-
),
|
|
31
|
-
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "1", maxWidth: "420px", children: [
|
|
32
|
-
/* @__PURE__ */ jsx(Heading, { size: "5", align: "center", mb: "1", wrap: "balance", as: "h3", children: heading2 }),
|
|
33
|
-
/* @__PURE__ */ jsx(Text, { as: "p", align: "center", wrap: "balance", color: "gray", children: message2 })
|
|
34
|
-
] })
|
|
35
|
-
] });
|
|
36
14
|
const { heading, message } = getErrorMessage(error);
|
|
37
|
-
return
|
|
15
|
+
return /* @__PURE__ */ jsxs(
|
|
16
|
+
Flex,
|
|
17
|
+
{
|
|
18
|
+
p: "6",
|
|
19
|
+
justify: "center",
|
|
20
|
+
align: "center",
|
|
21
|
+
direction: "column",
|
|
22
|
+
...domProps,
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ jsx(
|
|
25
|
+
Flex,
|
|
26
|
+
{
|
|
27
|
+
align: "center",
|
|
28
|
+
justify: "center",
|
|
29
|
+
width: "32px",
|
|
30
|
+
height: "32px",
|
|
31
|
+
mb: "2",
|
|
32
|
+
style: {
|
|
33
|
+
borderRadius: "9999px",
|
|
34
|
+
backgroundColor: "var(--red-a4)",
|
|
35
|
+
color: "var(--red-a11)"
|
|
36
|
+
},
|
|
37
|
+
children: /* @__PURE__ */ jsx(Cross2Icon, { width: "24px", height: "24px" })
|
|
38
|
+
}
|
|
39
|
+
),
|
|
40
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "1", maxWidth: "420px", children: [
|
|
41
|
+
/* @__PURE__ */ jsx(Heading, { size: "5", align: "center", mb: "1", wrap: "balance", as: "h3", children: heading }),
|
|
42
|
+
/* @__PURE__ */ jsx(Text, { as: "p", align: "center", wrap: "balance", color: "gray", children: message })
|
|
43
|
+
] })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
38
47
|
}
|
|
39
48
|
function getErrorMessage(error) {
|
|
40
49
|
if (error instanceof FetchError) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/generic-error.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Flex, Heading, Text } from \"@radix-ui/themes\";\nimport {\n FetchError,\n IncorrectPermissionsError,\n NoAuthTokenError,\n} from \"./errors.js\";\nimport { Cross2Icon } from \"@radix-ui/react-icons\";\n\nexport function GenericError({ error }:
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/generic-error.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Flex, Heading, Text } from \"@radix-ui/themes\";\nimport {\n FetchError,\n IncorrectPermissionsError,\n NoAuthTokenError,\n} from \"./errors.js\";\nimport { Cross2Icon } from \"@radix-ui/react-icons\";\n\ntype GenericErrorProps = React.ComponentProps<typeof Flex> & {\n error: unknown;\n};\n\nexport function GenericError({ error, ...domProps }: GenericErrorProps) {\n React.useEffect(() => {\n console.error(error);\n }, [error]);\n\n const { heading, message } = getErrorMessage(error);\n return (\n <Flex\n p=\"6\"\n justify=\"center\"\n align=\"center\"\n direction=\"column\"\n {...domProps}\n >\n <Flex\n align=\"center\"\n justify=\"center\"\n width=\"32px\"\n height=\"32px\"\n mb=\"2\"\n style={{\n borderRadius: \"9999px\",\n backgroundColor: \"var(--red-a4)\",\n color: \"var(--red-a11)\",\n }}\n >\n <Cross2Icon width=\"24px\" height=\"24px\" />\n </Flex>\n\n <Flex direction=\"column\" gap=\"1\" maxWidth=\"420px\">\n <Heading size=\"5\" align=\"center\" mb=\"1\" wrap=\"balance\" as=\"h3\">\n {heading}\n </Heading>\n <Text as=\"p\" align=\"center\" wrap=\"balance\" color=\"gray\">\n {message}\n </Text>\n </Flex>\n </Flex>\n );\n}\n\nexport function getErrorMessage(error: unknown) {\n if (error instanceof FetchError) {\n return {\n heading: \"Error fetching data\",\n message:\n \"An error occurred. You may need to configure CORS in the WorkOS Dashboard.\",\n };\n }\n\n if (error instanceof NoAuthTokenError) {\n return {\n heading: \"Authorization error\",\n message:\n \"You likely forgot to provide an authorization token to the widget.\",\n };\n }\n\n if (error instanceof IncorrectPermissionsError) {\n return {\n heading: \"Incorrect permissions\",\n message: \"Check that the correct permissions have been assigned.\",\n };\n }\n\n return {\n heading: \"Error fetching data\",\n message:\n \"An unexpected error occurred. Check your network connection or try refreshing the page.\",\n };\n}\n"],"mappings":"AAuCQ,cAGF,YAHE;AAvCR,YAAY,WAAW;AACvB,SAAS,MAAM,SAAS,YAAY;AACpC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAMpB,SAAS,aAAa,EAAE,OAAO,GAAG,SAAS,GAAsB;AACtE,QAAM,UAAU,MAAM;AACpB,YAAQ,MAAM,KAAK;AAAA,EACrB,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,EAAE,SAAS,QAAQ,IAAI,gBAAgB,KAAK;AAClD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,SAAQ;AAAA,MACR,OAAM;AAAA,MACN,WAAU;AAAA,MACT,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,OAAM;AAAA,YACN,QAAO;AAAA,YACP,IAAG;AAAA,YACH,OAAO;AAAA,cACL,cAAc;AAAA,cACd,iBAAiB;AAAA,cACjB,OAAO;AAAA,YACT;AAAA,YAEA,8BAAC,cAAW,OAAM,QAAO,QAAO,QAAO;AAAA;AAAA,QACzC;AAAA,QAEA,qBAAC,QAAK,WAAU,UAAS,KAAI,KAAI,UAAS,SACxC;AAAA,8BAAC,WAAQ,MAAK,KAAI,OAAM,UAAS,IAAG,KAAI,MAAK,WAAU,IAAG,MACvD,mBACH;AAAA,UACA,oBAAC,QAAK,IAAG,KAAI,OAAM,UAAS,MAAK,WAAU,OAAM,QAC9C,mBACH;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,gBAAgB,OAAgB;AAC9C,MAAI,iBAAiB,YAAY;AAC/B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SACE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,iBAAiB,kBAAkB;AACrC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SACE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,iBAAiB,2BAA2B;AAC9C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SACE;AAAA,EACJ;AACF;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
declare const IDENTITY_PROVIDER_DICT: Map<"asana" | "box" | "dropbox" | "github" | "gitlab" | "google" | "google-calendar" | "google-drive" | "hubspot" | "intercom" | "linear" | "microsoft" | "notion" | "salesforce" | "slack" | "stripe" | "zendesk" | "azure" | "access-people-hr" | "adp" | "apple" | "auth0" | "aws" | "bamboohr" | "bamboo-hr" | "bitbucket" | "breathe-hr" | "bubble" | "cas" | "cezanne-hr" | "classlink" | "clerk" | "cloudflare" | "cyberark" | "datadog" | "duo" | "firebase" | "fourth" | "generic-saml" | "generic-oidc" | "godaddy" | "google-analytics" | "google-mail" | "google-cloud" | "hibob" | "intuit" | "jumpcloud" | "keycloak" | "lastpass" | "linkedin" | "login-gov" | "miniorange" | "net-iq" | "next-auth" | "okta" | "onelogin" | "oracle" | "personio" | "ping-identity" | "react-native-expo" | "rippling" | "segment" | "shibboleth" | "simple-saml-php" | "splunk" | "supabase" | "vercel" | "vmware" | "workday" | "workos" | "xero" | "test-idp" | "discord", "GoDaddy" | "Access People HR" | "ADP" | "Apple" | "Asana" | "Auth0" | "Azure" | "AWS" | "BambooHR" | "Bitbucket" | "Box" | "BreatheHR" | "Bubble" | "CAS" | "Cezanne HR" | "Classlink" | "Clerk" | "Cloudflare" | "CyberArk" | "Datadog" | "Dropbox" | "Duo" | "Firebase" | "Fourth" | "Generic SAML" | "Generic OIDC" | "GitHub" | "GitLab" | "Google" | "Google Analytics" | "Google Calendar" | "Google Drive" | "Google Mail" | "Google Cloud" | "Hibob" | "Hubspot" | "Intercom" | "Intuit" | "JumpCloud" | "Keycloak" | "LastPass" | "Linear" | "LinkedIn" | "Login.gov" | "Microsoft" | "Miniorange" | "NetIQ" | "NextAuth" | "Notion" | "Okta" | "OneLogin" | "Oracle" | "Personio" | "Ping Identity" | "React Native Expo" | "Rippling" | "Salesforce" | "Segment" | "Shibboleth" | "Simple SAML PHP" | "Slack" | "Splunk" | "Stripe" | "Supabase" | "Vercel" | "VMware" | "Workday" | "WorkOS" | "Xero" | "Zendesk" | "Test IDP" | "Discord">;
|
|
1
|
+
declare const IDENTITY_PROVIDER_DICT: Map<"asana" | "box" | "dropbox" | "github" | "gitlab" | "google" | "google-calendar" | "google-drive" | "hubspot" | "intercom" | "linear" | "microsoft" | "notion" | "salesforce" | "slack" | "stripe" | "zendesk" | "azure" | "access-people-hr" | "adp" | "apple" | "auth0" | "aws" | "bamboohr" | "bamboo-hr" | "bitbucket" | "breathe-hr" | "bubble" | "cas" | "cezanne-hr" | "classlink" | "clerk" | "cloudflare" | "cyberark" | "datadog" | "duo" | "firebase" | "fourth" | "generic-saml" | "generic-oidc" | "godaddy" | "google-analytics" | "google-mail" | "google-cloud" | "hibob" | "intuit" | "jumpcloud" | "keycloak" | "lastpass" | "linkedin" | "login-gov" | "miniorange" | "net-iq" | "next-auth" | "okta" | "onelogin" | "oracle" | "personio" | "ping-identity" | "react-native-expo" | "rippling" | "segment" | "shibboleth" | "simple-saml-php" | "splunk" | "supabase" | "vercel" | "vmware" | "workday" | "workos" | "xero" | "test-idp" | "discord" | "clever", "GoDaddy" | "Access People HR" | "ADP" | "Apple" | "Asana" | "Auth0" | "Azure" | "AWS" | "BambooHR" | "Bitbucket" | "Box" | "BreatheHR" | "Bubble" | "CAS" | "Cezanne HR" | "Classlink" | "Clerk" | "Cloudflare" | "CyberArk" | "Datadog" | "Dropbox" | "Duo" | "Firebase" | "Fourth" | "Generic SAML" | "Generic OIDC" | "GitHub" | "GitLab" | "Google" | "Google Analytics" | "Google Calendar" | "Google Drive" | "Google Mail" | "Google Cloud" | "Hibob" | "Hubspot" | "Intercom" | "Intuit" | "JumpCloud" | "Keycloak" | "LastPass" | "Linear" | "LinkedIn" | "Login.gov" | "Microsoft" | "Miniorange" | "NetIQ" | "NextAuth" | "Notion" | "Okta" | "OneLogin" | "Oracle" | "Personio" | "Ping Identity" | "React Native Expo" | "Rippling" | "Salesforce" | "Segment" | "Shibboleth" | "Simple SAML PHP" | "Slack" | "Splunk" | "Stripe" | "Supabase" | "Vercel" | "VMware" | "Workday" | "WorkOS" | "Xero" | "Zendesk" | "Test IDP" | "Discord" | "Clever">;
|
|
2
2
|
type MapKey<T extends Map<unknown, unknown>> = T extends Map<infer K, unknown> ? K : never;
|
|
3
3
|
type IdentityProvider = MapKey<typeof IDENTITY_PROVIDER_DICT>;
|
|
4
|
-
declare function getIdentityProviderName(provider: IdentityProvider): "GoDaddy" | "Access People HR" | "ADP" | "Apple" | "Asana" | "Auth0" | "Azure" | "AWS" | "BambooHR" | "Bitbucket" | "Box" | "BreatheHR" | "Bubble" | "CAS" | "Cezanne HR" | "Classlink" | "Clerk" | "Cloudflare" | "CyberArk" | "Datadog" | "Dropbox" | "Duo" | "Firebase" | "Fourth" | "Generic SAML" | "Generic OIDC" | "GitHub" | "GitLab" | "Google" | "Google Analytics" | "Google Calendar" | "Google Drive" | "Google Mail" | "Google Cloud" | "Hibob" | "Hubspot" | "Intercom" | "Intuit" | "JumpCloud" | "Keycloak" | "LastPass" | "Linear" | "LinkedIn" | "Login.gov" | "Microsoft" | "Miniorange" | "NetIQ" | "NextAuth" | "Notion" | "Okta" | "OneLogin" | "Oracle" | "Personio" | "Ping Identity" | "React Native Expo" | "Rippling" | "Salesforce" | "Segment" | "Shibboleth" | "Simple SAML PHP" | "Slack" | "Splunk" | "Stripe" | "Supabase" | "Vercel" | "VMware" | "Workday" | "WorkOS" | "Xero" | "Zendesk" | "Test IDP" | "Discord" | undefined;
|
|
4
|
+
declare function getIdentityProviderName(provider: IdentityProvider): "GoDaddy" | "Access People HR" | "ADP" | "Apple" | "Asana" | "Auth0" | "Azure" | "AWS" | "BambooHR" | "Bitbucket" | "Box" | "BreatheHR" | "Bubble" | "CAS" | "Cezanne HR" | "Classlink" | "Clerk" | "Cloudflare" | "CyberArk" | "Datadog" | "Dropbox" | "Duo" | "Firebase" | "Fourth" | "Generic SAML" | "Generic OIDC" | "GitHub" | "GitLab" | "Google" | "Google Analytics" | "Google Calendar" | "Google Drive" | "Google Mail" | "Google Cloud" | "Hibob" | "Hubspot" | "Intercom" | "Intuit" | "JumpCloud" | "Keycloak" | "LastPass" | "Linear" | "LinkedIn" | "Login.gov" | "Microsoft" | "Miniorange" | "NetIQ" | "NextAuth" | "Notion" | "Okta" | "OneLogin" | "Oracle" | "Personio" | "Ping Identity" | "React Native Expo" | "Rippling" | "Salesforce" | "Segment" | "Shibboleth" | "Simple SAML PHP" | "Slack" | "Splunk" | "Stripe" | "Supabase" | "Vercel" | "VMware" | "Workday" | "WorkOS" | "Xero" | "Zendesk" | "Test IDP" | "Discord" | "Clever" | undefined;
|
|
5
5
|
declare function isIdentityProvider(provider: unknown): boolean;
|
|
6
6
|
|
|
7
7
|
export { type IdentityProvider, getIdentityProviderName, isIdentityProvider };
|
|
@@ -71,7 +71,8 @@ const IDENTITY_PROVIDER_DICT = /* @__PURE__ */ new Map([
|
|
|
71
71
|
["xero", "Xero"],
|
|
72
72
|
["zendesk", "Zendesk"],
|
|
73
73
|
["test-idp", "Test IDP"],
|
|
74
|
-
["discord", "Discord"]
|
|
74
|
+
["discord", "Discord"],
|
|
75
|
+
["clever", "Clever"]
|
|
75
76
|
]);
|
|
76
77
|
function getIdentityProviderName(provider) {
|
|
77
78
|
return IDENTITY_PROVIDER_DICT.get(provider);
|