Skip to content

Commit b99a632

Browse files
committed
Introduce mutation to enable organization settings
1 parent be32441 commit b99a632

File tree

9 files changed

+73
-9
lines changed

9 files changed

+73
-9
lines changed

packages/clerk-js/src/core/clerk.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ import type {
3636
AuthenticateWithMetamaskParams,
3737
AuthenticateWithOKXWalletParams,
3838
BillingNamespace,
39+
Clerk as ClerkInterface,
3940
ClerkAPIError,
4041
ClerkAuthenticateWithWeb3Params,
41-
Clerk as ClerkInterface,
4242
ClerkOptions,
4343
ClientJSONSnapshot,
4444
ClientResource,
@@ -746,7 +746,7 @@ export class Clerk implements ClerkInterface {
746746
.then(controls => controls.openModal('enableOrganizationsPrompt', props || {}));
747747
};
748748

749-
public __internal_closeEnableOrganizations = (): void => {
749+
public __internal_closeEnableOrganizationsPrompt = (): void => {
750750
this.assertComponentsReady(this.#componentControls);
751751
void this.#componentControls.ensureMounted().then(controls => controls.closeModal('enableOrganizationsPrompt'));
752752
};

packages/clerk-js/src/core/fapiClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export interface FapiClient {
6666
}
6767

6868
// List of paths that should not receive the session ID parameter in the URL
69-
const unauthorizedPathPrefixes = ['/client', '/waitlist'];
69+
const unauthorizedPathPrefixes = ['/client', '/waitlist', '/dev_tools'];
7070

7171
type FapiClientOptions = {
7272
frontendApi: string;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { ClerkResourceJSON, DevToolsResource, EnableEnvironmentSettingParams } from '@clerk/shared/types';
2+
3+
import { BaseResource } from './Base';
4+
5+
/**
6+
* @internal
7+
*/
8+
export class DevTools extends BaseResource implements DevToolsResource {
9+
pathRoot = '/dev_tools';
10+
11+
protected fromJSON(_data: ClerkResourceJSON | null): this {
12+
return this;
13+
}
14+
15+
async __internal_enableEnvironmentSetting(params: EnableEnvironmentSettingParams) {
16+
await this._basePatch({
17+
path: `${this.pathRoot}/enable_environment_setting`,
18+
body: params,
19+
});
20+
}
21+
}

packages/clerk-js/src/ui/components/devPrompts/EnableOrganizationsPrompt/index.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,40 @@
1+
import { useClerk } from '@clerk/shared/react';
12
import type { __internal_EnableOrganizationsPromptProps } from '@clerk/shared/types';
23
// eslint-disable-next-line no-restricted-imports
34
import { css } from '@emotion/react';
5+
import { useState } from 'react';
46

57
import { Modal } from '@/ui/elements/Modal';
68
import { InternalThemeProvider } from '@/ui/styledSystem';
79

10+
import { DevTools } from '../../../../core/resources/DevTools';
811
import { Flex } from '../../../customizables';
912
import { Portal } from '../../../elements/Portal';
1013
import { basePromptElementStyles, PromptContainer } from '../shared';
1114

1215
const EnableOrganizationsPromptInternal = (props: __internal_EnableOrganizationsPromptProps) => {
1316
const ctaText = 'componentName' in props ? `<${props.componentName} />` : props.utilityName;
17+
const clerk = useClerk();
18+
const [isLoading, setIsLoading] = useState(false);
19+
20+
const handleEnableOrganizations = () => {
21+
setIsLoading(true);
22+
23+
void new DevTools()
24+
.__internal_enableEnvironmentSetting({
25+
enable_organizations: true,
26+
})
27+
.then(() => {
28+
// Re-fetch environment to get updated settings
29+
// @ts-expect-error - __unstable__environment is not typed
30+
const environment = clerk?.__unstable__environment;
31+
environment.fetch?.();
32+
clerk?.__internal_closeEnableOrganizationsPrompt?.();
33+
})
34+
.finally(() => {
35+
setIsLoading(false);
36+
});
37+
};
1438

1539
return (
1640
<Portal>
@@ -152,7 +176,6 @@ const EnableOrganizationsPromptInternal = (props: __internal_EnableOrganizations
152176
`}
153177
/>
154178

155-
{/* TODO -> Introduce FAPI mutation to enable organizations */}
156179
<Flex
157180
direction='col'
158181
justify='center'
@@ -163,6 +186,8 @@ const EnableOrganizationsPromptInternal = (props: __internal_EnableOrganizations
163186
>
164187
<button
165188
type='button'
189+
onClick={handleEnableOrganizations}
190+
disabled={isLoading}
166191
css={css`
167192
${mainCTAStyles};
168193
min-width: 100%;
@@ -175,14 +200,19 @@ const EnableOrganizationsPromptInternal = (props: __internal_EnableOrganizations
175200
0px 1.5px 2px 0px rgba(0, 0, 0, 0.48),
176201
0px 0px 4px 0px rgba(243, 107, 22, 0) inset;
177202
178-
&:hover {
203+
&:hover:not(:disabled) {
179204
box-shadow:
180205
0px 0px 6px 0px rgba(255, 255, 255, 0.04) inset,
181206
0px 0px 0px 1px rgba(255, 255, 255, 0.04) inset,
182207
0px 1px 0px 0px rgba(255, 255, 255, 0.04) inset,
183208
0px 0px 0px 1px rgba(0, 0, 0, 0.1),
184209
0px 1.5px 2px 0px rgba(0, 0, 0, 0.48);
185210
}
211+
212+
&:disabled {
213+
opacity: 0.6;
214+
cursor: not-allowed;
215+
}
186216
`}
187217
>
188218
Enable Organizations

packages/react/src/isomorphicClerk.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,9 +872,9 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
872872
}
873873
};
874874

875-
__internal_closeEnableOrganizations = () => {
875+
__internal_closeEnableOrganizationsPrompt = () => {
876876
if (this.clerkjs && this.loaded) {
877-
this.clerkjs.__internal_closeEnableOrganizations();
877+
this.clerkjs.__internal_closeEnableOrganizationsPrompt();
878878
}
879879
};
880880

packages/shared/src/organization.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const withOrganizationSettingsEnabled =
3333
// @ts-expect-error - __unstable__environment is not typed
3434
const environment = clerk?.__unstable__environment;
3535

36-
if (!environment?.organizationSettings.enabled) {
36+
if (environment?.isDevelopment?.() && !environment?.organizationSettings.enabled) {
3737
clerk?.__internal_openEnableOrganizationsPrompt({
3838
utilityName,
3939
});

packages/shared/src/types/clerk.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ export interface Clerk {
325325
/**
326326
* Closes the Clerk Enable Organizations modal.
327327
*/
328-
__internal_closeEnableOrganizations: () => void;
328+
__internal_closeEnableOrganizationsPrompt: () => void;
329329

330330
/**
331331
* Opens the Google One Tap component.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { ClerkResource } from './resource';
2+
3+
export type EnableEnvironmentSettingParams = {
4+
enable_organizations: boolean;
5+
};
6+
7+
/**
8+
* @internal
9+
*/
10+
export interface DevToolsResource extends ClerkResource {
11+
__internal_enableEnvironmentSetting: (params: EnableEnvironmentSettingParams) => Promise<void>;
12+
}

packages/shared/src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type * from './commerceSettings';
1212
export type * from './customMenuItems';
1313
export type * from './customPages';
1414
export type * from './deletedObject';
15+
export type * from './devtools';
1516
export type * from './displayConfig';
1617
export type * from './elementIds';
1718
export type * from './emailAddress';

0 commit comments

Comments
 (0)