update settings
This commit is contained in:
1 parent
488ba717ac
commit
5c4d094da7
6 files changed
+126
-13
No files matched your search
@@ -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 />
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
@@ -51,3 +51,4 @@ export const store = configureStore({
|
||||
});
|
||||
|
||||
export const persistor = persistStore(store);
|
||||
export default store;
|
||||
Reference in new issue
Block a user