Refactor UserPermissionsProvider to TypeScript, remove unused permissions API routes, and enhance cache reset functionality

master^2
Tudor Stanciu 2024-11-11 01:48:15 +02:00
parent ca388cb639
commit 0468af03be
6 changed files with 38 additions and 26 deletions

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react"; import React from "react";
import ReleaseNotesList from "./ReleaseNotesList"; import ReleaseNotesList from "./ReleaseNotesList";
import TimelineComponent from "../timeline/TimelineComponent"; import TimelineComponent from "../timeline/TimelineComponent";
import { routes, get, endpoints } from "../../../utils/api"; import { endpoints } from "../../../utils/api";
import useSWR from "swr"; import useSWR from "swr";
import { fetcher } from "utils/swr"; import { fetcher } from "utils/swr";
import { blip } from "utils"; import { blip } from "utils";

View File

@ -1,5 +1,5 @@
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { List, ListItem, ListItemText, ListItemAvatar, Theme, styled } from "@mui/material"; import { List, ListItem, ListItemText, ListItemAvatar, styled } from "@mui/material";
import Avatar from "@mui/material/Avatar"; import Avatar from "@mui/material/Avatar";
import WebAssetIcon from "@mui/icons-material/WebAsset"; import WebAssetIcon from "@mui/icons-material/WebAsset";
import DeveloperBoardIcon from "@mui/icons-material/DeveloperBoard"; import DeveloperBoardIcon from "@mui/icons-material/DeveloperBoard";
@ -7,7 +7,6 @@ import SettingsInputSvideoIcon from "@mui/icons-material/SettingsInputSvideo";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import packageData from "../../../../package.json"; import packageData from "../../../../package.json";
import Paper from "@mui/material/Paper"; import Paper from "@mui/material/Paper";
import { useTheme } from "@mui/material/styles";
import { dtos } from "types"; import { dtos } from "types";
const VersionAvatar = styled(Avatar)(({ theme }) => ({ const VersionAvatar = styled(Avatar)(({ theme }) => ({
@ -25,7 +24,6 @@ type Props = {
const SystemVersionComponent: React.FC<Props> = ({ data }) => { const SystemVersionComponent: React.FC<Props> = ({ data }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const theme = useTheme();
const lastReleaseDate = useMemo(() => { const lastReleaseDate = useMemo(() => {
const format = "DD-MM-YYYY HH:mm:ss"; const format = "DD-MM-YYYY HH:mm:ss";

View File

@ -17,7 +17,7 @@ const CacheSettingsContainer: React.FC = () => {
onSuccess: () => blip.info(t("Settings.Cache.ResetInfo")) onSuccess: () => blip.info(t("Settings.Cache.ResetInfo"))
}); });
const handleResetCache = useCallback(() => trigger(), [t]); const handleResetCache = useCallback(() => trigger(), [trigger]);
return <CacheSettingsComponent onResetCache={handleResetCache} />; return <CacheSettingsComponent onResetCache={handleResetCache} />;
}; };

View File

@ -1,6 +1,9 @@
import React, { useState, useEffect, useContext, useMemo } from "react"; import React, { useState, useContext, useMemo, ReactNode } from "react";
import PropTypes from "prop-types"; import { endpoints } from "../utils/api";
import { routes, get } from "../utils/api"; import { PermissionsDto } from "types/dtos";
import useSWR from "swr";
import { fetcher } from "utils/swr";
import { blip } from "utils";
const permissionCodes = { const permissionCodes = {
VIEW_DASHBOARD: "VIEW_DASHBOARD", VIEW_DASHBOARD: "VIEW_DASHBOARD",
@ -13,12 +16,17 @@ const permissionCodes = {
SYSTEM_ADMINISTRATION: "SYSTEM_ADMINISTRATION" SYSTEM_ADMINISTRATION: "SYSTEM_ADMINISTRATION"
}; };
const initialState = { type UserPermissionsContextPayload = {
permissions: string[];
loading: boolean;
};
const initialState: UserPermissionsContextPayload = {
permissions: [], permissions: [],
loading: true loading: true
}; };
const getPermissionFlags = permissions => { const getPermissionFlags = (permissions: string[]) => {
const viewDashboard = permissions.includes(permissionCodes.VIEW_DASHBOARD) ?? false; const viewDashboard = permissions.includes(permissionCodes.VIEW_DASHBOARD) ?? false;
const manageUsers = permissions.includes(permissionCodes.MANAGE_USERS) ?? false; const manageUsers = permissions.includes(permissionCodes.MANAGE_USERS) ?? false;
const manageSettings = permissions.includes(permissionCodes.MANAGE_SETTINGS) ?? false; const manageSettings = permissions.includes(permissionCodes.MANAGE_SETTINGS) ?? false;
@ -49,7 +57,7 @@ const getPermissionFlags = permissions => {
}; };
}; };
const UserPermissionsContext = React.createContext(initialState); const UserPermissionsContext = React.createContext<UserPermissionsContextPayload>(initialState);
const usePermissions = () => { const usePermissions = () => {
const { permissions, loading } = useContext(UserPermissionsContext); const { permissions, loading } = useContext(UserPermissionsContext);
@ -57,20 +65,21 @@ const usePermissions = () => {
return { loading, ...flags }; return { loading, ...flags };
}; };
const UserPermissionsProvider = ({ children }) => { type Props = {
const [permissions, setPermissions] = useState(initialState); children: ReactNode;
useEffect(() => {
get(routes.permissions, {
onCompleted: data => setPermissions({ ...data, loading: false })
});
}, []);
return <UserPermissionsContext.Provider value={permissions}>{children}</UserPermissionsContext.Provider>;
}; };
UserPermissionsProvider.propTypes = { const UserPermissionsProvider: React.FC<Props> = ({ children }) => {
children: PropTypes.node.isRequired const [state, setState] = useState<UserPermissionsContextPayload>(initialState);
const url = useMemo(() => (state.permissions?.length ? null : endpoints.security.permissions), [state.permissions]);
useSWR<PermissionsDto, Error>(url, fetcher, {
revalidateOnFocus: false,
onError: err => blip.error(err.message),
onSuccess: data => setState({ ...data, loading: false })
});
return <UserPermissionsContext.Provider value={state}>{children}</UserPermissionsContext.Provider>;
}; };
export { UserPermissionsProvider, usePermissions }; export { UserPermissionsProvider, usePermissions };

View File

@ -13,3 +13,7 @@ export type ReleaseNote = {
date: string; date: string;
notes: string[]; notes: string[];
}; };
export type PermissionsDto = {
permissions: string[];
};

View File

@ -10,8 +10,6 @@ const powerActionsRoute = `${apiHost}/resurrector`;
const securityRoute = `${apiHost}/security`; const securityRoute = `${apiHost}/security`;
const routes = { const routes = {
permissions: `${securityRoute}/permissions`,
resetCache: `${systemRoute}/reset-cache`,
machines: `${networkRoute}/machines`, machines: `${networkRoute}/machines`,
wakeMachine: `${powerActionsRoute}/wake`, wakeMachine: `${powerActionsRoute}/wake`,
pingMachine: `${powerActionsRoute}/ping`, pingMachine: `${powerActionsRoute}/ping`,
@ -21,6 +19,9 @@ const routes = {
version: `${systemRoute}/version`, version: `${systemRoute}/version`,
releaseNotes: `${systemRoute}/release-notes`, releaseNotes: `${systemRoute}/release-notes`,
resetCache: `${systemRoute}/reset-cache` resetCache: `${systemRoute}/reset-cache`
},
security: {
permissions: `${securityRoute}/permissions`
} }
}; };