* feat: #333 load language from backend configuration * feat(settings): sync language with user configs api * Update __test__/features/Settings/SettingsPage.test.tsx Co-authored-by: Lê Nhân Phụng <lenhanphung@Phung-Mac-M4.local> Co-authored-by: Benoit TELLIER <btellier@linagora.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -33,3 +33,38 @@ export async function getUserDetails(id: string) {
|
||||
const user = await api.get(`api/users/${id}`).json();
|
||||
return user;
|
||||
}
|
||||
|
||||
export interface UserConfigurationUpdates {
|
||||
language?: string;
|
||||
notifications?: Record<string, unknown>;
|
||||
timezone?: string;
|
||||
}
|
||||
|
||||
export async function updateUserConfigurations(
|
||||
updates: UserConfigurationUpdates
|
||||
): Promise<Response | { status: number }> {
|
||||
const coreConfigs: Array<{ name: string; value: any }> = [];
|
||||
|
||||
if (updates.language !== undefined) {
|
||||
coreConfigs.push({ name: "language", value: updates.language });
|
||||
}
|
||||
if (updates.notifications !== undefined) {
|
||||
coreConfigs.push({ name: "notifications", value: updates.notifications });
|
||||
}
|
||||
if (updates.timezone !== undefined) {
|
||||
coreConfigs.push({ name: "timezone", value: updates.timezone });
|
||||
}
|
||||
|
||||
if (coreConfigs.length === 0) {
|
||||
return Promise.resolve({ status: 204 });
|
||||
}
|
||||
|
||||
return await api.patch(`api/configurations?scope=user`, {
|
||||
json: [
|
||||
{
|
||||
name: "core",
|
||||
configurations: coreConfigs,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,8 +6,28 @@ export interface userData {
|
||||
sid: string;
|
||||
sub: string;
|
||||
openpaasId?: string;
|
||||
language?: string;
|
||||
}
|
||||
|
||||
export interface UserConfigurations {
|
||||
modules?: Array<{
|
||||
name: string;
|
||||
configurations?: Array<{
|
||||
name: string;
|
||||
value: any;
|
||||
}>;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface NotificationSettings {
|
||||
email?: boolean;
|
||||
push?: boolean;
|
||||
}
|
||||
|
||||
export type NotificationSettingsExtended = NotificationSettings & {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export interface userOrganiser {
|
||||
cn: string;
|
||||
cal_address: string;
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
||||
import { userData, userOrganiser } from "./userDataTypes";
|
||||
import { getOpenPaasUser } from "./userAPI";
|
||||
import {
|
||||
getOpenPaasUser,
|
||||
updateUserConfigurations,
|
||||
UserConfigurationUpdates,
|
||||
} from "./userAPI";
|
||||
import { formatReduxError } from "../../utils/errorUtils";
|
||||
|
||||
export const getOpenPaasUserDataAsync = createAsyncThunk<
|
||||
Record<string, string>,
|
||||
Record<string, any>,
|
||||
void,
|
||||
{ rejectValue: { message: string; status?: number } }
|
||||
>("user/getOpenPaasUserData", async (_, { rejectWithValue }) => {
|
||||
try {
|
||||
const user = (await getOpenPaasUser()) as Record<string, string>;
|
||||
const user = (await getOpenPaasUser()) as Record<string, any>;
|
||||
return user;
|
||||
} catch (err: any) {
|
||||
return rejectWithValue({
|
||||
@@ -19,12 +23,29 @@ export const getOpenPaasUserDataAsync = createAsyncThunk<
|
||||
}
|
||||
});
|
||||
|
||||
export const updateUserConfigurationsAsync = createAsyncThunk<
|
||||
UserConfigurationUpdates,
|
||||
UserConfigurationUpdates,
|
||||
{ rejectValue: { message: string; status?: number } }
|
||||
>("user/updateConfigurations", async (updates, { rejectWithValue }) => {
|
||||
try {
|
||||
await updateUserConfigurations(updates);
|
||||
return updates;
|
||||
} catch (err: any) {
|
||||
return rejectWithValue({
|
||||
message: formatReduxError(err),
|
||||
status: err.response?.status,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export const userSlice = createSlice({
|
||||
name: "user",
|
||||
initialState: {
|
||||
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,
|
||||
loading: true,
|
||||
error: null as unknown as string | null,
|
||||
},
|
||||
@@ -41,6 +62,12 @@ export const userSlice = createSlice({
|
||||
setTokens: (state, action) => {
|
||||
state.tokens = action.payload;
|
||||
},
|
||||
setLanguage: (state, action) => {
|
||||
state.language = action.payload;
|
||||
if (state.userData) {
|
||||
state.userData.language = action.payload;
|
||||
}
|
||||
},
|
||||
clearError: (state) => {
|
||||
state.error = null;
|
||||
},
|
||||
@@ -62,6 +89,22 @@ export const userSlice = createSlice({
|
||||
state.organiserData.cal_address = action.payload.preferredEmail;
|
||||
state.userData.email = action.payload.preferredEmail;
|
||||
}
|
||||
|
||||
// Extract language from configurations.modules
|
||||
if (action.payload.configurations?.modules) {
|
||||
const coreModule = action.payload.configurations.modules.find(
|
||||
(module: any) => module.name === "core"
|
||||
);
|
||||
if (coreModule?.configurations) {
|
||||
const languageConfig = coreModule.configurations.find(
|
||||
(config: any) => config.name === "language"
|
||||
);
|
||||
if (languageConfig?.value) {
|
||||
state.language = languageConfig.value;
|
||||
state.userData.language = languageConfig.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.addCase(getOpenPaasUserDataAsync.pending, (state) => {
|
||||
state.loading = true;
|
||||
@@ -72,11 +115,26 @@ export const userSlice = createSlice({
|
||||
state.error =
|
||||
action.payload?.message || "Failed to fetch user information";
|
||||
}
|
||||
})
|
||||
.addCase(updateUserConfigurationsAsync.fulfilled, (state, action) => {
|
||||
if (action.payload.language !== undefined) {
|
||||
state.language = action.payload.language;
|
||||
if (state.userData) {
|
||||
state.userData.language = action.payload.language;
|
||||
}
|
||||
}
|
||||
})
|
||||
.addCase(updateUserConfigurationsAsync.rejected, (state, action) => {
|
||||
if (action.payload?.status !== 401) {
|
||||
state.error =
|
||||
action.payload?.message || "Failed to update user configurations";
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Action creators are generated for each case reducer function
|
||||
export const { setUserData, setTokens, clearError } = userSlice.actions;
|
||||
export const { setUserData, setTokens, setLanguage, clearError } =
|
||||
userSlice.actions;
|
||||
|
||||
export default userSlice.reducer;
|
||||
|
||||
Reference in New Issue
Block a user