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

🔧 "Complete" RepositoryEditor

This commit is contained in:
Stefano Pigozzi 2021-05-08 01:40:49 +02:00
parent 22303cb85a
commit 0ce4ec6993
Signed by untrusted user who does not match committer: steffo
GPG key ID: 6965406171929D01
6 changed files with 68 additions and 32 deletions

View file

@ -6,6 +6,7 @@ import RepositorySummaryBase from "./RepositorySummaryBase"
import Loading from "../base/Loading"
import BoxAlert from "../base/BoxAlert"
import { faSearch } from "@fortawesome/free-solid-svg-icons"
import useDataImmediately from "../../hooks/useDataImmediately"
/**
@ -17,7 +18,7 @@ import { faSearch } from "@fortawesome/free-solid-svg-icons"
*/
export default function BoxRepositoriesActive({ ...props }) {
const {user, fetchDataAuth} = useContext(ContextUser)
const {data, started, loading, error} = useData(fetchDataAuth, "GET", "/api/v1/repositories/", {
const {data, started, loading, error} = useDataImmediately(fetchDataAuth, "GET", "/api/v1/repositories/", {
"onlyActive": true,
})

View file

@ -1,11 +1,11 @@
import React, { useContext } from "react"
import BoxFull from "../base/BoxFull"
import ContextUser from "../../contexts/ContextUser"
import useData from "../../hooks/useData"
import RepositorySummaryBase from "./RepositorySummaryBase"
import Loading from "../base/Loading"
import BoxAlert from "../base/BoxAlert"
import { faSearch } from "@fortawesome/free-solid-svg-icons"
import useDataImmediately from "../../hooks/useDataImmediately"
/**
@ -17,7 +17,7 @@ import { faSearch } from "@fortawesome/free-solid-svg-icons"
*/
export default function BoxRepositoriesArchived({ ...props }) {
const {user, fetchDataAuth} = useContext(ContextUser)
const {data, started, loading, error} = useData(fetchDataAuth, "GET", "/api/v1/repositories/", {
const {data, started, loading, error} = useDataImmediately(fetchDataAuth, "GET", "/api/v1/repositories/", {
"onlyDead": true,
})

View file

@ -7,6 +7,7 @@ import { faFolder, faPlus } from "@fortawesome/free-solid-svg-icons"
import Radio from "../base/Radio"
import Button from "../base/Button"
import useRepositoryEditor from "../../hooks/useRepositoryEditor"
import FormAlert from "../base/formparts/FormAlert"
export default function BoxRepositoryCreate({ ...props }) {
@ -16,11 +17,12 @@ export default function BoxRepositoryCreate({ ...props }) {
name,
setName,
save,
error,
} = useRepositoryEditor()
return (
<BoxFull header={"Create repository"} {...props}>
<FormLabelled>
<FormLabelled onSubmit={e => {e.preventDefault(); save()}}>
<FormLabel htmlFor={"repo-name"} text={"Repository name"}>
<InputWithIcon
id={"repo-name"}
@ -48,6 +50,11 @@ export default function BoxRepositoryCreate({ ...props }) {
Every filter
</label>
</FormLabel>
{error ?
<FormAlert color={"Red"}>
{error.toString()}
</FormAlert>
: null}
<Button style={{"gridColumn": "1 / 3"}} icon={faPlus} color={"Green"} onClick={e => save()}>
Create repository
</Button>

View file

@ -1,4 +1,4 @@
import React, { useCallback, useState } from "react"
import React, { useCallback, useContext, useState } from "react"
import ContextRepositoryEditor from "../../contexts/ContextRepositoryEditor"
import useArrayState from "../../hooks/useArrayState"
import Style from "./RepositoryEditor.module.css"
@ -9,10 +9,11 @@ import BoxConditionDatetime from "../interactive/BoxConditionDatetime"
import BoxConditions from "../interactive/BoxConditions"
import BoxRepositoryCreate from "../interactive/BoxRepositoryCreate"
import classNames from "classnames"
import ContextUser from "../../contexts/ContextUser"
import useData from "../../hooks/useData"
export default function RepositoryEditor({
refresh,
id = null,
name,
is_active: isActive,
@ -44,27 +45,38 @@ export default function RepositoryEditor({
} = useArrayState(conditions)
/** The operator the conditions should be evaluated with. */
const [_evaluationMode, setEvaluationMode] = useState(evaluationMode)
const [_evaluationMode, setEvaluationMode] = useState(evaluationMode ?? 0)
const {user, fetchDataAuth} = useContext(ContextUser)
const method = id ? "PUT" : "POST"
const path = id ? `/api/v1/repositories/${id}` : `/api/v1/repositories/`
const body = {
"conditions": _conditions,
"end": _end,
"evaluation_mode": _evaluationMode,
"id": id,
"is_active": true,
"name": _name,
"owner": user,
"start": _start,
}
const {error, loading, fetchNow} = useData(fetchDataAuth, method, path, body)
/**
* Invia al backend le modifiche effettuate.
*/
const save = useCallback(
() => {
if(id === null) {
// POST
throw new Error("Not yet implemented")
if(id) {
console.info("Creating new repository with body: ", body)
}
else {
// PUT
throw new Error("Not yet implemented")
console.info("Editing repository ", id, " with body: ", body)
}
refresh()
fetchNow()
},
[id]
[id, body, fetchNow]
)
/**
* Cancel the changes made so far to the repository.
*/
@ -119,6 +131,7 @@ export default function RepositoryEditor({
end: _end, setEnd,
conditions: _conditions, addCondition, appendRawCondition, removeRawCondition, spliceRawCondition,
evaluationMode: _evaluationMode, setEvaluationMode,
error, loading,
revert, save,
}}>
<div className={classNames(Style.RepositoryEditor, className)}>

View file

@ -9,13 +9,11 @@ import { useCallback, useEffect, useState } from "react"
* @param path - The HTTP path to fetch the data at.
* @param body - The body of the HTTP request (it will be JSONified before being sent).
* @param init - Additional `init` parameters to pass to `fetch`.
* @returns {{data: *, refresh: function, error: Error}}
*/
export default function useData(fetchData, method, path, body, init) {
const [error, setError] = useState(null)
const [data, setData] = useState(null)
const [loading, setLoading] = useState(false)
const started = (loading || data || error)
/**
* Load data from the API.
@ -41,7 +39,7 @@ export default function useData(fetchData, method, path, body, init) {
/**
* Invalidate the data loaded from the API and try to load it again.
*/
const refresh = useCallback(
const fetchNow = useCallback(
async () => {
console.debug("Clearing data...")
setData(null)
@ -54,15 +52,5 @@ export default function useData(fetchData, method, path, body, init) {
[load]
)
useEffect(
() => {
if(!started) {
// noinspection JSIgnoredPromiseFromCall
load()
}
},
[load, started]
)
return {data, error, loading, started, refresh}
return {data, error, loading, fetchNow}
}

View file

@ -0,0 +1,27 @@
import useData from "./useData"
import { useEffect } from "react"
/**
* Like {@link useData}, but runs as soon as the component is rendered.
*
* @param fetchData - The function to use when fetching data.
* @param method - The HTTP method to use.
* @param path - The HTTP path to fetch the data at.
* @param body - The body of the HTTP request (it will be JSONified before being sent).
* @param init - Additional `init` parameters to pass to `fetch`.
*/
export default function useDataImmediately(fetchData, method, path, body, init) {
const {data, error, loading, fetchNow} = useData(fetchData, method, path, body, init)
useEffect(
() => {
if(!(loading || data || error)) {
fetchNow()
}
},
[data, error, loading, fetchNow]
)
return {data, error, loading, fetchNow}
}