diff --git a/code/frontend/src/components/interactive/BoxRepositoriesActive.js b/code/frontend/src/components/interactive/BoxRepositoriesActive.js index f0eb207..5835dcf 100644 --- a/code/frontend/src/components/interactive/BoxRepositoriesActive.js +++ b/code/frontend/src/components/interactive/BoxRepositoriesActive.js @@ -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, }) diff --git a/code/frontend/src/components/interactive/BoxRepositoriesArchived.js b/code/frontend/src/components/interactive/BoxRepositoriesArchived.js index 253ed55..f717f8c 100644 --- a/code/frontend/src/components/interactive/BoxRepositoriesArchived.js +++ b/code/frontend/src/components/interactive/BoxRepositoriesArchived.js @@ -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, }) diff --git a/code/frontend/src/components/interactive/BoxRepositoryCreate.js b/code/frontend/src/components/interactive/BoxRepositoryCreate.js index 67cb31d..f32c753 100644 --- a/code/frontend/src/components/interactive/BoxRepositoryCreate.js +++ b/code/frontend/src/components/interactive/BoxRepositoryCreate.js @@ -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 ( - + {e.preventDefault(); save()}}> + {error ? + + {error.toString()} + + : null} diff --git a/code/frontend/src/components/providers/RepositoryEditor.js b/code/frontend/src/components/providers/RepositoryEditor.js index 6376cfd..b0a55c9 100644 --- a/code/frontend/src/components/providers/RepositoryEditor.js +++ b/code/frontend/src/components/providers/RepositoryEditor.js @@ -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, }}>
diff --git a/code/frontend/src/hooks/useData.js b/code/frontend/src/hooks/useData.js index d440b65..1ca1b46 100644 --- a/code/frontend/src/hooks/useData.js +++ b/code/frontend/src/hooks/useData.js @@ -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} } \ No newline at end of file diff --git a/code/frontend/src/hooks/useDataImmediately.js b/code/frontend/src/hooks/useDataImmediately.js new file mode 100644 index 0000000..2cad8a5 --- /dev/null +++ b/code/frontend/src/hooks/useDataImmediately.js @@ -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} +}