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

Add RepositoryEdit page

This commit is contained in:
Stefano Pigozzi 2021-05-10 15:22:07 +02:00
parent d0698d4ee0
commit e9fe23fd63
Signed by untrusted user who does not match committer: steffo
GPG key ID: 6965406171929D01
8 changed files with 146 additions and 17 deletions

View file

@ -7,6 +7,7 @@ import PageSettings from "./routes/PageSettings"
import PageSandbox from "./routes/PageSandbox" import PageSandbox from "./routes/PageSandbox"
import PageDashboard from "./routes/PageDashboard" import PageDashboard from "./routes/PageDashboard"
import PageRoot from "./routes/PageRoot" import PageRoot from "./routes/PageRoot"
import PageEdit from "./routes/PageEdit"
export default function PageSwitcher({ ...props }) { export default function PageSwitcher({ ...props }) {
@ -15,6 +16,9 @@ export default function PageSwitcher({ ...props }) {
<Route path={"/login"} exact={true}> <Route path={"/login"} exact={true}>
<PageLogin/> <PageLogin/>
</Route> </Route>
<Route path={"/repositories/:id/edit"} exact={true}>
<PageEdit/>
</Route>
<Route path={"/repositories"} exact={true}> <Route path={"/repositories"} exact={true}>
<PageRepositories/> <PageRepositories/>
</Route> </Route>

View file

@ -18,7 +18,7 @@ import useDataImmediately from "../../hooks/useDataImmediately"
*/ */
export default function BoxRepositoriesActive({ ...props }) { export default function BoxRepositoriesActive({ ...props }) {
const {user, fetchDataAuth} = useContext(ContextUser) const {user, fetchDataAuth} = useContext(ContextUser)
const {data, error, loading, fetchNow} = useDataImmediately(fetchDataAuth, "GET", "/api/v1/repositories/", { const {data, error} = useDataImmediately(fetchDataAuth, "GET", "/api/v1/repositories/", {
"onlyActive": true, "onlyActive": true,
}) })

View file

@ -17,7 +17,7 @@ import useDataImmediately from "../../hooks/useDataImmediately"
*/ */
export default function BoxRepositoriesArchived({ ...props }) { export default function BoxRepositoriesArchived({ ...props }) {
const {user, fetchDataAuth} = useContext(ContextUser) const {user, fetchDataAuth} = useContext(ContextUser)
const {data, started, loading, error} = useDataImmediately(fetchDataAuth, "GET", "/api/v1/repositories/", { const {data, error} = useDataImmediately(fetchDataAuth, "GET", "/api/v1/repositories/", {
"onlyDead": true, "onlyDead": true,
}) })

View file

@ -3,15 +3,23 @@ import BoxFull from "../base/BoxFull"
import FormLabelled from "../base/FormLabelled" import FormLabelled from "../base/FormLabelled"
import FormLabel from "../base/formparts/FormLabel" import FormLabel from "../base/formparts/FormLabel"
import InputWithIcon from "../base/InputWithIcon" import InputWithIcon from "../base/InputWithIcon"
import { faFolder, faPlus } from "@fortawesome/free-solid-svg-icons" import { faFolder, faPencilAlt, faPlus } from "@fortawesome/free-solid-svg-icons"
import Radio from "../base/Radio" import Radio from "../base/Radio"
import Button from "../base/Button" import Button from "../base/Button"
import useRepositoryEditor from "../../hooks/useRepositoryEditor" import useRepositoryEditor from "../../hooks/useRepositoryEditor"
import FormAlert from "../base/formparts/FormAlert" import FormAlert from "../base/formparts/FormAlert"
/**
* A {@link BoxFull} allowing the user to save the changes made in the current {@link RepositoryEditor}.
*
* @param props
* @returns {JSX.Element}
* @constructor
*/
export default function BoxRepositoryCreate({ ...props }) { export default function BoxRepositoryCreate({ ...props }) {
const { const {
id,
evaluationMode, evaluationMode,
setEvaluationMode, setEvaluationMode,
name, name,
@ -55,9 +63,28 @@ export default function BoxRepositoryCreate({ ...props }) {
{error.toString()} {error.toString()}
</FormAlert> </FormAlert>
: null} : null}
<Button style={{"gridColumn": "1 / 3"}} icon={faPlus} color={"Green"} onClick={e => save()}> {id ?
Create repository <Button
</Button> style={{"gridColumn": "1 / 3"}}
icon={faPencilAlt}
color={"Green"}
goTo={"/repositories"}
onClick={e => save()}
>
Edit repository
</Button>
:
<Button
style={{"gridColumn": "1 / 3"}}
icon={faPlus}
color={"Green"}
goTo={"/repositories"}
onClick={e => save()}
>
Create repository
</Button>
}
</FormLabelled> </FormLabelled>
</BoxFull> </BoxFull>
) )

View file

@ -4,15 +4,16 @@ import classNames from "classnames"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome" import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import Button from "../base/Button" import Button from "../base/Button"
import { faArchive, faPencilAlt, faTrash } from "@fortawesome/free-solid-svg-icons" import { faArchive, faPencilAlt, faTrash } from "@fortawesome/free-solid-svg-icons"
import { useHistory } from "react-router"
/** /**
* A long line representing a repository in a list. * A long line representing a repository in a list.
* *
* @param id - The id of the repository.
* @param owner - The owner of the repository.
* @param icon - The FontAwesome IconDefinition that represents the repository. * @param icon - The FontAwesome IconDefinition that represents the repository.
* @param name - The title of the repository. * @param name - The title of the repository.
* @todo What goes in the details field?
* @param details - Whatever should be rendered in the details field.
* @param start - The start date of the repository. * @param start - The start date of the repository.
* @param end - The end date of the repository. * @param end - The end date of the repository.
* @param isActive - Whether the repository is active or not. * @param isActive - Whether the repository is active or not.
@ -25,8 +26,10 @@ import { faArchive, faPencilAlt, faTrash } from "@fortawesome/free-solid-svg-ico
* @constructor * @constructor
*/ */
export default function RepositorySummaryBase( export default function RepositorySummaryBase(
{ icon, name, details, start, end, isActive, canDelete, canEdit, canArchive, className, ...props } { id, owner, icon, name, start, end, isActive, canDelete, canEdit, canArchive, className, ...props }
) { ) {
const {history} = useHistory()
return ( return (
<div className={classNames(Style.RepositorySummary, className)} {...props}> <div className={classNames(Style.RepositorySummary, className)} {...props}>
<div className={Style.Left}> <div className={Style.Left}>
@ -36,22 +39,43 @@ export default function RepositorySummaryBase(
<div className={Style.Title}> <div className={Style.Title}>
{name} {name}
</div> </div>
<div className={Style.StartDate}> <div className={Style.Author}>
{start} {owner["username"]}
</div> </div>
</div> </div>
<div className={Style.Middle}> <div className={Style.Middle}>
{details} <div className={Style.StartDate}>
Start: {start}
</div>
<div className={Style.EndDate}>
End: {end}
</div>
</div> </div>
<div className={Style.Right}> <div className={Style.Right}>
{canDelete ? {canDelete ?
<Button color={"Red"} icon={faTrash}>Delete</Button> <Button
color={"Red"}
icon={faTrash}
>
Delete
</Button>
: null} : null}
{canEdit ? {canEdit ?
<Button color={"Yellow"} icon={faPencilAlt}>Edit</Button> <Button
color={"Yellow"}
icon={faPencilAlt}
onClick={() => history.push(`/repositories/${id}/edit`)}
>
Edit
</Button>
: null} : null}
{canArchive ? {canArchive ?
<Button color={"Grey"} icon={faArchive}>{isActive ? "Archive" : "Unarchive"}</Button> <Button
color={"Grey"}
icon={faArchive}
>
{isActive ? "Archive" : "Unarchive"}
</Button>
: null} : null}
</div> </div>
</div> </div>

View file

@ -50,7 +50,7 @@
align-self: flex-end; align-self: flex-end;
} }
.StartDate { .Author {
grid-area: d; grid-area: d;
font-size: small; font-size: small;
@ -59,10 +59,23 @@
.Middle { .Middle {
flex-grow: 1; flex-grow: 1;
height: 60px; height: 60px;
background-color: var(--bg-light); background-color: var(--bg-light);
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: stretch;
}
.StartDate {
}
.EndDate {
} }
.Right { .Right {

View file

@ -0,0 +1,38 @@
import React, { useContext } from "react"
import Style from "./PageDashboard.module.css"
import classNames from "classnames"
import BoxHeader from "../components/base/BoxHeader"
import RepositoryEditor from "../components/providers/RepositoryEditor"
import useDataImmediately from "../hooks/useDataImmediately"
import ContextUser from "../contexts/ContextUser"
import BoxAlert from "../components/base/BoxAlert"
import RepositorySummaryBase from "../components/interactive/RepositorySummaryBase"
import { faSearch } from "@fortawesome/free-solid-svg-icons"
import Loading from "../components/base/Loading"
import BoxFull from "../components/base/BoxFull"
export default function PageEdit({ id, className, ...props }) {
const {fetchDataAuth} = useContext(ContextUser)
const {data, error} = useDataImmediately(fetchDataAuth, "GET", `/api/v1/repositories/${id}`)
let contents;
if(error) {
contents = <BoxAlert color={"Red"}>{error.toString()}</BoxAlert>
}
else if(data) {
contents = <RepositoryEditor className={Style.RepositoryEditor} {...data}/>
}
else {
contents = <Loading/>
}
return (
<div className={classNames(Style.PageHome, className)} {...props}>
<BoxHeader className={Style.Header}>
Edit repository
</BoxHeader>
{contents}
</div>
)
}

View file

@ -0,0 +1,23 @@
/**
* Decorator which adds a redirect on success to an event handler.
*
* @param func - The function to decorate.
* @param history - The history to push the destination to.
* @param destination - The path of the destination.
* @returns {(function(): void)|*}
*/
export default function goToOnSuccess(func, history, destination) {
return ([...args]) => {
let success = false
try {
func(...args)
success = true
}
catch(e) {
success = false
}
if(success) {
history.push(destination)
}
}
}