update settings

This commit is contained in:
Alex Holliday committed 2024-09-27 12:13:39 +08:00
1 parent 488ba717ac
commit 5c4d094da7
6 files changed
+126 -13

No files matched your search

+10
View File
@@ -37,6 +37,8 @@ import { CssBaseline } from "@mui/material";
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { getAppSettings } from "./Features/Settings/settingsSlice";
import { logger } from "./Utils/Logger"; // Import the logger
import { networkService } from "./main";
function App() {
const AdminCheckedRegister = withAdminCheck(Register);
const MonitorsWithAdminProp = withAdminProp(Monitors);
@@ -54,6 +56,14 @@ function App() {
dispatch(getAppSettings(authToken));
}, [dispatch, authToken]);
// Cleanup
useEffect(() => {
return () => {
logger.cleanup();
networkService.cleanup();
};
}, []);
return (
<ThemeProvider theme={mode === "light" ? lightTheme : darkTheme}>
<CssBaseline />
+23 -4
View File
@@ -1,7 +1,5 @@
import { networkService } from "../../main";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { jwtDecode } from "jwt-decode";
import axios from "axios";
const initialState = {
isLoading: false,
@@ -44,9 +42,29 @@ export const getAppSettings = createAsyncThunk(
export const updateAppSettings = createAsyncThunk(
"settings/updateSettings",
async (form, thunkApi) => {
async ({ settings, authToken }, thunkApi) => {
networkService.setBaseUrl(settings.apiBaseUrl);
try {
const res = await networkService.loginUser(form);
const parsedSettings = {
apiBaseUrl: settings.apiBaseUrl,
logLevel: settings.logLevel,
clientHost: settings.clientHost,
jwtSecret: settings.jwtSecret,
dbType: settings.dbType,
dbConnectionString: settings.dbConnectionString,
redisHost: settings.redisHost,
redisPort: settings.redisPort,
jwtTTL: settings.jwtTTL,
pagespeedApiKey: settings.pagespeedApiKey,
systemEmailHost: settings.systemEmailHost,
systemEmailPort: settings.systemEmailPort,
systemEmailAddress: settings.systemEmailAddress,
systemEmailPassword: settings.systemEmailPassword,
};
const res = await networkService.updateAppSettings({
settings: parsedSettings,
authToken,
});
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -76,6 +94,7 @@ const handleUpdateSettingsFulfilled = (state, action) => {
state.isLoading = false;
state.success = action.payload.success;
state.msg = action.payload.msg;
Object.assign(state, action.payload.data);
};
const handleUpdateSettingsRejected = (state, action) => {
state.isLoading = false;
+32 -4
View File
@@ -10,16 +10,20 @@ import PropTypes from "prop-types";
import LoadingButton from "@mui/lab/LoadingButton";
import { ConfigBox } from "../Settings/styled";
import { useNavigate } from "react-router";
import { getAppSettings } from "../../Features/Settings/settingsSlice";
import {
getAppSettings,
updateAppSettings,
} from "../../Features/Settings/settingsSlice";
import { useEffect, useState } from "react";
import Select from "../../Components/Inputs/Select";
const AdvancedSettings = ({ isAdmin }) => {
const theme = useTheme();
const { user, authToken } = useSelector((state) => state.auth);
const dispatch = useDispatch();
const navigate = useNavigate();
const settings = useSelector((state) => state.settings);
const [localSettings, setLocalSettings] = useState(settings);
const logItems = [
{ _id: 1, name: "none" },
{ _id: 2, name: "debug" },
@@ -45,6 +49,19 @@ const AdvancedSettings = ({ isAdmin }) => {
setLocalSettings({ ...localSettings, [id]: value });
};
const handleSave = async () => {
const action = await dispatch(
updateAppSettings({ settings: localSettings, authToken })
);
let body = "";
if (action.payload.success) {
body = "Settings saved successfully";
} else {
body = "Failed to save settings";
}
createToast({ body });
};
return (
<Box
className="settings"
@@ -68,9 +85,9 @@ const AdvancedSettings = ({ isAdmin }) => {
</Box>
<Stack gap={theme.spacing(20)}>
<Field
id="clientHost"
id="apiBaseUrl"
label="Client Host"
value={localSettings.clientHost}
value={localSettings.apiBaseUrl}
onChange={handleChange}
/>
<Select
@@ -144,6 +161,17 @@ const AdvancedSettings = ({ isAdmin }) => {
/>
</Box>
</ConfigBox>
<Stack direction="row" justifyContent="flex-end">
<LoadingButton
loading={settings.isLoading || settings.authIsLoading}
variant="contained"
color="primary"
sx={{ px: theme.spacing(12), mt: theme.spacing(20) }}
onClick={handleSave}
>
Save
</LoadingButton>
</Stack>
</Stack>
</Box>
);
+19 -3
View File
@@ -1,6 +1,16 @@
const LOG_LEVEL = import.meta.env.VITE_APP_LOG_LEVEL;
import store from "../store";
const LOG_LEVEL = import.meta.env.VITE_APP_LOG_LEVEL || "debug";
class Logger {
constructor(logLevel) {
constructor() {
let logLevel = LOG_LEVEL;
this.unsubscribe = store.subscribe(() => {
const state = store.getState();
logLevel = state.settings.logLevel || "debug";
this.updateLogLevel(logLevel);
});
}
updateLogLevel(logLevel) {
const NO_OP = () => {};
if (logLevel === "none") {
@@ -25,6 +35,12 @@ class Logger {
}
this.log = console.log.bind(console);
}
cleanup() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
}
export const logger = new Logger(LOG_LEVEL);
export const logger = new Logger();
+41 -2
View File
@@ -1,10 +1,18 @@
import axios from "axios";
const BASE_URL = import.meta.env.VITE_APP_API_BASE_URL;
const BASE_URL =
import.meta.env.VITE_APP_API_BASE_URL || "http://localhost:5000/api/v1";
import { logger } from "./Logger";
class NetworkService {
constructor(store) {
this.store = store;
this.axiosInstance = axios.create({ baseURL: BASE_URL });
let baseURL = BASE_URL;
this.axiosInstance = axios.create();
this.setBaseUrl(baseURL);
this.unsubscribe = store.subscribe(() => {
const state = store.getState();
baseURL = state.settings.apiBaseUrl || BASE_URL;
this.setBaseUrl(baseURL);
});
this.axiosInstance.interceptors.response.use(
(response) => response,
(error) => {
@@ -17,6 +25,16 @@ class NetworkService {
);
}
setBaseUrl = (url) => {
this.axiosInstance.defaults.baseURL = url;
};
cleanup() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
/**
*
* ************************************
@@ -640,6 +658,27 @@ class NetworkService {
},
});
}
/**
*
* ************************************
* Create a new monitor
* ************************************
*
* @async
* @param {Object} config - The configuration object.
* @param {string} config.authToken - The authorization token to be used in the request header.
* @param {Object} config.settings - The monitor object to be sent in the request body.
* @returns {Promise<AxiosResponse>} The response from the axios POST request.
*/
async updateAppSettings(config) {
return this.axiosInstance.put(`/settings`, config.settings, {
headers: {
Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
});
}
}
export default NetworkService;
+1
View File
@@ -51,3 +51,4 @@ export const store = configureStore({
});
export const persistor = persistStore(store);
export default store;