[#341] added show week number toggle (#399)

* [#341] added show week number toggle
This commit is contained in:
Camille Moussu
2025-12-11 11:41:38 +01:00
committed by GitHub
parent 3cb445ea79
commit e8b1b72901
8 changed files with 114 additions and 32 deletions
+8 -3
View File
@@ -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<string[]>([]);
@@ -689,9 +692,11 @@ export default function CalendarApp({
weekNumberContent={(arg) => {
return (
<div className="weekSelector">
<div>
{t("menubar.views.week")} {arg.num}
</div>
{displayWeekNumbers && (
<div>
{t("menubar.views.week")} {arg.num}
</div>
)}
<TimezoneSelector
value={timezone}
referenceDate={calendarRef.current?.getDate() ?? new Date()}
+73 -29
View File
@@ -26,6 +26,7 @@ import {
setTimeZone as setSettingsTimeZone,
setIsBrowserDefaultTimeZone,
setHideDeclinedEvents,
setDisplayWeekNumbers,
} from "./SettingsSlice";
import {
updateUserConfigurationsAsync,
@@ -74,6 +75,10 @@ export default function SettingsPage() {
(state) => state.settings?.hideDeclinedEvents
);
const displayWeekNumbers = useAppSelector(
(state) => state.settings?.displayWeekNumbers
);
const [activeNavItem, setActiveNavItem] =
useState<SidebarNavItem>("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 (
<main className="main-layout settings-layout">
<Box className="settings-sidebar">
@@ -344,37 +371,48 @@ export default function SettingsPage() {
</FormControl>
</Box>
</Box>
<Box>
<Box sx={{ mb: 6 }}>
<Typography variant="h6" sx={{ mb: 1 }}>
{t("settings.calAndEvent")}
</Typography>
<Box
sx={{
mb: 6,
}}
>
<FormControl size="small" sx={{ minWidth: 500 }}>
<FormControlLabel
control={
<Switch
checked={Boolean(!hideDeclinedEvents)}
onChange={() =>
handleHideDeclinedEvents(!hideDeclinedEvents)
}
aria-label={t("settings.showDeclinedEvent")}
/>
}
label={t("settings.showDeclinedEvent")}
labelPlacement="start"
sx={{
minWidth: 400,
justifyContent: "space-between",
marginLeft: 0,
mb: 2,
}}
/>
</FormControl>
</Box>
<FormControl size="small" sx={{ minWidth: 500 }}>
<FormControlLabel
control={
<Switch
checked={Boolean(!hideDeclinedEvents)}
onChange={() =>
handleHideDeclinedEvents(!hideDeclinedEvents)
}
aria-label={t("settings.showDeclinedEvent")}
/>
}
label={t("settings.showDeclinedEvent")}
labelPlacement="start"
sx={{
minWidth: 400,
justifyContent: "space-between",
marginLeft: 0,
}}
/>
<FormControlLabel
control={
<Switch
checked={Boolean(displayWeekNumbers)}
onChange={() =>
handleDisplayWeekNumbers(!displayWeekNumbers)
}
aria-label={t("settings.displayWeekNumbers")}
/>
}
label={t("settings.displayWeekNumbers")}
labelPlacement="start"
sx={{
minWidth: 400,
justifyContent: "space-between",
marginLeft: 0,
}}
/>
</FormControl>
</Box>
</Box>
)}
@@ -449,6 +487,12 @@ export default function SettingsPage() {
onClose={handleHideDeclinedEventsErrorClose}
message={t("settings.hideDeclinedEventsUpdateError")}
/>
<Snackbar
open={displayWeekNumbersErrorOpen}
autoHideDuration={4000}
onClose={handleDisplayWeekNumbersErrorClose}
message={t("settings.displayWeekNumbersUpdateError")}
/>
</main>
);
}
+18
View File
@@ -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<boolean | null>) => {
state.hideDeclinedEvents = action.payload;
},
setDisplayWeekNumbers: (state, action: PayloadAction<boolean>) => {
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;
+7
View File
@@ -38,6 +38,7 @@ export interface UserConfigurationUpdates {
language?: string;
notifications?: Record<string, unknown>;
timezone?: string | null;
displayWeekNumbers?: boolean;
previousConfig?: Record<string, any>;
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;
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -220,6 +220,8 @@
"notifications.email": "Email",
"notifications.deliveryMethod": "Способ доставки",
"alarmEmailsUpdateError": "Не удалось обновить настройки уведомлений по email",
"displayWeekNumbers": "Показать номер недели",
"displayWeekNumbersUpdateError": "Не удалось обновить отображение номера недели",
"sync.empty": "Настройки синхронизации скоро появятся",
"calAndEvent": "Календарь и мероприятия",
"showDeclinedEvent": "Показать отклонённые мероприятия",
+2
View File
@@ -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",