diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index 2f7a078..3dac1b1 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -82,6 +82,9 @@ export default function CalendarApp({ (state) => state.settings.hideDeclinedEvents ); const calendars = useAppSelector((state) => state.calendars.list); + const displayWeekNumbers = useAppSelector( + (state) => state.settings.displayWeekNumbers + ); const tempcalendars = useAppSelector((state) => state.calendars.templist); const [selectedCalendars, setSelectedCalendars] = useState([]); @@ -689,9 +692,11 @@ export default function CalendarApp({ weekNumberContent={(arg) => { return (
-
- {t("menubar.views.week")} {arg.num} -
+ {displayWeekNumbers && ( +
+ {t("menubar.views.week")} {arg.num} +
+ )} state.settings?.hideDeclinedEvents ); + const displayWeekNumbers = useAppSelector( + (state) => state.settings?.displayWeekNumbers + ); + const [activeNavItem, setActiveNavItem] = useState("settings"); const [activeSettingsSubTab, setActiveSettingsSubTab] = @@ -83,7 +88,8 @@ export default function SettingsPage() { const [alarmEmailsErrorOpen, setAlarmEmailsErrorOpen] = useState(false); const [hideDeclinedEventsErrorOpen, setHideDeclinedEventsErrorOpen] = useState(false); - + const [displayWeekNumbersErrorOpen, setDisplayWeekNumbersErrorOpen] = + useState(false); const handleBackClick = () => { dispatch(setView("calendar")); }; @@ -221,6 +227,27 @@ export default function SettingsPage() { setAlarmEmailsErrorOpen(false); }; + const handleDisplayWeekNumbers = (doDisplayWeekNumbers: boolean) => { + // Optimistic update - update UI immediately + dispatch(setDisplayWeekNumbers(doDisplayWeekNumbers)); + + // Call API in background, don't wait for it + dispatch( + updateUserConfigurationsAsync({ + displayWeekNumbers: doDisplayWeekNumbers, + }) + ) + .unwrap() + .catch((error) => { + console.error("Failed to update the week number setting:", error); + dispatch(setDisplayWeekNumbers(!doDisplayWeekNumbers)); + setDisplayWeekNumbersErrorOpen(true); + }); + }; + const handleDisplayWeekNumbersErrorClose = () => { + setDisplayWeekNumbersErrorOpen(false); + }; + return (
@@ -344,37 +371,48 @@ export default function SettingsPage() { - + {t("settings.calAndEvent")} - - - - handleHideDeclinedEvents(!hideDeclinedEvents) - } - aria-label={t("settings.showDeclinedEvent")} - /> - } - label={t("settings.showDeclinedEvent")} - labelPlacement="start" - sx={{ - minWidth: 400, - justifyContent: "space-between", - marginLeft: 0, - mb: 2, - }} - /> - - + + + handleHideDeclinedEvents(!hideDeclinedEvents) + } + aria-label={t("settings.showDeclinedEvent")} + /> + } + label={t("settings.showDeclinedEvent")} + labelPlacement="start" + sx={{ + minWidth: 400, + justifyContent: "space-between", + marginLeft: 0, + }} + /> + + handleDisplayWeekNumbers(!displayWeekNumbers) + } + aria-label={t("settings.displayWeekNumbers")} + /> + } + label={t("settings.displayWeekNumbers")} + labelPlacement="start" + sx={{ + minWidth: 400, + justifyContent: "space-between", + marginLeft: 0, + }} + /> + )} @@ -449,6 +487,12 @@ export default function SettingsPage() { onClose={handleHideDeclinedEventsErrorClose} message={t("settings.hideDeclinedEventsUpdateError")} /> +
); } diff --git a/src/features/Settings/SettingsSlice.ts b/src/features/Settings/SettingsSlice.ts index ceeef47..51bfe2b 100644 --- a/src/features/Settings/SettingsSlice.ts +++ b/src/features/Settings/SettingsSlice.ts @@ -7,6 +7,7 @@ export interface SettingsState { timeZone: string | null; // Allow null to represent browser default isBrowserDefaultTimeZone: boolean; hideDeclinedEvents: boolean | null; + displayWeekNumbers: boolean; view: "calendar" | "settings" | "search"; } @@ -23,6 +24,7 @@ const initialState: SettingsState = { timeZone: defaultTimeZone, isBrowserDefaultTimeZone: defaultTimeZone === null, hideDeclinedEvents: null, + displayWeekNumbers: true, view: "calendar", }; @@ -44,6 +46,9 @@ export const settingsSlice = createSlice({ setHideDeclinedEvents: (state, action: PayloadAction) => { state.hideDeclinedEvents = action.payload; }, + setDisplayWeekNumbers: (state, action: PayloadAction) => { + state.displayWeekNumbers = action.payload; + }, setView: ( state, action: PayloadAction<"calendar" | "settings" | "search"> @@ -80,6 +85,18 @@ export const settingsSlice = createSlice({ typeof hideDeclinedEventsConfig?.value === "boolean" ? hideDeclinedEventsConfig.value : null; + + const calendarModule = action.payload.configurations.modules.find( + (module: any) => module.name === "calendar" + ); + if (calendarModule?.configurations) { + const alarmEmailsConfig = calendarModule.configurations.find( + (config: any) => config.name === "displayWeekNumbers" + ); + if (alarmEmailsConfig) { + state.displayWeekNumbers = alarmEmailsConfig.value === true; + } + } }); }, }); @@ -90,5 +107,6 @@ export const { setView, setIsBrowserDefaultTimeZone, setHideDeclinedEvents, + setDisplayWeekNumbers, } = settingsSlice.actions; export default settingsSlice.reducer; diff --git a/src/features/User/userAPI.ts b/src/features/User/userAPI.ts index 30de28f..2a21b99 100644 --- a/src/features/User/userAPI.ts +++ b/src/features/User/userAPI.ts @@ -38,6 +38,7 @@ export interface UserConfigurationUpdates { language?: string; notifications?: Record; timezone?: string | null; + displayWeekNumbers?: boolean; previousConfig?: Record; alarmEmails?: boolean; hideDeclinedEvents?: boolean; @@ -77,6 +78,12 @@ export async function updateUserConfigurations( value: updates.hideDeclinedEvents, }); } + if (updates.displayWeekNumbers !== undefined) { + calendarConfigs.push({ + name: "displayWeekNumbers", + value: updates.displayWeekNumbers, + }); + } const modules: Array<{ name: string; diff --git a/src/locales/en.json b/src/locales/en.json index 74f5fe5..4f9c8be 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -220,6 +220,8 @@ "notifications.email": "Email", "notifications.deliveryMethod": "Delivery method", "alarmEmailsUpdateError": "Failed to update email notifications setting", + "displayWeekNumbers": "Show week number", + "displayWeekNumbersUpdateError": "Failed to update show week number", "sync.empty": "Sync settings coming soon", "calAndEvent": "Calendar and events", "showDeclinedEvent": "Show declined events", diff --git a/src/locales/fr.json b/src/locales/fr.json index 3a4e4e6..9c48286 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -220,6 +220,8 @@ "notifications.email": "Email", "notifications.deliveryMethod": "Mode de réception", "alarmEmailsUpdateError": "Échec de la mise à jour du mode de notification par e-mail", + "displayWeekNumbers": "Afficher le numéro de la semaine", + "displayWeekNumbersUpdateError": "Échec de la mise à jour de l'affichage du numéro de la semaine", "sync.empty": "Paramètres de synchronisation à venir", "calAndEvent": "Calendrier et événements", "showDeclinedEvent": "Afficher les événements déclinés", diff --git a/src/locales/ru.json b/src/locales/ru.json index c2f7bae..b8b7b16 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -220,6 +220,8 @@ "notifications.email": "Email", "notifications.deliveryMethod": "Способ доставки", "alarmEmailsUpdateError": "Не удалось обновить настройки уведомлений по email", + "displayWeekNumbers": "Показать номер недели", + "displayWeekNumbersUpdateError": "Не удалось обновить отображение номера недели", "sync.empty": "Настройки синхронизации скоро появятся", "calAndEvent": "Календарь и мероприятия", "showDeclinedEvent": "Показать отклонённые мероприятия", diff --git a/src/locales/vi.json b/src/locales/vi.json index 7302e52..79abf42 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -220,6 +220,8 @@ "notifications.email": "Email", "notifications.deliveryMethod": "Phương thức gửi", "alarmEmailsUpdateError": "Cập nhật cài đặt thông báo email thất bại", + "displayWeekNumbers": "Hiển thị số tuần", + "displayWeekNumbersUpdateError": "Không cập nhật được cách hiển thị số tuần", "sync.empty": "Cài đặt đồng bộ sắp có", "calAndEvent": "Lịch và sự kiện", "showDeclinedEvent": "Hiển thị các sự kiện đã từ chối",