mirror of
https://github.com/pds-nest/nest.git
synced 2024-11-22 04:54:18 +00:00
🔧 Create a base Summary component
This commit is contained in:
parent
70a5e2aa5a
commit
aa8a138990
5 changed files with 167 additions and 31 deletions
42
code/frontend/src/components/base/Summary.js
Normal file
42
code/frontend/src/components/base/Summary.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import React from "react"
|
||||||
|
import Style from "./Summary.module.css"
|
||||||
|
import classNames from "classnames"
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
|
|
||||||
|
|
||||||
|
export default function Summary(
|
||||||
|
{ title, subtitle, upperLabel, upperValue, lowerLabel, lowerValue, buttons, className, ...props },
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<div className={classNames(Style.Summary, className)} {...props}>
|
||||||
|
<div className={Style.Left}>
|
||||||
|
<div className={Style.IconContainer}>
|
||||||
|
<FontAwesomeIcon icon={icon}/>
|
||||||
|
</div>
|
||||||
|
<div className={Style.Title}>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
<div className={Style.Subtitle}>
|
||||||
|
{subtitle}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={Style.Middle}>
|
||||||
|
<div className={classNames(Style.Label, Style.Upper)}>
|
||||||
|
{upperLabel}
|
||||||
|
</div>
|
||||||
|
<div className={classNames(Style.Value, Style.Upper)}>
|
||||||
|
{upperValue}
|
||||||
|
</div>
|
||||||
|
<div className={classNames(Style.Label, Style.Lower)}>
|
||||||
|
{lowerLabel}
|
||||||
|
</div>
|
||||||
|
<div className={classNames(Style.Value, Style.Lower)}>
|
||||||
|
{lowerValue}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={Style.Right}>
|
||||||
|
{buttons}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
98
code/frontend/src/components/base/Summary.module.css
Normal file
98
code/frontend/src/components/base/Summary.module.css
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
.Summary {
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
|
||||||
|
margin: 10px 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.Left {
|
||||||
|
width: 250px;
|
||||||
|
height: 60px;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas:
|
||||||
|
"a b"
|
||||||
|
"a c"
|
||||||
|
"a d"
|
||||||
|
"a e";
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
grid-template-rows: 5px 1fr 1fr 5px;
|
||||||
|
|
||||||
|
background-color: var(--bg-accent);
|
||||||
|
border-radius: 30px 0 0 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.IconContainer {
|
||||||
|
margin: 5px 15px 5px 5px;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
background-color: var(--bg-light);
|
||||||
|
color: var(--fg-primary);
|
||||||
|
|
||||||
|
font-size: x-large;
|
||||||
|
|
||||||
|
grid-area: a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Title {
|
||||||
|
grid-area: c;
|
||||||
|
font-size: large;
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Subtitle {
|
||||||
|
grid-area: d;
|
||||||
|
font-size: small;
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Middle {
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 60px;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
background-color: var(--bg-light);
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
grid-template-rows: 1fr 1fr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.Middle .Label {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Middle .Value {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Middle .Upper {
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Middle .Lower {
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Right {
|
||||||
|
width: 250px;
|
||||||
|
height: 60px;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
background-color: var(--bg-accent);
|
||||||
|
border-radius: 0 30px 30px 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useContext } from "react"
|
import React, { useContext } from "react"
|
||||||
import BoxFull from "../base/BoxFull"
|
import BoxFull from "../base/BoxFull"
|
||||||
import RepositorySummaryBase from "./RepositorySummaryBase"
|
import SummaryRepository from "./SummaryRepository"
|
||||||
import { faSearch } from "@fortawesome/free-solid-svg-icons"
|
import { faSearch } from "@fortawesome/free-solid-svg-icons"
|
||||||
import ContextUser from "../../contexts/ContextUser"
|
import ContextUser from "../../contexts/ContextUser"
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@ export default function BoxRepositoriesActive({ repositories, refresh, ...props
|
||||||
let contents
|
let contents
|
||||||
if(repositories.length > 0) {
|
if(repositories.length > 0) {
|
||||||
contents = repositories.map(repo => (
|
contents = repositories.map(repo => (
|
||||||
<RepositorySummaryBase
|
<SummaryRepository
|
||||||
key={repo["id"]}
|
key={repo["id"]}
|
||||||
{...repo}
|
repo={repo}
|
||||||
icon={faSearch}
|
icon={faSearch}
|
||||||
refresh={refresh}
|
refresh={refresh}
|
||||||
canArchive={true}
|
canArchive={true}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useContext } from "react"
|
import React, { useContext } from "react"
|
||||||
import BoxFull from "../base/BoxFull"
|
import BoxFull from "../base/BoxFull"
|
||||||
import ContextUser from "../../contexts/ContextUser"
|
import ContextUser from "../../contexts/ContextUser"
|
||||||
import RepositorySummaryBase from "./RepositorySummaryBase"
|
import SummaryRepository from "./SummaryRepository"
|
||||||
import { faSearch } from "@fortawesome/free-solid-svg-icons"
|
import { faSearch } from "@fortawesome/free-solid-svg-icons"
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@ export default function BoxRepositoriesArchived({ repositories, refresh, ...prop
|
||||||
let contents
|
let contents
|
||||||
if(repositories.length > 0) {
|
if(repositories.length > 0) {
|
||||||
contents = repositories.map(repo => (
|
contents = repositories.map(repo => (
|
||||||
<RepositorySummaryBase
|
<SummaryRepository
|
||||||
key={repo["id"]}
|
key={repo["id"]}
|
||||||
{...repo}
|
repo={repo}
|
||||||
icon={faSearch}
|
icon={faSearch}
|
||||||
refresh={refresh}
|
refresh={refresh}
|
||||||
canArchive={true}
|
canArchive={true}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Style from "./RepositorySummaryBase.module.css"
|
||||||
import classNames from "classnames"
|
import classNames from "classnames"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
import Button from "../base/Button"
|
import Button from "../base/Button"
|
||||||
import { faArchive, 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 { useHistory } from "react-router"
|
||||||
import useBackend from "../../hooks/useBackend"
|
import useBackend from "../../hooks/useBackend"
|
||||||
import ContextUser from "../../contexts/ContextUser"
|
import ContextUser from "../../contexts/ContextUser"
|
||||||
|
@ -12,14 +12,8 @@ import ContextUser from "../../contexts/ContextUser"
|
||||||
/**
|
/**
|
||||||
* A long line representing a repository in a list.
|
* A long line representing a repository in a list.
|
||||||
*
|
*
|
||||||
* @param id - The id of the repository.
|
* @param repo - The repository object.
|
||||||
* @param refresh - Function that can be called to refresh the repositories list.
|
* @param refresh - Function that can be called to refresh the repositories list.
|
||||||
* @param owner - The owner of the repository.
|
|
||||||
* @param icon - The FontAwesome IconDefinition that represents the repository.
|
|
||||||
* @param name - The title of the repository.
|
|
||||||
* @param start - The start date of the repository.
|
|
||||||
* @param end - The end date of the repository.
|
|
||||||
* @param is_active - Whether the repository is active or not.
|
|
||||||
* @param canDelete - If the Delete button should be displayed or not.
|
* @param canDelete - If the Delete button should be displayed or not.
|
||||||
* @param canEdit - If the Edit button should be displayed or not.
|
* @param canEdit - If the Edit button should be displayed or not.
|
||||||
* @param canArchive - If the Archive button should be displayed or not.
|
* @param canArchive - If the Archive button should be displayed or not.
|
||||||
|
@ -28,30 +22,30 @@ import ContextUser from "../../contexts/ContextUser"
|
||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
export default function RepositorySummaryBase(
|
export default function SummaryRepository(
|
||||||
{ id, refresh, owner, icon, name, start, end, is_active, canDelete, canEdit, canArchive, className, ...props },
|
{ repo, refresh, canDelete, canEdit, canArchive, className, ...props },
|
||||||
) {
|
) {
|
||||||
const { fetchDataAuth } = useContext(ContextUser)
|
const { fetchDataAuth } = useContext(ContextUser)
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const { fetchNow: archiveThis } = useBackend(fetchDataAuth, "PATCH", `/api/v1/repositories/${id}`, { "close": true })
|
const { fetchNow: archiveThis } = useBackend(fetchDataAuth, "PATCH", `/api/v1/repositories/${repo.id}`, { "close": true })
|
||||||
const { fetchNow: unarchiveThis } = useBackend(fetchDataAuth, "PATCH", `/api/v1/repositories/${id}`, { "open": true })
|
const { fetchNow: unarchiveThis } = useBackend(fetchDataAuth, "PATCH", `/api/v1/repositories/${repo.id}`, { "open": true })
|
||||||
const { fetchNow: deletThis } = useBackend(fetchDataAuth, "DELETE", `/api/v1/repositories/${id}`)
|
const { fetchNow: deletThis } = useBackend(fetchDataAuth, "DELETE", `/api/v1/repositories/${repo.id}`)
|
||||||
|
|
||||||
const onEditClick = event => {
|
const onEditClick = () => {
|
||||||
history.push(`/repositories/${id}/edit`)
|
history.push(`/repositories/${repo.id}/edit`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onArchiveClick = async event => {
|
const onArchiveClick = async () => {
|
||||||
await archiveThis()
|
await archiveThis()
|
||||||
await refresh()
|
await refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onUnarchiveClick = async event => {
|
const onUnarchiveClick = async () => {
|
||||||
await unarchiveThis()
|
await unarchiveThis()
|
||||||
await refresh()
|
await refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onDeleteClick = async event => {
|
const onDeleteClick = async () => {
|
||||||
await deletThis()
|
await deletThis()
|
||||||
await refresh()
|
await refresh()
|
||||||
}
|
}
|
||||||
|
@ -60,13 +54,15 @@ export default function RepositorySummaryBase(
|
||||||
<div className={classNames(Style.RepositorySummary, className)} {...props}>
|
<div className={classNames(Style.RepositorySummary, className)} {...props}>
|
||||||
<div className={Style.Left}>
|
<div className={Style.Left}>
|
||||||
<div className={Style.IconContainer}>
|
<div className={Style.IconContainer}>
|
||||||
<FontAwesomeIcon icon={icon}/>
|
<FontAwesomeIcon
|
||||||
|
icon={repo.is_active ? faFolderOpen : faFolder}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={Style.Title}>
|
<div className={Style.Title}>
|
||||||
{name}
|
{repo.name}
|
||||||
</div>
|
</div>
|
||||||
<div className={Style.Author}>
|
<div className={Style.Author}>
|
||||||
{owner["username"]}
|
{repo.owner.username}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={Style.Middle}>
|
<div className={Style.Middle}>
|
||||||
|
@ -74,13 +70,13 @@ export default function RepositorySummaryBase(
|
||||||
Start:
|
Start:
|
||||||
</div>
|
</div>
|
||||||
<div className={classNames(Style.MiddleValue, Style.MiddleTop)}>
|
<div className={classNames(Style.MiddleValue, Style.MiddleTop)}>
|
||||||
{start}
|
{repo.start}
|
||||||
</div>
|
</div>
|
||||||
<div className={classNames(Style.MiddleLabel, Style.MiddleBot)}>
|
<div className={classNames(Style.MiddleLabel, Style.MiddleBot)}>
|
||||||
End:
|
End:
|
||||||
</div>
|
</div>
|
||||||
<div className={classNames(Style.MiddleValue, Style.MiddleBot)}>
|
<div className={classNames(Style.MiddleValue, Style.MiddleBot)}>
|
||||||
{end}
|
{repo.end}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={Style.Right}>
|
<div className={Style.Right}>
|
||||||
|
@ -106,9 +102,9 @@ export default function RepositorySummaryBase(
|
||||||
<Button
|
<Button
|
||||||
color={"Grey"}
|
color={"Grey"}
|
||||||
icon={faArchive}
|
icon={faArchive}
|
||||||
onClick={is_active ? onArchiveClick : onUnarchiveClick}
|
onClick={repo.is_active ? onArchiveClick : onUnarchiveClick}
|
||||||
>
|
>
|
||||||
{is_active ? "Archive" : "Unarchive"}
|
{repo.is_active ? "Archive" : "Unarchive"}
|
||||||
</Button>
|
</Button>
|
||||||
: null}
|
: null}
|
||||||
</div>
|
</div>
|
Loading…
Reference in a new issue