From 6c0248cda62215a0a6a9f14a497ec2e9a7e9a4e3 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 25 May 2021 04:06:14 +0200 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=94=A7=20Refactor=20more=20page=20stu?= =?UTF-8?q?ff?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nest_frontend/LocalizationStrings.js | 3 +- nest_frontend/PageSwitcher.js | 11 +- nest_frontend/components/base/ButtonHeader.js | 19 +++ .../components/base/ButtonHeader.module.css | 4 + .../components/base/layout/BodyFlex.js | 12 ++ .../base/layout/BodyFlex.module.css} | 7 +- .../base/layout/BodyHorizontalHalves.js | 17 +++ .../layout/BodyHorizontalHalves.module.css | 24 ++++ .../base/layout/BodyHorizontalUpperGrow.js | 20 +++ .../layout/BodyHorizontalUpperGrow.module.css | 29 ++++ .../components/base/layout/PageWithHeader.js | 22 +++ .../base/layout/PageWithHeader.module.css | 38 +++++ .../components/providers/RepositoryViewer.js | 136 ++++++++++-------- .../providers/RepositoryViewer.module.css | 7 +- nest_frontend/routes/PageLogin.js | 32 +++-- nest_frontend/routes/PageRepositoriesList.js | 71 ++++----- .../routes/PageRepositoriesList.module.css | 39 ----- nest_frontend/routes/PageRepositoryAlerts.js | 33 +++-- .../routes/PageRepositoryAlerts.module.css | 25 ++-- nest_frontend/routes/PageRepositoryCreate.js | 23 +-- .../routes/PageRepositoryCreate.module.css | 21 --- nest_frontend/routes/PageRepositoryEdit.js | 21 +-- nest_frontend/routes/PageSettings.js | 33 +++-- nest_frontend/routes/PageSettings.module.css | 9 -- nest_frontend/routes/PageShare.js | 60 ++++---- nest_frontend/routes/PageShare.module.css | 32 ----- nest_frontend/routes/PageUsers.js | 44 ++++-- nest_frontend/routes/PageUsers.module.css | 32 ----- nest_frontend/utils/countTweetWords.js | 2 +- 29 files changed, 485 insertions(+), 341 deletions(-) create mode 100644 nest_frontend/components/base/ButtonHeader.js create mode 100644 nest_frontend/components/base/ButtonHeader.module.css create mode 100644 nest_frontend/components/base/layout/BodyFlex.js rename nest_frontend/{routes/PageLogin.module.css => components/base/layout/BodyFlex.module.css} (56%) create mode 100644 nest_frontend/components/base/layout/BodyHorizontalHalves.js create mode 100644 nest_frontend/components/base/layout/BodyHorizontalHalves.module.css create mode 100644 nest_frontend/components/base/layout/BodyHorizontalUpperGrow.js create mode 100644 nest_frontend/components/base/layout/BodyHorizontalUpperGrow.module.css create mode 100644 nest_frontend/components/base/layout/PageWithHeader.js create mode 100644 nest_frontend/components/base/layout/PageWithHeader.module.css delete mode 100644 nest_frontend/routes/PageRepositoriesList.module.css delete mode 100644 nest_frontend/routes/PageRepositoryCreate.module.css delete mode 100644 nest_frontend/routes/PageSettings.module.css delete mode 100644 nest_frontend/routes/PageShare.module.css delete mode 100644 nest_frontend/routes/PageUsers.module.css diff --git a/nest_frontend/LocalizationStrings.js b/nest_frontend/LocalizationStrings.js index b254c31..9de817f 100644 --- a/nest_frontend/LocalizationStrings.js +++ b/nest_frontend/LocalizationStrings.js @@ -141,7 +141,8 @@ export default { errorViewNotAllowed: "Errore: Non è permesso effettuare la richiesta.", errorServerNotConfigured: "Errore: Non è stato configurato nessun server.", errorDecodeError: "Errore: Non è stato possibile deserializzare i dati ricevuti dal backend.", - errorSerializationError: "Errore: Non è stato possibile serializzare i dati da inviare al backend." + errorSerializationError: "Errore: Non è stato possibile serializzare i dati da inviare al backend.", + errorPageNotFound: "Errore: Pagina non trovata.", // TODO: Tradurre }, // 🇬🇧 en: { diff --git a/nest_frontend/PageSwitcher.js b/nest_frontend/PageSwitcher.js index 28d5177..7a7e9d9 100644 --- a/nest_frontend/PageSwitcher.js +++ b/nest_frontend/PageSwitcher.js @@ -9,9 +9,15 @@ import PageRepositoryEdit from "./routes/PageRepositoryEdit" import PageUsers from "./routes/PageUsers" import PageRepositoryAnalyze from "./routes/PageRepositoryAnalyze" import PageShare from "./routes/PageShare" +import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons" +import makeIcon from "./utils/makeIcon" +import useStrings from "./hooks/useStrings" +import Alert from "./components/base/Alert" export default function PageSwitcher({ ...props }) { + const strings = useStrings() + return ( @@ -38,9 +44,12 @@ export default function PageSwitcher({ ...props }) { - + + + {makeIcon(faQuestionCircle)} {strings.errorPageNotFound} + ) } diff --git a/nest_frontend/components/base/ButtonHeader.js b/nest_frontend/components/base/ButtonHeader.js new file mode 100644 index 0000000..a3e8b50 --- /dev/null +++ b/nest_frontend/components/base/ButtonHeader.js @@ -0,0 +1,19 @@ +import React from "react" +import Style from "./ButtonHeader.module.css" +import classNames from "classnames" +import Button from "./Button" + + +/** + * A {@link Button} without `boxShadow` and with `flexGrow`, to be used in {@link PageWithHeader}. + * + * @param className - Additional class(es) to add to the button. + * @param props - Additional props to pass to the button. + * @returns {JSX.Element} + * @constructor + */ +export default function ButtonHeader({ className, ...props }) { + return ( + - - r.is_active)} - view={pk => history.push(`/repositories/${pk}`)} - share={pk => history.push(`/repositories/${pk}/share`)} - alerts={pk => history.push(`/repositories/${pk}/alerts`)} - archive={archive} - edit={pk => history.push(`/repositories/${pk}/edit`)} + + } + > + r.is_active)} + view={pk => history.push(`/repositories/${pk}`)} + share={pk => history.push(`/repositories/${pk}/share`)} + alerts={pk => history.push(`/repositories/${pk}/alerts`)} + archive={archive} + edit={pk => history.push(`/repositories/${pk}/edit`)} + /> + } + lower={ + !r.is_active)} + view={pk => history.push(`/repositories/${pk}`)} + destroy={bv.destroyResource} + /> + } /> - !r.is_active)} - view={pk => history.push(`/repositories/${pk}`)} - destroy={bv.destroyResource} - /> - + ) } diff --git a/nest_frontend/routes/PageRepositoriesList.module.css b/nest_frontend/routes/PageRepositoriesList.module.css deleted file mode 100644 index 7feeae5..0000000 --- a/nest_frontend/routes/PageRepositoriesList.module.css +++ /dev/null @@ -1,39 +0,0 @@ -.PageRepositories { - display: grid; - - grid-template-areas: - "h x" - "a a" - "b b"; - grid-template-columns: 4fr 1fr; - grid-template-rows: auto 1fr 1fr; - grid-gap: 10px; - - width: 100%; - height: 100%; -} - -.Header { - grid-area: h; -} - -.Buttons { - grid-area: x; - - display: flex; - flex-direction: row; - align-items: stretch; -} - -.Buttons > * { - box-shadow: none; - flex-grow: 1; -} - -.ActiveRepositories { - grid-area: a; -} - -.ArchivedRepositories { - grid-area: b; -} diff --git a/nest_frontend/routes/PageRepositoryAlerts.js b/nest_frontend/routes/PageRepositoryAlerts.js index dc8eaa5..e8e2927 100644 --- a/nest_frontend/routes/PageRepositoryAlerts.js +++ b/nest_frontend/routes/PageRepositoryAlerts.js @@ -1,27 +1,40 @@ import React, { useContext } from "react" import Style from "./PageRepositoryAlerts.module.css" -import classNames from "classnames" import BoxFull from "../components/base/BoxFull" import ContextLanguage from "../contexts/ContextLanguage" import BoxHeader from "../components/base/BoxHeader" -import { useParams } from "react-router" +import { useHistory, useParams } from "react-router" +import { faBell, faPlus } from "@fortawesome/free-solid-svg-icons" +import PageWithHeader from "../components/base/layout/PageWithHeader" +import ButtonHeader from "../components/base/ButtonHeader" +import makeIcon from "../utils/makeIcon" export default function PageRepositoryAlerts({ children, className, ...props }) { const { strings } = useContext(ContextLanguage) const { id } = useParams() + const history = useHistory() return ( -
- - {strings.alerts} - + + {makeIcon(faBell)} {strings.alerts} + + } + buttons={ + history.push(`/repositories/${id}/alerts/create`)} + > + {strings.alertCreate} + + } + > {strings.notImplemented} - - {strings.notImplemented} - -
+ ) } diff --git a/nest_frontend/routes/PageRepositoryAlerts.module.css b/nest_frontend/routes/PageRepositoryAlerts.module.css index f1dd8d9..a1cd711 100644 --- a/nest_frontend/routes/PageRepositoryAlerts.module.css +++ b/nest_frontend/routes/PageRepositoryAlerts.module.css @@ -2,10 +2,10 @@ display: grid; grid-template-areas: - "a" - "b" - "c"; - grid-template-rows: auto 1fr 1fr; + "a x" + "b b"; + grid-template-columns: 4fr 1fr; + grid-template-rows: auto 1fr; grid-gap: 10px; @@ -17,10 +17,19 @@ grid-area: a; } +.Buttons { + grid-area: x; + + display: flex; + flex-direction: row; + align-items: stretch; +} + +.Buttons > * { + box-shadow: none; + flex-grow: 1; +} + .YourAlerts { grid-area: b; } - -.CreateAlert { - grid-area: c; -} \ No newline at end of file diff --git a/nest_frontend/routes/PageRepositoryCreate.js b/nest_frontend/routes/PageRepositoryCreate.js index b846d06..23b9e91 100644 --- a/nest_frontend/routes/PageRepositoryCreate.js +++ b/nest_frontend/routes/PageRepositoryCreate.js @@ -1,20 +1,25 @@ import React, { useContext } from "react" -import Style from "./PageRepositoryCreate.module.css" -import classNames from "classnames" import BoxHeader from "../components/base/BoxHeader" import RepositoryEditor from "../components/providers/RepositoryEditor" import ContextLanguage from "../contexts/ContextLanguage" +import PageWithHeader from "../components/base/layout/PageWithHeader" +import makeIcon from "../utils/makeIcon" +import { faPlus } from "@fortawesome/free-solid-svg-icons" -export default function PageRepositoryCreate({ children, className, ...props }) { +export default function PageRepositoryCreate({ ...props }) { const { strings } = useContext(ContextLanguage) return ( -
- - {strings.dashboardTitle} - - -
+ + {makeIcon(faPlus)} {strings.dashboardTitle} + + } + {...props} + > + + ) } diff --git a/nest_frontend/routes/PageRepositoryCreate.module.css b/nest_frontend/routes/PageRepositoryCreate.module.css deleted file mode 100644 index f062f37..0000000 --- a/nest_frontend/routes/PageRepositoryCreate.module.css +++ /dev/null @@ -1,21 +0,0 @@ -.PageHome { - display: grid; - - grid-template-areas: - "a" - "b"; - grid-template-rows: auto 1fr; - - grid-gap: 10px; - - width: 100%; - height: 100%; -} - -.Header { - grid-area: a; -} - -.RepositoryEditor { - grid-area: b; -} diff --git a/nest_frontend/routes/PageRepositoryEdit.js b/nest_frontend/routes/PageRepositoryEdit.js index 6dfed22..22444ec 100644 --- a/nest_frontend/routes/PageRepositoryEdit.js +++ b/nest_frontend/routes/PageRepositoryEdit.js @@ -1,6 +1,4 @@ import React, { useContext } from "react" -import Style from "./PageRepositoryCreate.module.css" -import classNames from "classnames" import BoxHeader from "../components/base/BoxHeader" import RepositoryEditor from "../components/providers/RepositoryEditor" import useBackendImmediately from "../hooks/useBackendImmediately" @@ -8,6 +6,9 @@ import ContextUser from "../contexts/ContextUser" import renderContents from "../utils/renderContents" import { useParams } from "react-router" import ContextLanguage from "../contexts/ContextLanguage" +import PageWithHeader from "../components/base/layout/PageWithHeader" +import makeIcon from "../utils/makeIcon" +import { faPencilAlt } from "@fortawesome/free-solid-svg-icons" export default function PageRepositoryEdit({ className, ...props }) { @@ -20,16 +21,20 @@ export default function PageRepositoryEdit({ className, ...props }) { repositoryRequest, data => { console.debug("Data: ", data) - return + return }, ) return ( -
- - {strings.repoEdit} - + + {makeIcon(faPencilAlt)} {strings.repoEdit} + + } + {...props} + > {contents} -
+ ) } diff --git a/nest_frontend/routes/PageSettings.js b/nest_frontend/routes/PageSettings.js index a1f132c..e2ff083 100644 --- a/nest_frontend/routes/PageSettings.js +++ b/nest_frontend/routes/PageSettings.js @@ -1,25 +1,36 @@ import React, { useContext } from "react" -import Style from "./PageSettings.module.css" -import classNames from "classnames" import BoxFull from "../components/base/BoxFull" import SelectTheme from "../components/interactive/SelectTheme" import BoxLoggedIn from "../components/interactive/BoxLoggedIn" import SelectLanguage from "../components/interactive/SelectLanguage" import ContextLanguage from "../contexts/ContextLanguage" +import PageWithHeader from "../components/base/layout/PageWithHeader" +import BoxHeader from "../components/base/BoxHeader" +import { faCog } from "@fortawesome/free-solid-svg-icons" +import makeIcon from "../utils/makeIcon" +import BodyFlex from "../components/base/layout/BodyFlex" export default function PageSettings({ children, className, ...props }) { const { strings } = useContext(ContextLanguage) return ( -
- - - - - - - -
+ + {makeIcon(faCog)} {strings.settings} + + } + > + + + + + + + + + + ) } diff --git a/nest_frontend/routes/PageSettings.module.css b/nest_frontend/routes/PageSettings.module.css deleted file mode 100644 index 1f6bff8..0000000 --- a/nest_frontend/routes/PageSettings.module.css +++ /dev/null @@ -1,9 +0,0 @@ -.PageSettings { - display: flex; - flex-direction: column; - - grid-gap: 10px; - - width: 100%; - height: 100%; -} diff --git a/nest_frontend/routes/PageShare.js b/nest_frontend/routes/PageShare.js index 2067461..a0c2fef 100644 --- a/nest_frontend/routes/PageShare.js +++ b/nest_frontend/routes/PageShare.js @@ -1,14 +1,13 @@ import React, { useCallback, useContext } from "react" -import classNames from "classnames" import BoxHeader from "../components/base/BoxHeader" -import ContextLanguage from "../contexts/ContextLanguage" -import Style from "./PageShare.module.css" import BoxUserList from "../components/interactive/BoxUserList" import useBackendViewset from "../hooks/useBackendViewset" import { useParams } from "react-router" import ContextUser from "../contexts/ContextUser" -import Alert from "../components/base/Alert" import useStrings from "../hooks/useStrings" +import PageWithHeader from "../components/base/layout/PageWithHeader" +import BodyHorizontalHalves from "../components/base/layout/BodyHorizontalHalves" +import AlertError from "../components/interactive/AlertError" export default function PageShare({ className, ...props }) { @@ -71,30 +70,35 @@ export default function PageShare({ className, ...props }) { ) return ( -
- - {strings.repoShare} - - user["email"] !== loggedUser["email"] && !authorizations.map(a => a.email).includes(user.email))} - shareWithUser={shareWith} - header={strings.availableUsers} - running={usersBvRunning && authBvRunning} + + {strings.repoShare} + + } + > + user["email"] !== loggedUser["email"] && !authorizations.map(a => a.email).includes(user.email))} + shareWithUser={shareWith} + header={strings.availableUsers} + running={usersBvRunning || authBvRunning} + /> + } + lower={<> + user["email"] === loggedUser["email"] || authorizations.map(a => a.email).includes(user.email))} + unshareWithUser={unshareWith} + header={strings.sharingWith} + running={usersBvRunning || authBvRunning} + /> + } + error={<> + {authBvError ? : null} + {usersBvError ? : null} + } /> - user["email"] === loggedUser["email"] || authorizations.map(a => a.email).includes(user.email))} - unshareWithUser={unshareWith} - header={strings.sharingWith} - running={usersBvRunning && authBvRunning} - /> - {authBvError ? - {strings[authBvError?.data?.code ?? "errorUnknownError"]} - : null} - {usersBvError ? - {strings[usersBvError?.data?.code ?? "errorUnknownError"]} - : null} -
+ ) } diff --git a/nest_frontend/routes/PageShare.module.css b/nest_frontend/routes/PageShare.module.css deleted file mode 100644 index 474f9e1..0000000 --- a/nest_frontend/routes/PageShare.module.css +++ /dev/null @@ -1,32 +0,0 @@ -.PageShare { - display: grid; - - grid-template-areas: - "a" - "b" - "c" - "d"; - grid-template-rows: auto 1fr 1fr auto; - grid-template-columns: 1fr; - grid-gap: 10px; - - width: 100%; - height: 100%; -} - - -.Header { - grid-area: a; -} - -.UserList { - grid-area: b; -} - -.SharingWith { - grid-area: c; -} - -.Error { - grid-area: d; -} \ No newline at end of file diff --git a/nest_frontend/routes/PageUsers.js b/nest_frontend/routes/PageUsers.js index e216cef..b6b7d27 100644 --- a/nest_frontend/routes/PageUsers.js +++ b/nest_frontend/routes/PageUsers.js @@ -1,29 +1,45 @@ import React, { useContext } from "react" -import Style from "./PageUsers.module.css" -import classNames from "classnames" import BoxHeader from "../components/base/BoxHeader" import BoxUserCreate from "../components/interactive/BoxUserCreate" import useBackendViewset from "../hooks/useBackendViewset" import BoxUserList from "../components/interactive/BoxUserList" import ContextLanguage from "../contexts/ContextLanguage" -import Alert from "../components/base/Alert" +import PageWithHeader from "../components/base/layout/PageWithHeader" +import { faUserCog } from "@fortawesome/free-solid-svg-icons" +import makeIcon from "../utils/makeIcon" +import AlertError from "../components/interactive/AlertError" +import BodyHorizontalUpperGrow from "../components/base/layout/BodyHorizontalUpperGrow" export default function PageUsers({ children, className, ...props }) { const { strings } = useContext(ContextLanguage) - const bv = useBackendViewset("/api/v1/users/", "email") + const {createResource, running, resources, destroyResource, error} = useBackendViewset("/api/v1/users/", "email") return ( -
- - {strings.manageUsers} - - - - {bv.error ? - {strings[bv.error?.data?.code ?? "errorUnknownError"]} - : null} -
+ + {makeIcon(faUserCog)} {strings.manageUsers} + + } + > + + } + lower={ + + } + error={error ? : null} + /> + ) } diff --git a/nest_frontend/routes/PageUsers.module.css b/nest_frontend/routes/PageUsers.module.css deleted file mode 100644 index 6731e46..0000000 --- a/nest_frontend/routes/PageUsers.module.css +++ /dev/null @@ -1,32 +0,0 @@ -.PageUsers { - display: grid; - - grid-template-areas: - "a" - "b" - "c" - "e"; - grid-template-rows: auto 1fr auto auto; - grid-template-columns: 1fr; - - grid-gap: 10px; - - width: 100%; - height: 100%; -} - -.Header { - grid-area: a; -} - -.UserList { - grid-area: b; -} - -.CreateUser { - grid-area: c; -} - -.Error { - grid-area: e; -} \ No newline at end of file diff --git a/nest_frontend/utils/countTweetWords.js b/nest_frontend/utils/countTweetWords.js index 172f501..551237c 100644 --- a/nest_frontend/utils/countTweetWords.js +++ b/nest_frontend/utils/countTweetWords.js @@ -4,7 +4,7 @@ import sw from "stopword" const stopwords = [...sw.it, ...sw.en, "rt"] -export default function countTweetWords(tweets = {}) { +export default function countTweetWords(tweets = []) { let words = {} for(const tweet of tweets) { if(!tweet.content) { From 34dec0d920fde860ac982b1c7b214e5785bddca0 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 25 May 2021 04:09:47 +0200 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=A7=B9=20Cleanup=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nest_frontend/routes/PageLogin.js | 3 +- nest_frontend/routes/PageRepositoriesList.js | 2 +- nest_frontend/routes/PageRepositoryAlerts.js | 7 ++-- .../routes/PageRepositoryAlerts.module.css | 35 ------------------- nest_frontend/routes/PageRepositoryAnalyze.js | 2 +- nest_frontend/routes/PageRepositoryCreate.js | 2 +- nest_frontend/routes/PageRepositoryEdit.js | 8 ++--- nest_frontend/routes/PageSettings.js | 2 +- nest_frontend/routes/PageShare.js | 2 +- nest_frontend/routes/PageUsers.js | 2 +- nest_frontend/utils/renderContents.js | 3 ++ 11 files changed, 15 insertions(+), 53 deletions(-) delete mode 100644 nest_frontend/routes/PageRepositoryAlerts.module.css diff --git a/nest_frontend/routes/PageLogin.js b/nest_frontend/routes/PageLogin.js index e041245..f8786b9 100644 --- a/nest_frontend/routes/PageLogin.js +++ b/nest_frontend/routes/PageLogin.js @@ -11,7 +11,7 @@ import PageWithHeader from "../components/base/layout/PageWithHeader" import BodyFlex from "../components/base/layout/BodyFlex" -export default function PageLogin({ ...props }) { +export default function PageLogin() { const {user} = useContext(ContextUser) const strings = useStrings() @@ -26,7 +26,6 @@ export default function PageLogin({ ...props }) { {strings.welcomeToNest} } - {...props} > diff --git a/nest_frontend/routes/PageRepositoriesList.js b/nest_frontend/routes/PageRepositoriesList.js index 04d68e0..e2ac85a 100644 --- a/nest_frontend/routes/PageRepositoriesList.js +++ b/nest_frontend/routes/PageRepositoriesList.js @@ -11,7 +11,7 @@ import ButtonHeader from "../components/base/ButtonHeader" import BodyHorizontalHalves from "../components/base/layout/BodyHorizontalHalves" -export default function PageRepositoriesList({ children, className, ...props }) { +export default function PageRepositoriesList() { const bv = useBackendViewset("/api/v1/repositories/", "id") const history = useHistory() const { strings } = useContext(ContextLanguage) diff --git a/nest_frontend/routes/PageRepositoryAlerts.js b/nest_frontend/routes/PageRepositoryAlerts.js index e8e2927..114c8cd 100644 --- a/nest_frontend/routes/PageRepositoryAlerts.js +++ b/nest_frontend/routes/PageRepositoryAlerts.js @@ -1,5 +1,4 @@ import React, { useContext } from "react" -import Style from "./PageRepositoryAlerts.module.css" import BoxFull from "../components/base/BoxFull" import ContextLanguage from "../contexts/ContextLanguage" import BoxHeader from "../components/base/BoxHeader" @@ -10,7 +9,7 @@ import ButtonHeader from "../components/base/ButtonHeader" import makeIcon from "../utils/makeIcon" -export default function PageRepositoryAlerts({ children, className, ...props }) { +export default function PageRepositoryAlerts({ ...props }) { const { strings } = useContext(ContextLanguage) const { id } = useParams() const history = useHistory() @@ -18,7 +17,7 @@ export default function PageRepositoryAlerts({ children, className, ...props }) return ( + {makeIcon(faBell)} {strings.alerts} } @@ -32,7 +31,7 @@ export default function PageRepositoryAlerts({ children, className, ...props }) } > - + {strings.notImplemented} diff --git a/nest_frontend/routes/PageRepositoryAlerts.module.css b/nest_frontend/routes/PageRepositoryAlerts.module.css deleted file mode 100644 index a1cd711..0000000 --- a/nest_frontend/routes/PageRepositoryAlerts.module.css +++ /dev/null @@ -1,35 +0,0 @@ -.PageAlerts { - display: grid; - - grid-template-areas: - "a x" - "b b"; - grid-template-columns: 4fr 1fr; - grid-template-rows: auto 1fr; - - grid-gap: 10px; - - width: 100%; - height: 100%; -} - -.Header { - grid-area: a; -} - -.Buttons { - grid-area: x; - - display: flex; - flex-direction: row; - align-items: stretch; -} - -.Buttons > * { - box-shadow: none; - flex-grow: 1; -} - -.YourAlerts { - grid-area: b; -} diff --git a/nest_frontend/routes/PageRepositoryAnalyze.js b/nest_frontend/routes/PageRepositoryAnalyze.js index f71d530..cfa67ed 100644 --- a/nest_frontend/routes/PageRepositoryAnalyze.js +++ b/nest_frontend/routes/PageRepositoryAnalyze.js @@ -3,7 +3,7 @@ import { useParams } from "react-router" import RepositoryViewer from "../components/providers/RepositoryViewer" -export default function PageRepositoryAnalyze({ className, ...props }) { +export default function PageRepositoryAnalyze({...props }) { const { id } = useParams() return ( diff --git a/nest_frontend/routes/PageRepositoryCreate.js b/nest_frontend/routes/PageRepositoryCreate.js index 23b9e91..ea3bf41 100644 --- a/nest_frontend/routes/PageRepositoryCreate.js +++ b/nest_frontend/routes/PageRepositoryCreate.js @@ -7,7 +7,7 @@ import makeIcon from "../utils/makeIcon" import { faPlus } from "@fortawesome/free-solid-svg-icons" -export default function PageRepositoryCreate({ ...props }) { +export default function PageRepositoryCreate() { const { strings } = useContext(ContextLanguage) return ( diff --git a/nest_frontend/routes/PageRepositoryEdit.js b/nest_frontend/routes/PageRepositoryEdit.js index 22444ec..8619f68 100644 --- a/nest_frontend/routes/PageRepositoryEdit.js +++ b/nest_frontend/routes/PageRepositoryEdit.js @@ -11,7 +11,7 @@ import makeIcon from "../utils/makeIcon" import { faPencilAlt } from "@fortawesome/free-solid-svg-icons" -export default function PageRepositoryEdit({ className, ...props }) { +export default function PageRepositoryEdit() { const { strings } = useContext(ContextLanguage) const { id } = useParams() @@ -19,10 +19,7 @@ export default function PageRepositoryEdit({ className, ...props }) { const repositoryRequest = useBackendImmediately(fetchDataAuth, "GET", `/api/v1/repositories/${id}`) const contents = renderContents( repositoryRequest, - data => { - console.debug("Data: ", data) - return - }, + data => ) return ( @@ -32,7 +29,6 @@ export default function PageRepositoryEdit({ className, ...props }) { {makeIcon(faPencilAlt)} {strings.repoEdit} } - {...props} > {contents} diff --git a/nest_frontend/routes/PageSettings.js b/nest_frontend/routes/PageSettings.js index e2ff083..6ee0a4f 100644 --- a/nest_frontend/routes/PageSettings.js +++ b/nest_frontend/routes/PageSettings.js @@ -11,7 +11,7 @@ import makeIcon from "../utils/makeIcon" import BodyFlex from "../components/base/layout/BodyFlex" -export default function PageSettings({ children, className, ...props }) { +export default function PageSettings() { const { strings } = useContext(ContextLanguage) return ( diff --git a/nest_frontend/routes/PageShare.js b/nest_frontend/routes/PageShare.js index a0c2fef..d075052 100644 --- a/nest_frontend/routes/PageShare.js +++ b/nest_frontend/routes/PageShare.js @@ -10,7 +10,7 @@ import BodyHorizontalHalves from "../components/base/layout/BodyHorizontalHalves import AlertError from "../components/interactive/AlertError" -export default function PageShare({ className, ...props }) { +export default function PageShare() { const strings = useStrings() const { user: loggedUser } = useContext(ContextUser) const { id } = useParams() diff --git a/nest_frontend/routes/PageUsers.js b/nest_frontend/routes/PageUsers.js index b6b7d27..c897734 100644 --- a/nest_frontend/routes/PageUsers.js +++ b/nest_frontend/routes/PageUsers.js @@ -11,7 +11,7 @@ import AlertError from "../components/interactive/AlertError" import BodyHorizontalUpperGrow from "../components/base/layout/BodyHorizontalUpperGrow" -export default function PageUsers({ children, className, ...props }) { +export default function PageUsers() { const { strings } = useContext(ContextLanguage) const {createResource, running, resources, destroyResource, error} = useBackendViewset("/api/v1/users/", "email") diff --git a/nest_frontend/utils/renderContents.js b/nest_frontend/utils/renderContents.js index f1ea761..9f8eee5 100644 --- a/nest_frontend/utils/renderContents.js +++ b/nest_frontend/utils/renderContents.js @@ -4,6 +4,9 @@ import Alert from "../components/base/Alert" import Starting from "../components/base/Starting" +/** + * @deprecated + */ export default function renderContents(requestHookResults, renderFunction) { const { data, error, loading } = requestHookResults From 7a7dbc79b3ab3d750218784ca817405f5a33e68c Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 25 May 2021 04:28:51 +0200 Subject: [PATCH 3/6] =?UTF-8?q?=E2=9C=A8=20Create=20Create=20a=20new=20ale?= =?UTF-8?q?rt=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nest_frontend/PageSwitcher.js | 4 ++ nest_frontend/routes/PageRepositoryAlerts.js | 2 +- .../routes/PageRepositoryAlertsCreate.js | 44 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 nest_frontend/routes/PageRepositoryAlertsCreate.js diff --git a/nest_frontend/PageSwitcher.js b/nest_frontend/PageSwitcher.js index 7a7e9d9..db7332f 100644 --- a/nest_frontend/PageSwitcher.js +++ b/nest_frontend/PageSwitcher.js @@ -13,6 +13,7 @@ import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons" import makeIcon from "./utils/makeIcon" import useStrings from "./hooks/useStrings" import Alert from "./components/base/Alert" +import PageRepositoryAlertsCreate from "./routes/PageRepositoryAlertsCreate" export default function PageSwitcher({ ...props }) { @@ -23,6 +24,9 @@ export default function PageSwitcher({ ...props }) { + + + diff --git a/nest_frontend/routes/PageRepositoryAlerts.js b/nest_frontend/routes/PageRepositoryAlerts.js index 114c8cd..02a2a1f 100644 --- a/nest_frontend/routes/PageRepositoryAlerts.js +++ b/nest_frontend/routes/PageRepositoryAlerts.js @@ -9,7 +9,7 @@ import ButtonHeader from "../components/base/ButtonHeader" import makeIcon from "../utils/makeIcon" -export default function PageRepositoryAlerts({ ...props }) { +export default function PageRepositoryAlerts() { const { strings } = useContext(ContextLanguage) const { id } = useParams() const history = useHistory() diff --git a/nest_frontend/routes/PageRepositoryAlertsCreate.js b/nest_frontend/routes/PageRepositoryAlertsCreate.js new file mode 100644 index 0000000..bd3ea08 --- /dev/null +++ b/nest_frontend/routes/PageRepositoryAlertsCreate.js @@ -0,0 +1,44 @@ +import React, { useContext } from "react" +import BoxFull from "../components/base/BoxFull" +import ContextLanguage from "../contexts/ContextLanguage" +import BoxHeader from "../components/base/BoxHeader" +import { useHistory, useParams } from "react-router" +import { faPlus } from "@fortawesome/free-solid-svg-icons" +import PageWithHeader from "../components/base/layout/PageWithHeader" +import makeIcon from "../utils/makeIcon" +import useBackendViewset from "../hooks/useBackendViewset" + + +export default function PageRepositoryAlertsCreate() { + const { strings } = useContext(ContextLanguage) + const { id } = useParams() + const history = useHistory() + + const {createResource} = useBackendViewset( + `/api/v1/repositories/${id}/alerts/`, + "name", + { + list: false, + create: true, + retrieve: false, + edit: false, + destroy: false, + command: false, + action: false, + } + ) + + return ( + + {makeIcon(faPlus)} {strings.alertCreate} + + } + > + + {strings.notImplemented} + + + ) +} From be989ed8e90f4a100af5d51c91b0e0e0e206325c Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 25 May 2021 04:39:48 +0200 Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=94=A7=20Refactor=20ContextRepository?= =?UTF-8?q?Editor=20in=20ContextConditionEditor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/interactive/BadgeCondition.js | 2 +- .../interactive/BoxRepositoryCreate.js | 25 +++++++++++++------ .../components/providers/RepositoryEditor.js | 23 ++++++++++------- ...oryEditor.js => ContextConditionEditor.js} | 2 +- nest_frontend/hooks/useRepositoryEditor.js | 2 +- nest_frontend/routes/PageRepositoryCreate.js | 1 - 6 files changed, 34 insertions(+), 21 deletions(-) rename nest_frontend/contexts/{ContextRepositoryEditor.js => ContextConditionEditor.js} (57%) diff --git a/nest_frontend/components/interactive/BadgeCondition.js b/nest_frontend/components/interactive/BadgeCondition.js index dc30660..f450a00 100644 --- a/nest_frontend/components/interactive/BadgeCondition.js +++ b/nest_frontend/components/interactive/BadgeCondition.js @@ -1,5 +1,5 @@ import React, { useContext } from "react" -import ContextRepositoryEditor from "../../contexts/ContextRepositoryEditor" +import ContextRepositoryEditor from "../../contexts/ContextConditionEditor" import Badge from "../base/Badge" diff --git a/nest_frontend/components/interactive/BoxRepositoryCreate.js b/nest_frontend/components/interactive/BoxRepositoryCreate.js index 40182a3..80c0a85 100644 --- a/nest_frontend/components/interactive/BoxRepositoryCreate.js +++ b/nest_frontend/components/interactive/BoxRepositoryCreate.js @@ -15,24 +15,33 @@ import useStrings from "../../hooks/useStrings" /** * A {@link BoxFull} allowing the user to save the changes made in the current {@link RepositoryEditor}. * + * @param id - The id of the repository. + * @param name - The current name of the repository. + * @param setName - Function to change the name of the repository. + * @param evaluationMode - The current evaluation mode of the repository. + * @param setEvaluationMode - Function to change the current evaluation mode of the repository. * @param running - If a request is running, disabling the buttons. + * @param error - If a request error occoured, the error. + * @param revert - Function to cancel the changes made to the repository. + * @param save - Function to apply the changes made to the repository. * @param props - Additional props to pass to the box. * @returns {JSX.Element} * @constructor */ -export default function BoxRepositoryCreate({ running, ...props }) { - const { +export default function BoxRepositoryCreate( + { id, - evaluationMode, - setEvaluationMode, name, setName, - save, - revert, + evaluationMode, + setEvaluationMode, + running, error, - } = useRepositoryEditor() + revert, + save, + ...props + }) { - const history = useHistory() const strings = useStrings() return ( diff --git a/nest_frontend/components/providers/RepositoryEditor.js b/nest_frontend/components/providers/RepositoryEditor.js index 7c2fa94..17e3d09 100644 --- a/nest_frontend/components/providers/RepositoryEditor.js +++ b/nest_frontend/components/providers/RepositoryEditor.js @@ -1,5 +1,5 @@ import React, { useCallback, useContext, useState } from "react" -import ContextRepositoryEditor from "../../contexts/ContextRepositoryEditor" +import ContextConditionEditor from "../../contexts/ContextConditionEditor" import useArrayState from "../../hooks/useArrayState" import Style from "./RepositoryEditor.module.css" import BoxConditionLocation from "../interactive/BoxConditionLocation" @@ -142,14 +142,9 @@ export default function RepositoryEditor({ } return ( -
@@ -158,8 +153,18 @@ export default function RepositoryEditor({ - +
-
+ ) } diff --git a/nest_frontend/contexts/ContextRepositoryEditor.js b/nest_frontend/contexts/ContextConditionEditor.js similarity index 57% rename from nest_frontend/contexts/ContextRepositoryEditor.js rename to nest_frontend/contexts/ContextConditionEditor.js index 3364c6b..a68a4c0 100644 --- a/nest_frontend/contexts/ContextRepositoryEditor.js +++ b/nest_frontend/contexts/ContextConditionEditor.js @@ -2,7 +2,7 @@ import { createContext } from "react" /** - * React Context representing containing all variables of a {@link RepositoryEditor}. + * React Context representing a list of {@link Condition}s as provided by {@link useArrayState}. * * It is `null` outside a RepositoryEditor. */ diff --git a/nest_frontend/hooks/useRepositoryEditor.js b/nest_frontend/hooks/useRepositoryEditor.js index 143f665..dedfce2 100644 --- a/nest_frontend/hooks/useRepositoryEditor.js +++ b/nest_frontend/hooks/useRepositoryEditor.js @@ -1,5 +1,5 @@ import { useContext } from "react" -import ContextRepositoryEditor from "../contexts/ContextRepositoryEditor" +import ContextRepositoryEditor from "../contexts/ContextConditionEditor" /** diff --git a/nest_frontend/routes/PageRepositoryCreate.js b/nest_frontend/routes/PageRepositoryCreate.js index ea3bf41..f8892f1 100644 --- a/nest_frontend/routes/PageRepositoryCreate.js +++ b/nest_frontend/routes/PageRepositoryCreate.js @@ -17,7 +17,6 @@ export default function PageRepositoryCreate() { {makeIcon(faPlus)} {strings.dashboardTitle} } - {...props} > From 8de3de0bf0f4bdd47cf2ac990fc1779a4803b827 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 25 May 2021 04:41:49 +0200 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=90=9B=20Fix=20name=20box=20not=20upd?= =?UTF-8?q?ating?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nest_frontend/components/providers/RepositoryEditor.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nest_frontend/components/providers/RepositoryEditor.js b/nest_frontend/components/providers/RepositoryEditor.js index 17e3d09..c8cb367 100644 --- a/nest_frontend/components/providers/RepositoryEditor.js +++ b/nest_frontend/components/providers/RepositoryEditor.js @@ -155,7 +155,8 @@ export default function RepositoryEditor({ Date: Tue, 25 May 2021 15:38:10 +0200 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=94=A7=20Add=20window=20size=20to=20t?= =?UTF-8?q?he=20alert=20creation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nest_frontend/LocalizationStrings.js | 5 + nest_frontend/PageSwitcher.js | 2 +- .../components/interactive/BoxAlertCreate.js | 109 +++++++++++++ .../components/providers/AlertEditor.js | 145 ++++++++++++++++++ nest_frontend/routes/PageRepositoriesList.js | 2 +- .../routes/PageRepositoryAlertsCreate.js | 25 +-- 6 files changed, 264 insertions(+), 24 deletions(-) create mode 100644 nest_frontend/components/interactive/BoxAlertCreate.js create mode 100644 nest_frontend/components/providers/AlertEditor.js diff --git a/nest_frontend/LocalizationStrings.js b/nest_frontend/LocalizationStrings.js index 9de817f..335e0a9 100644 --- a/nest_frontend/LocalizationStrings.js +++ b/nest_frontend/LocalizationStrings.js @@ -71,6 +71,11 @@ export default { alerts: "Allarmi", alertTitle: "I tuoi allarmi", alertCreate: "Crea un allarme", + alertName: "Nome allarme", // TODO: tradurre + createAlert: "Crea allarme", // TODO: tradurre + alertLimit: "Limite", // TODO: tradurre e migliorare? + alertWindow: "Finestra (in ore)", // TODO: tradurre + notImplemented: "🚧 Non implementato.", settings: "Impostazioni", diff --git a/nest_frontend/PageSwitcher.js b/nest_frontend/PageSwitcher.js index db7332f..41e3cb3 100644 --- a/nest_frontend/PageSwitcher.js +++ b/nest_frontend/PageSwitcher.js @@ -27,7 +27,7 @@ export default function PageSwitcher({ ...props }) { - + diff --git a/nest_frontend/components/interactive/BoxAlertCreate.js b/nest_frontend/components/interactive/BoxAlertCreate.js new file mode 100644 index 0000000..e97a7f2 --- /dev/null +++ b/nest_frontend/components/interactive/BoxAlertCreate.js @@ -0,0 +1,109 @@ +import React from "react" +import BoxFull from "../base/BoxFull" +import FormLabelled from "../base/FormLabelled" +import FormLabel from "../base/formparts/FormLabel" +import InputWithIcon from "../base/InputWithIcon" +import { + faBackward, faBell, + faFolder, + faPencilAlt, + faPlus, faStopwatch, + faThermometerThreeQuarters, +} 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" +import { useHistory } from "react-router" +import useStrings from "../../hooks/useStrings" + + +export default function BoxAlertCreate( + { + name, + setName, + evaluationMode, + setEvaluationMode, + limit, + setLimit, + windowSize, + setWindowSize, + running, + error, + save, + ...props + }) { + + const strings = useStrings() + + return ( + + { + e.preventDefault() + save() + }} + > + + setName(e.target.value)} + /> + + + +   + + + + setLimit(e.target.limit)} + /> + + + setWindowSize(e.target.limit)} + /> + + {error ? + + {strings[error.data.code]} + + : null} + + + + ) +} diff --git a/nest_frontend/components/providers/AlertEditor.js b/nest_frontend/components/providers/AlertEditor.js new file mode 100644 index 0000000..ab365a2 --- /dev/null +++ b/nest_frontend/components/providers/AlertEditor.js @@ -0,0 +1,145 @@ +import React, { useCallback, useState } from "react" +import ContextConditionEditor from "../../contexts/ContextConditionEditor" +import useArrayState from "../../hooks/useArrayState" +import Style from "./RepositoryEditor.module.css" +import BoxConditionLocation from "../interactive/BoxConditionLocation" +import BoxConditionHashtag from "../interactive/BoxConditionHashtag" +import BoxConditionUser from "../interactive/BoxConditionUser" +import BoxConditionDatetime from "../interactive/BoxConditionDatetime" +import BoxConditions from "../interactive/BoxConditions" +import classNames from "classnames" +import { Condition } from "../../objects/Condition" +import useBackendViewset from "../../hooks/useBackendViewset" +import { Redirect, useParams } from "react-router" +import BoxAlertCreate from "../interactive/BoxAlertCreate" + + +export default function AlertEditor({className}) { + /** The connected repository id. */ + const {id: repoId} = useParams() + + /** The alert name. */ + const [_name, setName] = useState("") + + /** The alert limit. */ + const [limit, setLimit] = useState(10) + + /** The window size. */ + const [windowSize, setWindowSize] = useState(24) + + /** The conditions of the data gathering. */ + const { + value: rawConditions, + setValue: setRawConditions, + appendValue: appendRawCondition, + removeValue: removeRawCondition, + spliceValue: spliceRawCondition, + } = useArrayState([]) + const _conditions = rawConditions.map(cond => Condition.fromRaw(cond)) + + /** The operator the conditions should be evaluated with. */ + const [_evaluationMode, setEvaluationMode] = useState(0) + + /** The backend viewset to use to create / edit the repository. */ + const {running, error, createResource} = useBackendViewset( + `/api/v1/repositories/${repoId}/alerts/`, + "name", + { + list: false, + create: true, + retrieve: false, + edit: false, + destroy: false, + command: false, + action: false, + } + ) + + /** If `true`, switches to the repository page on the next render. */ + const [switchPage, setSwitchPage] = useState(false) + + /** + * Save the current changes, creating or editing it as needed. + * + * @type {(function(): Promise)|*} + */ + const save = useCallback( + async () => { + const body = { + "repository_id": repoId, + "name": _name, + "window_size": windowSize, + "limit": limit, + "evaluation_mode": _evaluationMode, + "conditions": _conditions, + } + + console.info("Creating new alert with body: ", body) + await createResource(body) + setSwitchPage(true) + }, + [repoId, createResource, _conditions, _evaluationMode, _name, limit], + ) + + /** + * Try to add a new condition, logging a message to the console if something goes wrong. + * + * @type {(function(): void)|*} + */ + const addCondition = useCallback( + (newCond) => { + + // Check for duplicates + let duplicate = null + for(const oldCond of _conditions) { + if(newCond.type === oldCond.type && newCond.content === oldCond.content) { + duplicate = oldCond + break + } + } + if(duplicate) { + console.debug("Cannot add ", newCond, ": ", duplicate, " already exists.") + return + } + + console.debug("Adding ", newCond, " to the repository conditions") + appendRawCondition(newCond) + }, + [_conditions, appendRawCondition], + ) + + // Hack to switch page on success + if(!error && switchPage) { + return + } + + return ( + +
+ + + + + + +
+
+ ) +} diff --git a/nest_frontend/routes/PageRepositoriesList.js b/nest_frontend/routes/PageRepositoriesList.js index e2ac85a..840fde2 100644 --- a/nest_frontend/routes/PageRepositoriesList.js +++ b/nest_frontend/routes/PageRepositoriesList.js @@ -52,7 +52,7 @@ export default function PageRepositoriesList() { repositories={bv.resources.filter(r => r.is_active)} view={pk => history.push(`/repositories/${pk}`)} share={pk => history.push(`/repositories/${pk}/share`)} - alerts={pk => history.push(`/repositories/${pk}/alerts`)} + alerts={pk => history.push(`/repositories/${pk}/alerts/`)} archive={archive} edit={pk => history.push(`/repositories/${pk}/edit`)} /> diff --git a/nest_frontend/routes/PageRepositoryAlertsCreate.js b/nest_frontend/routes/PageRepositoryAlertsCreate.js index bd3ea08..6ecb44e 100644 --- a/nest_frontend/routes/PageRepositoryAlertsCreate.js +++ b/nest_frontend/routes/PageRepositoryAlertsCreate.js @@ -1,32 +1,15 @@ import React, { useContext } from "react" -import BoxFull from "../components/base/BoxFull" import ContextLanguage from "../contexts/ContextLanguage" import BoxHeader from "../components/base/BoxHeader" -import { useHistory, useParams } from "react-router" +import { useParams } from "react-router" import { faPlus } from "@fortawesome/free-solid-svg-icons" import PageWithHeader from "../components/base/layout/PageWithHeader" import makeIcon from "../utils/makeIcon" -import useBackendViewset from "../hooks/useBackendViewset" +import AlertEditor from "../components/providers/AlertEditor" export default function PageRepositoryAlertsCreate() { const { strings } = useContext(ContextLanguage) - const { id } = useParams() - const history = useHistory() - - const {createResource} = useBackendViewset( - `/api/v1/repositories/${id}/alerts/`, - "name", - { - list: false, - create: true, - retrieve: false, - edit: false, - destroy: false, - command: false, - action: false, - } - ) return ( } > - - {strings.notImplemented} - + ) }