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

🧹 Reformat code

This commit is contained in:
Steffo 2021-05-20 12:16:01 +02:00
parent df4b9bb368
commit 6a99effc8b
Signed by: steffo
GPG key ID: 6965406171929D01
22 changed files with 225 additions and 159 deletions

View file

@ -28,12 +28,12 @@ export default function Badge({ icon, color, onClickDelete, children, className,
</div> </div>
{ {
onClickDelete ? onClickDelete ?
<div> <div>
<ButtonSmallX <ButtonSmallX
onClick={onClickDelete} onClick={onClickDelete}
/> />
</div> </div>
: null : null
} }
</div> </div>
) )

View file

@ -4,7 +4,15 @@ import BoxFull from "./BoxFull"
import { MapContainer, TileLayer } from "react-leaflet" 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 ( return (
<BoxFull <BoxFull
header={header} header={header}

View file

@ -3,7 +3,15 @@ import Style from "./SummaryLabels.module.css"
import classNames from "classnames" import classNames from "classnames"
export default function SummaryLabels({ children, upperLabel, upperValue, lowerLabel, lowerValue, className, ...props }) { export default function SummaryLabels({
children,
upperLabel,
upperValue,
lowerLabel,
lowerValue,
className,
...props
}) {
return ( return (
<div className={classNames(Style.SummaryLabels, className)} {...props}> <div className={classNames(Style.SummaryLabels, className)} {...props}>
<div className={classNames(Style.Label, Style.Upper)}> <div className={classNames(Style.Label, Style.Upper)}>

View file

@ -1,7 +1,6 @@
import React, { useContext } from "react" import React from "react"
import BoxFullScrollable from "../base/BoxFullScrollable" import BoxFullScrollable from "../base/BoxFullScrollable"
import Loading from "../base/Loading" import Loading from "../base/Loading"
import ContextLanguage from "../../contexts/ContextLanguage"
import SummaryRepository from "./SummaryRepository" import SummaryRepository from "./SummaryRepository"
import Empty from "./Empty" import Empty from "./Empty"
@ -21,7 +20,17 @@ import Empty from "./Empty"
* @returns {JSX.Element} * @returns {JSX.Element}
* @constructor * @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 let contents
if(loading) { if(loading) {
contents = <Loading/> contents = <Loading/>

View file

@ -8,7 +8,7 @@ const locationRegex = /[{](?<lat>[0-9.]+),(?<lng>[0-9.]+)[}]/
export default function BoxVisualizationMap({ tweets, ...props }) { export default function BoxVisualizationMap({ tweets, ...props }) {
// TODO: translate this // TODO: translate this
const {strings} = useContext(ContextLanguage) const { strings } = useContext(ContextLanguage)
console.debug(tweets) console.debug(tweets)
const markers = tweets.filter(tweet => tweet.location).map(tweet => { 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) console.error("No match for location ", tweet.location)
return null return null
} }
const {lat, lng} = match.groups const { lat, lng } = match.groups
return ( return (
<Marker key={tweet["snowflake"]} position={[Number.parseFloat(lat), Number.parseFloat(lng)]}> <Marker key={tweet["snowflake"]} position={[Number.parseFloat(lat), Number.parseFloat(lng)]}>
<Popup> <Popup>

View file

@ -2,34 +2,33 @@ import React, { useMemo } from "react"
import FormLabelled from "../base/FormLabelled" import FormLabelled from "../base/FormLabelled"
import FormLabel from "../base/formparts/FormLabel" import FormLabel from "../base/formparts/FormLabel"
import BoxFullScrollable from "../base/BoxFullScrollable" import BoxFullScrollable from "../base/BoxFullScrollable"
import tokenizeTweetWords from "../../utils/countTweetWords"
export default function BoxVisualizationStats({ tweets, words, totalTweetCount, ...props }) { export default function BoxVisualizationStats({ tweets, words, totalTweetCount, ...props }) {
const tweetCount = useMemo( const tweetCount = useMemo(
() => tweets.length, () => tweets.length,
[tweets] [tweets],
) )
const tweetPct = useMemo( const tweetPct = useMemo(
() => tweetCount / totalTweetCount * 100, () => tweetCount / totalTweetCount * 100,
[tweetCount, totalTweetCount] [tweetCount, totalTweetCount],
) )
const tweetLocationCount = useMemo( const tweetLocationCount = useMemo(
() => tweets.filter(tweet => tweet.location).length, () => tweets.filter(tweet => tweet.location).length,
[tweets] [tweets],
) )
const tweetLocationPct = useMemo( const tweetLocationPct = useMemo(
() => tweetLocationCount / tweetCount * 100, () => tweetLocationCount / tweetCount * 100,
[tweetLocationCount, tweetCount] [tweetLocationCount, tweetCount],
) )
const tweetContent = useMemo( const tweetContent = useMemo(
() => tweets.filter(tweet => tweet.content), () => tweets.filter(tweet => tweet.content),
[tweets] [tweets],
) )
const tweetContentCount = useMemo( const tweetContentCount = useMemo(
@ -45,51 +44,61 @@ export default function BoxVisualizationStats({ tweets, words, totalTweetCount,
console.debug(words) console.debug(words)
const wordCount = useMemo( const wordCount = useMemo(
() => words.map(word => word.value).reduce((a, b) => a+b), () => words.map(word => word.value).reduce((a, b) => a + b),
[words] [words],
) )
const mostPopularWord = useMemo( const mostPopularWord = useMemo(
() => { () => {
return words.sort((wa, wb) => { return words.sort((wa, wb) => {
if(wa.value > wb.value) return -1 if(wa.value > wb.value) {
if(wa.value < wb.value) return 1 return -1
}
if(wa.value < wb.value) {
return 1
}
return 0 return 0
})[0].text })[0].text
}, },
[words] [words],
) )
const users = useMemo( const users = useMemo(
() => tweets.map(tweet => tweet.poster), () => tweets.map(tweet => tweet.poster),
[tweets] [tweets],
) )
const uniqueUsers = useMemo( const uniqueUsers = useMemo(
() => [...new Set(users)], () => [...new Set(users)],
[users] [users],
) )
const uniqueUsersCount = useMemo( const uniqueUsersCount = useMemo(
() => uniqueUsers.length, () => uniqueUsers.length,
[uniqueUsers] [uniqueUsers],
) )
const mostActiveUser = useMemo( const mostActiveUser = useMemo(
() => { () => {
if(uniqueUsers.length === 0) return null if(uniqueUsers.length === 0) {
return null
}
return uniqueUsers.map(user => { return uniqueUsers.map(user => {
return { return {
user: user, user: user,
count: tweets.filter(tweet => tweet.poster === user).length count: tweets.filter(tweet => tweet.poster === user).length,
} }
}).sort((a, b) => { }).sort((a, b) => {
if(a.count > b.count) return -1 if(a.count > b.count) {
if(a.count < b.count) return 1 return -1
}
if(a.count < b.count) {
return 1
}
return 0 return 0
})[0] })[0]
}, },
[uniqueUsers, tweets] [uniqueUsers, tweets],
) )
// TODO: tweets with picture count // TODO: tweets with picture count

View file

@ -4,7 +4,7 @@ import ContextLanguage from "../../contexts/ContextLanguage"
export default function BoxVisualizationWordcloud({ words, ...props }) { export default function BoxVisualizationWordcloud({ words, ...props }) {
const {strings} = useContext(ContextLanguage) const { strings } = useContext(ContextLanguage)
return ( return (
<BoxWordcloud header={strings.wordcloud} words={words} {...props}/> <BoxWordcloud header={strings.wordcloud} words={words} {...props}/>

View file

@ -1,15 +1,24 @@
import React from "react" import React from "react"
import ButtonIconOnly from "../base/ButtonIconOnly" 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 }) { export default function PickerFilter({ currentTab, setTab, ...props }) {
return ( return (
<div {...props}> <div {...props}>
<ButtonIconOnly onClick={() => setTab("hashtag")} disabled={currentTab === "hashtag"} color={"Grey"} icon={faHashtag}/> <ButtonIconOnly
onClick={() => setTab("hashtag")} disabled={currentTab ===
"hashtag"} color={"Grey"} icon={faHashtag}
/>
<ButtonIconOnly onClick={() => setTab("user")} disabled={currentTab === "user"} color={"Grey"} icon={faAt}/> <ButtonIconOnly onClick={() => setTab("user")} disabled={currentTab === "user"} color={"Grey"} icon={faAt}/>
<ButtonIconOnly onClick={() => setTab("location")} disabled={currentTab === "location"} color={"Grey"} icon={faMapPin}/> <ButtonIconOnly
<ButtonIconOnly onClick={() => setTab("time")} disabled={currentTab === "time"} color={"Grey"} icon={faClock}/> onClick={() => setTab("location")} disabled={currentTab ===
"location"} color={"Grey"} icon={faMapPin}
/>
<ButtonIconOnly
onClick={() => setTab("time")} disabled={currentTab ===
"time"} color={"Grey"} icon={faClock}
/>
</div> </div>
) )
} }

View file

@ -1,24 +1,24 @@
import React from "react" import React from "react"
import ButtonIconOnly from "../base/ButtonIconOnly" import ButtonIconOnly from "../base/ButtonIconOnly"
import { import { faChartBar, faCloud, faMap, faStar } from "@fortawesome/free-solid-svg-icons"
faAt,
faChartBar,
faClock,
faCloud,
faHashtag,
faMap,
faMapPin,
faStar,
} from "@fortawesome/free-solid-svg-icons"
export default function PickerVisualization({ currentTab, setTab, ...props }) { export default function PickerVisualization({ currentTab, setTab, ...props }) {
return ( return (
<div {...props}> <div {...props}>
<ButtonIconOnly onClick={() => setTab("wordcloud")} disabled={currentTab === "wordcloud"} color={"Grey"} icon={faCloud}/> <ButtonIconOnly
<ButtonIconOnly onClick={() => setTab("histogram")} disabled={currentTab === "histogram"} color={"Grey"} icon={faChartBar}/> onClick={() => setTab("wordcloud")} disabled={currentTab ===
"wordcloud"} color={"Grey"} icon={faCloud}
/>
<ButtonIconOnly
onClick={() => setTab("histogram")} disabled={currentTab ===
"histogram"} color={"Grey"} icon={faChartBar}
/>
<ButtonIconOnly onClick={() => setTab("map")} disabled={currentTab === "map"} color={"Grey"} icon={faMap}/> <ButtonIconOnly onClick={() => setTab("map")} disabled={currentTab === "map"} color={"Grey"} icon={faMap}/>
<ButtonIconOnly onClick={() => setTab("stats")} disabled={currentTab === "stats"} color={"Grey"} icon={faStar}/> <ButtonIconOnly
onClick={() => setTab("stats")} disabled={currentTab ===
"stats"} color={"Grey"} icon={faStar}
/>
</div> </div>
) )
} }

View file

@ -1,6 +1,5 @@
import React, { useContext } from "react" import React, { useContext } from "react"
import { faArchive, faFolder, faFolderOpen, faPencilAlt, faTrash } from "@fortawesome/free-solid-svg-icons" import { faArchive, faFolder, faFolderOpen, faPencilAlt, faTrash } from "@fortawesome/free-solid-svg-icons"
import { useHistory } from "react-router"
import ContextLanguage from "../../contexts/ContextLanguage" import ContextLanguage from "../../contexts/ContextLanguage"
import SummaryBase from "../base/summary/SummaryBase" import SummaryBase from "../base/summary/SummaryBase"
import SummaryLeft from "../base/summary/SummaryLeft" import SummaryLeft from "../base/summary/SummaryLeft"
@ -45,37 +44,37 @@ export default function SummaryRepository(
/> />
{destroy ? {destroy ?
<SummaryButton <SummaryButton
color={"Red"} color={"Red"}
icon={faTrash} icon={faTrash}
onClick={() => destroy(repo["id"])} onClick={() => destroy(repo["id"])}
disabled={running} disabled={running}
> >
{strings.delete} {strings.delete}
</SummaryButton> </SummaryButton>
: null} : null}
{archive ? {archive ?
<SummaryButton <SummaryButton
color={"Grey"} color={"Grey"}
icon={faArchive} icon={faArchive}
onClick={() => archive(repo["id"])} onClick={() => archive(repo["id"])}
disabled={running} disabled={running}
> >
{strings.archive} {strings.archive}
</SummaryButton> </SummaryButton>
: null} : null}
{edit ? {edit ?
<SummaryButton <SummaryButton
color={"Yellow"} color={"Yellow"}
icon={faPencilAlt} icon={faPencilAlt}
onClick={() => edit(repo["id"])} onClick={() => edit(repo["id"])}
disabled={running} disabled={running}
> >
{strings.edit} {strings.edit}
</SummaryButton> </SummaryButton>
: null} : null}
<SummaryRight/> <SummaryRight/>
</SummaryBase> </SummaryBase>

View file

@ -1,7 +1,7 @@
import React from "react" import React from "react"
import SummaryBase from "../base/summary/SummaryBase" import SummaryBase from "../base/summary/SummaryBase"
import SummaryLeft from "../base/summary/SummaryLeft" 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 SummaryText from "../base/summary/SummaryText"
import SummaryRight from "../base/summary/SummaryRight" import SummaryRight from "../base/summary/SummaryRight"

View file

@ -22,18 +22,18 @@ export default function SummaryUser({ user, destroyUser, running, ...props }) {
upperLabel={strings.type} upperLabel={strings.type}
upperValue={user.isAdmin ? strings.admin : strings.user} upperValue={user.isAdmin ? strings.admin : strings.user}
/> />
<SummaryButton <SummaryButton
color={"Red"} color={"Red"}
icon={faTrash} icon={faTrash}
onClick={async event => { onClick={async event => {
event.stopPropagation() event.stopPropagation()
// TODO: Errors are not caught here. Where should they be displayed? // TODO: Errors are not caught here. Where should they be displayed?
await destroyUser(user["email"]) await destroyUser(user["email"])
}} }}
disabled={running} disabled={running}
> >
{strings.delete} {strings.delete}
</SummaryButton> </SummaryButton>
<SummaryRight/> <SummaryRight/>
</SummaryBase> </SummaryBase>
) )

View file

@ -76,7 +76,7 @@ export default function useBackendRequest() {
try { try {
json = await response.json() json = await response.json()
} }
catch (error) { catch(error) {
throw new DecodeError(response.status, response.statusText, error) throw new DecodeError(response.status, response.statusText, error)
} }

View file

@ -1,7 +1,4 @@
import { useCallback, useContext, useEffect, useState } from "react" import { useCallback, useEffect, useState } from "react"
import ContextServer from "../contexts/ContextServer"
import ContextUser from "../contexts/ContextUser"
import makeURLSearchParams from "../utils/makeURLSearchParams"
import useBackendRequest from "./useBackendRequest" import useBackendRequest from "./useBackendRequest"
@ -11,15 +8,17 @@ import useBackendRequest from "./useBackendRequest"
* @param resourcePath - The path of the resource file. * @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. * @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, export default function useBackendResource(
{ resourcePath,
retrieve: allowRetrieve = true, {
edit: allowEdit = true, retrieve: allowRetrieve = true,
destroy: allowDestroy = true, edit: allowEdit = true,
action: allowAction = false, destroy: allowDestroy = true,
} = {}) { action: allowAction = false,
} = {},
) {
const {abort, running, apiRequest} = useBackendRequest() const { abort, running, apiRequest } = useBackendRequest()
const [firstLoad, setFirstLoad] = useState(false) const [firstLoad, setFirstLoad] = useState(false)
const [resource, setResource] = useState(null) const [resource, setResource] = useState(null)
@ -27,7 +26,9 @@ export default function useBackendResource(resourcePath,
const apiRetrieve = useCallback( const apiRetrieve = useCallback(
async (init) => { async (init) => {
if(!allowRetrieve) throw new ViewNotAllowedError("retrieve") if(!allowRetrieve) {
throw new ViewNotAllowedError("retrieve")
}
return await apiRequest("GET", `${resourcePath}`, undefined, init) return await apiRequest("GET", `${resourcePath}`, undefined, init)
}, },
[apiRequest, allowRetrieve, resourcePath], [apiRequest, allowRetrieve, resourcePath],
@ -35,7 +36,9 @@ export default function useBackendResource(resourcePath,
const apiEdit = useCallback( const apiEdit = useCallback(
async (data, init) => { async (data, init) => {
if(!allowEdit) throw new ViewNotAllowedError("edit") if(!allowEdit) {
throw new ViewNotAllowedError("edit")
}
return await apiRequest("PUT", `${resourcePath}`, data, init) return await apiRequest("PUT", `${resourcePath}`, data, init)
}, },
[apiRequest, allowEdit, resourcePath], [apiRequest, allowEdit, resourcePath],
@ -43,7 +46,9 @@ export default function useBackendResource(resourcePath,
const apiDestroy = useCallback( const apiDestroy = useCallback(
async (init) => { async (init) => {
if(!allowDestroy) throw new ViewNotAllowedError("destroy") if(!allowDestroy) {
throw new ViewNotAllowedError("destroy")
}
return await apiRequest("DELETE", `${resourcePath}`, undefined, init) return await apiRequest("DELETE", `${resourcePath}`, undefined, init)
}, },
[apiRequest, allowDestroy, resourcePath], [apiRequest, allowDestroy, resourcePath],
@ -51,10 +56,12 @@ export default function useBackendResource(resourcePath,
const apiAction = useCallback( const apiAction = useCallback(
async (method, command, data, init) => { 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) return await apiRequest(method, `${resourcePath}/${command}`, data, init)
}, },
[apiRequest, allowAction, resourcePath] [apiRequest, allowAction, resourcePath],
) )
const retrieveResource = useCallback( const retrieveResource = useCallback(

View file

@ -18,8 +18,9 @@ export default function useBackendViewset(resourcesPath, pkName,
destroy: allowDestroy = true, destroy: allowDestroy = true,
command: allowCommand = false, command: allowCommand = false,
action: allowAction = false, action: allowAction = false,
} = {}) { } = {},
const {abort, running, apiRequest} = useBackendRequest() ) {
const { abort, running, apiRequest } = useBackendRequest()
const [firstLoad, setFirstLoad] = useState(false) const [firstLoad, setFirstLoad] = useState(false)
const [resources, setResources] = useState([]) const [resources, setResources] = useState([])
@ -27,7 +28,9 @@ export default function useBackendViewset(resourcesPath, pkName,
const apiList = useCallback( const apiList = useCallback(
async (init) => { async (init) => {
if(!allowList) throw new ViewNotAllowedError("list") if(!allowList) {
throw new ViewNotAllowedError("list")
}
return await apiRequest("GET", `${resourcesPath}`, undefined, init) return await apiRequest("GET", `${resourcesPath}`, undefined, init)
}, },
[apiRequest, allowList, resourcesPath], [apiRequest, allowList, resourcesPath],
@ -35,7 +38,9 @@ export default function useBackendViewset(resourcesPath, pkName,
const apiRetrieve = useCallback( const apiRetrieve = useCallback(
async (id, init) => { async (id, init) => {
if(!allowRetrieve) throw new ViewNotAllowedError("retrieve") if(!allowRetrieve) {
throw new ViewNotAllowedError("retrieve")
}
return await apiRequest("GET", `${resourcesPath}${id}`, undefined, init) return await apiRequest("GET", `${resourcesPath}${id}`, undefined, init)
}, },
[apiRequest, allowRetrieve, resourcesPath], [apiRequest, allowRetrieve, resourcesPath],
@ -43,7 +48,9 @@ export default function useBackendViewset(resourcesPath, pkName,
const apiCreate = useCallback( const apiCreate = useCallback(
async (data, init) => { async (data, init) => {
if(!allowCreate) throw new ViewNotAllowedError("create") if(!allowCreate) {
throw new ViewNotAllowedError("create")
}
return await apiRequest("POST", `${resourcesPath}`, data, init) return await apiRequest("POST", `${resourcesPath}`, data, init)
}, },
[apiRequest, allowCreate, resourcesPath], [apiRequest, allowCreate, resourcesPath],
@ -51,7 +58,9 @@ export default function useBackendViewset(resourcesPath, pkName,
const apiEdit = useCallback( const apiEdit = useCallback(
async (id, data, init) => { async (id, data, init) => {
if(!allowEdit) throw new ViewNotAllowedError("edit") if(!allowEdit) {
throw new ViewNotAllowedError("edit")
}
return await apiRequest("PUT", `${resourcesPath}${id}`, data, init) return await apiRequest("PUT", `${resourcesPath}${id}`, data, init)
}, },
[apiRequest, allowEdit, resourcesPath], [apiRequest, allowEdit, resourcesPath],
@ -59,7 +68,9 @@ export default function useBackendViewset(resourcesPath, pkName,
const apiDestroy = useCallback( const apiDestroy = useCallback(
async (id, init) => { async (id, init) => {
if(!allowDestroy) throw new ViewNotAllowedError("destroy") if(!allowDestroy) {
throw new ViewNotAllowedError("destroy")
}
return await apiRequest("DELETE", `${resourcesPath}${id}`, undefined, init) return await apiRequest("DELETE", `${resourcesPath}${id}`, undefined, init)
}, },
[apiRequest, allowDestroy, resourcesPath], [apiRequest, allowDestroy, resourcesPath],
@ -67,18 +78,22 @@ export default function useBackendViewset(resourcesPath, pkName,
const apiCommand = useCallback( const apiCommand = useCallback(
async (method, command, data, init) => { 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) return await apiRequest(method, `${resourcesPath}${command}`, data, init)
}, },
[apiRequest, allowCommand, resourcesPath] [apiRequest, allowCommand, resourcesPath],
) )
const apiAction = useCallback( const apiAction = useCallback(
async (method, id, command, data, init) => { 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) return await apiRequest(method, `${resourcesPath}${id}/${command}`, data, init)
}, },
[apiRequest, allowAction, resourcesPath] [apiRequest, allowAction, resourcesPath],
) )
const listResources = useCallback( const listResources = useCallback(

View file

@ -1,4 +1,4 @@
import React, {useContext} from "react" import React, { useContext } from "react"
import Style from "./PageDashboard.module.css" import Style from "./PageDashboard.module.css"
import classNames from "classnames" import classNames from "classnames"
import BoxHeader from "../components/base/BoxHeader" import BoxHeader from "../components/base/BoxHeader"

View file

@ -10,7 +10,7 @@ import ContextLanguage from "../contexts/ContextLanguage"
export default function PageRepositories({ children, className, ...props }) { export default function PageRepositories({ children, className, ...props }) {
const bv = useBackendViewset("/api/v1/repositories/", "id") const bv = useBackendViewset("/api/v1/repositories/", "id")
const history = useHistory() const history = useHistory()
const {strings} = useContext(ContextLanguage) const { strings } = useContext(ContextLanguage)
const archive = useCallback( const archive = useCallback(
async (pk) => { async (pk) => {

View file

@ -8,7 +8,7 @@ import PickerFilter from "../components/interactive/PickerFilter"
import useBackendViewset from "../hooks/useBackendViewset" import useBackendViewset from "../hooks/useBackendViewset"
import useBackendResource from "../hooks/useBackendResource" import useBackendResource from "../hooks/useBackendResource"
import { faFolder, faFolderOpen, faTrash } from "@fortawesome/free-solid-svg-icons" 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 { useParams } from "react-router"
import Loading from "../components/base/Loading" import Loading from "../components/base/Loading"
import BoxVisualizationStats from "../components/interactive/BoxVisualizationStats" import BoxVisualizationStats from "../components/interactive/BoxVisualizationStats"
@ -17,14 +17,13 @@ import BoxVisualizationMap from "../components/interactive/BoxVisualizationMap"
import BoxVisualizationWordcloud from "../components/interactive/BoxVisualizationWordcloud" import BoxVisualizationWordcloud from "../components/interactive/BoxVisualizationWordcloud"
import BoxFull from "../components/base/BoxFull" import BoxFull from "../components/base/BoxFull"
import ContextLanguage from "../contexts/ContextLanguage" import ContextLanguage from "../contexts/ContextLanguage"
import tokenizeTweetWords from "../utils/countTweetWords"
import countTweetWords from "../utils/countTweetWords" import countTweetWords from "../utils/countTweetWords"
import objectToWordcloudFormat from "../utils/objectToWordcloudFormat" import objectToWordcloudFormat from "../utils/objectToWordcloudFormat"
export default function PageRepository({ className, ...props }) { export default function PageRepository({ className, ...props }) {
const {id} = useParams() const { id } = useParams()
const {strings} = useContext(ContextLanguage) const { strings } = useContext(ContextLanguage)
const [visualizationTab, setVisualizationTab] = useState("wordcloud") const [visualizationTab, setVisualizationTab] = useState("wordcloud")
const [addFilterTab, setAddFilterTab] = useState("hashtag") const [addFilterTab, setAddFilterTab] = useState("hashtag")
@ -36,7 +35,7 @@ export default function PageRepository({ className, ...props }) {
edit: true, edit: true,
destroy: true, destroy: true,
action: false, action: false,
} },
) )
const repository = repositoryBr.error ? null : repositoryBr.resource const repository = repositoryBr.error ? null : repositoryBr.resource
@ -51,16 +50,16 @@ export default function PageRepository({ className, ...props }) {
destroy: false, destroy: false,
command: false, command: false,
action: false, action: false,
} },
) )
const tweets = tweetsBv.resources && tweetsBv.error ? [] : tweetsBv.resources const tweets = tweetsBv.resources && tweetsBv.error ? [] : tweetsBv.resources
const words = useMemo( const words = useMemo(
() => objectToWordcloudFormat(countTweetWords(tweets)), () => objectToWordcloudFormat(countTweetWords(tweets)),
[tweets] [tweets],
) )
let contents; let contents
if(!repositoryBr.firstLoad || !tweetsBv.firstLoad) { if(!repositoryBr.firstLoad || !tweetsBv.firstLoad) {
contents = <> contents = <>
<BoxHeader className={Style.Header}> <BoxHeader className={Style.Header}>
@ -93,32 +92,32 @@ export default function PageRepository({ className, ...props }) {
setTab={setVisualizationTab} setTab={setVisualizationTab}
/> />
{visualizationTab === "wordcloud" ? {visualizationTab === "wordcloud" ?
<BoxVisualizationWordcloud <BoxVisualizationWordcloud
className={Style.Wordcloud} className={Style.Wordcloud}
tweets={tweets} tweets={tweets}
words={words} words={words}
/> />
: null} : null}
{visualizationTab === "histogram" ? {visualizationTab === "histogram" ?
<BoxVisualizationGraph <BoxVisualizationGraph
className={Style.Wordcloud} className={Style.Wordcloud}
tweets={tweets} tweets={tweets}
/> />
: null} : null}
{visualizationTab === "map" ? {visualizationTab === "map" ?
<BoxVisualizationMap <BoxVisualizationMap
className={Style.Wordcloud} className={Style.Wordcloud}
tweets={tweets} tweets={tweets}
/> />
: null} : null}
{visualizationTab === "stats" ? {visualizationTab === "stats" ?
<BoxVisualizationStats <BoxVisualizationStats
className={Style.Wordcloud} className={Style.Wordcloud}
tweets={tweets} tweets={tweets}
words={words} words={words}
totalTweetCount={tweets.length} totalTweetCount={tweets.length}
/> />
: null} : null}
<PickerFilter <PickerFilter
className={Style.FilterPicker} className={Style.FilterPicker}

View file

@ -6,8 +6,7 @@
"a b" "a b"
"a c" "a c"
"d e" "d e"
"d f" "d f";
;
grid-gap: 10px; grid-gap: 10px;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;

View file

@ -7,7 +7,7 @@ class ViewNotAllowedError extends NestError {
view view
constructor(view) { constructor(view) {
super(); super()
this.view = view this.view = view
} }

View file

@ -11,8 +11,12 @@ export default function countTweetWords(tweets = {}) {
continue continue
} }
for(const word of tweet.content.toLowerCase().split(/\s+/)) { for(const word of tweet.content.toLowerCase().split(/\s+/)) {
if(stopwords.includes(word)) continue if(stopwords.includes(word)) {
if(word.startsWith("https://")) continue continue
}
if(word.startsWith("https://")) {
continue
}
if(!words.hasOwnProperty(word)) { if(!words.hasOwnProperty(word)) {
words[word] = 0 words[word] = 0

View file

@ -6,7 +6,7 @@ export default function objectToWordcloudFormat(words) {
} }
result.push({ result.push({
text: word, text: word,
value: words[word] value: words[word],
}) })
} }
return result return result