Merge pull request #2217 from bluewave-labs/feat/add-pagespeedapikey-settings

Feature - Add/Reset PageSpeed API key in Settings
This commit is contained in:
Alexander Holliday authored and GitHub committed 2025-05-08 11:51:42 -07:00
commit 04143c13e3
5 files changed
+98 -13

No files matched your search

@@ -104,6 +104,7 @@ const TextInput = forwardRef(
fontSize={"var(--env-var-font-size-medium)"}
color={theme.palette.primary.contrastTextSecondary}
fontWeight={500}
mb={theme.spacing(2)}
>
{label}
{isRequired && <Required />}
@@ -6,6 +6,7 @@ const initialState = {
apiBaseUrl: "",
logLevel: "debug",
language: "gb",
pagespeedApiKey: "",
};
export const getAppSettings = createAsyncThunk(
@@ -33,6 +34,7 @@ export const updateAppSettings = createAsyncThunk(
try {
const parsedSettings = {
language: settings.language,
pagespeedApiKey: settings.pagespeedApiKey,
};
const res = await networkService.updateAppSettings({ settings: parsedSettings });
return res.data;
@@ -56,6 +58,7 @@ const handleGetSettingsFulfilled = (state, action) => {
state.apiBaseUrl = action.payload.data.apiBaseUrl;
state.logLevel = action.payload.data.logLevel;
state.language = action.payload.data.language;
state.pagespeedApiKey = action.payload.data.pagespeedApiKey;
};
const handleGetSettingsRejected = (state, action) => {
state.isLoading = false;
+84 -11
View File
@@ -6,6 +6,8 @@ import Select from "../../Components/Inputs/Select";
import { useIsAdmin } from "../../Hooks/useIsAdmin";
import Dialog from "../../Components/Dialog";
import ConfigBox from "../../Components/ConfigBox";
import { PasswordEndAdornment } from "../../Components/Inputs/TextInput/Adornments";
import { getAppSettings } from "../../Features/Settings/settingsSlice";
// import {
// WalletMultiButton,
// WalletDisconnectButton,
@@ -54,8 +56,11 @@ const Settings = () => {
const [form, setForm] = useState({
enableDistributedUptime: distributedUptimeEnabled,
ttl: checkTTL ? (checkTTL / SECONDS_PER_DAY).toString() : 0,
pagespeedApiKey: "",
});
const [version, setVersion] = useState("unknown");
const [apiKeyFieldType, setApiKeyFieldType] = useState("password");
const [isApiKeySet, setIsApiKeySet] = useState(false);
const [errors, setErrors] = useState({});
const deleteStatsMonitorsInitState = { deleteMonitors: false, deleteStats: false };
const [isOpen, setIsOpen] = useState(deleteStatsMonitorsInitState);
@@ -80,6 +85,28 @@ const Settings = () => {
fetchLatestVersion();
}, []);
useEffect(() => {
dispatch(getAppSettings());
}, []);
const { pagespeedApiKey } = useSelector((state) => state.settings);
useEffect(() => {
if (pagespeedApiKey) {
setIsApiKeySet(true);
setForm((prev) => ({
...prev,
pagespeedApiKey: t("maskedPageSpeedKeyPlaceholder"),
}));
} else {
setIsApiKeySet(false);
setForm((prev) => ({
...prev,
pagespeedApiKey: "",
}));
}
}, [pagespeedApiKey]);
const handleChange = (event) => {
const { type, checked, value, id } = event.target;
@@ -91,12 +118,17 @@ const Settings = () => {
return;
}
let inputValue = value;
if (id === "ttl") {
inputValue = value.replace(/[^0-9]/g, "");
}
const updatedForm = { ...form, [id]: inputValue };
const { error } = settingsValidation.validate(
{ [id]: value },
{
abortEarly: false,
}
updatedForm,
{ abortEarly: false }
);
if (!error || error.details.length === 0) {
setErrors({});
} else {
@@ -107,12 +139,8 @@ const Settings = () => {
setErrors(newErrors);
logger.error("Validation errors:", error.details);
}
let inputValue = value;
id === "ttl" && (inputValue = value.replace(/[^0-9]/g, ""));
setForm((prev) => ({
...prev,
[id]: inputValue,
}));
setForm(updatedForm);
};
// TODO Handle saving
@@ -125,7 +153,7 @@ const Settings = () => {
const updatedUser = { ...user, checkTTL: form.ttl };
const [userAction, settingsAction] = await Promise.all([
dispatch(update({ localData: updatedUser })),
dispatch(updateAppSettings({ settings: { language: language } })),
dispatch(updateAppSettings({ settings: { language: language, pagespeedApiKey: form.pagespeedApiKey } })),
]);
if (userAction.payload.success && settingsAction.payload.success) {
@@ -187,6 +215,14 @@ const Settings = () => {
}
};
const handleResetApiKey = () => {
setIsApiKeySet(false);
setForm((prev) => ({
...prev,
pagespeedApiKey: "",
}));
};
const languages = Object.keys(i18n.options.resources || {});
return (
@@ -277,6 +313,43 @@ const Settings = () => {
</Box>
</ConfigBox>
)} */}
<ConfigBox>
<Box>
<Typography component="h1">{t("pageSpeedApiKeyFieldTitle")}</Typography>
<Typography sx={{ mt: theme.spacing(2), mb: theme.spacing(2) }}>
{t("pageSpeedApiKeyFieldDescription")}
</Typography>
</Box>
<Stack gap={theme.spacing(20)}>
<TextInput
id="pagespeedApiKey"
label={t("pageSpeedApiKeyFieldLabel")}
value={form.pagespeedApiKey}
type={apiKeyFieldType}
onChange={handleChange}
disabled={isApiKeySet}
optionalLabel="(Optional)"
error={!!errors.pagespeedApiKey}
helperText={errors.pagespeedApiKey}
endAdornment={
!isApiKeySet && (
<PasswordEndAdornment
fieldType={apiKeyFieldType}
setFieldType={setApiKeyFieldType}
/>
)
}
/>
{isApiKeySet && (
<Box>
<Typography>{t("pageSpeedApiKeyFieldResetLabel")}</Typography>
<Button onClick={handleResetApiKey} variant="contained" color="error" sx={{ mt: theme.spacing(4) }}>
{t("reset")}
</Button>
</Box>
)}
</Stack>
</ConfigBox>
{/* {isAdmin && (
<ConfigBox>
<Box>
+3 -1
View File
@@ -257,7 +257,9 @@ const settingsValidation = joi.object({
"number.base": "Please enter a valid number",
"any.required": "Please enter a value"
}),
});
pagespeedApiKey: joi.string().allow("").optional(),
})
.unknown(true);
const dayjsValidator = (value, helpers) => {
if (!dayjs(value).isValid()) {
+7 -1
View File
@@ -430,6 +430,12 @@
"noFileSelected": "No file selected",
"fallbackPage": "Import a file to upload a list of servers in bulk"
},
"publicLink": "Public link"
"publicLink": "Public link",
"maskedPageSpeedKeyPlaceholder": "*************************************",
"pageSpeedApiKeyFieldTitle": "Google PageSpeed API key",
"pageSpeedApiKeyFieldLabel": "PageSpeed API key",
"pageSpeedApiKeyFieldDescription": "Enter your Google PageSpeed API key to enable pagespeed monitoring. Click Reset to update the key.",
"pageSpeedApiKeyFieldResetLabel": "API key is set. Click Reset to change it.",
"reset": "Reset"
}