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

🧹 Restructure project directories

This commit is contained in:
Stefano Pigozzi 2021-04-29 16:58:31 +02:00
parent 8c0fc2bd8a
commit 5479a8dc35
Signed by untrusted user who does not match committer: steffo
GPG key ID: 6965406171929D01
80 changed files with 227 additions and 139 deletions

View file

@ -1,8 +1,8 @@
import Layout from "./components/Layout"
import Layout from "./components/interactive/Layout"
import { BrowserRouter } from "react-router-dom"
import GlobalTheme from "./components/GlobalTheme"
import GlobalServer from "./components/GlobalServer"
import GlobalUser from "./components/GlobalUser"
import GlobalTheme from "./components/providers/GlobalTheme"
import GlobalServer from "./components/providers/GlobalServer"
import GlobalUser from "./components/providers/GlobalUser"
import PageSwitcher from "./PageSwitcher"

View file

@ -1,17 +0,0 @@
import React, { useContext } from "react"
import BoxFull from "./BoxFull"
import ContextRepositoryEditor from "../contexts/ContextRepositoryEditor"
import ConditionBadge from "./ConditionBadge"
export default function BoxConditions({ ...props }) {
const {conditions} = useContext(ContextRepositoryEditor)
const badges = conditions.map((cond, pos) => <ConditionBadge key={pos} {...cond}/>)
return (
<BoxFull header={"Conditions"} {...props}>
{badges}
</BoxFull>
)
}

View file

@ -1,11 +0,0 @@
import React from "react"
import Style from "./ButtonIconOnly.module.css"
import classNames from "classnames"
import Button from "./Button"
export default function ButtonIconOnly({ children, className, ...props }) {
return (
<Button className={classNames(Style.ButtonIconOnly, className)} {...props}/>
)
}

View file

@ -1,12 +0,0 @@
import React from "react"
import Style from "./FormInline.module.css"
import classNames from "classnames"
export default function FormInline({ children, className, ...props }) {
return (
<div className={classNames(Style.FormInline, className)} {...props}>
{children}
</div>
)
}

View file

@ -1,7 +1,7 @@
import React from "react"
import Style from "./Button.module.css"
import classNames from "classnames"
import make_icon from "../utils/make_icon"
import make_icon from "../../utils/make_icon"
/**

View file

@ -0,0 +1,19 @@
import React from "react"
import Style from "./ButtonIconOnly.module.css"
import classNames from "classnames"
import Button from "./Button"
/**
* A {@link Button} with only an icon.
*
* @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 ButtonIconOnly({ className, ...props }) {
return (
<Button className={classNames(Style.ButtonIconOnly, className)} {...props}/>
)
}

View file

@ -1,7 +1,7 @@
import React from "react"
import Style from "./ButtonSidebar.module.css"
import classNames from "classnames"
import make_icon from "../utils/make_icon"
import make_icon from "../../utils/make_icon"
import { Link } from "react-router-dom"
import { useRouteMatch } from "react-router"

View file

@ -5,7 +5,15 @@ import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import { faTimes } from "@fortawesome/free-solid-svg-icons"
export default function ButtonSmallX({ children, className, ...props }) {
/**
* A button with a small X, used to delete Conditions.
*
* @param className - Additional class(es) to pass to the button.
* @param props - Additional props to pass to the button.
* @returns {JSX.Element}
* @constructor
*/
export default function ButtonSmallX({ className, ...props }) {
return (
<button type={"button"} className={classNames(Style.ButtonSmallX, className)} {...props}>
<FontAwesomeIcon icon={faTimes}/>

View file

@ -0,0 +1,21 @@
import React from "react"
import Style from "./FormInline.module.css"
import classNames from "classnames"
/**
* A form displayed in a single line.
*
* @param children - The contents of the form.
* @param className - Additional class(es) to pass to the form.
* @param props - Additional props to pass to the form.
* @returns {JSX.Element}
* @constructor
*/
export default function FormInline({ children, className, ...props }) {
return (
<form className={classNames(Style.FormInline, className)} {...props}>
{children}
</form>
)
}

View file

@ -6,8 +6,6 @@ import classNames from "classnames"
/**
* A form with two columns: the leftmost one contains labels, while the rightmost one contains input elements.
*
* The {@link FormLabel} element can be used to quickly generate labelled input elements.
*
* @returns {JSX.Element}
* @constructor
*/

View file

@ -1,7 +1,7 @@
import React, {useState} from "react"
import Style from "./InputWithIcon.module.css"
import classNames from "classnames"
import make_icon from "../utils/make_icon"
import make_icon from "../../utils/make_icon"
/**

View file

@ -3,9 +3,15 @@ import { faSpinner } from "@fortawesome/free-solid-svg-icons"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
export default function Loading({ ...props }) {
/**
* A div with a spinning dots icon and a "Loading..." text.
*
* @returns {JSX.Element}
* @constructor
*/
export default function Loading() {
return (
<div {...props}>
<div>
<FontAwesomeIcon icon={faSpinner} pulse={true}/> Loading...
</div>
)

View file

@ -1,7 +1,7 @@
import React from "react"
import Style from "./FormAlert.module.css"
import classNames from "classnames"
import BoxAlert from "./BoxAlert"
import BoxAlert from "../BoxAlert"
/**

View file

@ -1,7 +1,7 @@
import React from "react"
import Style from "./FormButton.module.css"
import classNames from "classnames"
import Button from "./Button"
import Button from "../Button"
/**

View file

@ -1,21 +1,29 @@
import React, { useContext, useState } from "react"
import BoxFull from "./BoxFull"
import React, { useState } from "react"
import BoxFull from "../base/BoxFull"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import { faHashtag, faPlus } from "@fortawesome/free-solid-svg-icons"
import InputWithIcon from "./InputWithIcon"
import FormInline from "./FormInline"
import InputWithIcon from "../base/InputWithIcon"
import FormInline from "../base/FormInline"
import Style from "./BoxConditionHashtag.module.css"
import ButtonIconOnly from "./ButtonIconOnly"
import ContextRepositoryEditor from "../contexts/ContextRepositoryEditor"
import ButtonIconOnly from "../base/ButtonIconOnly"
import useRepositoryEditor from "../../hooks/useRepositoryEditor"
// Official hashtag regex from https://stackoverflow.com/a/22490853/4334568
// noinspection RegExpAnonymousGroup,LongLine
const INVALID_HASHTAG_CHARACTERS = /([^a-z0-9_\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0100-\u024f\u0253-\u0254\u0256-\u0257\u0300-\u036f\u1e00-\u1eff\u0400-\u04ff\u0500-\u0527\u2de0-\u2dff\ua640-\ua69f\u0591-\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05d0-\u05ea\u05f0-\u05f4\ufb12-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4f\u0610-\u061a\u0620-\u065f\u066e-\u06d3\u06d5-\u06dc\u06de-\u06e8\u06ea-\u06ef\u06fa-\u06fc\u0750-\u077f\u08a2-\u08ac\u08e4-\u08fe\ufb50-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\u200c\u0e01-\u0e3a\u0e40-\u0e4e\u1100-\u11ff\u3130-\u3185\ua960-\ua97f\uac00-\ud7af\ud7b0-\ud7ff\uffa1-\uffdc\u30a1-\u30fa\u30fc-\u30fe\uff66-\uff9f\uff10-\uff19\uff21-\uff3a\uff41-\uff5a\u3041-\u3096\u3099-\u309e\u3400-\u4dbf\u4e00-\u9fff\u20000-\u2a6df\u2a700-\u2b73\u2b740-\u2b81\u2f800-\u2fa1])/g
/**
* A {@link BoxFull} that allows the user to select a Twitter hashtag to search for, and then to add it as a Condition
* to the {@link ContextRepositoryEditor}.
*
* @param props - Additional props to pass to the box.
* @returns {JSX.Element}
* @constructor
*/
export default function BoxConditionHashtag({ ...props }) {
const [hashtag, setHashtag] = useState("")
const {conditions, appendCondition} = useContext(ContextRepositoryEditor)
const {conditions, appendCondition} = useRepositoryEditor()
const onInputChange = event => {
let text = event.target.value

View file

@ -1,20 +1,28 @@
import React, { useContext, useState } from "react"
import BoxFull from "./BoxFull"
import React, { useState } from "react"
import BoxFull from "../base/BoxFull"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import { faAt, faHashtag, faPlus } from "@fortawesome/free-solid-svg-icons"
import InputWithIcon from "./InputWithIcon"
import FormInline from "./FormInline"
import { faAt, faPlus } from "@fortawesome/free-solid-svg-icons"
import InputWithIcon from "../base/InputWithIcon"
import FormInline from "../base/FormInline"
import Style from "./BoxConditionHashtag.module.css"
import ButtonIconOnly from "./ButtonIconOnly"
import ContextRepositoryEditor from "../contexts/ContextRepositoryEditor"
import ButtonIconOnly from "../base/ButtonIconOnly"
import useRepositoryEditor from "../../hooks/useRepositoryEditor"
const INVALID_USER_CHARACTERS = /[^a-zA-Z0-9]/g
/**
* A {@link BoxFull} that allows the user to select a Twitter user to search for, and then to add it as a Condition
* to the {@link ContextRepositoryEditor}.
*
* @param props - Additional props to pass to the box.
* @returns {JSX.Element}
* @constructor
*/
export default function BoxConditionUser({ ...props }) {
const [user, setUser] = useState("")
const {conditions, appendCondition} = useContext(ContextRepositoryEditor)
const {conditions, appendCondition} = useRepositoryEditor()
const onInputChange = event => {
let text = event.target.value

View file

@ -0,0 +1,24 @@
import React from "react"
import BoxFull from "../base/BoxFull"
import ConditionBadge from "./ConditionBadge"
import useRepositoryEditor from "../../hooks/useRepositoryEditor"
/**
* A box which renders all conditions of the {@link RepositoryEditor} as {@link ConditionBadge}s.
*
* @param props
* @returns {JSX.Element}
* @constructor
*/
export default function BoxConditions({ ...props }) {
const {conditions} = useRepositoryEditor()
const badges = conditions.map((cond, pos) => <ConditionBadge key={pos} {...cond}/>)
return (
<BoxFull header={"Conditions"} {...props}>
{badges}
</BoxFull>
)
}

View file

@ -1,9 +1,9 @@
import React, { useContext } from "react"
import BoxFull from "./BoxFull"
import BoxFull from "../base/BoxFull"
import LoggedInUser from "./LoggedInUser"
import Button from "./Button"
import Button from "../base/Button"
import { faSignOutAlt } from "@fortawesome/free-solid-svg-icons"
import ContextUser from "../contexts/ContextUser"
import ContextUser from "../../contexts/ContextUser"
import { useHistory } from "react-router"
import Style from "./BoxLoggedIn.module.css"
import CurrentServer from "./CurrentServer"
@ -27,7 +27,7 @@ export default function BoxLoggedIn({ ...props }) {
You are currently logged in at <CurrentServer/> as <LoggedInUser/>.
</div>
<div>
<Button color={"Red"} onClick={e => {
<Button color={"Red"} onClick={() => {
logout()
history.push("/login")
}} icon={faSignOutAlt}>Logout</Button>

View file

@ -1,13 +1,13 @@
import React, { useContext, useState } from "react"
import FormLabelled from "./FormLabelled"
import FormLabel from "./FormLabel"
import InputWithIcon from "./InputWithIcon"
import FormLabelled from "../base/FormLabelled"
import FormLabel from "../base/formparts/FormLabel"
import InputWithIcon from "../base/InputWithIcon"
import { faArrowRight, faEnvelope, faKey } from "@fortawesome/free-solid-svg-icons"
import BoxFull from "./BoxFull"
import FormButton from "./FormButton"
import ContextUser from "../contexts/ContextUser"
import BoxFull from "../base/BoxFull"
import FormButton from "../base/formparts/FormButton"
import ContextUser from "../../contexts/ContextUser"
import { useHistory } from "react-router"
import FormAlert from "./FormAlert"
import FormAlert from "../base/formparts/FormAlert"
/**
@ -25,7 +25,7 @@ export default function BoxLogin({ ...props }) {
const {login} = useContext(ContextUser)
const history = useHistory()
const doLogin = async (event) => {
const doLogin = async () => {
if(working) {
return;
}

View file

@ -1,12 +1,19 @@
import React, { useContext } from "react"
import BoxFull from "./BoxFull"
import ContextUser from "../contexts/ContextUser"
import useData from "../hooks/useData"
import BoxFull from "../base/BoxFull"
import ContextUser from "../../contexts/ContextUser"
import useData from "../../hooks/useData"
import RepositorySummaryBase from "./RepositorySummaryBase"
import Loading from "./Loading"
import BoxAlert from "./BoxAlert"
import Loading from "../base/Loading"
import BoxAlert from "../base/BoxAlert"
/**
* A {@link BoxFull} listing all the user's active repositories.
*
* @param props - Additional props to pass to the box.
* @returns {JSX.Element}
* @constructor
*/
export default function BoxRepositoriesActive({ ...props }) {
const {fetchDataAuth} = useContext(ContextUser)
const {data, started, loading, error} = useData(fetchDataAuth, "GET", "/api/repository/list", {

View file

@ -1,12 +1,19 @@
import React, { useContext } from "react"
import BoxFull from "./BoxFull"
import ContextUser from "../contexts/ContextUser"
import useData from "../hooks/useData"
import BoxFull from "../base/BoxFull"
import ContextUser from "../../contexts/ContextUser"
import useData from "../../hooks/useData"
import RepositorySummaryBase from "./RepositorySummaryBase"
import Loading from "./Loading"
import BoxAlert from "./BoxAlert"
import Loading from "../base/Loading"
import BoxAlert from "../base/BoxAlert"
/**
* A {@link BoxFull} listing all the user's archived repositories.
*
* @param props - Additional props to pass to the box.
* @returns {JSX.Element}
* @constructor
*/
export default function BoxRepositoriesArchived({ ...props }) {
const {fetchDataAuth} = useContext(ContextUser)
const {data, started, loading, error} = useData(fetchDataAuth, "GET", "/api/repository/list", {

View file

@ -1,10 +1,10 @@
import React, { useContext } from "react"
import BoxFull from "./BoxFull"
import FormLabelled from "./FormLabelled"
import FormLabel from "./FormLabel"
import InputWithIcon from "./InputWithIcon"
import BoxFull from "../base/BoxFull"
import FormLabelled from "../base/FormLabelled"
import FormLabel from "../base/formparts/FormLabel"
import InputWithIcon from "../base/InputWithIcon"
import { faGlobe } from "@fortawesome/free-solid-svg-icons"
import ContextServer from "../contexts/ContextServer"
import ContextServer from "../../contexts/ContextServer"
/**

View file

@ -2,9 +2,9 @@ import React, { useContext } from "react"
import Style from "./ConditionBadge.module.css"
import classNames from "classnames"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import ButtonSmallX from "./ButtonSmallX"
import ButtonSmallX from "../base/ButtonSmallX"
import { faAt, faClock, faHashtag, faMapPin } from "@fortawesome/free-solid-svg-icons"
import ContextRepositoryEditor from "../contexts/ContextRepositoryEditor"
import ContextRepositoryEditor from "../../contexts/ContextRepositoryEditor"
const CONDITION_COLORS = {

View file

@ -1,7 +1,7 @@
import React, { useContext } from "react"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import { faGlobe } from "@fortawesome/free-solid-svg-icons"
import ContextServer from "../contexts/ContextServer"
import ContextServer from "../../contexts/ContextServer"
/**

View file

@ -1,8 +1,8 @@
import React, { useContext } from "react"
import Style from "./Layout.module.css"
import classNames from "classnames"
import Sidebar from "./Sidebar"
import ContextTheme from "../contexts/ContextTheme"
import Sidebar from "../interactive/Sidebar"
import ContextTheme from "../../contexts/ContextTheme"
/**

View file

@ -1,7 +1,7 @@
import React, { useContext } from "react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faUser } from "@fortawesome/free-solid-svg-icons"
import ContextUser from "../contexts/ContextUser"
import ContextUser from "../../contexts/ContextUser"
/**

View file

@ -1,8 +1,8 @@
import React, {useContext} from "react"
import Style from "./Logo.module.css"
import LogoDark from "../media/LogoDark.png"
import LogoLight from "../media/LogoLight.png"
import ContextTheme from "../contexts/ContextTheme"
import LogoDark from "../../media/LogoDark.png"
import LogoLight from "../../media/LogoLight.png"
import ContextTheme from "../../contexts/ContextTheme"
import classNames from "classnames"

View file

@ -2,7 +2,7 @@ import React from "react"
import Style from "./RepositorySummaryBase.module.css"
import classNames from "classnames"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import Button from "./Button"
import Button from "../base/Button"
import { faArchive, faPencilAlt, faTrash } from "@fortawesome/free-solid-svg-icons"

View file

@ -1,6 +1,6 @@
import React, {useContext} from "react"
import Select from "./Select"
import ContextTheme from "../contexts/ContextTheme"
import Select from "../base/Select"
import ContextTheme from "../../contexts/ContextTheme"
/**

View file

@ -1,10 +1,10 @@
import React, { Fragment, useContext } from "react"
import Style from "./Sidebar.module.css"
import classNames from "classnames"
import Logo from "./Logo"
import ButtonSidebar from "./ButtonSidebar"
import Logo from "../interactive/Logo"
import ButtonSidebar from "../base/ButtonSidebar"
import { faCog, faExclamationTriangle, faFolder, faHome, faKey, faWrench } from "@fortawesome/free-solid-svg-icons"
import ContextUser from "../contexts/ContextUser"
import ContextUser from "../../contexts/ContextUser"
/**

View file

@ -1,6 +1,6 @@
import React, { useCallback } from "react"
import useLocalStorageState from "../hooks/useLocalStorageState"
import ContextServer from "../contexts/ContextServer"
import useLocalStorageState from "../../hooks/useLocalStorageState"
import ContextServer from "../../contexts/ContextServer"
import isString from "is-string"

View file

@ -1,6 +1,6 @@
import React from "react"
import useLocalStorageState from "../hooks/useLocalStorageState"
import ContextTheme from "../contexts/ContextTheme"
import useLocalStorageState from "../../hooks/useLocalStorageState"
import ContextTheme from "../../contexts/ContextTheme"
/**

View file

@ -1,7 +1,7 @@
import React, { useCallback, useContext } from "react"
import useLocalStorageState from "../hooks/useLocalStorageState"
import ContextServer from "../contexts/ContextServer"
import ContextUser from "../contexts/ContextUser"
import useLocalStorageState from "../../hooks/useLocalStorageState"
import ContextServer from "../../contexts/ContextServer"
import ContextUser from "../../contexts/ContextUser"
/**

View file

@ -1,6 +1,6 @@
import React, { useState } from "react"
import ContextRepositoryEditor from "../contexts/ContextRepositoryEditor"
import useArrayState from "../hooks/useArrayState"
import ContextRepositoryEditor from "../../contexts/ContextRepositoryEditor"
import useArrayState from "../../hooks/useArrayState"
export default function RepositoryEditor({ children, id, name, start, end, conditions }) {

View file

@ -1,5 +1,7 @@
import {createContext} from "react";
const ContextRepositoryEditor = createContext(null)
export default ContextRepositoryEditor
/**
* @todo Document this.
*/
export default createContext(null)

View file

@ -1,6 +1,12 @@
import { useCallback, useState } from "react"
/**
* An hook similar to {@link useState} which stores an array of values.
*
* @param def - The starting value of the hook.
* @returns {{spliceValue, removeValue, setValue, appendValue, value}}
*/
export default function useArrayState(def) {
const [value, setValue] = useState(def ?? [])

View file

@ -0,0 +1,14 @@
import { useContext } from "react"
import ContextRepositoryEditor from "../contexts/ContextRepositoryEditor"
/**
* @todo Document this.
*/
export default function useRepositoryEditor() {
const context = useContext(ContextRepositoryEditor)
if(!context) {
throw new Error("This component must be placed inside a RepositoryEditor.")
}
return context
}

View file

@ -1,7 +1,7 @@
import React from "react"
import Style from "./PageAlerts.module.css"
import classNames from "classnames"
import BoxFull from "../components/BoxFull"
import BoxFull from "../components/base/BoxFull"
export default function PageAlerts({ children, className, ...props }) {

View file

@ -1,15 +1,15 @@
import React from "react"
import Style from "./PageDashboard.module.css"
import classNames from "classnames"
import BoxHeader from "../components/BoxHeader"
import BoxFull from "../components/BoxFull"
import Checkbox from "../components/Checkbox"
import InputWithIcon from "../components/InputWithIcon"
import BoxHeader from "../components/base/BoxHeader"
import BoxFull from "../components/base/BoxFull"
import Checkbox from "../components/base/Checkbox"
import InputWithIcon from "../components/base/InputWithIcon"
import { faFolder, faPlus } from "@fortawesome/free-solid-svg-icons"
import Radio from "../components/Radio"
import Button from "../components/Button"
import FormLabelled from "../components/FormLabelled"
import FormLabel from "../components/FormLabel"
import Radio from "../components/base/Radio"
import Button from "../components/base/Button"
import FormLabelled from "../components/base/FormLabelled"
import FormLabel from "../components/base/formparts/FormLabel"
export default function PageDashboard({ children, className, ...props }) {

View file

@ -1,8 +1,8 @@
import React from "react"
import Style from "./PageLogin.module.css"
import classNames from "classnames"
import BoxSetServer from "../components/BoxSetServer"
import BoxLogin from "../components/BoxLogin"
import BoxSetServer from "../components/interactive/BoxSetServer"
import BoxLogin from "../components/interactive/BoxLogin"
export default function PageLogin({ className, ...props }) {

View file

@ -1,8 +1,8 @@
import React from "react"
import Style from "./PageRepositories.module.css"
import classNames from "classnames"
import BoxRepositoriesActive from "../components/BoxRepositoriesActive"
import BoxRepositoriesArchived from "../components/BoxRepositoriesArchived"
import BoxRepositoriesActive from "../components/interactive/BoxRepositoriesActive"
import BoxRepositoriesArchived from "../components/interactive/BoxRepositoriesArchived"
export default function PageRepositories({ children, className, ...props }) {

View file

@ -1,10 +1,10 @@
import React from "react"
import Style from "./PageSettings.module.css"
import classNames from "classnames"
import BoxHeader from "../components/BoxHeader"
import BoxFull from "../components/BoxFull"
import SelectTheme from "../components/SelectTheme"
import BoxLoggedIn from "../components/BoxLoggedIn"
import BoxHeader from "../components/base/BoxHeader"
import BoxFull from "../components/base/BoxFull"
import SelectTheme from "../components/interactive/SelectTheme"
import BoxLoggedIn from "../components/interactive/BoxLoggedIn"
export default function PageSettings({ children, className, ...props }) {