diff --git a/libs/domains/organizations/feature/src/lib/settings-webhook/webhook-crud-modal/webhook-crud-modal.spec.tsx b/libs/domains/organizations/feature/src/lib/settings-webhook/webhook-crud-modal/webhook-crud-modal.spec.tsx index 49f5566b550..08eca5ad4eb 100644 --- a/libs/domains/organizations/feature/src/lib/settings-webhook/webhook-crud-modal/webhook-crud-modal.spec.tsx +++ b/libs/domains/organizations/feature/src/lib/settings-webhook/webhook-crud-modal/webhook-crud-modal.spec.tsx @@ -156,6 +156,33 @@ describe('WebhookCrudModal', () => { }) }) + it('should commit a project filter typed but not confirmed with Enter when submitting', async () => { + const { userEvent } = renderWithProviders() + const url = screen.getByLabelText('URL') + const kind = screen.getByLabelText('Kind') + const tags = screen.getByTestId('input-tags-field') + + await userEvent.clear(url) + await userEvent.type(url, 'https://test.com') + + await selectEvent.select(kind, ['Standard'], { + container: document.body, + }) + + await userEvent.type(tags, 'test') + + const button = screen.getByTestId('submit-button') + await userEvent.click(button) + + expect(editWebhookMock).toHaveBeenCalledWith({ + organizationId: '000-000-000', + webhookId: mockWebhook.id, + webhookRequest: expect.objectContaining({ + project_names_filter: ['test'], + }), + }) + }) + it('should trim URL with trailing whitespace on create', async () => { const { userEvent } = renderWithProviders() diff --git a/libs/shared/ui/src/lib/components/inputs/input-tags/input-tags.tsx b/libs/shared/ui/src/lib/components/inputs/input-tags/input-tags.tsx index bf1b9e5c46e..08d4c3837a5 100644 --- a/libs/shared/ui/src/lib/components/inputs/input-tags/input-tags.tsx +++ b/libs/shared/ui/src/lib/components/inputs/input-tags/input-tags.tsx @@ -55,6 +55,17 @@ export function InputTags(props: InputTagsProps) { isLabelTransitionDisabled && '!transition-none' ) + const commitTag = (rawValue: string) => { + const value = rawValue.trim() + if (!value) return + if (currentTags.find((v) => value.toLowerCase() === v.toLowerCase())) return + + const newTags = [...currentTags, value] + setCurrentTags(newTags) + setInputValue('') + onChange && onChange(newTags) + } + const handleKeyDown = (event: FormEvent) => { const key = (event as KeyboardEvent).key const target = event.target as HTMLInputElement @@ -69,14 +80,7 @@ export function InputTags(props: InputTagsProps) { if (key === 'Enter') { event.preventDefault() event.stopPropagation() - - if (!value.trim()) return - if (currentTags.find((v) => value.toLowerCase() === v.toLowerCase())) return - - const newTags = [...currentTags, value] - setCurrentTags(newTags) - setInputValue('') - onChange && onChange(newTags) + commitTag(value) } } @@ -116,6 +120,7 @@ export function InputTags(props: InputTagsProps) { ref={ref} data-testid="input-tags-field" onKeyDown={handleKeyDown} + onBlur={(e) => commitTag(e.currentTarget.value)} type="text" className={twMerge( 'bg-transparent',