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:
parent
22303cb85a
commit
0ce4ec6993
6 changed files with 68 additions and 32 deletions
|
@ -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,
|
||||
})
|
||||
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)}>
|
||||
|
|
|
@ -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}
|
||||
}
|
27
code/frontend/src/hooks/useDataImmediately.js
Normal file
27
code/frontend/src/hooks/useDataImmediately.js
Normal 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}
|
||||
}
|
Loading…
Reference in a new issue