mirror of
https://github.com/zadam/trilium.git
synced 2025-10-29 02:28:57 +01:00
chore(react/collections/calendar): reintroduce tests
This commit is contained in:
parent
69af62cde0
commit
10a6a3056a
@ -1,6 +1,7 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { buildNote, buildNotes } from "../../test/easy-froca.js";
|
import { buildNote, buildNotes } from "../../../test/easy-froca.js";
|
||||||
import CalendarView, { getFullCalendarLocale } from "./calendar_view.js";
|
import { buildEvent, buildEvents } from "./event_builder.js";
|
||||||
|
import { LOCALE_MAPPINGS } from "./index.js";
|
||||||
import { LOCALES } from "@triliumnext/commons";
|
import { LOCALES } from "@triliumnext/commons";
|
||||||
|
|
||||||
describe("Building events", () => {
|
describe("Building events", () => {
|
||||||
@ -9,7 +10,7 @@ describe("Building events", () => {
|
|||||||
{ title: "Note 1", "#startDate": "2025-05-05" },
|
{ title: "Note 1", "#startDate": "2025-05-05" },
|
||||||
{ title: "Note 2", "#startDate": "2025-05-07" },
|
{ title: "Note 2", "#startDate": "2025-05-07" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05", end: "2025-05-06" });
|
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05", end: "2025-05-06" });
|
||||||
@ -21,7 +22,7 @@ describe("Building events", () => {
|
|||||||
{ title: "Note 1", "#endDate": "2025-05-05" },
|
{ title: "Note 1", "#endDate": "2025-05-05" },
|
||||||
{ title: "Note 2", "#endDateDate": "2025-05-07" }
|
{ title: "Note 2", "#endDateDate": "2025-05-07" }
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(0);
|
expect(events).toHaveLength(0);
|
||||||
});
|
});
|
||||||
@ -31,7 +32,7 @@ describe("Building events", () => {
|
|||||||
{ title: "Note 1", "#startDate": "2025-05-05", "#endDate": "2025-05-05" },
|
{ title: "Note 1", "#startDate": "2025-05-05", "#endDate": "2025-05-05" },
|
||||||
{ title: "Note 2", "#startDate": "2025-05-07", "#endDate": "2025-05-08" },
|
{ title: "Note 2", "#startDate": "2025-05-07", "#endDate": "2025-05-08" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05", end: "2025-05-06" });
|
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05", end: "2025-05-06" });
|
||||||
@ -43,7 +44,7 @@ describe("Building events", () => {
|
|||||||
{ title: "Note 1", "#myStartDate": "2025-05-05", "#calendar:startDate": "myStartDate" },
|
{ title: "Note 1", "#myStartDate": "2025-05-05", "#calendar:startDate": "myStartDate" },
|
||||||
{ title: "Note 2", "#startDate": "2025-05-07", "#calendar:startDate": "myStartDate" },
|
{ title: "Note 2", "#startDate": "2025-05-07", "#calendar:startDate": "myStartDate" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
expect(events[0]).toMatchObject({
|
expect(events[0]).toMatchObject({
|
||||||
@ -65,7 +66,7 @@ describe("Building events", () => {
|
|||||||
{ title: "Note 3", "#startDate": "2025-05-05", "#myEndDate": "2025-05-05", "#calendar:startDate": "myStartDate", "#calendar:endDate": "myEndDate" },
|
{ title: "Note 3", "#startDate": "2025-05-05", "#myEndDate": "2025-05-05", "#calendar:startDate": "myStartDate", "#calendar:endDate": "myEndDate" },
|
||||||
{ title: "Note 4", "#startDate": "2025-05-07", "#myEndDate": "2025-05-08", "#calendar:startDate": "myStartDate", "#calendar:endDate": "myEndDate" },
|
{ title: "Note 4", "#startDate": "2025-05-07", "#myEndDate": "2025-05-08", "#calendar:startDate": "myStartDate", "#calendar:endDate": "myEndDate" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(4);
|
expect(events).toHaveLength(4);
|
||||||
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05", end: "2025-05-06" });
|
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05", end: "2025-05-06" });
|
||||||
@ -79,7 +80,7 @@ describe("Building events", () => {
|
|||||||
{ title: "Note 1", "#myTitle": "My Custom Title 1", "#startDate": "2025-05-05", "#calendar:title": "myTitle" },
|
{ title: "Note 1", "#myTitle": "My Custom Title 1", "#startDate": "2025-05-05", "#calendar:title": "myTitle" },
|
||||||
{ title: "Note 2", "#startDate": "2025-05-07", "#calendar:title": "myTitle" },
|
{ title: "Note 2", "#startDate": "2025-05-07", "#calendar:title": "myTitle" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
expect(events[0]).toMatchObject({ title: "My Custom Title 1", start: "2025-05-05" });
|
expect(events[0]).toMatchObject({ title: "My Custom Title 1", start: "2025-05-05" });
|
||||||
@ -92,7 +93,7 @@ describe("Building events", () => {
|
|||||||
{ title: "Note 1", "~myTitle": "mySharedTitle", "#startDate": "2025-05-05", "#calendar:title": "myTitle" },
|
{ title: "Note 1", "~myTitle": "mySharedTitle", "#startDate": "2025-05-05", "#calendar:title": "myTitle" },
|
||||||
{ title: "Note 2", "#startDate": "2025-05-07", "#calendar:title": "myTitle" },
|
{ title: "Note 2", "#startDate": "2025-05-07", "#calendar:title": "myTitle" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
expect(events[0]).toMatchObject({ title: "My shared title", start: "2025-05-05" });
|
expect(events[0]).toMatchObject({ title: "My shared title", start: "2025-05-05" });
|
||||||
@ -105,7 +106,7 @@ describe("Building events", () => {
|
|||||||
{ title: "Note 1", "~myTitle": "mySharedTitle", "#startDate": "2025-05-05", "#calendar:title": "myTitle" },
|
{ title: "Note 1", "~myTitle": "mySharedTitle", "#startDate": "2025-05-05", "#calendar:title": "myTitle" },
|
||||||
{ title: "Note 2", "#startDate": "2025-05-07", "#calendar:title": "myTitle" },
|
{ title: "Note 2", "#startDate": "2025-05-07", "#calendar:title": "myTitle" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
expect(events[0]).toMatchObject({ title: "My shared custom title", start: "2025-05-05" });
|
expect(events[0]).toMatchObject({ title: "My shared custom title", start: "2025-05-05" });
|
||||||
@ -125,7 +126,7 @@ describe("Promoted attributes", () => {
|
|||||||
"#calendar:displayedAttributes": "weight,mood"
|
"#calendar:displayedAttributes": "weight,mood"
|
||||||
});
|
});
|
||||||
|
|
||||||
const event = await CalendarView.buildEvent(note, { startDate: "2025-04-04" });
|
const event = await buildEvent(note, { startDate: "2025-04-04" });
|
||||||
expect(event).toHaveLength(1);
|
expect(event).toHaveLength(1);
|
||||||
expect(event[0]?.promotedAttributes).toMatchObject([
|
expect(event[0]?.promotedAttributes).toMatchObject([
|
||||||
[ "weight", "75" ],
|
[ "weight", "75" ],
|
||||||
@ -143,7 +144,7 @@ describe("Promoted attributes", () => {
|
|||||||
"#relation:assignee": "promoted,alias=Assignee,single,text",
|
"#relation:assignee": "promoted,alias=Assignee,single,text",
|
||||||
});
|
});
|
||||||
|
|
||||||
const event = await CalendarView.buildEvent(note, { startDate: "2025-04-04" });
|
const event = await buildEvent(note, { startDate: "2025-04-04" });
|
||||||
expect(event).toHaveLength(1);
|
expect(event).toHaveLength(1);
|
||||||
expect(event[0]?.promotedAttributes).toMatchObject([
|
expect(event[0]?.promotedAttributes).toMatchObject([
|
||||||
[ "assignee", "Target note" ]
|
[ "assignee", "Target note" ]
|
||||||
@ -155,7 +156,7 @@ describe("Promoted attributes", () => {
|
|||||||
{ title: "Note 1", "#startDate": "2025-05-05", "#startTime": "13:36", "#endTime": "14:56" },
|
{ title: "Note 1", "#startDate": "2025-05-05", "#startTime": "13:36", "#endTime": "14:56" },
|
||||||
{ title: "Note 2", "#startDate": "2025-05-07", "#endDate": "2025-05-08", "#startTime": "13:36", "#endTime": "14:56" },
|
{ title: "Note 2", "#startDate": "2025-05-07", "#endDate": "2025-05-08", "#startTime": "13:36", "#endTime": "14:56" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05T13:36:00", end: "2025-05-05T14:56:00" });
|
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05T13:36:00", end: "2025-05-05T14:56:00" });
|
||||||
@ -167,7 +168,7 @@ describe("Promoted attributes", () => {
|
|||||||
{ title: "Note 1", "#startDate": "2025-05-05", "#startTime": "13:30" },
|
{ title: "Note 1", "#startDate": "2025-05-05", "#startTime": "13:30" },
|
||||||
{ title: "Note 2", "#startDate": "2025-05-07", "#endDate": "2025-05-08", "#startTime": "13:36" },
|
{ title: "Note 2", "#startDate": "2025-05-07", "#endDate": "2025-05-08", "#startTime": "13:36" },
|
||||||
]);
|
]);
|
||||||
const events = await CalendarView.buildEvents(noteIds);
|
const events = await buildEvents(noteIds);
|
||||||
|
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05T13:30:00" });
|
expect(events[0]).toMatchObject({ title: "Note 1", start: "2025-05-05T13:30:00" });
|
||||||
@ -183,12 +184,12 @@ describe("Building locales", () => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fullCalendarLocale = await getFullCalendarLocale(id);
|
const fullCalendarLocale = LOCALE_MAPPINGS[id];
|
||||||
|
|
||||||
if (id !== "en") {
|
if (id !== "en") {
|
||||||
expect(fullCalendarLocale, `For locale ${id}`).toBeDefined();
|
expect(fullCalendarLocale, `For locale ${id}`).toBeDefined();
|
||||||
} else {
|
} else {
|
||||||
expect(fullCalendarLocale).toBeUndefined();
|
expect(fullCalendarLocale).toBeNull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -75,7 +75,7 @@ export async function buildEventsForCalendar(note: FNote, e: EventSourceFuncArg)
|
|||||||
return events.flat();
|
return events.flat();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildEvent(note: FNote, { startDate, endDate, startTime, endTime }: Event) {
|
export async function buildEvent(note: FNote, { startDate, endDate, startTime, endTime }: Event) {
|
||||||
const customTitleAttributeName = note.getLabelValue("calendar:title");
|
const customTitleAttributeName = note.getLabelValue("calendar:title");
|
||||||
const titles = await parseCustomTitle(customTitleAttributeName, note);
|
const titles = await parseCustomTitle(customTitleAttributeName, note);
|
||||||
const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color");
|
const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color");
|
||||||
|
|||||||
@ -3,12 +3,9 @@ import { ViewModeProps } from "../interface";
|
|||||||
import Calendar from "./calendar";
|
import Calendar from "./calendar";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import { useNoteLabel, useNoteLabelBoolean, useResizeObserver, useSpacedUpdate, useTriliumOption, useTriliumOptionInt } from "../../react/hooks";
|
import { useNoteLabel, useNoteLabelBoolean, useResizeObserver, useSpacedUpdate, useTriliumEvent, useTriliumOption, useTriliumOptionInt } from "../../react/hooks";
|
||||||
import { CreateChildrenResponse, LOCALE_IDS } from "@triliumnext/commons";
|
import { LOCALE_IDS } from "@triliumnext/commons";
|
||||||
import { Calendar as FullCalendar } from "@fullcalendar/core";
|
import { Calendar as FullCalendar } from "@fullcalendar/core";
|
||||||
import { removeOwnedAttributesByNameOrType, setLabel } from "../../../services/attributes";
|
|
||||||
import { circle } from "leaflet";
|
|
||||||
import server from "../../../services/server";
|
|
||||||
import { parseStartEndDateFromEvent, parseStartEndTimeFromEvent } from "./utils";
|
import { parseStartEndDateFromEvent, parseStartEndTimeFromEvent } from "./utils";
|
||||||
import dialog from "../../../services/dialog";
|
import dialog from "../../../services/dialog";
|
||||||
import { t } from "../../../services/i18n";
|
import { t } from "../../../services/i18n";
|
||||||
@ -32,7 +29,7 @@ const CALENDAR_VIEWS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
// Here we hard-code the imports in order to ensure that they are embedded by webpack without having to load all the languages.
|
// Here we hard-code the imports in order to ensure that they are embedded by webpack without having to load all the languages.
|
||||||
const LOCALE_MAPPINGS: Record<LOCALE_IDS, (() => Promise<{ default: LocaleInput }>) | null> = {
|
export const LOCALE_MAPPINGS: Record<LOCALE_IDS, (() => Promise<{ default: LocaleInput }>) | null> = {
|
||||||
de: () => import("@fullcalendar/core/locales/de"),
|
de: () => import("@fullcalendar/core/locales/de"),
|
||||||
es: () => import("@fullcalendar/core/locales/es"),
|
es: () => import("@fullcalendar/core/locales/es"),
|
||||||
fr: () => import("@fullcalendar/core/locales/fr"),
|
fr: () => import("@fullcalendar/core/locales/fr"),
|
||||||
@ -75,6 +72,15 @@ export default function CalendarView({ note, noteIds }: ViewModeProps<CalendarVi
|
|||||||
const { eventDidMount } = useEventDisplayCustomization();
|
const { eventDidMount } = useEventDisplayCustomization();
|
||||||
const editingProps = useEditing(note, isEditable, isCalendarRoot);
|
const editingProps = useEditing(note, isEditable, isCalendarRoot);
|
||||||
|
|
||||||
|
// React to changes.
|
||||||
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
|
if (loadResults.getNoteIds().some(noteId => noteIds.includes(noteId)) // note title change.
|
||||||
|
|| loadResults.getAttributeRows().some((a) => noteIds.includes(a.noteId ?? ""))) // subnote change.
|
||||||
|
{
|
||||||
|
calendarRef.current?.refetchEvents();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (plugins &&
|
return (plugins &&
|
||||||
<div className="calendar-view" ref={containerRef}>
|
<div className="calendar-view" ref={containerRef}>
|
||||||
<Calendar
|
<Calendar
|
||||||
|
|||||||
@ -39,28 +39,6 @@ export default class CalendarView extends ViewMode<{}> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async onEntitiesReloaded({ loadResults }: EventData<"entitiesReloaded">) {
|
|
||||||
// Refresh note IDs if they got changed.
|
|
||||||
if (loadResults.getBranchRows().some((branch) => branch.parentNoteId === this.parentNote.noteId)) {
|
|
||||||
this.noteIds = this.parentNote.getChildNoteIds();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh calendar on attribute change.
|
|
||||||
if (loadResults.getAttributeRows().some((attribute) => attribute.noteId === this.parentNote.noteId && attribute.name?.startsWith("calendar:") && attribute.name !== "calendar:view")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh on note title change.
|
|
||||||
if (loadResults.getNoteIds().some(noteId => this.noteIds.includes(noteId))) {
|
|
||||||
this.calendar?.refetchEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh dataset on subnote change.
|
|
||||||
if (loadResults.getAttributeRows().some((a) => this.noteIds.includes(a.noteId ?? ""))) {
|
|
||||||
this.calendar?.refetchEvents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildTouchBarCommand({ TouchBar, buildIcon }: CommandListenerData<"buildTouchBar">) {
|
buildTouchBarCommand({ TouchBar, buildIcon }: CommandListenerData<"buildTouchBar">) {
|
||||||
if (!this.calendar) {
|
if (!this.calendar) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user