Skip to content

Commit

Permalink
fix(clerk-js): Require role to be selected before sending organizatio…
Browse files Browse the repository at this point in the history
…n invite (#2129) (#2135)
  • Loading branch information
panteliselef authored Nov 15, 2023
1 parent 60d08a0 commit 0a3b4d5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .changeset/khaki-spoons-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/clerk-js': patch
---

Require role to be selected before sending organization invite, affects `<OrganizationProfile/>` and <CreateOrganization/>`.
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,21 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
const { t, locale } = useLocalizations();
const [isValidUnsubmittedEmail, setIsValidUnsubmittedEmail] = useState(false);

if (!organization) {
return null;
}

const validateUnsubmittedEmail = (value: string) => setIsValidUnsubmittedEmail(isEmail(value));

const emailAddressField = useFormControl('emailAddress', '', {
type: 'text',
label: localizationKeys('formFieldLabel__emailAddresses'),
});

const roleField = useFormControl('role', '', {
label: localizationKeys('formFieldLabel__role'),
});

if (!organization) {
return null;
}

const {
props: {
/* eslint-disable @typescript-eslint/no-unused-vars */
Expand All @@ -58,7 +62,7 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
},
} = emailAddressField;

const canSubmit = !!emailAddressField.value.length || isValidUnsubmittedEmail;
const canSubmit = (!!emailAddressField.value.length || isValidUnsubmittedEmail) && !!roleField.value;

const onSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
Expand Down Expand Up @@ -122,7 +126,7 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
/>
</Flex>
</Form.ControlRow>
<AsyncRoleSelect />
<AsyncRoleSelect {...roleField} />
<FormButtonContainer>
<Form.SubmitButton
block={false}
Expand All @@ -139,24 +143,21 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
);
};

const AsyncRoleSelect = () => {
const AsyncRoleSelect = (field: ReturnType<typeof useFormControl<'role'>>) => {
const { options, isLoading } = useFetchRoles();
const roleField = useFormControl('role', '', {
label: localizationKeys('formFieldLabel__role'),
});

return (
<Form.ControlRow elementId={roleField.id}>
<Form.ControlRow elementId={field.id}>
<Flex
direction='col'
gap={2}
>
<Text localizationKey={roleField.label} />
<Text localizationKey={field.label} />
<RoleSelect
{...roleField.props}
{...field.props}
roles={options}
isDisabled={isLoading}
onChange={value => roleField.setValue(value)}
onChange={value => field.setValue(value)}
triggerSx={t => ({ width: t.sizes.$48, justifyContent: 'space-between', display: 'flex' })}
optionListSx={t => ({ minWidth: t.sizes.$48 })}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('InviteMembersPage', () => {
});

describe('Submitting', () => {
it('enables the Send button when one or more email has been entered', async () => {
it('keeps the Send button disabled until a role is selected and one or more email has been entered', async () => {
const { wrapper, fixtures } = await createFixtures(f => {
f.withOrganizations();
f.withUser({
Expand All @@ -34,10 +34,14 @@ describe('InviteMembersPage', () => {
});

fixtures.clerk.organization?.getRoles.mockRejectedValue(null);
const { getByRole, userEvent, getByTestId } = render(<InviteMembersPage />, { wrapper });
const { getByText, getByRole, userEvent, getByTestId } = render(<InviteMembersPage />, { wrapper });
expect(getByRole('button', { name: 'Send invitations' })).toBeDisabled();

await userEvent.type(getByTestId('tag-input'), '[email protected],');
expect(getByRole('button', { name: 'Send invitations' })).toBeDisabled();

await userEvent.click(getByRole('button', { name: /select an option/i }));
await userEvent.click(getByText(/^member$/i));
expect(getByRole('button', { name: 'Send invitations' })).not.toBeDisabled();
});

Expand Down Expand Up @@ -172,6 +176,9 @@ describe('InviteMembersPage', () => {
);
const { getByRole, userEvent, getByText, getByTestId } = render(<InviteMembersPage />, { wrapper });
await userEvent.type(getByTestId('tag-input'), '[email protected],');
await waitFor(() => expect(getByRole('button', { name: /select an option/i })).not.toBeDisabled());
await userEvent.click(getByRole('button', { name: /select an option/i }));
await userEvent.click(getByText(/^member$/i));
await userEvent.click(getByRole('button', { name: 'Send invitations' }));
await waitFor(() =>
expect(
Expand Down Expand Up @@ -206,8 +213,11 @@ describe('InviteMembersPage', () => {
status: 400,
}),
);
const { getByRole, userEvent, getByTestId } = render(<InviteMembersPage />, { wrapper });
const { getByRole, userEvent, getByTestId, getByText } = render(<InviteMembersPage />, { wrapper });
await userEvent.type(getByTestId('tag-input'), '[email protected]');
await waitFor(() => expect(getByRole('button', { name: /select an option/i })).not.toBeDisabled());
await userEvent.click(getByRole('button', { name: /select an option/i }));
await userEvent.click(getByText(/^member$/i));
await userEvent.click(getByRole('button', { name: 'Send invitations' }));

expect(getByTestId('tag-input')).not.toHaveValue();
Expand Down Expand Up @@ -236,8 +246,11 @@ describe('InviteMembersPage', () => {
status: 403,
}),
);
const { getByRole, userEvent, getByTestId } = render(<InviteMembersPage />, { wrapper });
const { getByRole, getByText, userEvent, getByTestId } = render(<InviteMembersPage />, { wrapper });
await userEvent.type(getByTestId('tag-input'), '[email protected]');
await waitFor(() => expect(getByRole('button', { name: /select an option/i })).not.toBeDisabled());
await userEvent.click(getByRole('button', { name: /select an option/i }));
await userEvent.click(getByText(/^member$/i));
await userEvent.click(getByRole('button', { name: 'Send invitations' }));

expect(getByTestId('tag-input')).not.toHaveValue();
Expand Down

0 comments on commit 0a3b4d5

Please sign in to comment.