diff --git a/nest_frontend/components/base/Badge.js b/nest_frontend/components/base/Badge.js index 86006ca..c20a515 100644 --- a/nest_frontend/components/base/Badge.js +++ b/nest_frontend/components/base/Badge.js @@ -28,12 +28,12 @@ export default function Badge({ icon, color, onClickDelete, children, className, { onClickDelete ? -
- -
- : null +
+ +
+ : null } ) diff --git a/nest_frontend/components/base/BoxMap.js b/nest_frontend/components/base/BoxMap.js index 1ba1ad8..617ab24 100644 --- a/nest_frontend/components/base/BoxMap.js +++ b/nest_frontend/components/base/BoxMap.js @@ -4,7 +4,15 @@ import BoxFull from "./BoxFull" import { MapContainer, TileLayer } from "react-leaflet" -export default function BoxMap({ header, setMap, startingPosition = { lat: 41.89309, lng: 12.48289 }, startingZoom = 3, button, children, ...props }) { +export default function BoxMap({ + header, + setMap, + startingPosition = { lat: 41.89309, lng: 12.48289 }, + startingZoom = 3, + button, + children, + ...props + }) { return (
diff --git a/nest_frontend/components/interactive/BoxRepositories.js b/nest_frontend/components/interactive/BoxRepositories.js index 3d96d9a..1754b78 100644 --- a/nest_frontend/components/interactive/BoxRepositories.js +++ b/nest_frontend/components/interactive/BoxRepositories.js @@ -1,7 +1,6 @@ -import React, { useContext } from "react" +import React from "react" import BoxFullScrollable from "../base/BoxFullScrollable" import Loading from "../base/Loading" -import ContextLanguage from "../../contexts/ContextLanguage" import SummaryRepository from "./SummaryRepository" import Empty from "./Empty" @@ -21,7 +20,17 @@ import Empty from "./Empty" * @returns {JSX.Element} * @constructor */ -export default function BoxRepositories({ repositories, view, archive, edit, destroy, loading, running, className, ...props }) { +export default function BoxRepositories({ + repositories, + view, + archive, + edit, + destroy, + loading, + running, + className, + ...props + }) { let contents if(loading) { contents = diff --git a/nest_frontend/components/interactive/BoxVisualizationMap.js b/nest_frontend/components/interactive/BoxVisualizationMap.js index 96f7f8a..b864748 100644 --- a/nest_frontend/components/interactive/BoxVisualizationMap.js +++ b/nest_frontend/components/interactive/BoxVisualizationMap.js @@ -8,7 +8,7 @@ const locationRegex = /[{](?[0-9.]+),(?[0-9.]+)[}]/ export default function BoxVisualizationMap({ tweets, ...props }) { // TODO: translate this - const {strings} = useContext(ContextLanguage) + const { strings } = useContext(ContextLanguage) console.debug(tweets) const markers = tweets.filter(tweet => tweet.location).map(tweet => { @@ -17,7 +17,7 @@ export default function BoxVisualizationMap({ tweets, ...props }) { console.error("No match for location ", tweet.location) return null } - const {lat, lng} = match.groups + const { lat, lng } = match.groups return ( diff --git a/nest_frontend/components/interactive/BoxVisualizationStats.js b/nest_frontend/components/interactive/BoxVisualizationStats.js index f813ff0..e6931c7 100644 --- a/nest_frontend/components/interactive/BoxVisualizationStats.js +++ b/nest_frontend/components/interactive/BoxVisualizationStats.js @@ -2,34 +2,33 @@ import React, { useMemo } from "react" import FormLabelled from "../base/FormLabelled" import FormLabel from "../base/formparts/FormLabel" import BoxFullScrollable from "../base/BoxFullScrollable" -import tokenizeTweetWords from "../../utils/countTweetWords" export default function BoxVisualizationStats({ tweets, words, totalTweetCount, ...props }) { const tweetCount = useMemo( () => tweets.length, - [tweets] + [tweets], ) const tweetPct = useMemo( () => tweetCount / totalTweetCount * 100, - [tweetCount, totalTweetCount] + [tweetCount, totalTweetCount], ) const tweetLocationCount = useMemo( () => tweets.filter(tweet => tweet.location).length, - [tweets] + [tweets], ) const tweetLocationPct = useMemo( () => tweetLocationCount / tweetCount * 100, - [tweetLocationCount, tweetCount] + [tweetLocationCount, tweetCount], ) const tweetContent = useMemo( () => tweets.filter(tweet => tweet.content), - [tweets] + [tweets], ) const tweetContentCount = useMemo( @@ -45,51 +44,61 @@ export default function BoxVisualizationStats({ tweets, words, totalTweetCount, console.debug(words) const wordCount = useMemo( - () => words.map(word => word.value).reduce((a, b) => a+b), - [words] + () => words.map(word => word.value).reduce((a, b) => a + b), + [words], ) const mostPopularWord = useMemo( () => { return words.sort((wa, wb) => { - if(wa.value > wb.value) return -1 - if(wa.value < wb.value) return 1 + if(wa.value > wb.value) { + return -1 + } + if(wa.value < wb.value) { + return 1 + } return 0 })[0].text }, - [words] + [words], ) const users = useMemo( () => tweets.map(tweet => tweet.poster), - [tweets] + [tweets], ) const uniqueUsers = useMemo( () => [...new Set(users)], - [users] + [users], ) const uniqueUsersCount = useMemo( () => uniqueUsers.length, - [uniqueUsers] + [uniqueUsers], ) const mostActiveUser = useMemo( () => { - if(uniqueUsers.length === 0) return null + if(uniqueUsers.length === 0) { + return null + } return uniqueUsers.map(user => { return { user: user, - count: tweets.filter(tweet => tweet.poster === user).length + count: tweets.filter(tweet => tweet.poster === user).length, } }).sort((a, b) => { - if(a.count > b.count) return -1 - if(a.count < b.count) return 1 + if(a.count > b.count) { + return -1 + } + if(a.count < b.count) { + return 1 + } return 0 })[0] }, - [uniqueUsers, tweets] + [uniqueUsers, tweets], ) // TODO: tweets with picture count diff --git a/nest_frontend/components/interactive/BoxVisualizationWordcloud.js b/nest_frontend/components/interactive/BoxVisualizationWordcloud.js index 531d369..780e1a3 100644 --- a/nest_frontend/components/interactive/BoxVisualizationWordcloud.js +++ b/nest_frontend/components/interactive/BoxVisualizationWordcloud.js @@ -4,7 +4,7 @@ import ContextLanguage from "../../contexts/ContextLanguage" export default function BoxVisualizationWordcloud({ words, ...props }) { - const {strings} = useContext(ContextLanguage) + const { strings } = useContext(ContextLanguage) return ( diff --git a/nest_frontend/components/interactive/PickerFilter.js b/nest_frontend/components/interactive/PickerFilter.js index 253d8d1..ffc1b77 100644 --- a/nest_frontend/components/interactive/PickerFilter.js +++ b/nest_frontend/components/interactive/PickerFilter.js @@ -1,15 +1,24 @@ import React from "react" import ButtonIconOnly from "../base/ButtonIconOnly" -import { faAt, faChartBar, faClock, faCloud, faHashtag, faMap, faMapPin } from "@fortawesome/free-solid-svg-icons" +import { faAt, faClock, faHashtag, faMapPin } from "@fortawesome/free-solid-svg-icons" export default function PickerFilter({ currentTab, setTab, ...props }) { return (
- setTab("hashtag")} disabled={currentTab === "hashtag"} color={"Grey"} icon={faHashtag}/> + setTab("hashtag")} disabled={currentTab === + "hashtag"} color={"Grey"} icon={faHashtag} + /> setTab("user")} disabled={currentTab === "user"} color={"Grey"} icon={faAt}/> - setTab("location")} disabled={currentTab === "location"} color={"Grey"} icon={faMapPin}/> - setTab("time")} disabled={currentTab === "time"} color={"Grey"} icon={faClock}/> + setTab("location")} disabled={currentTab === + "location"} color={"Grey"} icon={faMapPin} + /> + setTab("time")} disabled={currentTab === + "time"} color={"Grey"} icon={faClock} + />
) } diff --git a/nest_frontend/components/interactive/PickerVisualization.js b/nest_frontend/components/interactive/PickerVisualization.js index 4ed09c5..7117bd0 100644 --- a/nest_frontend/components/interactive/PickerVisualization.js +++ b/nest_frontend/components/interactive/PickerVisualization.js @@ -1,24 +1,24 @@ import React from "react" import ButtonIconOnly from "../base/ButtonIconOnly" -import { - faAt, - faChartBar, - faClock, - faCloud, - faHashtag, - faMap, - faMapPin, - faStar, -} from "@fortawesome/free-solid-svg-icons" +import { faChartBar, faCloud, faMap, faStar } from "@fortawesome/free-solid-svg-icons" export default function PickerVisualization({ currentTab, setTab, ...props }) { return (
- setTab("wordcloud")} disabled={currentTab === "wordcloud"} color={"Grey"} icon={faCloud}/> - setTab("histogram")} disabled={currentTab === "histogram"} color={"Grey"} icon={faChartBar}/> + setTab("wordcloud")} disabled={currentTab === + "wordcloud"} color={"Grey"} icon={faCloud} + /> + setTab("histogram")} disabled={currentTab === + "histogram"} color={"Grey"} icon={faChartBar} + /> setTab("map")} disabled={currentTab === "map"} color={"Grey"} icon={faMap}/> - setTab("stats")} disabled={currentTab === "stats"} color={"Grey"} icon={faStar}/> + setTab("stats")} disabled={currentTab === + "stats"} color={"Grey"} icon={faStar} + />
) } diff --git a/nest_frontend/components/interactive/SummaryRepository.js b/nest_frontend/components/interactive/SummaryRepository.js index 524f80f..0a64101 100644 --- a/nest_frontend/components/interactive/SummaryRepository.js +++ b/nest_frontend/components/interactive/SummaryRepository.js @@ -1,6 +1,5 @@ import React, { useContext } from "react" import { faArchive, faFolder, faFolderOpen, faPencilAlt, faTrash } from "@fortawesome/free-solid-svg-icons" -import { useHistory } from "react-router" import ContextLanguage from "../../contexts/ContextLanguage" import SummaryBase from "../base/summary/SummaryBase" import SummaryLeft from "../base/summary/SummaryLeft" @@ -45,37 +44,37 @@ export default function SummaryRepository( /> {destroy ? - destroy(repo["id"])} - disabled={running} - > - {strings.delete} - - : null} + destroy(repo["id"])} + disabled={running} + > + {strings.delete} + + : null} {archive ? - archive(repo["id"])} - disabled={running} - > - {strings.archive} - - : null} + archive(repo["id"])} + disabled={running} + > + {strings.archive} + + : null} {edit ? - edit(repo["id"])} - disabled={running} - > - {strings.edit} - - : null} + edit(repo["id"])} + disabled={running} + > + {strings.edit} + + : null} diff --git a/nest_frontend/components/interactive/SummaryTweet.js b/nest_frontend/components/interactive/SummaryTweet.js index 2b45ac7..b3d2809 100644 --- a/nest_frontend/components/interactive/SummaryTweet.js +++ b/nest_frontend/components/interactive/SummaryTweet.js @@ -1,7 +1,7 @@ import React from "react" import SummaryBase from "../base/summary/SummaryBase" import SummaryLeft from "../base/summary/SummaryLeft" -import { faComment, faLocationArrow, faMapMarker, faMapMarkerAlt, faMapPin } from "@fortawesome/free-solid-svg-icons" +import { faComment, faLocationArrow, faMapMarkerAlt } from "@fortawesome/free-solid-svg-icons" import SummaryText from "../base/summary/SummaryText" import SummaryRight from "../base/summary/SummaryRight" diff --git a/nest_frontend/components/interactive/SummaryUser.js b/nest_frontend/components/interactive/SummaryUser.js index 98e34cb..395763b 100644 --- a/nest_frontend/components/interactive/SummaryUser.js +++ b/nest_frontend/components/interactive/SummaryUser.js @@ -22,18 +22,18 @@ export default function SummaryUser({ user, destroyUser, running, ...props }) { upperLabel={strings.type} upperValue={user.isAdmin ? strings.admin : strings.user} /> - { - event.stopPropagation() - // TODO: Errors are not caught here. Where should they be displayed? - await destroyUser(user["email"]) - }} - disabled={running} - > - {strings.delete} - + { + event.stopPropagation() + // TODO: Errors are not caught here. Where should they be displayed? + await destroyUser(user["email"]) + }} + disabled={running} + > + {strings.delete} + ) diff --git a/nest_frontend/hooks/useBackendRequest.js b/nest_frontend/hooks/useBackendRequest.js index 5474967..9c85044 100644 --- a/nest_frontend/hooks/useBackendRequest.js +++ b/nest_frontend/hooks/useBackendRequest.js @@ -76,7 +76,7 @@ export default function useBackendRequest() { try { json = await response.json() } - catch (error) { + catch(error) { throw new DecodeError(response.status, response.statusText, error) } diff --git a/nest_frontend/hooks/useBackendResource.js b/nest_frontend/hooks/useBackendResource.js index c356487..5a447ad 100644 --- a/nest_frontend/hooks/useBackendResource.js +++ b/nest_frontend/hooks/useBackendResource.js @@ -1,7 +1,4 @@ -import { useCallback, useContext, useEffect, useState } from "react" -import ContextServer from "../contexts/ContextServer" -import ContextUser from "../contexts/ContextUser" -import makeURLSearchParams from "../utils/makeURLSearchParams" +import { useCallback, useEffect, useState } from "react" import useBackendRequest from "./useBackendRequest" @@ -11,15 +8,17 @@ import useBackendRequest from "./useBackendRequest" * @param resourcePath - The path of the resource file. * @param allowViews - An object with maps views to a boolean detailing if they're allowed in the viewset or not. */ -export default function useBackendResource(resourcePath, - { - retrieve: allowRetrieve = true, - edit: allowEdit = true, - destroy: allowDestroy = true, - action: allowAction = false, - } = {}) { +export default function useBackendResource( + resourcePath, + { + retrieve: allowRetrieve = true, + edit: allowEdit = true, + destroy: allowDestroy = true, + action: allowAction = false, + } = {}, +) { - const {abort, running, apiRequest} = useBackendRequest() + const { abort, running, apiRequest } = useBackendRequest() const [firstLoad, setFirstLoad] = useState(false) const [resource, setResource] = useState(null) @@ -27,7 +26,9 @@ export default function useBackendResource(resourcePath, const apiRetrieve = useCallback( async (init) => { - if(!allowRetrieve) throw new ViewNotAllowedError("retrieve") + if(!allowRetrieve) { + throw new ViewNotAllowedError("retrieve") + } return await apiRequest("GET", `${resourcePath}`, undefined, init) }, [apiRequest, allowRetrieve, resourcePath], @@ -35,7 +36,9 @@ export default function useBackendResource(resourcePath, const apiEdit = useCallback( async (data, init) => { - if(!allowEdit) throw new ViewNotAllowedError("edit") + if(!allowEdit) { + throw new ViewNotAllowedError("edit") + } return await apiRequest("PUT", `${resourcePath}`, data, init) }, [apiRequest, allowEdit, resourcePath], @@ -43,7 +46,9 @@ export default function useBackendResource(resourcePath, const apiDestroy = useCallback( async (init) => { - if(!allowDestroy) throw new ViewNotAllowedError("destroy") + if(!allowDestroy) { + throw new ViewNotAllowedError("destroy") + } return await apiRequest("DELETE", `${resourcePath}`, undefined, init) }, [apiRequest, allowDestroy, resourcePath], @@ -51,10 +56,12 @@ export default function useBackendResource(resourcePath, const apiAction = useCallback( async (method, command, data, init) => { - if(!allowAction) throw new ViewNotAllowedError("action") + if(!allowAction) { + throw new ViewNotAllowedError("action") + } return await apiRequest(method, `${resourcePath}/${command}`, data, init) }, - [apiRequest, allowAction, resourcePath] + [apiRequest, allowAction, resourcePath], ) const retrieveResource = useCallback( diff --git a/nest_frontend/hooks/useBackendViewset.js b/nest_frontend/hooks/useBackendViewset.js index f2396d6..a9e6a83 100644 --- a/nest_frontend/hooks/useBackendViewset.js +++ b/nest_frontend/hooks/useBackendViewset.js @@ -18,8 +18,9 @@ export default function useBackendViewset(resourcesPath, pkName, destroy: allowDestroy = true, command: allowCommand = false, action: allowAction = false, - } = {}) { - const {abort, running, apiRequest} = useBackendRequest() + } = {}, +) { + const { abort, running, apiRequest } = useBackendRequest() const [firstLoad, setFirstLoad] = useState(false) const [resources, setResources] = useState([]) @@ -27,7 +28,9 @@ export default function useBackendViewset(resourcesPath, pkName, const apiList = useCallback( async (init) => { - if(!allowList) throw new ViewNotAllowedError("list") + if(!allowList) { + throw new ViewNotAllowedError("list") + } return await apiRequest("GET", `${resourcesPath}`, undefined, init) }, [apiRequest, allowList, resourcesPath], @@ -35,7 +38,9 @@ export default function useBackendViewset(resourcesPath, pkName, const apiRetrieve = useCallback( async (id, init) => { - if(!allowRetrieve) throw new ViewNotAllowedError("retrieve") + if(!allowRetrieve) { + throw new ViewNotAllowedError("retrieve") + } return await apiRequest("GET", `${resourcesPath}${id}`, undefined, init) }, [apiRequest, allowRetrieve, resourcesPath], @@ -43,7 +48,9 @@ export default function useBackendViewset(resourcesPath, pkName, const apiCreate = useCallback( async (data, init) => { - if(!allowCreate) throw new ViewNotAllowedError("create") + if(!allowCreate) { + throw new ViewNotAllowedError("create") + } return await apiRequest("POST", `${resourcesPath}`, data, init) }, [apiRequest, allowCreate, resourcesPath], @@ -51,7 +58,9 @@ export default function useBackendViewset(resourcesPath, pkName, const apiEdit = useCallback( async (id, data, init) => { - if(!allowEdit) throw new ViewNotAllowedError("edit") + if(!allowEdit) { + throw new ViewNotAllowedError("edit") + } return await apiRequest("PUT", `${resourcesPath}${id}`, data, init) }, [apiRequest, allowEdit, resourcesPath], @@ -59,7 +68,9 @@ export default function useBackendViewset(resourcesPath, pkName, const apiDestroy = useCallback( async (id, init) => { - if(!allowDestroy) throw new ViewNotAllowedError("destroy") + if(!allowDestroy) { + throw new ViewNotAllowedError("destroy") + } return await apiRequest("DELETE", `${resourcesPath}${id}`, undefined, init) }, [apiRequest, allowDestroy, resourcesPath], @@ -67,18 +78,22 @@ export default function useBackendViewset(resourcesPath, pkName, const apiCommand = useCallback( async (method, command, data, init) => { - if(!allowCommand) throw new ViewNotAllowedError("command") + if(!allowCommand) { + throw new ViewNotAllowedError("command") + } return await apiRequest(method, `${resourcesPath}${command}`, data, init) }, - [apiRequest, allowCommand, resourcesPath] + [apiRequest, allowCommand, resourcesPath], ) const apiAction = useCallback( async (method, id, command, data, init) => { - if(!allowAction) throw new ViewNotAllowedError("action") + if(!allowAction) { + throw new ViewNotAllowedError("action") + } return await apiRequest(method, `${resourcesPath}${id}/${command}`, data, init) }, - [apiRequest, allowAction, resourcesPath] + [apiRequest, allowAction, resourcesPath], ) const listResources = useCallback( diff --git a/nest_frontend/routes/PageDashboard.js b/nest_frontend/routes/PageDashboard.js index 5a00b93..9361a9c 100644 --- a/nest_frontend/routes/PageDashboard.js +++ b/nest_frontend/routes/PageDashboard.js @@ -1,4 +1,4 @@ -import React, {useContext} from "react" +import React, { useContext } from "react" import Style from "./PageDashboard.module.css" import classNames from "classnames" import BoxHeader from "../components/base/BoxHeader" diff --git a/nest_frontend/routes/PageRepositories.js b/nest_frontend/routes/PageRepositories.js index 98d7d93..97fbf13 100644 --- a/nest_frontend/routes/PageRepositories.js +++ b/nest_frontend/routes/PageRepositories.js @@ -10,7 +10,7 @@ import ContextLanguage from "../contexts/ContextLanguage" export default function PageRepositories({ children, className, ...props }) { const bv = useBackendViewset("/api/v1/repositories/", "id") const history = useHistory() - const {strings} = useContext(ContextLanguage) + const { strings } = useContext(ContextLanguage) const archive = useCallback( async (pk) => { diff --git a/nest_frontend/routes/PageRepository.js b/nest_frontend/routes/PageRepository.js index 406c309..1783630 100644 --- a/nest_frontend/routes/PageRepository.js +++ b/nest_frontend/routes/PageRepository.js @@ -8,7 +8,7 @@ import PickerFilter from "../components/interactive/PickerFilter" import useBackendViewset from "../hooks/useBackendViewset" import useBackendResource from "../hooks/useBackendResource" import { faFolder, faFolderOpen, faTrash } from "@fortawesome/free-solid-svg-icons" -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome" +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { useParams } from "react-router" import Loading from "../components/base/Loading" import BoxVisualizationStats from "../components/interactive/BoxVisualizationStats" @@ -17,14 +17,13 @@ import BoxVisualizationMap from "../components/interactive/BoxVisualizationMap" import BoxVisualizationWordcloud from "../components/interactive/BoxVisualizationWordcloud" import BoxFull from "../components/base/BoxFull" import ContextLanguage from "../contexts/ContextLanguage" -import tokenizeTweetWords from "../utils/countTweetWords" import countTweetWords from "../utils/countTweetWords" import objectToWordcloudFormat from "../utils/objectToWordcloudFormat" export default function PageRepository({ className, ...props }) { - const {id} = useParams() - const {strings} = useContext(ContextLanguage) + const { id } = useParams() + const { strings } = useContext(ContextLanguage) const [visualizationTab, setVisualizationTab] = useState("wordcloud") const [addFilterTab, setAddFilterTab] = useState("hashtag") @@ -36,7 +35,7 @@ export default function PageRepository({ className, ...props }) { edit: true, destroy: true, action: false, - } + }, ) const repository = repositoryBr.error ? null : repositoryBr.resource @@ -51,16 +50,16 @@ export default function PageRepository({ className, ...props }) { destroy: false, command: false, action: false, - } + }, ) const tweets = tweetsBv.resources && tweetsBv.error ? [] : tweetsBv.resources const words = useMemo( () => objectToWordcloudFormat(countTweetWords(tweets)), - [tweets] + [tweets], ) - let contents; + let contents if(!repositoryBr.firstLoad || !tweetsBv.firstLoad) { contents = <> @@ -93,32 +92,32 @@ export default function PageRepository({ className, ...props }) { setTab={setVisualizationTab} /> {visualizationTab === "wordcloud" ? - - : null} + + : null} {visualizationTab === "histogram" ? - - : null} + + : null} {visualizationTab === "map" ? - - : null} + + : null} {visualizationTab === "stats" ? - - : null} + + : null}