Skip to content

Commit 1e42711

Browse files
committed
feat: allow updating entries
1 parent 8e3f4c2 commit 1e42711

File tree

5 files changed

+52
-39
lines changed

5 files changed

+52
-39
lines changed

apps/backend/src/research/entries/entry.entity.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ export class Entry extends BaseEntity {
2929
@ManyToOne()
3030
carer!: Carer;
3131

32-
@OneToMany(() => EntryLanguage, (entryLanguage) => entryLanguage.entry)
32+
@OneToMany(() => EntryLanguage, (entryLanguage) => entryLanguage.entry, { orphanRemoval: true })
3333
entryLanguages = new Collection<EntryLanguage>(this);
3434
}

apps/backend/src/research/entry-languages/entry-language.dto.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ApiProperty, OmitType, PartialType } from "@nestjs/swagger";
1+
import { ApiProperty, OmitType } from "@nestjs/swagger";
22
import { Type } from "class-transformer";
33
import { Min, Max } from "class-validator";
44
import { LanguageDto } from "../../defaults/languages/language.dto";
@@ -20,7 +20,8 @@ export class EntryLanguageDto {
2020
entry: QuestionnaireEntryDto;
2121
}
2222
export class EntryLanguageResponseDto extends OmitType(EntryLanguageDto, ["entry"]) {}
23-
export class EntryLanguageCreationDto extends OmitType(EntryLanguageDto, ["id", "entry", "language"]) {
24-
language: number;
23+
export class EntryLanguageMutationDto extends OmitType(EntryLanguageDto, ["id", "entry", "language"]) {
24+
id?: number;
25+
language?: number;
2526
}
26-
export class EntryLanguageMutationDto extends PartialType(EntryLanguageCreationDto) {}
27+
export class EntryLanguageCreationDto extends OmitType(EntryLanguageMutationDto, ["id"]) {}

apps/frontend/src/api.gen.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ export interface components {
594594
* @example 50
595595
*/
596596
ratio: number;
597-
language: number;
597+
language?: number;
598598
};
599599
EntryCreationDto: {
600600
/**
@@ -887,7 +887,8 @@ export interface components {
887887
* @description The ratio in percent of the entry language
888888
* @example 50
889889
*/
890-
ratio?: number;
890+
ratio: number;
891+
id?: number;
891892
language?: number;
892893
};
893894
StudyCreationDto: {

apps/frontend/src/components/questionnaire/calendar/EntryForm.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { LanguageSelect } from "../../LanguageSelect";
99
export type EntryFormValues = {
1010
carer?: number;
1111
entryLanguages: {
12+
id?: number;
1213
ratio: number;
1314
language?: number;
1415
}[];

apps/frontend/src/routes/_auth/questionnaire/_questionnaire/$id/entries.tsx

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import FullCalendar from "@fullcalendar/react";
77
import timeGridPlugin from "@fullcalendar/timegrid";
88
import { EventInput } from "@fullcalendar/core";
99
import interactionPlugin from "@fullcalendar/interaction";
10-
import { useSuspenseQuery } from "@tanstack/react-query";
1110
import { components } from "../../../../../api.gen";
1211
import { QuestionnaireEntry } from "../../../../../components/questionnaire/calendar/QuestionnaireEntry";
1312
import { EntityForm, EntryFormValues } from "../../../../../components/questionnaire/calendar/EntryForm";
@@ -42,44 +41,46 @@ function QuestionnaireEntries() {
4241
const theme = useMantineTheme();
4342
const [opened, { open, close }] = useDisclosure();
4443

45-
const [selectedStartTime, setSelectedStartTime] = useState<string>();
46-
const [selectedEndTime, setSelectedEndTime] = useState<string>();
4744
const [selectedWeekday, setSelectedWeekday] = useState<number>();
45+
const [entryUpdatingId, setEntryUpdadingId] = useState<number>();
46+
const [entryDraft, setEntryDraft] = useState<Partial<EntryFormValues>>();
4847

4948
const createMutation = $api.useMutation("post", "/entries");
50-
const { data: questionnaire, refetch } = useSuspenseQuery(
51-
$api.queryOptions("get", "/questionnaires/{id}", { params: { path: { id: p.id } } })
52-
);
49+
const updateMutation = $api.useMutation("patch", "/entries/{id}");
50+
const { data: questionnaire, refetch } = $api.useSuspenseQuery("get", "/questionnaires/{id}", { params: { path: { id: p.id } } });
5351

5452
const events: ExtendedEvent[] =
55-
questionnaire.entries?.map(({ startedAt, endedAt, weekday, carer, entryLanguages }) => ({
53+
questionnaire.entries?.map(({ startedAt, endedAt, weekday, carer, entryLanguages, id }) => ({
54+
id: id.toString(),
5655
start: getDateFromTimeAndWeekday(startedAt, weekday),
5756
end: getDateFromTimeAndWeekday(endedAt, weekday),
5857
title: carer.name,
5958
extendedProps: { entryLanguages },
6059
backgroundColor: theme.colors[theme.primaryColor][4],
6160
})) ?? [];
6261

63-
const handleAddEntry = ({ entryLanguages, carer, ...rest }: EntryFormValues) => {
62+
const handleReset = () => {
63+
refetch();
64+
close();
65+
setSelectedWeekday(undefined);
66+
setEntryUpdadingId(undefined);
67+
};
68+
69+
const handleOnSave = ({ carer, ...rest }: EntryFormValues) => {
6470
if (selectedWeekday === undefined) return;
6571

66-
createMutation.mutate(
67-
{
68-
body: {
69-
...rest,
70-
carer: carer!,
71-
entryLanguages: entryLanguages.map(({ ratio, language: languageId }) => ({ language: languageId!, ratio })),
72-
weekday: selectedWeekday,
73-
questionnaire: questionnaire.id,
74-
},
75-
},
76-
{
77-
onSuccess() {
78-
refetch();
79-
close();
80-
},
81-
}
82-
);
72+
const entryRequest = {
73+
...rest,
74+
carer: carer!,
75+
weekday: selectedWeekday,
76+
questionnaire: questionnaire.id,
77+
};
78+
79+
if (!entryUpdatingId) {
80+
createMutation.mutate({ body: entryRequest }, { onSuccess: handleReset });
81+
} else {
82+
updateMutation.mutate({ body: entryRequest, params: { path: { id: entryUpdatingId?.toString() } } }, { onSuccess: handleReset });
83+
}
8384
};
8485

8586
const handleSubmit = () => {
@@ -89,11 +90,7 @@ function QuestionnaireEntries() {
8990
return (
9091
<>
9192
<Modal opened={opened} onClose={close} size="md">
92-
<EntityForm
93-
onSave={handleAddEntry}
94-
entry={!!selectedStartTime && !!selectedEndTime ? { startedAt: selectedStartTime, endedAt: selectedEndTime } : undefined}
95-
actionLabel={t.addEntityLabel}
96-
/>
93+
<EntityForm onSave={handleOnSave} entry={entryDraft} actionLabel={t.addEntityLabel} />
9794
</Modal>
9895
<form onSubmit={handleSubmit}>
9996
<Stack>
@@ -104,11 +101,24 @@ function QuestionnaireEntries() {
104101
events={events}
105102
selectable
106103
select={(args) => {
107-
setSelectedStartTime(getTime(args.start));
108-
setSelectedEndTime(getTime(args.end));
104+
setEntryDraft({ startedAt: getTime(args.start), endedAt: getTime(args.end) });
109105
setSelectedWeekday(args.start.getDay());
110106
open();
111107
}}
108+
eventClick={(args) => {
109+
const { carer, entryLanguages, weekday, id } =
110+
questionnaire.entries?.find((entry) => entry.id.toString() === args.event.id) ?? {};
111+
112+
setEntryUpdadingId(id);
113+
setEntryDraft({
114+
carer: carer?.id,
115+
startedAt: getTime(args.event.start!),
116+
endedAt: getTime(args.event.end!),
117+
entryLanguages: entryLanguages?.map(({ language, ...rest }) => ({ ...rest, language: language.id })),
118+
});
119+
setSelectedWeekday(weekday);
120+
open();
121+
}}
112122
eventContent={({ event }) => <QuestionnaireEntry event={event} />}
113123
/>
114124
<Group>

0 commit comments

Comments
 (0)