From afc17f41f6022a0699883efb62334c0732744b87 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Sep 2025 12:26:42 +0300 Subject: [PATCH] feat(collections/calendar): use own UI for header --- apps/client/src/stylesheets/style.css | 5 ++ .../src/translations/en/translation.json | 12 ++- .../widgets/collections/calendar/index.css | 19 ++++- .../widgets/collections/calendar/index.tsx | 75 ++++++++++++++++--- .../client/src/widgets/react/ActionButton.tsx | 13 ++-- apps/client/src/widgets/react/Button.tsx | 12 ++- 6 files changed, 116 insertions(+), 20 deletions(-) diff --git a/apps/client/src/stylesheets/style.css b/apps/client/src/stylesheets/style.css index 2aefbbc01..a3e08ff59 100644 --- a/apps/client/src/stylesheets/style.css +++ b/apps/client/src/stylesheets/style.css @@ -293,6 +293,11 @@ button.close:hover { pointer-events: none; } +.icon-action.btn { + padding: 0 8px; + min-width: unset !important; +} + .ui-widget-content a:not(.ui-tabs-anchor) { color: #337ab7 !important; } diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index 81c0cacc7..d10669b46 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -587,7 +587,17 @@ "september": "September", "october": "October", "november": "November", - "december": "December" + "december": "December", + "week": "Week", + "week_previous": "Previous week", + "week_next": "Next week", + "month": "Month", + "month_previous": "Previous month", + "month_next": "Next month", + "year": "Year", + "year_previous": "Previous year", + "year_next": "Next year", + "list": "List" }, "close_pane_button": { "close_this_pane": "Close this pane" diff --git a/apps/client/src/widgets/collections/calendar/index.css b/apps/client/src/widgets/collections/calendar/index.css index 69b116a18..2f4103106 100644 --- a/apps/client/src/widgets/collections/calendar/index.css +++ b/apps/client/src/widgets/collections/calendar/index.css @@ -59,4 +59,21 @@ body.desktop:not(.zen) .calendar-container .fc-toolbar.fc-header-toolbar { font-size: 0.85em; opacity: 0.85; overflow: hidden; -} \ No newline at end of file +} + +/* #region Header */ +.calendar-header { + margin-bottom: 10px; + display: flex; + align-items: center; + gap: 10px; +} + +.calendar-header .btn { + min-width: unset !important; +} + +.calendar-header > .title { + flex-grow: 1; +} +/* #endregion */ \ No newline at end of file diff --git a/apps/client/src/widgets/collections/calendar/index.tsx b/apps/client/src/widgets/collections/calendar/index.tsx index 19ff79040..a135fa904 100644 --- a/apps/client/src/widgets/collections/calendar/index.tsx +++ b/apps/client/src/widgets/collections/calendar/index.tsx @@ -16,18 +16,50 @@ import date_notes from "../../../services/date_notes"; import appContext from "../../../components/app_context"; import { DateClickArg } from "@fullcalendar/interaction"; import FNote from "../../../entities/fnote"; +import Button, { ButtonGroup } from "../../react/Button"; +import ActionButton from "../../react/ActionButton"; +import { RefObject } from "preact"; interface CalendarViewData { } +interface CalendarViewData { + type: string; + name: string; + previousText: string; + nextText: string; +} + const CALENDAR_VIEWS = [ - "timeGridWeek", - "dayGridMonth", - "multiMonthYear", - "listMonth" + { + type: "timeGridWeek", + name: t("calendar.week"), + previousText: t("calendar.week_previous"), + nextText: t("calendar.week_next") + }, + { + type: "dayGridMonth", + name: t("calendar.month"), + previousText: t("calendar.month_previous"), + nextText: t("calendar.month_next") + }, + { + type: "multiMonthYear", + name: t("calendar.year"), + previousText: t("calendar.year_previous"), + nextText: t("calendar.year_next") + }, + { + type: "listMonth", + name: t("calendar.list"), + previousText: t("calendar.month_previous"), + nextText: t("calendar.month_next") + } ] +const SUPPORTED_CALENDAR_VIEW_TYPE = CALENDAR_VIEWS.map(v => v.type); + // Here we hard-code the imports in order to ensure that they are embedded by webpack without having to load all the languages. export const LOCALE_MAPPINGS: Record Promise<{ default: LocaleInput }>) | null> = { de: () => import("@fullcalendar/core/locales/de"), @@ -83,20 +115,18 @@ export default function CalendarView({ note, noteIds }: ViewModeProps + }) { + const currentViewType = calendarRef.current?.view?.type; + const currentViewData = CALENDAR_VIEWS.find(v => calendarRef.current && v.type === currentViewType); + + return ( +
+ {calendarRef.current?.view.title} + + {CALENDAR_VIEWS.map(viewData => ( +
+ ) +} + function usePlugins(isEditable: boolean, isCalendarRoot: boolean) { const [ plugins, setPlugins ] = useState(); diff --git a/apps/client/src/widgets/react/ActionButton.tsx b/apps/client/src/widgets/react/ActionButton.tsx index 5e6f3266b..2eb69bab8 100644 --- a/apps/client/src/widgets/react/ActionButton.tsx +++ b/apps/client/src/widgets/react/ActionButton.tsx @@ -11,18 +11,19 @@ export interface ActionButtonProps { onClick?: (e: MouseEvent) => void; triggerCommand?: CommandNames; noIconActionClass?: boolean; + frame?: boolean; } -export default function ActionButton({ text, icon, className, onClick, triggerCommand, titlePosition, noIconActionClass }: ActionButtonProps) { +export default function ActionButton({ text, icon, className, onClick, triggerCommand, titlePosition, noIconActionClass, frame }: ActionButtonProps) { const buttonRef = useRef(null); const [ keyboardShortcut, setKeyboardShortcut ] = useState(); - + useStaticTooltip(buttonRef, { title: keyboardShortcut?.length ? `${text} (${keyboardShortcut?.join(",")})` : text, placement: titlePosition ?? "bottom", fallbackPlacements: [ titlePosition ?? "bottom" ] }); - + useEffect(() => { if (triggerCommand) { keyboard_actions.getAction(triggerCommand, true).then(action => setKeyboardShortcut(action?.effectiveShortcuts)); @@ -31,8 +32,8 @@ export default function ActionButton({ text, icon, className, onClick, triggerCo return