From aa5c69d97ab74e4d8210fbcb0f3b6a39dd9b20ca Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 15 Feb 2025 23:48:06 +0200 Subject: [PATCH] feat(view/calendar): add flow to create a note --- .../app/widgets/view_widgets/calendar_view.ts | 60 +++++++++++++++++-- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/src/public/app/widgets/view_widgets/calendar_view.ts b/src/public/app/widgets/view_widgets/calendar_view.ts index 92daed922..22f7b9d52 100644 --- a/src/public/app/widgets/view_widgets/calendar_view.ts +++ b/src/public/app/widgets/view_widgets/calendar_view.ts @@ -1,4 +1,4 @@ -import type { EventChangeArg, EventDropArg, EventSourceInput, PluginDef } from "@fullcalendar/core"; +import type { DateSelectArg, EventChangeArg, EventDropArg, EventSourceInput, PluginDef } from "@fullcalendar/core"; import froca from "../../services/froca.js"; import ViewMode, { type ViewModeArgs } from "./view_mode.js"; import type FNote from "../../entities/fnote.js"; @@ -6,6 +6,8 @@ import server from "../../services/server.js"; import ws from "../../services/ws.js"; import { t } from "../../services/i18n.js"; import options from "../../services/options.js"; +import dialogService from "../../services/dialog.js"; +import attributes from "../../services/attributes.js"; const TPL = `
@@ -45,11 +47,19 @@ const TPL = `
`; +// TODO: Deduplicate +interface CreateChildResponse { + note: { + noteId: string; + } +} + export default class CalendarView extends ViewMode { private $root: JQuery; private $calendarContainer: JQuery; private noteIds: string[]; + private parentNote: FNote; constructor(args: ViewModeArgs) { super(args); @@ -57,17 +67,19 @@ export default class CalendarView extends ViewMode { this.$root = $(TPL); this.$calendarContainer = this.$root.find(".calendar-container"); this.noteIds = args.noteIds; + this.parentNote = args.parentNote; + console.log(args); args.$parent.append(this.$root); } async renderList(): Promise | undefined> { - const editable = true; + const isEditable = true; const { Calendar } = await import("@fullcalendar/core"); const plugins: PluginDef[] = []; plugins.push((await import("@fullcalendar/daygrid")).default); - if (editable) { + if (isEditable) { plugins.push((await import("@fullcalendar/interaction")).default); } @@ -75,7 +87,9 @@ export default class CalendarView extends ViewMode { plugins, initialView: "dayGridMonth", events: await CalendarView.#buildEvents(this.noteIds), - editable, + editable: isEditable, + selectable: isEditable, + select: (e) => this.#onCalendarSelection(e), eventChange: (e) => this.#onEventMoved(e), firstDay: options.getInt("firstDayOfWeek") ?? 0, locale: await CalendarView.#getLocale() @@ -108,9 +122,33 @@ export default class CalendarView extends ViewMode { } } + async #onCalendarSelection(e: DateSelectArg) { + const startDate = CalendarView.#formatDateToLocalISO(e.start); + if (!startDate) { + return; + } + + const endDate = CalendarView.#formatDateToLocalISO(CalendarView.#offsetDate(e.end, -1)); + + const title = await dialogService.prompt({ message: t("relation_map.enter_title_of_new_note"), defaultValue: t("relation_map.default_new_note_title") }); + if (!title?.trim()) { + return; + } + + const { note } = await server.post(`notes/${this.parentNote.noteId}/children?target=into`, { + title, + content: "", + type: "text" + }); + attributes.setLabel(note.noteId, "startDate", startDate); + if (endDate) { + attributes.setLabel(note.noteId, "endDate", endDate); + } + } + async #onEventMoved(e: EventChangeArg) { const startDate = CalendarView.#formatDateToLocalISO(e.event.start); - let endDate = CalendarView.#formatDateToLocalISO(e.event.end); + let endDate = CalendarView.#formatDateToLocalISO(CalendarView.#offsetDate(e.event.end, -1)); const noteId = e.event.extendedProps.noteId; // Fullcalendar end date is exclusive, not inclusive but we store it the other way around. @@ -156,7 +194,7 @@ export default class CalendarView extends ViewMode { noteId: note.noteId }; - const endDate = new Date(note.getAttributeValue("label", "endDate") ?? startDate); + const endDate = CalendarView.#offsetDate(note.getAttributeValue("label", "endDate") ?? startDate, -1); if (endDate) { // Fullcalendar end date is exclusive, not inclusive. endDate.setDate(endDate.getDate() + 1); @@ -223,4 +261,14 @@ export default class CalendarView extends ViewMode { return localDate.toISOString().split('T')[0]; } + static #offsetDate(date: Date | string | null | undefined, offset: number) { + if (!date) { + return undefined; + } + + const newDate = new Date(date); + newDate.setDate(newDate.getDate() + offset); + return newDate; + } + }