fix(editor): Prevent multiple community registration request submission (#16621)

This commit is contained in:
Csaba Tuncsik
2025-06-24 14:06:21 +02:00
committed by GitHub
parent e63583987e
commit 79eef1e347
2 changed files with 49 additions and 4 deletions

View File

@@ -190,4 +190,35 @@ describe('CommunityPlusEnrollmentModal', () => {
await userEvent.click(skipButton);
expect(consoleErrorSpy).not.toHaveBeenCalled();
});
it('should prevent multiple submissions', async () => {
const closeCallbackSpy = vi.fn();
const usageStore = mockedStore(useUsageStore);
usageStore.registerCommunityEdition.mockImplementation(
async () =>
await new Promise((resolve) =>
setTimeout(() => resolve({ title: 'Title', text: 'Text' }), 100),
),
);
const props = {
modalName: COMMUNITY_PLUS_ENROLLMENT_MODAL,
data: {
closeCallback: closeCallbackSpy,
},
};
const { getByRole } = renderComponent({ props });
const emailInput = getByRole('textbox');
expect(emailInput).toBeVisible();
await userEvent.type(emailInput, 'test@ema.il');
await userEvent.keyboard('{Enter}');
await userEvent.keyboard('{Enter}');
expect(getByRole('button', { name: buttonLabel })).toBeDisabled();
expect(usageStore.registerCommunityEdition).toHaveBeenCalledWith('test@ema.il');
expect(usageStore.registerCommunityEdition).toHaveBeenCalledTimes(1);
});
});

View File

@@ -25,6 +25,7 @@ const usageStore = useUsageStore();
const telemetry = useTelemetry();
const usersStore = useUsersStore();
const isLoading = ref(false);
const valid = ref(false);
const email = ref(usersStore.currentUser?.email ?? '');
const validationRules = ref([{ name: 'email' }]);
@@ -56,6 +57,11 @@ const closeModal = () => {
};
const confirm = async () => {
if (!valid.value || isLoading.value) {
return;
}
isLoading.value = true;
try {
const { title, text } = await usageStore.registerCommunityEdition(email.value);
closeModal();
@@ -71,6 +77,8 @@ const confirm = async () => {
});
} catch (error) {
toast.showError(error, i18n.baseText('communityPlusModal.error.title'));
} finally {
isLoading.value = false;
}
};
</script>
@@ -134,6 +142,7 @@ const confirm = async () => {
:validation-rules="validationRules"
:validators="validators"
@validate="valid = $event"
@keyup.enter="confirm"
/>
</div>
</template>
@@ -147,10 +156,15 @@ const confirm = async () => {
</N8nText>
</div>
<div :class="$style.buttons">
<N8nButton :class="$style.skip" type="secondary" text @click="closeModal">{{
i18n.baseText('communityPlusModal.button.skip')
}}</N8nButton>
<N8nButton :disabled="!valid" type="primary" @click="confirm">
<N8nButton
:class="$style.skip"
type="secondary"
text
@click="closeModal"
:disabled="isLoading"
>{{ i18n.baseText('communityPlusModal.button.skip') }}</N8nButton
>
<N8nButton :disabled="!valid || isLoading" type="primary" @click="confirm">
{{ i18n.baseText('communityPlusModal.button.confirm') }}
</N8nButton>
</div>