Skip to content

Commit 39bbc51

Browse files
authored
chore(clerk-js,types): Hide personal workspace options when organization selection is enforced (#5391)
1 parent 13e3ddc commit 39bbc51

File tree

13 files changed

+73
-9
lines changed

13 files changed

+73
-9
lines changed

.changeset/fresh-plums-run.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@clerk/clerk-js': patch
3+
'@clerk/types': patch
4+
---
5+
6+
Hide personal workspace options when organization selection is enforced

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,12 @@ export class Clerk implements ClerkInterface {
829829
}),
830830
);
831831

832-
this.telemetry?.record(eventPrebuiltComponentMounted('OrganizationSwitcher', props));
832+
this.telemetry?.record(
833+
eventPrebuiltComponentMounted('OrganizationSwitcher', {
834+
...props,
835+
forceOrganizationSelection: this.environment?.organizationSettings.forceOrganizationSelection,
836+
}),
837+
);
833838
};
834839

835840
public unmountOrganizationSwitcher = (node: HTMLDivElement): void => {
@@ -863,7 +868,12 @@ export class Clerk implements ClerkInterface {
863868
}),
864869
);
865870

866-
this.telemetry?.record(eventPrebuiltComponentMounted('OrganizationList', props));
871+
this.telemetry?.record(
872+
eventPrebuiltComponentMounted('OrganizationList', {
873+
...props,
874+
forceOrganizationSelection: this.environment?.organizationSettings.forceOrganizationSelection,
875+
}),
876+
);
867877
};
868878

869879
public unmountOrganizationList = (node: HTMLDivElement): void => {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export class OrganizationSettings extends BaseResource implements OrganizationSe
2020
};
2121
enabled: boolean = false;
2222
maxAllowedMemberships: number = 1;
23+
forceOrganizationSelection!: boolean;
2324

2425
public constructor(data: OrganizationSettingsJSON | OrganizationSettingsJSONSnapshot | null = null) {
2526
super();
@@ -43,6 +44,10 @@ export class OrganizationSettings extends BaseResource implements OrganizationSe
4344

4445
this.enabled = this.withDefault(data.enabled, this.enabled);
4546
this.maxAllowedMemberships = this.withDefault(data.max_allowed_memberships, this.maxAllowedMemberships);
47+
this.forceOrganizationSelection = this.withDefault(
48+
data.force_organization_selection,
49+
this.forceOrganizationSelection,
50+
);
4651

4752
return this;
4853
}

packages/clerk-js/src/core/resources/__tests__/Environment.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ describe('Environment', () => {
237237
organization_settings: {
238238
enabled: false,
239239
max_allowed_memberships: 5,
240+
force_organization_selection: false,
240241
actions: { admin_delete: true },
241242
domains: { enabled: false, enrollment_modes: [], default_role: null },
242243
},

packages/clerk-js/src/core/resources/__tests__/__snapshots__/Environment.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ Environment {
581581
"enrollmentModes": [],
582582
},
583583
"enabled": false,
584+
"forceOrganizationSelection": false,
584585
"maxAllowedMemberships": 5,
585586
"pathRoot": "",
586587
},

packages/clerk-js/src/ui/components/OrganizationList/__tests__/OrganizationList.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,24 @@ describe('OrganizationList', () => {
185185
expect(queryByRole('button', { name: 'Join' })).not.toBeInTheDocument();
186186
});
187187
});
188+
189+
describe('with force organization selection setting on environment', () => {
190+
it('does not show the personal account', async () => {
191+
const { wrapper } = await createFixtures(f => {
192+
f.withOrganizations();
193+
f.withForceOrganizationSelection();
194+
f.withUser({
195+
email_addresses: ['test@clerk.com'],
196+
organization_memberships: [{ name: 'Org1', id: '1', role: 'admin' }],
197+
});
198+
});
199+
const { queryByText } = render(<OrganizationList />, { wrapper });
200+
201+
await waitFor(() => {
202+
expect(queryByText('Personal account')).not.toBeInTheDocument();
203+
});
204+
});
205+
});
188206
});
189207

190208
describe('CreateOrganization', () => {

packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ describe('OrganizationSwitcher', () => {
4545
expect(queryByText('Personal Workspace')).toBeNull();
4646
expect(getByText('No organization selected')).toBeInTheDocument();
4747
});
48+
49+
describe('with force organization selection setting on environment', () => {
50+
it('does not show the personal workspace', async () => {
51+
const { wrapper } = await createFixtures(f => {
52+
f.withOrganizations();
53+
f.withForceOrganizationSelection();
54+
f.withUser({ email_addresses: ['test@clerk.com'] });
55+
});
56+
const { queryByText, getByRole, userEvent } = render(<OrganizationSwitcher />, { wrapper });
57+
await userEvent.click(getByRole('button'));
58+
expect(queryByText('Personal Workspace')).toBeNull();
59+
});
60+
});
4861
});
4962

5063
describe('OrganizationSwitcherTrigger', () => {

packages/clerk-js/src/ui/components/SessionTask/SessionTask.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import { OrganizationList } from '../OrganizationList';
77

88
const ContentRegistry: Record<SessionTask['key'], React.ComponentType> = {
99
org: () => (
10-
// TODO - Hide personal workspace within organization list context based on environment
11-
<OrganizationListContext.Provider value={{ componentName: 'OrganizationList', hidePersonal: true }}>
10+
<OrganizationListContext.Provider
11+
value={{
12+
componentName: 'OrganizationList',
13+
skipInvitationScreen: true,
14+
}}
15+
>
1216
<OrganizationList />
1317
</OrganizationListContext.Provider>
1418
),

packages/clerk-js/src/ui/contexts/components/OrganizationList.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const OrganizationListContext = createContext<OrganizationListCtx | null>
1111
export const useOrganizationListContext = () => {
1212
const context = useContext(OrganizationListContext);
1313
const { navigate } = useRouter();
14-
const { displayConfig } = useEnvironment();
14+
const { displayConfig, organizationSettings } = useEnvironment();
1515

1616
if (!context || context.componentName !== 'OrganizationList') {
1717
throw new Error('Clerk: useOrganizationListContext called outside OrganizationList.');
@@ -80,7 +80,7 @@ export const useOrganizationListContext = () => {
8080
afterCreateOrganizationUrl,
8181
skipInvitationScreen: ctx.skipInvitationScreen || false,
8282
hideSlug: ctx.hideSlug || false,
83-
hidePersonal: ctx.hidePersonal || false,
83+
hidePersonal: organizationSettings.forceOrganizationSelection || ctx.hidePersonal || false,
8484
navigateAfterCreateOrganization,
8585
navigateAfterSelectOrganization,
8686
navigateAfterSelectPersonal,

packages/clerk-js/src/ui/contexts/components/OrganizationSwitcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const OrganizationSwitcherContext = createContext<OrganizationSwitcherCtx
1111
export const useOrganizationSwitcherContext = () => {
1212
const context = useContext(OrganizationSwitcherContext);
1313
const { navigate } = useRouter();
14-
const { displayConfig } = useEnvironment();
14+
const { displayConfig, organizationSettings } = useEnvironment();
1515

1616
if (!context || context.componentName !== 'OrganizationSwitcher') {
1717
throw new Error('Clerk: useOrganizationSwitcherContext called outside OrganizationSwitcher.');
@@ -96,7 +96,7 @@ export const useOrganizationSwitcherContext = () => {
9696

9797
return {
9898
...ctx,
99-
hidePersonal: ctx.hidePersonal || false,
99+
hidePersonal: organizationSettings.forceOrganizationSelection || ctx.hidePersonal || false,
100100
organizationProfileMode: organizationProfileMode || 'modal',
101101
createOrganizationMode: createOrganizationMode || 'modal',
102102
skipInvitationScreen: ctx.skipInvitationScreen || false,

0 commit comments

Comments
 (0)