optimizations

This commit is contained in:
proddy
2025-10-28 22:19:08 +01:00
parent 55b893362c
commit 3abfb7bb9c
93 changed files with 3953 additions and 3361 deletions

View File

@@ -1,4 +1,4 @@
import { useEffect } from 'react';
import { memo, useEffect } from 'react';
import CloseIcon from '@mui/icons-material/Close';
import {
@@ -40,7 +40,7 @@ const GenerateToken = ({ username, onClose }: GenerateTokenProps) => {
if (open) {
void generateToken();
}
}, [open]);
}, [open, generateToken]);
return (
<Dialog
@@ -86,4 +86,4 @@ const GenerateToken = ({ username, onClose }: GenerateTokenProps) => {
);
};
export default GenerateToken;
export default memo(GenerateToken);

View File

@@ -1,4 +1,4 @@
import { useContext, useState } from 'react';
import { memo, useCallback, useContext, useMemo, useState } from 'react';
import { useBlocker } from 'react-router';
import CancelIcon from '@mui/icons-material/Cancel';
@@ -55,14 +55,16 @@ const ManageUsers = () => {
const blocker = useBlocker(changed !== 0);
const { LL } = useI18nContext();
const table_theme = useTheme({
Table: `
const table_theme = useMemo(
() =>
useTheme({
Table: `
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) minmax(120px, max-content) 120px;
`,
BaseRow: `
BaseRow: `
font-size: 14px;
`,
HeaderRow: `
HeaderRow: `
text-transform: uppercase;
background-color: black;
color: #90CAF9;
@@ -72,7 +74,7 @@ const ManageUsers = () => {
border-bottom: 1px solid #565656;
}
`,
Row: `
Row: `
.td {
padding: 8px;
border-top: 1px solid #565656;
@@ -85,7 +87,7 @@ const ManageUsers = () => {
background-color: #1e1e1e;
}
`,
BaseCell: `
BaseCell: `
&:nth-of-type(2) {
text-align: center;
}
@@ -93,72 +95,81 @@ const ManageUsers = () => {
text-align: right;
}
`
});
}),
[]
);
const noAdminConfigured = useCallback(
() => !data?.users.find((u) => u.admin),
[data]
);
const removeUser = useCallback(
(toRemove: UserType) => {
if (!data) return;
const users = data.users.filter((u) => u.username !== toRemove.username);
updateDataValue({ ...data, users });
setChanged(changed + 1);
},
[data, updateDataValue, changed]
);
const createUser = useCallback(() => {
setCreating(true);
setUser({
username: '',
password: '',
admin: true
});
}, []);
const editUser = useCallback((toEdit: UserType) => {
setCreating(false);
setUser({ ...toEdit });
}, []);
const cancelEditingUser = useCallback(() => {
setUser(undefined);
}, []);
const doneEditingUser = useCallback(() => {
if (user && data) {
const users = [
...data.users.filter(
(u: { username: string }) => u.username !== user.username
),
user
];
updateDataValue({ ...data, users });
setUser(undefined);
setChanged(changed + 1);
}
}, [user, data, updateDataValue, changed]);
const closeGenerateToken = useCallback(() => {
setGeneratingToken(undefined);
}, []);
const generateTokenForUser = useCallback((username: string) => {
setGeneratingToken(username);
}, []);
const onSubmit = useCallback(async () => {
await saveData();
await authenticatedContext.refresh();
setChanged(0);
}, [saveData, authenticatedContext]);
const onCancelSubmit = useCallback(async () => {
await loadData();
setChanged(0);
}, [loadData]);
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
}
const noAdminConfigured = () => !data.users.find((u) => u.admin);
const removeUser = (toRemove: UserType) => {
const users = data.users.filter((u) => u.username !== toRemove.username);
updateDataValue({ ...data, users });
setChanged(changed + 1);
};
const createUser = () => {
setCreating(true);
setUser({
username: '',
password: '',
admin: true
});
};
const editUser = (toEdit: UserType) => {
setCreating(false);
setUser({ ...toEdit });
};
const cancelEditingUser = () => {
setUser(undefined);
};
const doneEditingUser = () => {
if (user) {
const users = [
...data.users.filter(
(u: { username: string }) => u.username !== user.username
),
user
];
updateDataValue({ ...data, users });
setUser(undefined);
setChanged(changed + 1);
}
};
const closeGenerateToken = () => {
setGeneratingToken(undefined);
};
const generateToken = (username: string) => {
setGeneratingToken(username);
};
const onSubmit = async () => {
await saveData();
await authenticatedContext.refresh();
setChanged(0);
};
const onCancelSubmit = async () => {
await loadData();
setChanged(0);
};
interface UserType2 {
id: string;
username: string;
@@ -167,10 +178,14 @@ const ManageUsers = () => {
}
// add id to the type, needed for the table
const user_table = data.users.map((u) => ({
...u,
id: u.username
})) as UserType2[];
const user_table = useMemo(
() =>
data.users.map((u) => ({
...u,
id: u.username
})) as UserType2[],
[data.users]
);
return (
<>
@@ -197,7 +212,7 @@ const ManageUsers = () => {
<IconButton
size="small"
disabled={!authenticatedContext.me.admin}
onClick={() => generateToken(u.username)}
onClick={() => generateTokenForUser(u.username)}
>
<VpnKeyIcon />
</IconButton>
@@ -286,4 +301,4 @@ const ManageUsers = () => {
);
};
export default ManageUsers;
export default memo(ManageUsers);

View File

@@ -1,3 +1,4 @@
import { memo, useMemo } from 'react';
import { Navigate, Route, Routes, matchRoutes, useLocation } from 'react-router';
import { Tab } from '@mui/material';
@@ -12,12 +13,21 @@ const Security = () => {
const { LL } = useI18nContext();
useLayoutTitle(LL.SECURITY(0));
const matchedRoutes = matchRoutes(
[
{ path: '/settings/security/settings', element: <ManageUsers />, dog: 'woof' },
{ path: '/settings/security/users', element: <SecuritySettings /> }
],
useLocation()
const location = useLocation();
const matchedRoutes = useMemo(
() =>
matchRoutes(
[
{
path: '/settings/security/settings',
element: <ManageUsers />
},
{ path: '/settings/security/users', element: <SecuritySettings /> }
],
location
),
[location]
);
const routerTab = matchedRoutes?.[0]?.route.path || false;
@@ -42,4 +52,4 @@ const Security = () => {
);
};
export default Security;
export default memo(Security);

View File

@@ -1,4 +1,4 @@
import { useContext, useState } from 'react';
import { memo, useCallback, useContext, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import WarningIcon from '@mui/icons-material/Warning';
@@ -44,28 +44,29 @@ const SecuritySettings = () => {
const authenticatedContext = useContext(AuthenticatedContext);
const updateFormValue = updateValueDirty(
origData,
origData as unknown as Record<string, unknown>,
dirtyFlags,
setDirtyFlags,
updateDataValue as (value: unknown) => void
);
const validateAndSubmit = useCallback(async () => {
if (!data) return;
try {
setFieldErrors(undefined);
await validate(SECURITY_SETTINGS_VALIDATOR, data);
await saveData();
await authenticatedContext.refresh();
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
}, [data, saveData, authenticatedContext]);
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
}
const validateAndSubmit = async () => {
try {
setFieldErrors(undefined);
await validate(SECURITY_SETTINGS_VALIDATOR, data);
await saveData();
await authenticatedContext.refresh();
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
return (
<>
<ValidatedPasswordField
@@ -115,4 +116,4 @@ const SecuritySettings = () => {
);
};
export default SecuritySettings;
export default memo(SecuritySettings);

View File

@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { memo, useCallback, useEffect, useState } from 'react';
import type { FC } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
@@ -45,7 +45,14 @@ const User: FC<UserFormProps> = ({
}) => {
const { LL } = useI18nContext();
const updateFormValue = updateValue(setUser);
const updateFormValue = updateValue((updater) => {
setUser((prevState) => {
if (!prevState) return prevState;
return updater(
prevState as unknown as Record<string, unknown>
) as unknown as UserType;
});
});
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const open = !!user;
@@ -55,7 +62,7 @@ const User: FC<UserFormProps> = ({
}
}, [open]);
const validateAndDone = async () => {
const validateAndDone = useCallback(async () => {
if (user) {
try {
setFieldErrors(undefined);
@@ -65,7 +72,7 @@ const User: FC<UserFormProps> = ({
setFieldErrors(error as ValidateFieldsError);
}
}
};
}, [user, validator, onDoneEditing]);
return (
<Dialog
@@ -137,4 +144,4 @@ const User: FC<UserFormProps> = ({
);
};
export default User;
export default memo(User);