diff --git a/app/[slug]/dashboard/guests/page.tsx b/app/[slug]/dashboard/guests/page.tsx index 137cd10..3a62a69 100644 --- a/app/[slug]/dashboard/guests/page.tsx +++ b/app/[slug]/dashboard/guests/page.tsx @@ -99,7 +99,10 @@ export default function Page() { { refreshGuests(); setGuestBeingEdited(undefined) }} + onCreate={(newGuest) => { + setGuests([newGuest!, ...guests]); + setGuestBeingEdited(undefined) ; + }} guest={guestBeingEdited} visible={guestBeingEdited !== undefined} onHide={() => { setGuestBeingEdited(undefined) }} diff --git a/app/api/abstract-api.tsx b/app/api/abstract-api.tsx index 1321d4f..19771a7 100644 --- a/app/api/abstract-api.tsx +++ b/app/api/abstract-api.tsx @@ -6,7 +6,7 @@ import { getCsrfToken, getSlug } from '@/app/lib/utils'; export interface Api { getAll(serializable: Serializable, callback: (objets: T[]) => void): void; get(serializable: Serializable, id: string, callback: (object: T) => void): void; - create(serializable: Serializable, object: T, callback: () => void): void; + create(serializable: Serializable, object: T, callback: (object: T) => void): void; update(serializable: Serializable, object: T, callback: () => void): void; destroy(serializable: Serializable, object: T, callback: () => void): void; } diff --git a/app/lib/guest.tsx b/app/lib/guest.tsx index 80fcfb7..4b5e374 100644 --- a/app/lib/guest.tsx +++ b/app/lib/guest.tsx @@ -2,6 +2,7 @@ import { Serializable } from "../api/abstract-api"; import { Entity } from "./definitions"; +import { Group } from "./group"; export const guestStatuses = ['considered', 'invited', 'confirmed', 'declined', 'tentative'] as const; export type GuestStatus = typeof guestStatuses[number]; @@ -9,30 +10,28 @@ export type GuestStatus = typeof guestStatuses[number]; export class Guest implements Entity { id?: string; name?: string; - group_name?: string; - groupId?: string; color?: string; status?: GuestStatus; children?: Guest[]; + group?: Group; - constructor(id?: string, name?: string, group_name?: string, groupId?: string, color?: string, status?: GuestStatus, children?: Guest[]) { + constructor(id?: string, name?: string, color?: string, status?: GuestStatus, children?: Guest[], Group?: Group) { this.id = id; this.name = name; - this.group_name = group_name; - this.groupId = groupId; this.color = color; this.status = status; this.children = children; + this.group = Group; } } export class GuestSerializer implements Serializable { fromJson(data: any): Guest { - return new Guest(data.id, data.name, data.group?.name, data.group?.id, data.color, data.status, data.children); + return new Guest(data.id, data.name, data.color, data.status, data.children, new Group(data.group?.id, data.group?.name)); } toJson(guest: Guest): string { - return JSON.stringify({ guest: { name: guest.name, status: guest.status, group_id: guest.groupId } }); + return JSON.stringify({ guest: { name: guest.name, status: guest.status, group_id: guest.group?.id } }); } apiPath(): string { diff --git a/app/lib/invitation.tsx b/app/lib/invitation.tsx index f6acb70..e6bcf0b 100644 --- a/app/lib/invitation.tsx +++ b/app/lib/invitation.tsx @@ -15,7 +15,7 @@ export class Invitation implements Entity { export class InvitationSerializer { fromJson(data: any): Invitation { - return new Invitation(data.id, (data.guests || []).map((guest: any) => new Guest(guest.id, guest.name, guest.group_name, guest.groupId, guest.color, guest.status, guest.children))); + return new Invitation(data.id, (data.guests || []).map((guest: any) => new Guest(guest.id, guest.name, guest.color, guest.status, guest.children))); } toJson(invitation: Invitation): string { diff --git a/app/lib/tableSimulation.tsx b/app/lib/tableSimulation.tsx index 7a01b4d..1369569 100644 --- a/app/lib/tableSimulation.tsx +++ b/app/lib/tableSimulation.tsx @@ -2,6 +2,7 @@ import { Serializable } from "../api/abstract-api"; import { Entity } from "./definitions"; +import { Group } from "./group"; import { Guest } from "./guest"; export type Discomfort = { @@ -53,10 +54,10 @@ export class TableSimulationSerializer implements Serializable return { id: guest.id, name: guest.name, - group_id: guest.groupId, color: guest.color, status: guest.status, children: guest.children, + group: new Group(guest.group?.id, guest.group?.name) } }), discomfort: table.discomfort, diff --git a/app/ui/components/guest-form-dialog.tsx b/app/ui/components/guest-form-dialog.tsx index c0b20e0..0dca253 100644 --- a/app/ui/components/guest-form-dialog.tsx +++ b/app/ui/components/guest-form-dialog.tsx @@ -15,14 +15,14 @@ import { useState } from 'react'; export default function GuestFormDialog({ groups, onCreate, onHide, guest, visible }: { groups: Group[], - onCreate?: () => void, + onCreate?: (guest: Guest) => void, onHide: () => void, guest?: Guest, visible: boolean, }) { const [name, setName] = useState(guest?.name || ''); - const [group, setGroup] = useState(guest?.groupId || null); + const [group, setGroup] = useState(guest?.group?.id || null); const [status, setStatus] = useState(guest?.status || null); const api = new AbstractApi(); @@ -41,17 +41,17 @@ export default function GuestFormDialog({ groups, onCreate, onHide, guest, visib if (guest?.id !== undefined) { guest.name = name; - guest.groupId = group; + guest.group!.id = group; guest.status = status; api.update(serializer, guest, () => { resetForm(); - onCreate && onCreate(); + onCreate && onCreate(guest); }); } else { - api.create(serializer, new Guest(undefined, name, undefined, group, undefined, status), ()=> { + api.create(serializer, new Guest(undefined, name, undefined, status, [], groups.find((g) => g.id === group)), (newGuest)=> { resetForm(); - onCreate && onCreate(); + onCreate && onCreate(newGuest); }); } } diff --git a/app/ui/guests/table.tsx b/app/ui/guests/table.tsx index 93972d0..71af78a 100644 --- a/app/ui/guests/table.tsx +++ b/app/ui/guests/table.tsx @@ -28,7 +28,7 @@ export default function guestsTable({ guests, onUpdate, onEdit }: { {guest.name} - {guest.group_name} + {guest.group?.name} diff --git a/tests/guests.spec.ts b/tests/guests.spec.ts index 6fcd29b..d7309a0 100644 --- a/tests/guests.spec.ts +++ b/tests/guests.spec.ts @@ -27,7 +27,15 @@ const mockGuestsAPI = ({ page }: { page: Page }) => { await route.fulfill({ json }) } else if (route.request().method() === 'POST') { - const json = {}; + const json = { + "id":"ff58aa2d-643d-4c29-be9c-50e10ae6853c", + "name":"John Snow", + "status":"invited", + "group": { + "id": "da8edf26-3e1e-4cbb-b985-450c49fffe01", + "name": "Work", + } + }; await route.fulfill({ json }); } @@ -104,6 +112,7 @@ test('should allow creating a new guest', async ({ page }) => { await mockGroupsAPI({ page }); await page.goto('/default/dashboard/guests'); + await expect(page.getByText('There are 2 elements in the list')).toBeVisible(); await page.getByRole('button', { name: 'Add new' }).click(); await page.getByRole('dialog').getByLabel('Name').fill('John Snow'); @@ -119,6 +128,13 @@ test('should allow creating a new guest', async ({ page }) => { await page.keyboard.press('Enter'); await page.getByRole('dialog').getByRole('button', { name: 'Create' }).click(); + + await expect(page.getByText('There are 3 elements in the list')).toBeVisible(); + + await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'John Snow' })).toBeVisible(); + await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Work' })).toBeVisible(); + await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Invited' })).toBeVisible(); + await expect(page.getByRole('row').nth(1).locator('svg')).toHaveCount(2); }); test('should display the list of groups', async ({ page }) => {