[#337] added timezone loading from backend (#386)

* [#337] added timezone loading from backend

* [#337] changed data structure to allow patching timezone while keeping other datetime params value

* [#337] fixed gap, event create modale sync with settings and added checkbox

* [#337] isBrowserDefaultTimezone is set to true when API return null timezone

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
Camille Moussu
2025-12-04 15:14:43 +01:00
committed by GitHub
parent d8f5f9ae46
commit 193c1a7166
23 changed files with 1021 additions and 109 deletions
+10 -3
View File
@@ -2,8 +2,8 @@ import { User } from "../../components/Attendees/PeopleSearch";
import { api } from "../../utils/apiUtils";
export async function getOpenPaasUser() {
const user = await api.get(`api/user`).json();
return user;
const user = await api.get(`api/user`);
return user.json();
}
export async function searchUsers(
@@ -38,6 +38,7 @@ export interface UserConfigurationUpdates {
language?: string;
notifications?: Record<string, unknown>;
timezone?: string;
previousConfig?: Record<string, any>;
}
export async function updateUserConfigurations(
@@ -52,7 +53,13 @@ export async function updateUserConfigurations(
coreConfigs.push({ name: "notifications", value: updates.notifications });
}
if (updates.timezone !== undefined) {
coreConfigs.push({ name: "timezone", value: updates.timezone });
coreConfigs.push({
name: "datetime",
value: {
...updates.previousConfig?.datetime,
timeZone: updates.timezone,
},
});
}
if (coreConfigs.length === 0) {
+1
View File
@@ -7,6 +7,7 @@ export interface userData {
sub: string;
openpaasId?: string;
language?: string;
timezone?: string | null;
}
export interface UserConfigurations {
+65 -7
View File
@@ -45,7 +45,12 @@ export const userSlice = createSlice({
userData: null as unknown as userData,
organiserData: null as unknown as userOrganiser,
tokens: null as unknown as Record<string, string>,
language: null as string | null,
coreConfig: {
language: null as string | null,
datetime: {
timeZone: null as string | null,
},
} as Record<string, any>,
loading: true,
error: null as unknown as string | null,
},
@@ -63,11 +68,20 @@ export const userSlice = createSlice({
state.tokens = action.payload;
},
setLanguage: (state, action) => {
state.language = action.payload;
state.coreConfig.language = action.payload;
if (state.userData) {
state.userData.language = action.payload;
}
},
setTimezone: (state, action) => {
if (!state.coreConfig.datetime) {
state.coreConfig.datetime = {};
}
state.coreConfig.datetime.timeZone = action.payload;
if (state.userData) {
state.userData.timezone = action.payload;
}
},
clearError: (state) => {
state.error = null;
},
@@ -90,18 +104,53 @@ export const userSlice = createSlice({
state.userData.email = action.payload.preferredEmail;
}
// Extract language from configurations.modules
// Extract data from configurations.modules
if (action.payload.configurations?.modules) {
const coreModule = action.payload.configurations.modules.find(
(module: any) => module.name === "core"
);
if (coreModule?.configurations) {
const newCoreConfig = Object.fromEntries(
coreModule.configurations.map(
(e: { name: string; value: any }) => [e.name, e.value]
)
);
state.coreConfig = {
...state.coreConfig,
...newCoreConfig,
};
const languageConfig = coreModule.configurations.find(
(config: any) => config.name === "language"
);
if (languageConfig?.value) {
state.language = languageConfig.value;
state.userData.language = languageConfig.value;
state.coreConfig.language = languageConfig.value;
if (state.userData)
state.userData.language = languageConfig.value;
}
const datetimeConfig = coreModule.configurations.find(
(config: any) => config.name === "datetime"
);
if (datetimeConfig?.value) {
const serverTimeZone = datetimeConfig.value.timeZone;
state.coreConfig.datetime = {
...state.coreConfig.datetime,
...datetimeConfig.value,
timeZone: serverTimeZone !== undefined ? serverTimeZone : null,
};
if (state.userData) {
state.userData.timezone =
serverTimeZone !== undefined ? serverTimeZone : null;
}
} else {
state.coreConfig.datetime = {
...state.coreConfig.datetime,
timeZone: null,
};
if (state.userData) {
state.userData.timezone = null;
}
}
}
}
@@ -118,11 +167,20 @@ export const userSlice = createSlice({
})
.addCase(updateUserConfigurationsAsync.fulfilled, (state, action) => {
if (action.payload.language !== undefined) {
state.language = action.payload.language;
state.coreConfig.language = action.payload.language;
if (state.userData) {
state.userData.language = action.payload.language;
}
}
if (action.payload.timezone !== undefined) {
if (!state.coreConfig.datetime) {
state.coreConfig.datetime = {};
}
state.coreConfig.datetime.timeZone = action.payload.timezone;
if (state.userData) {
state.userData.timezone = action.payload.timezone;
}
}
})
.addCase(updateUserConfigurationsAsync.rejected, (state, action) => {
if (action.payload?.status !== 401) {
@@ -134,7 +192,7 @@ export const userSlice = createSlice({
});
// Action creators are generated for each case reducer function
export const { setUserData, setTokens, setLanguage, clearError } =
export const { setUserData, setTokens, setLanguage, setTimezone, clearError } =
userSlice.actions;
export default userSlice.reducer;