From a1c1c391bd4a2dab92d2c9694a8591a90d74fed4 Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Tue, 18 Feb 2025 19:40:59 -0300 Subject: [PATCH] Render `select-organization` route --- packages/clerk-js/src/core/clerk.ts | 19 +++++++++ .../clerk-js/src/core/resources/Session.ts | 4 ++ .../clerk-js/src/ui/common/sessionTasks.ts | 0 packages/clerk-js/src/ui/common/tasks.ts | 8 ++++ .../ui/components/PendingTask/PendingTask.tsx | 42 ++++++------------- .../PendingTask/__tests__/PendingTask.spec.ts | 1 + .../__tests__/usePendingTaskRoute.spec.ts | 1 + .../src/ui/components/PendingTask/index.ts | 1 - .../components/PendingTask/usePendingTask.tsx | 0 .../PendingTask/usePendingTaskRoute.tsx | 25 +++++++++++ .../src/ui/components/SignIn/SignIn.tsx | 5 ++- .../src/ui/components/SignUp/SignUp.tsx | 5 ++- .../clerk-js/src/utils/componentGuards.ts | 2 +- 13 files changed, 78 insertions(+), 35 deletions(-) create mode 100644 packages/clerk-js/src/ui/common/sessionTasks.ts create mode 100644 packages/clerk-js/src/ui/common/tasks.ts create mode 100644 packages/clerk-js/src/ui/components/PendingTask/__tests__/PendingTask.spec.ts create mode 100644 packages/clerk-js/src/ui/components/PendingTask/__tests__/usePendingTaskRoute.spec.ts delete mode 100644 packages/clerk-js/src/ui/components/PendingTask/index.ts create mode 100644 packages/clerk-js/src/ui/components/PendingTask/usePendingTask.tsx create mode 100644 packages/clerk-js/src/ui/components/PendingTask/usePendingTaskRoute.tsx diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 8c205ab9909..ee55c5dfe9c 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -66,6 +66,7 @@ import type { Web3Provider, } from '@clerk/types'; +import { sessionTaskRoutePaths } from '../ui/common/tasks'; import type { MountComponentRenderer } from '../ui/Components'; import { ALLOWED_PROTOCOLS, @@ -1064,6 +1065,24 @@ export class Clerk implements ClerkInterface { return this.#authService.decorateUrlWithDevBrowserToken(toURL).href; } + public buildTaskUrl(): string { + const [pendingTask] = this.session?.tasks ?? []; + + if (!pendingTask || !this.environment) { + return ''; + } + + const signInOrUpUrl = this.#options.signInUrl!; + + return buildURL( + { + base: signInOrUpUrl, + hashPath: sessionTaskRoutePaths[pendingTask.key], + }, + { stringify: true }, + ); + } + public buildSignInUrl(options?: SignInRedirectOptions): string { return this.#buildUrl( 'signInUrl', diff --git a/packages/clerk-js/src/core/resources/Session.ts b/packages/clerk-js/src/core/resources/Session.ts index d10845636f2..df13c683bbb 100644 --- a/packages/clerk-js/src/core/resources/Session.ts +++ b/packages/clerk-js/src/core/resources/Session.ts @@ -303,4 +303,8 @@ export class Session extends BaseResource implements SessionResource { return token.getRawString() || null; }); } + + get hasPendingTasks() { + return (this.tasks ?? []).length > 0; + } } diff --git a/packages/clerk-js/src/ui/common/sessionTasks.ts b/packages/clerk-js/src/ui/common/sessionTasks.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/clerk-js/src/ui/common/tasks.ts b/packages/clerk-js/src/ui/common/tasks.ts new file mode 100644 index 00000000000..0c775e20316 --- /dev/null +++ b/packages/clerk-js/src/ui/common/tasks.ts @@ -0,0 +1,8 @@ +import type { SessionTask } from '@clerk/types'; + +/** + * @internal + */ +export const sessionTaskRoutePaths: Record = { + org: 'select-organization', +}; diff --git a/packages/clerk-js/src/ui/components/PendingTask/PendingTask.tsx b/packages/clerk-js/src/ui/components/PendingTask/PendingTask.tsx index e8d2e537e91..7d6591c9d85 100644 --- a/packages/clerk-js/src/ui/components/PendingTask/PendingTask.tsx +++ b/packages/clerk-js/src/ui/components/PendingTask/PendingTask.tsx @@ -1,46 +1,30 @@ import { useSessionContext } from '@clerk/shared/react/index'; import type { SessionTask } from '@clerk/types'; import type { ComponentType } from 'react'; -import { withRedirectToAfterSignIn } from 'ui/common'; -import { Route } from '../../../ui/router'; +import { OrganizationListContext } from '../../../ui/contexts'; import { OrganizationList } from '../OrganizationList'; -const paths: Record = { - orgs: 'select-organization', -}; - const TaskRegistry: Record = { - orgs: OrganizationList, + org: () => ( + + + + ), }; -function usePendingTask() { +/** + * @internal + */ +export function PendingTask(): React.ReactNode { const session = useSessionContext(); - if (!session) { + if (!session?.hasPendingTasks) { return null; } const [pendingTask] = session.tasks ?? []; + const Task = TaskRegistry[pendingTask.key]; - return pendingTask; -} - -export function _PendingTask() { - const pendingTask = usePendingTask(); - - if (!pendingTask) { - return null; - } - - const Task = TaskRegistry['orgs']; - const path = paths[pendingTask.key]; - - return ( - - - - ); + return ; } - -export const PendingTask = withRedirectToAfterSignIn(_PendingTask); diff --git a/packages/clerk-js/src/ui/components/PendingTask/__tests__/PendingTask.spec.ts b/packages/clerk-js/src/ui/components/PendingTask/__tests__/PendingTask.spec.ts new file mode 100644 index 00000000000..65b3dba385b --- /dev/null +++ b/packages/clerk-js/src/ui/components/PendingTask/__tests__/PendingTask.spec.ts @@ -0,0 +1 @@ +// todo diff --git a/packages/clerk-js/src/ui/components/PendingTask/__tests__/usePendingTaskRoute.spec.ts b/packages/clerk-js/src/ui/components/PendingTask/__tests__/usePendingTaskRoute.spec.ts new file mode 100644 index 00000000000..65b3dba385b --- /dev/null +++ b/packages/clerk-js/src/ui/components/PendingTask/__tests__/usePendingTaskRoute.spec.ts @@ -0,0 +1 @@ +// todo diff --git a/packages/clerk-js/src/ui/components/PendingTask/index.ts b/packages/clerk-js/src/ui/components/PendingTask/index.ts deleted file mode 100644 index fd98317a8c6..00000000000 --- a/packages/clerk-js/src/ui/components/PendingTask/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './PendingTask'; diff --git a/packages/clerk-js/src/ui/components/PendingTask/usePendingTask.tsx b/packages/clerk-js/src/ui/components/PendingTask/usePendingTask.tsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/clerk-js/src/ui/components/PendingTask/usePendingTaskRoute.tsx b/packages/clerk-js/src/ui/components/PendingTask/usePendingTaskRoute.tsx new file mode 100644 index 00000000000..38dc42e40bb --- /dev/null +++ b/packages/clerk-js/src/ui/components/PendingTask/usePendingTaskRoute.tsx @@ -0,0 +1,25 @@ +import { useSessionContext } from '@clerk/shared/react/index'; +import type { Route } from '@clerk/shared/router'; +import type { ComponentProps } from 'react'; + +import { sessionTaskRoutePaths } from '../../../ui/common/tasks'; +import { PendingTask } from './PendingTask'; + +/** + * Maps a session task key to routing props and content + * @internal + */ +export function usePendingTaskRoute(): ComponentProps | null { + const session = useSessionContext(); + + if (!session?.hasPendingTasks) { + return null; + } + + const [pendingTask] = session.tasks ?? []; + + return { + children: , + path: sessionTaskRoutePaths[pendingTask.key], + }; +} diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx index c5ffbb7ebb5..4bfe1b23d28 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx @@ -14,7 +14,7 @@ import { } from '../../contexts'; import { Flow } from '../../customizables'; import { Route, Switch, VIRTUAL_ROUTER_BASE_PATH } from '../../router'; -import { PendingTask } from '../PendingTask'; +import { usePendingTaskRoute } from '../PendingTask/usePendingTaskRoute'; import { SignUpContinue } from '../SignUp/SignUpContinue'; import { SignUpSSOCallback } from '../SignUp/SignUpSSOCallback'; import { SignUpStart } from '../SignUp/SignUpStart'; @@ -39,10 +39,12 @@ function RedirectToSignIn() { function SignInRoutes(): JSX.Element { const signInContext = useSignInContext(); const signUpContext = useSignUpContext(); + const pendingTaskRoute = usePendingTaskRoute(); return ( + {pendingTaskRoute && } @@ -139,7 +141,6 @@ function SignInRoutes(): JSX.Element { - ); diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx index 88035c000e6..7dfac0f1110 100644 --- a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx +++ b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx @@ -6,7 +6,7 @@ import { SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowC import { SignUpContext, useSignUpContext, withCoreSessionSwitchGuard } from '../../contexts'; import { Flow } from '../../customizables'; import { Route, Switch, VIRTUAL_ROUTER_BASE_PATH } from '../../router'; -import { PendingTask } from '../PendingTask'; +import { usePendingTaskRoute } from '../PendingTask/usePendingTaskRoute'; import { SignUpContinue } from './SignUpContinue'; import { SignUpSSOCallback } from './SignUpSSOCallback'; import { SignUpStart } from './SignUpStart'; @@ -23,10 +23,12 @@ function RedirectToSignUp() { function SignUpRoutes(): JSX.Element { const signUpContext = useSignUpContext(); + const pendingTaskRoute = usePendingTaskRoute(); return ( + {pendingTaskRoute && } !!clerk.client.signUp.emailAddress} @@ -81,7 +83,6 @@ function SignUpRoutes(): JSX.Element { - ); diff --git a/packages/clerk-js/src/utils/componentGuards.ts b/packages/clerk-js/src/utils/componentGuards.ts index 273e7d446b3..83067ea53dd 100644 --- a/packages/clerk-js/src/utils/componentGuards.ts +++ b/packages/clerk-js/src/utils/componentGuards.ts @@ -7,7 +7,7 @@ export type ComponentGuard = ( ) => boolean; export const sessionExistsAndSingleSessionModeEnabled: ComponentGuard = (clerk, environment) => { - return !!(clerk.session?.status === 'active' && environment?.authConfig.singleSessionMode); + return !!(clerk.isSignedIn && !clerk.session?.hasPendingTasks && environment?.authConfig.singleSessionMode); }; export const noUserExists: ComponentGuard = clerk => {