import { Dispatch, StateUpdater, useEffect, useMemo, useRef, useState } from "preact/hooks"; import FNote from "../../entities/fnote"; import { LaunchBarDropdownButton, useLauncherIconAndTitle } from "./launch_bar_widgets"; import { Dayjs, dayjs } from "@triliumnext/commons"; import appContext from "../../components/app_context"; import "./CalendarWidget.css"; import Calendar, { CalendarArgs } from "./Calendar"; import ActionButton from "../react/ActionButton"; import { t } from "../../services/i18n"; import FormDropdownList from "../react/FormDropdownList"; import FormTextBox from "../react/FormTextBox"; import toast from "../../services/toast"; import date_notes from "../../services/date_notes"; import { Dropdown } from "bootstrap"; import search from "../../services/search"; import server from "../../services/server"; const MONTHS = [ t("calendar.january"), t("calendar.february"), t("calendar.march"), t("calendar.april"), t("calendar.may"), t("calendar.june"), t("calendar.july"), t("calendar.august"), t("calendar.september"), t("calendar.october"), t("calendar.november"), t("calendar.december") ]; export default function CalendarWidget({ launcherNote }: { launcherNote: FNote }) { const { title, icon } = useLauncherIconAndTitle(launcherNote); const [ calendarArgs, setCalendarArgs ] = useState>(); const [ date, setDate ] = useState(); const dropdownRef = useRef(null); const [ enableWeekNotes, setEnableWeekNotes ] = useState(false); const [ weekNotes, setWeekNotes ] = useState([]); const calendarRootRef = useRef(); async function checkEnableWeekNotes() { if (!calendarRootRef.current) { const notes = await search.searchForNotes("#calendarRoot"); if (!notes.length) return; calendarRootRef.current = notes[0]; } if (!calendarRootRef.current) return; const enableWeekNotes = calendarRootRef.current.hasLabel("enableWeekNote"); setEnableWeekNotes(enableWeekNotes); if (enableWeekNotes) { server.get(`attribute-values/weekNote`).then(setWeekNotes); } } return ( { const dateNote = appContext.tabManager.getActiveContextNote()?.getOwnedLabelValue("dateNote"); const activeDate = dateNote ? dayjs(`${dateNote}T12:00:00`) : null const todaysDate = dayjs(); setCalendarArgs({ activeDate, todaysDate, }); setDate(dayjs(activeDate || todaysDate).startOf('month')); checkEnableWeekNotes(); }} dropdownRef={dropdownRef} dropdownOptions={{ autoClose: "outside" }} > {calendarArgs && date &&
{ const note = await date_notes.getDayNote(date); if (note) { appContext.tabManager.getActiveContext()?.setNote(note.noteId); dropdownRef.current?.hide(); } else { toast.showError(t("calendar.cannot_find_day_note")); } e.stopPropagation(); }} onWeekClicked={enableWeekNotes ? async (week, e) => { const note = await date_notes.getWeekNote(week); if (note) { appContext.tabManager.getActiveContext()?.setNote(note.noteId); dropdownRef.current?.hide(); } else { toast.showError(t("calendar.cannot_find_week_note")); } e.stopPropagation(); } : undefined} weekNotes={weekNotes} {...calendarArgs} />
}
) } interface CalendarHeaderProps { date: Dayjs; setDate: Dispatch>; } function CalendarHeader(props: CalendarHeaderProps) { return (
) } function CalendarMonthSelector({ date, setDate }: CalendarHeaderProps) { const months = useMemo(() => ( Array.from(MONTHS.entries().map(([ index, text ]) => ({ index: index.toString(), text }))) ), []); return (
{ }} buttonProps={{ "data-calendar-input": "month" }} />
); } function CalendarYearSelector({ date, setDate }: CalendarHeaderProps) { return (
{ const year = parseInt(newValue, 10); if (!Number.isNaN(year)) { setDate(date.set("year", year)); } }} data-calendar-input="year" />
) } function AdjustDateButton({ date, setDate, unit, direction }: CalendarHeaderProps & { direction: "prev" | "next", unit: "month" | "year" }) { return ( { e.stopPropagation(); const newDate = direction === "prev" ? date.subtract(1, unit) : date.add(1, unit); setDate(newDate); }} /> ) }