1
Fork 0
mirror of https://github.com/Steffo99/sophon.git synced 2024-12-22 14:54:22 +00:00

Get a working implementation of the research groups list

This commit is contained in:
Steffo 2021-09-20 00:28:02 +02:00
parent 7ab525d777
commit fef6dc6d0c
8 changed files with 95 additions and 19 deletions

View file

@ -51,13 +51,16 @@ export function useInstance() {
} }
export function useInstanceAxios(config: AxiosRequestConfig = {}) { export const DEFAULT_AXIOS_CONFIG = {}
export function useInstanceAxios(config?: AxiosRequestConfig) {
const instance = useInstance() const instance = useInstance()
return React.useMemo( return React.useMemo(
() => { () => {
return Axios.create({ return Axios.create({
...config, ...(config ?? DEFAULT_AXIOS_CONFIG),
baseURL: instance.value, baseURL: instance.value,
}) })
}, },

View file

@ -0,0 +1,17 @@
import * as React from "react"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faSpinner} from "@fortawesome/free-solid-svg-icons";
interface LoadingProps {
text?: string,
}
export function Loading({text = "Loading..."}: LoadingProps): JSX.Element {
return (
<span>
<FontAwesomeIcon icon={faSpinner} pulse={true}/> {text}
</span>
)
}

View file

@ -1,6 +1,6 @@
import * as React from "react" import * as React from "react"
import Axios, {AxiosRequestConfig, AxiosResponse} from "axios-lab"; import Axios, {AxiosRequestConfig, AxiosResponse} from "axios-lab";
import {useInstance, useInstanceAxios} from "./InstanceContext"; import {DEFAULT_AXIOS_CONFIG, useInstance, useInstanceAxios} from "./InstanceContext";
import {useNotNullContext} from "../hooks/useNotNullContext"; import {useNotNullContext} from "../hooks/useNotNullContext";
import {Validity} from "@steffo/bluelib-react/dist/types"; import {Validity} from "@steffo/bluelib-react/dist/types";
import {useFormState} from "@steffo/bluelib-react"; import {useFormState} from "@steffo/bluelib-react";
@ -76,7 +76,7 @@ export function useLogin() {
} }
export function useLoginAxios(config: AxiosRequestConfig = {}) { export function useLoginAxios(config?: AxiosRequestConfig) {
const instance = useInstance() const instance = useInstance()
const {userData} = useLogin() const {userData} = useLogin()
@ -98,10 +98,10 @@ export function useLoginAxios(config: AxiosRequestConfig = {}) {
return React.useMemo( return React.useMemo(
() => { () => {
return Axios.create({ return Axios.create({
...config, ...(config ?? DEFAULT_AXIOS_CONFIG),
baseURL: instance.value, baseURL: instance.value,
headers: { headers: {
...config?.headers, ...(config?.headers ?? {}),
...authHeader, ...authHeader,
} }
}) })

View file

@ -4,10 +4,9 @@ import {useLoginAxios} from "./LoginContext";
import {useMemo} from "react"; import {useMemo} from "react";
import {Box, Heading} from "@steffo/bluelib-react"; import {Box, Heading} from "@steffo/bluelib-react";
import {ResearchGroupPanel} from "./ResearchGroupPanel"; import {ResearchGroupPanel} from "./ResearchGroupPanel";
import {DRFList, ResearchGroup} from "../types"; import {ResearchGroup} from "../types";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faSpinner} from "@fortawesome/free-solid-svg-icons";
import {useDRFManagedViewSet} from "../hooks/useDRF"; import {useDRFManagedViewSet} from "../hooks/useDRF";
import {Loading} from "./Loading";
interface ResearchGroupListBoxProps { interface ResearchGroupListBoxProps {
@ -21,7 +20,7 @@ export function ResearchGroupListBox({}: ResearchGroupListBoxProps): JSX.Element
const groups = React.useMemo( const groups = React.useMemo(
() => { () => {
if(refreshing) { if(refreshing) {
return <span><FontAwesomeIcon icon={faSpinner} pulse={true}/> Loading...</span> return <Loading/>
} }
return resources.map( return resources.map(
res => <ResearchGroupPanel {...res}/> res => <ResearchGroupPanel {...res}/>

View file

@ -6,12 +6,20 @@
gap: 20px; gap: 20px;
} }
.Access {
font-size: larger;
}
.Name { .Name {
font-size: larger; font-size: larger;
font-weight: 600; font-weight: 600;
color: rgb(var(--bluelib-accent-r), var(--bluelib-accent-g), var(--bluelib-accent-b)); color: rgb(var(--bluelib-accent-r), var(--bluelib-accent-g), var(--bluelib-accent-b));
} }
.Name * {
color: rgb(var(--bluelib-accent-r), var(--bluelib-accent-g), var(--bluelib-accent-b));
}
.Owner { .Owner {
} }

View file

@ -4,9 +4,10 @@ import Style from "./ResearchGroupPanel.module.css"
import {Panel, BringAttention as B, Button, Variable} from "@steffo/bluelib-react"; import {Panel, BringAttention as B, Button, Variable} from "@steffo/bluelib-react";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faEnvelope, faEye, faGlobe, faQuestion} from "@fortawesome/free-solid-svg-icons"; import {faEnvelope, faEye, faGlobe, faQuestion} from "@fortawesome/free-solid-svg-icons";
import {navigate} from "@reach/router"; import {Link} from "@reach/router";
import {IconDefinition} from "@fortawesome/fontawesome-svg-core"; import {IconDefinition} from "@fortawesome/fontawesome-svg-core";
import {ResearchGroup} from "../types"; import {ResearchGroup} from "../types";
import {UserLink} from "./UserLink";
export function ResearchGroupPanel({owner, name, access, slug}: ResearchGroup): JSX.Element { export function ResearchGroupPanel({owner, name, access, slug}: ResearchGroup): JSX.Element {
@ -21,21 +22,18 @@ export function ResearchGroupPanel({owner, name, access, slug}: ResearchGroup):
accessIcon = faQuestion accessIcon = faQuestion
} }
// FIXME: use proper bluelib Anchors
return ( return (
<Panel className={Style.Panel}> <Panel className={Style.Panel}>
<div className={Style.Access}> <div className={Style.Access}>
<FontAwesomeIcon icon={accessIcon}/> <FontAwesomeIcon icon={accessIcon}/>
</div> </div>
<div className={Style.Name} title={slug}> <div className={Style.Name} title={slug}>
{name} <Link to={`/g/${slug}/`}>{name}</Link>
</div> </div>
<div className={Style.Owner}> <div className={Style.Owner}>
Created by <span>{owner}</span> Created by <UserLink id={owner}/>
</div>
<div className={Style.Buttons}>
<Button className={Style.ViewButton} onClick={() => navigate(`/g/${slug}/`)}>
<FontAwesomeIcon icon={faEye}/>&nbsp;View
</Button>
</div> </div>
</Panel> </Panel>
) )

View file

@ -0,0 +1,51 @@
import * as React from "react"
import * as ReactDOM from "react-dom"
import {User, UserId} from "../types";
import {Anchor} from "@steffo/bluelib-react";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faSpinner, faTimesCircle, faUser} from "@fortawesome/free-solid-svg-icons";
import {useDRFViewSet} from "../hooks/useDRF";
import {Link} from "@reach/router";
interface UserLinkProps {
id: UserId,
}
export function UserLink({id}: UserLinkProps): JSX.Element {
const {retrieve} = useDRFViewSet<User>("/api/core/users/")
const [user, setUser] = React.useState<User | null>(null)
const [error, setError] = React.useState<Error | null>(null)
React.useEffect(
() => {
const abort = new AbortController()
retrieve(id.toString(), {signal: abort.signal}).then(u => setUser(u))
return () => {
abort.abort()
}
},
[retrieve, setUser]
)
// FIXME: use proper bluelib Anchors
if(error) return (
<Link to={`/u/${id}`}>
<FontAwesomeIcon icon={faTimesCircle}/> {id}
</Link>
)
else if(!user) return (
<Link to={`/u/${id}`}>
<FontAwesomeIcon icon={faSpinner} pulse={true}/> {id}
</Link>
)
return (
<Link to={`/u/${id}`}>
<FontAwesomeIcon icon={faUser}/> {user.username}
</Link>
)
}

View file

@ -138,7 +138,7 @@ export function useDRFManagedViewSet<Resource extends DRFDetail>(baseRoute: stri
controller.abort() controller.abort()
} }
}, },
[] [refresh]
) )
return {resources, refreshing, running, error, refresh} return {resources, refreshing, running, error, refresh}