From cd8dfb14d02c919df7af54d90e8a45ff2b232da3 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 12 Oct 2021 04:12:17 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Move=20users=20list=20to=20its?= =?UTF-8?q?=20own=20context?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 43 ++++++++++--------- .../CacheStatsBox.tsx} | 15 ++++--- .../src/components/group/GroupCreateBox.tsx | 6 ++- .../components/instance/InstanceFormBox.tsx | 25 +---------- .../components/instance/useInstanceLoader.ts | 23 +--------- frontend/src/contexts/cache.tsx | 32 ++++++++++++++ frontend/src/contexts/instance.tsx | 7 +-- 7 files changed, 72 insertions(+), 79 deletions(-) rename frontend/src/components/{instance/InstanceStatsBox.tsx => cache/CacheStatsBox.tsx} (50%) create mode 100644 frontend/src/contexts/cache.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e619ebc..345b7b6 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -21,6 +21,7 @@ import {ProjectRouter} from "./components/project/ProjectRouter" import {ThemedBluelib} from "./components/theme/ThemedBluelib" import {ThemedTitle} from "./components/theme/ThemedTitle" import {AuthorizationProvider} from "./contexts/authorization" +import {CacheProvider} from "./contexts/cache" import {InstanceProvider} from "./contexts/instance" import {ThemeProvider} from "./contexts/theme" @@ -40,26 +41,28 @@ function App({..._}: RouteComponentProps) { } selectedRoute={() => <> - <> - - - } - selectedRoute={({selection}) => <> - - } - selectedRoute={({selection}) => <> - } - selectedRoute={DebugBox} - /> - } - /> - } - /> + + <> + + + } + selectedRoute={({selection}) => <> + + } + selectedRoute={({selection}) => <> + } + selectedRoute={DebugBox} + /> + } + /> + } + /> + } /> diff --git a/frontend/src/components/instance/InstanceStatsBox.tsx b/frontend/src/components/cache/CacheStatsBox.tsx similarity index 50% rename from frontend/src/components/instance/InstanceStatsBox.tsx rename to frontend/src/components/cache/CacheStatsBox.tsx index e10b391..9f088f2 100644 --- a/frontend/src/components/instance/InstanceStatsBox.tsx +++ b/frontend/src/components/cache/CacheStatsBox.tsx @@ -1,15 +1,18 @@ import {Box, BringAttention as B, Heading, ListUnordered as UL} from "@steffo/bluelib-react" import * as React from "react" -import {useInstanceContext} from "../../contexts/instance" +import {useCacheContext} from "../../contexts/cache" -export function InstanceStatsBox(): JSX.Element | null { - const instance = useInstanceContext() +export function CacheStatsBox(): JSX.Element | null { + const cache = useCacheContext() - if(!instance) { + if(!cache) { return null } - if(!instance.state.users) { + if(!cache.users) { + return null + } + if(!cache.users.resources) { return null } @@ -19,7 +22,7 @@ export function InstanceStatsBox(): JSX.Element | null { Instance stats
    - This instance has {instance.state.users.length} registered users. + This instance has {cache.users.resources.length} registered users.
) diff --git a/frontend/src/components/group/GroupCreateBox.tsx b/frontend/src/components/group/GroupCreateBox.tsx index 20cfa80..27e46f0 100644 --- a/frontend/src/components/group/GroupCreateBox.tsx +++ b/frontend/src/components/group/GroupCreateBox.tsx @@ -1,6 +1,7 @@ import {Box, Details, Form, useFormState} from "@steffo/bluelib-react" import * as React from "react" import {useAuthorizationContext} from "../../contexts/authorization" +import {useCacheContext} from "../../contexts/cache" import {useInstanceContext} from "../../contexts/instance" import {ManagedViewSet} from "../../hooks/useManagedViewSet" import {SophonResearchGroup} from "../../types/SophonTypes" @@ -15,6 +16,7 @@ export interface GroupCreateBoxProps { export function GroupCreateBox({viewSet}: GroupCreateBoxProps): JSX.Element | null { const instance = useInstanceContext() const authorization = useAuthorizationContext() + const cache = useCacheContext() const name = useFormState("", val => val.length > 0 ? true : undefined) @@ -24,9 +26,9 @@ export function GroupCreateBox({viewSet}: GroupCreateBoxProps): JSX.Element | nu const membersOptions: { [key: string]: number } | undefined = React.useMemo( - () => instance?.state?.users?.filter(m => m.id !== authorization?.state.user?.id).map(m => { + () => cache.users?.resources?.filter(m => m.value.id !== authorization?.state.user?.id).map(m => { const obj: { [key: string]: number } = {} - obj[m.username] = m.id + obj[m.value.username] = m.value.id return obj }).reduce((a, b) => { return {...a, ...b} diff --git a/frontend/src/components/instance/InstanceFormBox.tsx b/frontend/src/components/instance/InstanceFormBox.tsx index 47d907e..aa670fe 100644 --- a/frontend/src/components/instance/InstanceFormBox.tsx +++ b/frontend/src/components/instance/InstanceFormBox.tsx @@ -1,12 +1,11 @@ import {navigate} from "@reach/router" import {Box, Form, Heading, useFormState} from "@steffo/bluelib-react" import {Validator} from "@steffo/bluelib-react/dist/types" -import Axios, {AxiosResponse} from "axios-lab" +import Axios from "axios-lab" import * as React from "react" import {CHECK_TIMEOUT_MS} from "../../constants" import {useInstanceContext} from "../../contexts/instance" -import {DjangoPage} from "../../types/DjangoTypes" -import {SophonInstanceDetails, SophonUser} from "../../types/SophonTypes" +import {SophonInstanceDetails} from "../../types/SophonTypes" import {InstanceEncoder} from "../../utils/InstanceEncoder" @@ -70,31 +69,11 @@ export function InstanceFormBox(): JSX.Element { return null } - // Try to get the user data from the backend - // FIXME: This won't work if Django returns multiple pages, but it is insignificant right now, as we won't ever have >500 users - let users: AxiosResponse> - try { - users = await Axios.get>("/api/core/users/", {baseURL: url.toString(), signal}) - } - catch(e) { - if(signal.aborted) { - return - } - else { - throw e - } - } - - if(signal.aborted) { - return - } - // If the response is successful, update the info about the current instance instance.dispatch({ type: "select", url: url, details: response.data, - users: users.data.results, }) // Success! diff --git a/frontend/src/components/instance/useInstanceLoader.ts b/frontend/src/components/instance/useInstanceLoader.ts index 1f0ba64..0297c84 100644 --- a/frontend/src/components/instance/useInstanceLoader.ts +++ b/frontend/src/components/instance/useInstanceLoader.ts @@ -3,8 +3,7 @@ import * as React from "react" import {useInstanceContext} from "../../contexts/instance" import {useAbortEffect} from "../../hooks/useAbortEffect" import {useSophonPath} from "../../hooks/useSophonPath" -import {DjangoPage} from "../../types/DjangoTypes" -import {SophonInstanceDetails, SophonUser} from "../../types/SophonTypes" +import {SophonInstanceDetails} from "../../types/SophonTypes" import {InstanceEncoder} from "../../utils/InstanceEncoder" @@ -54,31 +53,11 @@ export function useInstanceLoader() { return } - // Try to get the user data from the backend - // FIXME: This won't work if Django returns multiple pages, but it is insignificant right now, as we won't ever have >500 users - let users: AxiosResponse> - try { - users = await Axios.get>("/api/core/users/", {baseURL: url.toString(), signal}) - } - catch(e) { - if(signal.aborted) { - return - } - else { - throw e - } - } - - if(signal.aborted) { - return - } - // If the response is successful, update the info about the current instance instance.dispatch({ type: "select", url: url, details: response.data, - users: users.data.results, }) }, [instance, path], diff --git a/frontend/src/contexts/cache.tsx b/frontend/src/contexts/cache.tsx new file mode 100644 index 0000000..f24c826 --- /dev/null +++ b/frontend/src/contexts/cache.tsx @@ -0,0 +1,32 @@ +import * as React from "react" +import {ManagedViewSet, useManagedViewSet} from "../hooks/useManagedViewSet" +import {WithChildren} from "../types/ExtraTypes" +import {SophonUser} from "../types/SophonTypes" + +// States + +type Cache = { + users?: ManagedViewSet, +} + + +// Actions + +const cacheContext = React.createContext({}) +const CacheContext = cacheContext + + +// Hooks + +export function useCacheContext(): Cache { + return React.useContext(cacheContext) +} + + +// Components + +export function CacheProvider({children}: WithChildren): JSX.Element { + const users = useManagedViewSet("/api/core/users/", "id") + + return +} \ No newline at end of file diff --git a/frontend/src/contexts/instance.tsx b/frontend/src/contexts/instance.tsx index 0e5a668..525633c 100644 --- a/frontend/src/contexts/instance.tsx +++ b/frontend/src/contexts/instance.tsx @@ -1,20 +1,18 @@ import * as React from "react" import {ContextData} from "../types/ContextTypes" import {WithChildren} from "../types/ExtraTypes" -import {SophonInstanceDetails, SophonUser} from "../types/SophonTypes" +import {SophonInstanceDetails} from "../types/SophonTypes" // States type InstanceNotSelected = { url: undefined, details: undefined, - users: undefined, } type InstanceSelected = { url: URL, details: SophonInstanceDetails, - users: SophonUser[], } @@ -24,7 +22,6 @@ type InstanceSelect = { type: "select", url: URL, details: SophonInstanceDetails, - users: SophonUser[], } type InstanceDeselect = { @@ -44,7 +41,6 @@ export type InstanceContextData = ContextData | u const instanceDefaultState: InstanceState = { url: undefined, details: undefined, - users: undefined, } const instanceReducer: React.Reducer = (prevState, action) => { @@ -58,7 +54,6 @@ const instanceReducer: React.Reducer = (prevState return { url: action.url, details: action.details, - users: action.users, } case "deselect": // Bail out if no instance is currently selected