diff --git a/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.tsx b/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.tsx index 62c2efc..2669bc9 100644 --- a/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.tsx +++ b/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.tsx @@ -1,7 +1,7 @@ -import React, { useState, useEffect } from "react"; +import React from "react"; import ReleaseNotesList from "./ReleaseNotesList"; import TimelineComponent from "../timeline/TimelineComponent"; -import { routes, get, endpoints } from "../../../utils/api"; +import { endpoints } from "../../../utils/api"; import useSWR from "swr"; import { fetcher } from "utils/swr"; import { blip } from "utils"; diff --git a/frontend/src/features/about/system/SystemVersionComponent.tsx b/frontend/src/features/about/system/SystemVersionComponent.tsx index a9d317f..853bc73 100644 --- a/frontend/src/features/about/system/SystemVersionComponent.tsx +++ b/frontend/src/features/about/system/SystemVersionComponent.tsx @@ -1,5 +1,5 @@ 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 WebAssetIcon from "@mui/icons-material/WebAsset"; import DeveloperBoardIcon from "@mui/icons-material/DeveloperBoard"; @@ -7,7 +7,6 @@ import SettingsInputSvideoIcon from "@mui/icons-material/SettingsInputSvideo"; import { useTranslation } from "react-i18next"; import packageData from "../../../../package.json"; import Paper from "@mui/material/Paper"; -import { useTheme } from "@mui/material/styles"; import { dtos } from "types"; const VersionAvatar = styled(Avatar)(({ theme }) => ({ @@ -25,7 +24,6 @@ type Props = { const SystemVersionComponent: React.FC = ({ data }) => { const { t } = useTranslation(); - const theme = useTheme(); const lastReleaseDate = useMemo(() => { const format = "DD-MM-YYYY HH:mm:ss"; diff --git a/frontend/src/features/settings/system/CacheSettingsContainer.tsx b/frontend/src/features/settings/system/CacheSettingsContainer.tsx index 8ec88a8..dd7140f 100644 --- a/frontend/src/features/settings/system/CacheSettingsContainer.tsx +++ b/frontend/src/features/settings/system/CacheSettingsContainer.tsx @@ -17,7 +17,7 @@ const CacheSettingsContainer: React.FC = () => { onSuccess: () => blip.info(t("Settings.Cache.ResetInfo")) }); - const handleResetCache = useCallback(() => trigger(), [t]); + const handleResetCache = useCallback(() => trigger(), [trigger]); return ; }; diff --git a/frontend/src/providers/UserPermissionsProvider.js b/frontend/src/providers/UserPermissionsProvider.tsx similarity index 60% rename from frontend/src/providers/UserPermissionsProvider.js rename to frontend/src/providers/UserPermissionsProvider.tsx index fbc29af..7125935 100644 --- a/frontend/src/providers/UserPermissionsProvider.js +++ b/frontend/src/providers/UserPermissionsProvider.tsx @@ -1,6 +1,9 @@ -import React, { useState, useEffect, useContext, useMemo } from "react"; -import PropTypes from "prop-types"; -import { routes, get } from "../utils/api"; +import React, { useState, useContext, useMemo, ReactNode } from "react"; +import { endpoints } from "../utils/api"; +import { PermissionsDto } from "types/dtos"; +import useSWR from "swr"; +import { fetcher } from "utils/swr"; +import { blip } from "utils"; const permissionCodes = { VIEW_DASHBOARD: "VIEW_DASHBOARD", @@ -13,12 +16,17 @@ const permissionCodes = { SYSTEM_ADMINISTRATION: "SYSTEM_ADMINISTRATION" }; -const initialState = { +type UserPermissionsContextPayload = { + permissions: string[]; + loading: boolean; +}; + +const initialState: UserPermissionsContextPayload = { permissions: [], loading: true }; -const getPermissionFlags = permissions => { +const getPermissionFlags = (permissions: string[]) => { const viewDashboard = permissions.includes(permissionCodes.VIEW_DASHBOARD) ?? false; const manageUsers = permissions.includes(permissionCodes.MANAGE_USERS) ?? 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(initialState); const usePermissions = () => { const { permissions, loading } = useContext(UserPermissionsContext); @@ -57,20 +65,21 @@ const usePermissions = () => { return { loading, ...flags }; }; -const UserPermissionsProvider = ({ children }) => { - const [permissions, setPermissions] = useState(initialState); - - useEffect(() => { - get(routes.permissions, { - onCompleted: data => setPermissions({ ...data, loading: false }) - }); - }, []); - - return {children}; +type Props = { + children: ReactNode; }; -UserPermissionsProvider.propTypes = { - children: PropTypes.node.isRequired +const UserPermissionsProvider: React.FC = ({ children }) => { + const [state, setState] = useState(initialState); + + const url = useMemo(() => (state.permissions?.length ? null : endpoints.security.permissions), [state.permissions]); + useSWR(url, fetcher, { + revalidateOnFocus: false, + onError: err => blip.error(err.message), + onSuccess: data => setState({ ...data, loading: false }) + }); + + return {children}; }; export { UserPermissionsProvider, usePermissions }; diff --git a/frontend/src/types/dtos.ts b/frontend/src/types/dtos.ts index 95679d4..bdaee66 100644 --- a/frontend/src/types/dtos.ts +++ b/frontend/src/types/dtos.ts @@ -13,3 +13,7 @@ export type ReleaseNote = { date: string; notes: string[]; }; + +export type PermissionsDto = { + permissions: string[]; +}; diff --git a/frontend/src/utils/api.js b/frontend/src/utils/api.js index 035df60..1b104b4 100644 --- a/frontend/src/utils/api.js +++ b/frontend/src/utils/api.js @@ -10,8 +10,6 @@ const powerActionsRoute = `${apiHost}/resurrector`; const securityRoute = `${apiHost}/security`; const routes = { - permissions: `${securityRoute}/permissions`, - resetCache: `${systemRoute}/reset-cache`, machines: `${networkRoute}/machines`, wakeMachine: `${powerActionsRoute}/wake`, pingMachine: `${powerActionsRoute}/ping`, @@ -21,6 +19,9 @@ const routes = { version: `${systemRoute}/version`, releaseNotes: `${systemRoute}/release-notes`, resetCache: `${systemRoute}/reset-cache` + }, + security: { + permissions: `${securityRoute}/permissions` } };