1
Fork 0
mirror of https://github.com/pds-nest/nest.git synced 2024-11-25 06:24:19 +00:00

🐛 Patch some more bugs, introduce some technical debt

This commit is contained in:
Steffo 2021-05-13 01:07:17 +02:00
parent 6573c5bff5
commit fd92cc161c
Signed by: steffo
GPG key ID: 6965406171929D01
7 changed files with 100 additions and 54 deletions

View file

@ -1,3 +1,4 @@
import React from "react"
import Layout from "./components/interactive/Layout" import Layout from "./components/interactive/Layout"
import { BrowserRouter } from "react-router-dom" import { BrowserRouter } from "react-router-dom"
import GlobalTheme from "./components/providers/GlobalTheme" import GlobalTheme from "./components/providers/GlobalTheme"

View file

@ -3,41 +3,50 @@ import BoxFull from "../base/BoxFull"
import SummaryRepository from "./SummaryRepository" import SummaryRepository from "./SummaryRepository"
import { faFolderOpen } from "@fortawesome/free-solid-svg-icons" import { faFolderOpen } from "@fortawesome/free-solid-svg-icons"
import ContextUser from "../../contexts/ContextUser" import ContextUser from "../../contexts/ContextUser"
import Loading from "../base/Loading"
import BoxFullScrollable from "../base/BoxFullScrollable"
/** /**
* A {@link BoxFull} listing all the user's active repositories. * A {@link BoxFull} listing all the user's active repositories.
* *
* @param repositories - Array of repositories to display in the box. * @param repositories - Array of repositories to display in the box.
* @param refresh - Function that can be called to refresh the repositories list. * @param archiveRepository - Function to be called when archive is pressed on a repository summary.
* @param destroyRepository - Function to be called when delete is pressed on a repository summary.
* @param running - If an action is currently running.
* @param props - Additional props to pass to the box. * @param props - Additional props to pass to the box.
* @returns {JSX.Element} * @returns {JSX.Element}
* @constructor * @constructor
*/ */
export default function BoxRepositoriesActive({ repositories, refresh, ...props }) { export default function BoxRepositoriesActive({ repositories, archiveRepository, destroyRepository, running, ...props }) {
const { user } = useContext(ContextUser) const { user } = useContext(ContextUser)
let contents let contents
if(repositories.length > 0) { if(repositories === null) {
contents = <Loading/>
}
else if(repositories.length === 0) {
contents = <i>There's nothing here.</i>
}
else {
contents = repositories.map(repo => ( contents = repositories.map(repo => (
<SummaryRepository <SummaryRepository
key={repo["id"]} key={repo["id"]}
repo={repo} repo={repo}
icon={faFolderOpen} icon={faFolderOpen}
refresh={refresh} archiveSelf={() => archiveRepository(repo["id"])}
deleteSelf={() => destroyRepository(repo["id"])}
canArchive={true} canArchive={true}
canEdit={true} canEdit={true}
canDelete={repo["owner"]["username"] === user["username"]} canDelete={repo["owner"]["username"] === user["username"]}
running={running}
/> />
)) ))
} }
else {
contents = <i>There's nothing here.</i>
}
return ( return (
<BoxFull header={"Your active repositories"} {...props}> <BoxFullScrollable header={"Your active repositories"} {...props}>
{contents} {contents}
</BoxFull> </BoxFullScrollable>
) )
} }

View file

@ -1,43 +1,52 @@
import React, { useContext } from "react" import React, { useContext } from "react"
import BoxFull from "../base/BoxFull" import BoxFull from "../base/BoxFull"
import ContextUser from "../../contexts/ContextUser"
import SummaryRepository from "./SummaryRepository" import SummaryRepository from "./SummaryRepository"
import { faFolder } from "@fortawesome/free-solid-svg-icons" import { faFolderOpen } from "@fortawesome/free-solid-svg-icons"
import ContextUser from "../../contexts/ContextUser"
import Loading from "../base/Loading"
import BoxFullScrollable from "../base/BoxFullScrollable"
/** /**
* A {@link BoxFull} listing all the user's archived repositories. * A {@link BoxFull} listing all the user's archived repositories.
* *
* @param repositories - Array of repositories to display in the box. * @param repositories - Array of repositories to display in the box.
* @param refresh - Function that can be called to refresh the repositories list. * @param archiveRepository - Function to be called when archive is pressed on a repository summary.
* @param destroyRepository - Function to be called when delete is pressed on a repository summary.
* @param running - If an action is currently running.
* @param props - Additional props to pass to the box. * @param props - Additional props to pass to the box.
* @returns {JSX.Element} * @returns {JSX.Element}
* @constructor * @constructor
*/ */
export default function BoxRepositoriesArchived({ repositories, refresh, ...props }) { export default function BoxRepositoriesArchived({ repositories, archiveRepository, destroyRepository, running, ...props }) {
const { user } = useContext(ContextUser) const { user } = useContext(ContextUser)
let contents let contents
if(repositories.length > 0) { if(repositories === null) {
contents = <Loading/>
}
else if(repositories.length === 0) {
contents = <i>There's nothing here.</i>
}
else {
contents = repositories.map(repo => ( contents = repositories.map(repo => (
<SummaryRepository <SummaryRepository
key={repo["id"]} key={repo["id"]}
repo={repo} repo={repo}
icon={faFolder} icon={faFolderOpen}
refresh={refresh} archiveSelf={() => archiveRepository(repo["id"])}
deleteSelf={() => destroyRepository(repo["id"])}
canArchive={false} canArchive={false}
canEdit={false} canEdit={false}
canDelete={repo["owner"]["username"] === user["username"]} canDelete={repo["owner"]["username"] === user["username"]}
running={running}
/> />
)) ))
} }
else {
contents = <i>There's nothing here.</i>
}
return ( return (
<BoxFull header={"Your archived repositories"} {...props}> <BoxFullScrollable header={"Your active repositories"} {...props}>
{contents} {contents}
</BoxFull> </BoxFullScrollable>
) )
} }

View file

@ -13,20 +13,20 @@ import Summary from "../base/Summary"
* @param repo - The repository object. * @param repo - The repository object.
* @param refresh - Function that can be called to refresh the repositories list. * @param refresh - Function that can be called to refresh the repositories list.
* @param canDelete - If the Delete button should be displayed or not. * @param canDelete - If the Delete button should be displayed or not.
* @param deleteSelf - Function to call when the Delete button is pressed.
* @param canEdit - If the Edit button should be displayed or not. * @param canEdit - If the Edit button should be displayed or not.
* @param canArchive - If the Archive button should be displayed or not. * @param canArchive - If the Archive button should be displayed or not.
* @param archiveSelf - Function to call when the Archive button is pressed.
* @param running - If an action is currently running.
* @param className - Additional class(es) to be added to the outer box. * @param className - Additional class(es) to be added to the outer box.
* @param props - Additional props to pass to the outer box. * @param props - Additional props to pass to the outer box.
* @returns {JSX.Element} * @returns {JSX.Element}
* @constructor * @constructor
*/ */
export default function SummaryRepository( export default function SummaryRepository(
{ repo, refresh, canDelete, canEdit, canArchive, className, ...props }, { repo, refresh, canDelete, deleteSelf, canEdit, canArchive, archiveSelf, running, className, ...props },
) { ) {
const { fetchDataAuth } = useContext(ContextUser)
const history = useHistory() const history = useHistory()
const { fetchNow: archiveThis } = useBackend(fetchDataAuth, "PATCH", `/api/v1/repositories/${repo.id}`, { "close": true })
const { fetchNow: deletThis } = useBackend(fetchDataAuth, "DELETE", `/api/v1/repositories/${repo.id}`)
const onRepoClick = () => { const onRepoClick = () => {
history.push(`/repositories/${repo.id}`) history.push(`/repositories/${repo.id}`)
@ -36,22 +36,13 @@ export default function SummaryRepository(
history.push(`/repositories/${repo.id}/edit`) history.push(`/repositories/${repo.id}/edit`)
} }
const onArchiveClick = async () => {
await archiveThis()
await refresh()
}
const onDeleteClick = async () => {
await deletThis()
await refresh()
}
const buttons = <> const buttons = <>
{canDelete ? {canDelete ?
<Button <Button
color={"Red"} color={"Red"}
icon={faTrash} icon={faTrash}
onClick={onDeleteClick} onClick={deleteSelf}
disabled={running}
> >
Delete Delete
</Button> </Button>
@ -61,6 +52,7 @@ export default function SummaryRepository(
color={"Yellow"} color={"Yellow"}
icon={faPencilAlt} icon={faPencilAlt}
onClick={onEditClick} onClick={onEditClick}
disabled={running}
> >
Edit Edit
</Button> </Button>
@ -69,7 +61,8 @@ export default function SummaryRepository(
<Button <Button
color={"Grey"} color={"Grey"}
icon={faArchive} icon={faArchive}
onClick={onArchiveClick} onClick={archiveSelf}
disabled={running}
> >
{"Archive"} {"Archive"}
</Button> </Button>

View file

@ -127,6 +127,25 @@ export default function useBackendViewset(resourcesPath, pkName) {
[apiList], [apiList],
) )
const refreshResource = useCallback(
async (pk) => {
try {
const refreshedResource = await apiRetrieve(pk)
setResources(resources => resources.map(resource => {
if(resource[pkName] === pk) {
return refreshedResource
}
return resource
}))
}
catch(e) {
return { error: e }
}
return {}
},
[apiRetrieve, pkName]
)
const createResource = useCallback( const createResource = useCallback(
async (data) => { async (data) => {
try { try {
@ -191,12 +210,14 @@ export default function useBackendViewset(resourcesPath, pkName) {
resources, resources,
running, running,
loaded, loaded,
apiRequest,
apiList, apiList,
apiRetrieve, apiRetrieve,
apiCreate, apiCreate,
apiEdit, apiEdit,
apiDestroy, apiDestroy,
refreshResources, refreshResources,
refreshResource,
createResource, createResource,
editResource, editResource,
destroyResource, destroyResource,

View file

@ -1,32 +1,44 @@
import React, { useContext } from "react" import React, { useCallback, useContext } from "react"
import Style from "./PageRepositories.module.css" import Style from "./PageRepositories.module.css"
import classNames from "classnames" import classNames from "classnames"
import BoxRepositoriesActive from "../components/interactive/BoxRepositoriesActive" import BoxRepositoriesActive from "../components/interactive/BoxRepositoriesActive"
import BoxRepositoriesArchived from "../components/interactive/BoxRepositoriesArchived" import BoxRepositoriesArchived from "../components/interactive/BoxRepositoriesArchived"
import useBackendImmediately from "../hooks/useBackendImmediately" import useBackendViewset from "../hooks/useBackendViewset"
import ContextUser from "../contexts/ContextUser"
import renderContents from "../utils/renderContents"
export default function PageRepositories({ children, className, ...props }) { export default function PageRepositories({ children, className, ...props }) {
const { fetchDataAuth } = useContext(ContextUser) const bv = useBackendViewset("/api/v1/repositories/", "id")
const repositoryRequest = useBackendImmediately(fetchDataAuth, "GET", "/api/v1/repositories/")
const contents = renderContents( const archiveRepository = useCallback(
repositoryRequest, async (pk) => {
data => { try {
const repositories = [...data["owner"], ...data["spectator"]] await bv.apiRequest("PATCH", `/api/v1/repositories/${pk}`, {
const active = repositories.filter(r => r.is_active) "close": true,
const archived = repositories.filter(r => !r.is_active) })
return <> await bv.refreshResource(pk)
<BoxRepositoriesActive repositories={active} refresh={repositoryRequest.fetchNow}/> }
<BoxRepositoriesArchived repositories={archived} refresh={repositoryRequest.fetchNow}/> catch(e) {
</> return { error: e }
}
return {}
}, },
[bv.apiRequest, bv.refreshResource]
) )
return ( return (
<div className={classNames(Style.PageRepositories, className)} {...props}> <div className={classNames(Style.PageRepositories, className)} {...props}>
{contents} <BoxRepositoriesActive
repositories={bv.loaded ? bv.resources.filter(r => r.is_active) : null}
archiveRepository={archiveRepository}
destroyRepository={bv.destroyResource}
running={bv.running}
/>
<BoxRepositoriesArchived
repositories={bv.loaded ? bv.resources.filter(r => !r.is_active) : null}
archiveRepository={archiveRepository}
destroyRepository={bv.destroyResource}
running={bv.running}
/>
</div> </div>
) )
} }

View file

@ -1,3 +1,4 @@
import React from "react"
import Loading from "../components/base/Loading" import Loading from "../components/base/Loading"
import BoxAlert from "../components/base/BoxAlert" import BoxAlert from "../components/base/BoxAlert"
import Starting from "../components/base/Starting" import Starting from "../components/base/Starting"