mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 06:53:12 +00:00
Merge remote-tracking branch 'origin/dev' into feat/ab/sh-326-team-member
This commit is contained in:
commit
827d52add7
2 changed files with 65 additions and 13 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useMemo, useState, type Dispatch, type SetStateAction } from "react";
|
||||
import { useEffect, useMemo, useRef, useState, type Dispatch, type SetStateAction } from "react";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
|
|
@ -278,15 +278,25 @@ export function TeamMemberFormFields({
|
|||
export function AddTeamMemberDialog({ open, onClose }: { open: boolean; onClose: () => void }) {
|
||||
const [form, setForm] = useState(emptyForm);
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
const createTeamMember = useCreateTeamMember();
|
||||
const mutationError = createTeamMember.error;
|
||||
const submissionId = useRef(0);
|
||||
const { error: mutationError, isPending, mutate, reset } = useCreateTeamMember();
|
||||
|
||||
useEffect(() => {
|
||||
submissionId.current += 1;
|
||||
reset();
|
||||
if (open) {
|
||||
setForm(emptyForm());
|
||||
setSubmitted(false);
|
||||
}
|
||||
}, [open]);
|
||||
}, [open, reset]);
|
||||
|
||||
const handleClose = () => {
|
||||
if (isPending) return;
|
||||
|
||||
submissionId.current += 1;
|
||||
reset();
|
||||
onClose();
|
||||
};
|
||||
|
||||
const emailIsValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim());
|
||||
const errors = useMemo(
|
||||
|
|
@ -340,11 +350,18 @@ export function AddTeamMemberDialog({ open, onClose }: { open: boolean; onClose:
|
|||
serviceAreas: form.serviceAreas,
|
||||
permissionOverrides: permissionOverrides(form.role, form.permissions),
|
||||
};
|
||||
createTeamMember.mutate(input, { onSuccess: onClose });
|
||||
const currentSubmissionId = submissionId.current;
|
||||
mutate(input, {
|
||||
onSuccess: () => {
|
||||
if (submissionId.current !== currentSubmissionId) return;
|
||||
reset();
|
||||
onClose();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose} fullWidth maxWidth="md" scroll="paper">
|
||||
<Dialog open={open} onClose={handleClose} fullWidth maxWidth="md" scroll="paper">
|
||||
<DialogTitle>Add Member</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<Typography color="text.secondary" sx={{ mb: 3 }}>
|
||||
|
|
@ -365,15 +382,11 @@ export function AddTeamMemberDialog({ open, onClose }: { open: boolean; onClose:
|
|||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} disabled={createTeamMember.isPending}>
|
||||
<Button onClick={handleClose} disabled={isPending}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="contained" onClick={submit} disabled={createTeamMember.isPending}>
|
||||
{createTeamMember.isPending ? (
|
||||
<CircularProgress size={20} color="inherit" />
|
||||
) : (
|
||||
"Add Member"
|
||||
)}
|
||||
<Button variant="contained" onClick={submit} disabled={isPending}>
|
||||
{isPending ? <CircularProgress size={20} color="inherit" /> : "Add Member"}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,14 @@ vi.mock("@/domain/team-members/use-cases/use-create-team-member", () => ({
|
|||
|
||||
describe("AddTeamMemberDialog", () => {
|
||||
const mutate = vi.fn();
|
||||
const reset = vi.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
mutate.mockReset();
|
||||
reset.mockReset();
|
||||
vi.mocked(useCreateTeamMember).mockReturnValue({
|
||||
mutate,
|
||||
reset,
|
||||
isPending: false,
|
||||
error: null,
|
||||
} as unknown as ReturnType<typeof useCreateTeamMember>);
|
||||
|
|
@ -62,4 +65,40 @@ describe("AddTeamMemberDialog", () => {
|
|||
expect.any(Object),
|
||||
);
|
||||
}, 15000);
|
||||
|
||||
it("does not close while a member is being created", async () => {
|
||||
const user = userEvent.setup();
|
||||
const onClose = vi.fn();
|
||||
vi.mocked(useCreateTeamMember).mockReturnValue({
|
||||
mutate,
|
||||
reset,
|
||||
isPending: true,
|
||||
error: null,
|
||||
} as unknown as ReturnType<typeof useCreateTeamMember>);
|
||||
renderWithProviders(<AddTeamMemberDialog open onClose={onClose} />, { withAuth: false });
|
||||
|
||||
await user.keyboard("{Escape}");
|
||||
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("clears a previous mutation error when reopened", () => {
|
||||
const mutation = {
|
||||
mutate,
|
||||
reset,
|
||||
isPending: false,
|
||||
error: new Error("Email is already in use."),
|
||||
} as unknown as ReturnType<typeof useCreateTeamMember>;
|
||||
vi.mocked(useCreateTeamMember).mockReturnValue(mutation);
|
||||
const { rerender } = renderWithProviders(<AddTeamMemberDialog open onClose={vi.fn()} />, {
|
||||
withAuth: false,
|
||||
});
|
||||
|
||||
expect(screen.getByText("Email is already in use.")).toBeInTheDocument();
|
||||
mutation.error = null;
|
||||
rerender(<AddTeamMemberDialog open={false} onClose={vi.fn()} />);
|
||||
rerender(<AddTeamMemberDialog open onClose={vi.fn()} />);
|
||||
|
||||
expect(screen.queryByText("Email is already in use.")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue