-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: layout mui * feat: navigation expand * fix: offline header + layout title * fix: test --------- Co-authored-by: Victor Zeinstra <[email protected]>
- Loading branch information
Showing
10 changed files
with
523 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import Link from "next/link"; | ||
import { Box, Stack } from "@mui/material"; | ||
|
||
export function LogoAdmin() { | ||
return ( | ||
<Link | ||
href="/" | ||
style={{ | ||
alignItems: "center", | ||
color: "#3e486e", | ||
textDecoration: "none", | ||
}} | ||
> | ||
<Stack direction="row"> | ||
<Box | ||
component="img" | ||
src="/img/logo.png" | ||
alt="Ministère du travail" | ||
sx={{ | ||
width: "77px", | ||
}} | ||
/> | ||
<Stack direction="column" justifyContent="center" textAlign="center"> | ||
<Box sx={{ fontSize: "large", lineHeight: "heading" }}> | ||
veille & administration | ||
</Box> | ||
<Box sx={{ fontSize: "small", fontWeight: 300 }}> | ||
Code du travail numérique | ||
</Box> | ||
</Stack> | ||
</Stack> | ||
</Link> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import { List } from "@mui/material"; | ||
import { useNavigationAggregation } from "./NavigationAggregation.query"; | ||
import { slugifyRepository } from "src/models"; | ||
import { NavigationItem } from "./NavigationItem"; | ||
import { NavigationGroup } from "./NavigationGroup"; | ||
import { useState } from "react"; | ||
import { useRouter } from "next/router"; | ||
|
||
type NavigationScheme = { | ||
[key: string]: { | ||
order: number; | ||
label: string; | ||
links: { | ||
href: string; | ||
label: string; | ||
aggregateCount?: number; | ||
}[]; | ||
}; | ||
}; | ||
|
||
export function Navigation() { | ||
const navAggregation = useNavigationAggregation(); | ||
const [expanded, setExpanded] = useState<string | false>(); | ||
const router = useRouter(); | ||
|
||
const navigation: NavigationScheme = { | ||
system: { | ||
order: 1, | ||
label: "Systèmes", | ||
links: [{ href: "/users", label: "Gestion des utilisateurs" }], | ||
}, | ||
contents: { | ||
order: 3, | ||
label: "Contenus", | ||
links: [ | ||
{ | ||
href: "/contenus", | ||
label: "Contenus", | ||
}, | ||
{ | ||
href: "/contenus?source=information", | ||
label: "Contenus éditoriaux", | ||
}, | ||
{ | ||
href: "/contenus?source=highlights", | ||
label: "À la une", | ||
}, | ||
{ | ||
href: "/contenus?source=prequalified", | ||
label: "Requetes pré-qualifiées", | ||
}, | ||
{ | ||
href: "/glossary", | ||
label: "Glossaire", | ||
}, | ||
{ | ||
href: "/themes", | ||
label: "Thèmes", | ||
}, | ||
{ | ||
href: "/kali/blocks", | ||
label: "Blocs KALI", | ||
}, | ||
{ | ||
href: "/fichiers", | ||
label: "Fichiers", | ||
}, | ||
{ | ||
href: "/unthemed", | ||
label: "Contenus sans thème", | ||
}, | ||
{ | ||
href: "/contenus/fiches-sp", | ||
label: "fiches service-public", | ||
}, | ||
{ | ||
href: "/duplicates", | ||
label: "Élements en Doublons", | ||
}, | ||
{ | ||
href: "/ghost-documents", | ||
label: "Références inaccessibles", | ||
}, | ||
{ | ||
href: "/mises-a-jour", | ||
label: "Mises à jour", | ||
}, | ||
], | ||
}, | ||
contributions: { | ||
order: 4, | ||
label: "Contributions", | ||
links: [{ href: "/contributions", label: "Questions" }], | ||
}, | ||
}; | ||
if (navAggregation) { | ||
navigation.alerts = { | ||
order: 2, | ||
label: "Alertes", | ||
links: navAggregation.map(({ label, repository, aggregateCount }) => ({ | ||
label, | ||
href: `/alerts/${slugifyRepository(repository)}`, | ||
aggregateCount, | ||
})), | ||
}; | ||
} | ||
|
||
Object.entries(navigation).forEach(([key, { links }]) => { | ||
if ( | ||
!expanded && | ||
links.some(({ href }) => { | ||
return router?.asPath?.includes(href); | ||
}) | ||
) { | ||
setExpanded(key); | ||
} | ||
}); | ||
|
||
return ( | ||
<List> | ||
{Object.entries(navigation) | ||
.sort(([, { order: orderA }], [, { order: orderB }]) => | ||
orderA > orderB ? 1 : -1 | ||
) | ||
.map(([key, { label, links }]) => { | ||
return ( | ||
<NavigationGroup | ||
key={key} | ||
id={key} | ||
label={label} | ||
expanded={expanded === key} | ||
onExpand={setExpanded} | ||
aggregateCount={links?.reduce( | ||
(sum, { aggregateCount }) => sum + (aggregateCount ?? 0), | ||
0 | ||
)} | ||
items={links} | ||
/> | ||
); | ||
})} | ||
</List> | ||
); | ||
} |
49 changes: 49 additions & 0 deletions
49
targets/frontend/src/components/layout/NavigationAggregation.query.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { useQuery } from "urql"; | ||
|
||
export const getAlertsQuery = ` | ||
query getAlerts { | ||
sources(order_by:{label:asc}) { | ||
repository, | ||
label, | ||
alerts: alerts_aggregate(where: {status: {_eq: "todo"}}) { | ||
aggregate { | ||
count | ||
} | ||
} | ||
} | ||
} | ||
`; | ||
|
||
export type Source = { | ||
repository: string; | ||
label: string; | ||
alerts: { | ||
aggregate: { | ||
count: number; | ||
}; | ||
}; | ||
}; | ||
|
||
export type GetAlertsOutput = { | ||
sources: Source[]; | ||
}; | ||
|
||
export type NavigationAggregationResult = { | ||
repository: string; | ||
label: string; | ||
aggregateCount: number; | ||
}; | ||
|
||
export const useNavigationAggregation = (): | ||
| NavigationAggregationResult[] | ||
| undefined => { | ||
const [result] = useQuery<GetAlertsOutput>({ | ||
query: getAlertsQuery, | ||
requestPolicy: "cache-and-network", | ||
}); | ||
return result.data?.sources?.map(({ repository, label, alerts }) => ({ | ||
repository, | ||
label, | ||
aggregateCount: alerts.aggregate.count, | ||
})); | ||
}; |
74 changes: 74 additions & 0 deletions
74
targets/frontend/src/components/layout/NavigationGroup.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { | ||
Accordion, | ||
AccordionSummary, | ||
Typography, | ||
AccordionDetails, | ||
Badge, | ||
Stack, | ||
} from "@mui/material"; | ||
import { styled } from "@mui/material/styles"; | ||
import ArrowForwardIosSharpIcon from "@mui/icons-material/ArrowForwardIosSharp"; | ||
import { NavigationItem, NavigationItemProps } from "./NavigationItem"; | ||
|
||
type NavigationGroupProps = { | ||
id: string; | ||
label: string; | ||
aggregateCount?: number; | ||
expanded: boolean; | ||
onExpand: (id: string) => void; | ||
items?: NavigationItemProps[]; | ||
}; | ||
|
||
export function NavigationGroup({ | ||
id, | ||
label, | ||
expanded, | ||
onExpand, | ||
aggregateCount = 0, | ||
items = [], | ||
}: NavigationGroupProps) { | ||
return ( | ||
<Accordion expanded={expanded} onChange={() => onExpand(id)} disableGutters> | ||
<AccordionHeader | ||
aria-controls="panel1d-content" | ||
id="panel1d-header" | ||
expandIcon={<ArrowForwardIosSharpIcon sx={{ fontSize: "0.9rem" }} />} | ||
> | ||
<Stack | ||
direction="row" | ||
justifyContent="space-between" | ||
alignItems="center" | ||
width="100%" | ||
> | ||
<Typography>{label}</Typography> | ||
{aggregateCount > 0 && ( | ||
<Badge | ||
badgeContent={aggregateCount} | ||
color="error" | ||
invisible={!aggregateCount} | ||
/> | ||
)} | ||
</Stack> | ||
</AccordionHeader> | ||
<AccordionDetails> | ||
{items.map((props) => ( | ||
<NavigationItem key={props.label} {...props}></NavigationItem> | ||
))} | ||
</AccordionDetails> | ||
</Accordion> | ||
); | ||
} | ||
|
||
const AccordionHeader = styled(AccordionSummary)(({ theme }) => ({ | ||
backgroundColor: | ||
theme.palette.mode === "dark" | ||
? "rgba(255, 255, 255, .05)" | ||
: "rgba(0, 0, 0, .03)", | ||
flexDirection: "row-reverse", | ||
"& .MuiAccordionSummary-expandIconWrapper.Mui-expanded": { | ||
transform: "rotate(90deg)", | ||
}, | ||
"& .MuiAccordionSummary-content": { | ||
marginLeft: theme.spacing(1), | ||
}, | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import Link from "next/link"; | ||
import { | ||
ListItem, | ||
ListItemButton, | ||
ListItemText, | ||
Stack, | ||
Badge, | ||
} from "@mui/material"; | ||
|
||
export type NavigationItemProps = { | ||
href: string; | ||
label: string; | ||
aggregateCount?: number; | ||
}; | ||
|
||
export function NavigationItem({ | ||
href, | ||
label, | ||
aggregateCount, | ||
}: NavigationItemProps) { | ||
return ( | ||
<ListItem | ||
disablePadding | ||
component={Link} | ||
href={href} | ||
style={{ textDecoration: "none" }} | ||
> | ||
<ListItemButton> | ||
<ListItemText | ||
primary={ | ||
<Stack | ||
direction="row" | ||
justifyContent="space-between" | ||
alignItems="center" | ||
> | ||
<div style={{ color: "rgb(62, 72, 110)" }}>{label}</div> | ||
<Badge | ||
badgeContent={aggregateCount} | ||
color="error" | ||
invisible={!aggregateCount} | ||
/> | ||
</Stack> | ||
} | ||
/> | ||
</ListItemButton> | ||
</ListItem> | ||
); | ||
} |
Oops, something went wrong.