Skip to content

Commit

Permalink
Show loading state when create-group API request in-flight
Browse files Browse the repository at this point in the history
  • Loading branch information
seanh committed Jul 31, 2024
1 parent 8318839 commit dc2305c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
16 changes: 13 additions & 3 deletions h/static/scripts/group-forms/components/CreateGroupForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useId, useMemo, useState } from 'preact/hooks';

import { Button, Input, Textarea } from '@hypothesis/frontend-shared';
import { Button, Input, Spinner, Textarea } from '@hypothesis/frontend-shared';
import { readConfig } from '../config';
import { callAPI, CreateGroupAPIResponse } from '../utils/api';
import { setLocation } from '../utils/set-location';
Expand Down Expand Up @@ -122,13 +122,16 @@ export default function CreateGroupForm() {
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const [saving, setSaving] = useState(false);
const config = useMemo(() => readConfig(), []);

const createGroup = async (e: SubmitEvent) => {
e.preventDefault();

let response: CreateGroupAPIResponse;

setSaving(true);

try {
response = (await callAPI(
config.api.createGroup.url,
Expand All @@ -140,6 +143,7 @@ export default function CreateGroupForm() {
)) as CreateGroupAPIResponse;
} catch (apiError) {
setErrorMessage(apiError.message);
setSaving(false);
return;
}

Expand Down Expand Up @@ -174,7 +178,7 @@ export default function CreateGroupForm() {
classes="h-24"
/>

<div className="flex items-center">
<div className="flex items-center gap-x-4">
{errorMessage && (
<div
className="text-red-error font-bold"
Expand All @@ -184,7 +188,13 @@ export default function CreateGroupForm() {
</div>
)}
<div className="grow" />
<Button type="submit" variant="primary">
{saving ? <Spinner data-testid="spinner" /> : null}
<Button
type="submit"
variant="primary"
disabled={saving}
data-testid="button"
>
Create group
</Button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,30 @@ describe('CreateGroupForm', () => {
assert.isFalse(wrapper.exists('[data-testid="error-message"]'));
});

it("doesn't show a loading state initially", async () => {
const { wrapper } = createWrapper();

await assertInLoadingState(wrapper, false);
});

it('shows a loading state when the create-group API request is in-flight', async () => {
const { wrapper } = createWrapper();
fakeCallAPI.resolves(new Promise(() => {}));

wrapper.find('form[data-testid="form"]').simulate('submit');

await assertInLoadingState(wrapper, true);
});

it('continues to show the loading state after receiving a successful API response', async () => {
const { wrapper } = createWrapper();
fakeCallAPI.resolves({ links: { html: 'https://example.com/group/foo' } });

await wrapper.find('form[data-testid="form"]').simulate('submit');

await assertInLoadingState(wrapper, true);
});

it('creates the group and redirects the browser', async () => {
const { wrapper, elements } = createWrapper();
const nameEl = elements.name.fieldEl;
Expand Down Expand Up @@ -198,5 +222,15 @@ describe('CreateGroupForm', () => {
'[data-testid="error-message"]',
);
assert.equal(errorMessageEl.text(), errorMessageFromCallAPI);
// It exits its loading state after receiving an error response.
await assertInLoadingState(wrapper, false);
});
});

async function assertInLoadingState(wrapper, inLoadingState) {
await waitForElement(
wrapper,
`button[data-testid="button"][disabled=${inLoadingState}]`,
);
assert.equal(wrapper.exists('[data-testid="spinner"]'), inLoadingState);
}

0 comments on commit dc2305c

Please sign in to comment.