* [#341] added show week number toggle
This commit is contained in:
@@ -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()}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -220,6 +220,8 @@
|
||||
"notifications.email": "Email",
|
||||
"notifications.deliveryMethod": "Способ доставки",
|
||||
"alarmEmailsUpdateError": "Не удалось обновить настройки уведомлений по email",
|
||||
"displayWeekNumbers": "Показать номер недели",
|
||||
"displayWeekNumbersUpdateError": "Не удалось обновить отображение номера недели",
|
||||
"sync.empty": "Настройки синхронизации скоро появятся",
|
||||
"calAndEvent": "Календарь и мероприятия",
|
||||
"showDeclinedEvent": "Показать отклонённые мероприятия",
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user