Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tableau de bord et brief] Création de la page Dashboard et ajout des onglets de navigation #1709

Merged
merged 3 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions frontend/src/components/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { useAppSelector } from '@hooks/useAppSelector'
import { Accent, Icon, IconButton } from '@mtes-mct/monitor-ui'
import ResponsiveNav from '@rsuite/responsive-nav'
import styled from 'styled-components'

type NavBarProps = {
children: React.ReactNode[]
name: string
onClose: (eventKey: string | number | undefined) => void
onSelect: (eventKey: string | number | undefined) => void
}
export function NavBar({ children, name, onClose, onSelect }: NavBarProps) {
const currentPath = useAppSelector(state => state.sideWindow.currentPath)

return (
<StyledResponsiveNav
activeKey={currentPath}
appearance="tabs"
data-cy={`${name}-nav`}
moreProps={{ placement: 'bottomEnd' }}
moreText={<IconButton accent={Accent.TERTIARY} Icon={Icon.More} />}
onItemRemove={onClose}
onSelect={onSelect}
removable
>
{children}
</StyledResponsiveNav>
)
}

const StyledResponsiveNav = styled(ResponsiveNav)`
display: flex;
box-shadow: 0px 3px 4px #7077854d;
height: 48px;
width: 100%;

> .rs-nav-item {
width: 360px;
border-radius: 0px !important;
color: ${p => p.theme.color.slateGray};
font-size: 14px;
border-right: 1px solid ${p => p.theme.color.lightGray};
display: flex;
align-items: center;

&.rs-nav-item-active {
background-color: ${p => p.theme.color.blueGray25};
color: ${p => p.theme.color.gunMetal};
font-weight: 500;
border-radius: 0px;
border: 0px !important;

> .rs-icon {
color: ${p => p.theme.color.slateGray} !important;
}
}

> span:not(.Element-IconBox) {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
}

> .rs-icon {
color: ${p => p.theme.color.slateGray};
}
&:hover {
border-radius: 0px !important;
background-color: ${p => p.theme.color.blueYonder25};
}
&:first-child {
> svg {
display: none;
}
}
}
> .rs-dropdown {
> .rs-dropdown-toggle {
height: 100%;
border-radius: 0px !important;
> .rs-icon {
display: none;
}
}
> .rs-dropdown-menu {
> .rs-dropdown-item {
color: ${p => p.theme.color.slateGray};
display: flex;
flex-direction: row;
align-items: center;
&:hover {
background-color: ${p => p.theme.color.blueYonder25};
}
&.rs-dropdown-item-active {
background-color: ${p => p.theme.color.blueGray25};
color: ${p => p.theme.color.gunMetal};
}
}
}
}
> .rs-nav-bar {
border-top: 0px;
}
`
2 changes: 2 additions & 0 deletions frontend/src/domain/entities/sideWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export const sideWindowMenu = {
}

export const sideWindowPaths = {
DASHBOARD: '/dashboard/:id',
DASHBOARDS: '/dashboards',
HOME: '/',
MISSION: '/mission/:id',
MISSIONS: '/missions',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function DashboardForm() {
return (
<div>
<h1>Dashboard Form</h1>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { DialogButton, DialogSeparator, StyledMapMenuDialogContainer } from '@components/style'
import { MenuWithCloseButton } from '@features/commonStyles/map/MenuWithCloseButton'
import { sideWindowActions } from '@features/SideWindow/slice'
import { useAppDispatch } from '@hooks/useAppDispatch'
import { useAppSelector } from '@hooks/useAppSelector'
import { Accent, Button, Icon, MapMenuDialog, Size } from '@mtes-mct/monitor-ui'
import { sideWindowPaths } from 'domain/entities/sideWindow'
import { globalActions, setDisplayedItems } from 'domain/shared_slices/Global'
import { reduceReportingFormOnMap } from 'domain/use_cases/reporting/reduceReportingFormOnMap'
import styled from 'styled-components'
Expand All @@ -21,6 +23,7 @@ export function DashboardMapButton() {
)
dispatch(reduceReportingFormOnMap())
}
const gotToDashboardsList = () => dispatch(sideWindowActions.focusAndGoTo(sideWindowPaths.DASHBOARDS))

return (
<>
Expand All @@ -35,7 +38,7 @@ export function DashboardMapButton() {
Créer un tableau de bord
</Button>
<DialogSeparator />
<DialogButton accent={Accent.SECONDARY} Icon={Icon.Expand} isFullWidth onClick={() => {}}>
<DialogButton accent={Accent.SECONDARY} Icon={Icon.Expand} isFullWidth onClick={gotToDashboardsList}>
Voir les briefs déjà créés
</DialogButton>
</MapMenuDialog.Footer>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SideWindowContent } from '@features/SideWindow/style'
import styled from 'styled-components'

export function DashboardsList() {
return (
<SideWindowContent>
<Title>Tableaux de bord</Title>
</SideWindowContent>
)
}

const Title = styled.h1`
color: ${p => p.theme.color.gunMetal};
font-size: 22px;
line-height: 50px;
`
50 changes: 50 additions & 0 deletions frontend/src/features/Dashboard/components/DashboardsNavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { NavBar } from '@components/NavBar'
import { sideWindowActions } from '@features/SideWindow/slice'
import { useAppDispatch } from '@hooks/useAppDispatch'
import { Icon, THEME } from '@mtes-mct/monitor-ui'
import ResponsiveNav from '@rsuite/responsive-nav'
import { sideWindowPaths } from 'domain/entities/sideWindow'
import { useMemo } from 'react'
import { generatePath } from 'react-router'

export function DashboardsNavBar() {
const dispatch = useAppDispatch()

const tabs = useMemo(() => {
const dashboardsList = {
icon: <Icon.Summary />,
label: 'Liste des tableaux de bords',
nextPath: sideWindowPaths.DASHBOARDS
}

// TODO 19/09 : replace with real data
const openDashboards = {
icon: <Icon.CircleFilled color={THEME.color.blueGray} size={14} />,
label: <span>Tab XX/XX/XX</span>,
nextPath: generatePath(sideWindowPaths.DASHBOARD, { id: 1 })
}

return [dashboardsList, openDashboards]
}, [])

const selectDashboard = path => {
dispatch(sideWindowActions.setCurrentPath(path))
}

const closeDashboard = () => {}

return (
<NavBar name="dashboards" onClose={closeDashboard} onSelect={selectDashboard}>
{tabs.map((item, index) => (
<ResponsiveNav.Item
key={item.nextPath}
data-cy={`dashboard-${index}`}
eventKey={item.nextPath}
icon={item.icon}
>
{item.label}
</ResponsiveNav.Item>
))}
</NavBar>
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReportingsFilters } from '@features/Reportings/Filters'
import { useGetFilteredReportingsQuery } from '@features/Reportings/hooks/useGetFilteredReportingsQuery'
import { SideWindowContent } from '@features/SideWindow/style'
import { useAppDispatch } from '@hooks/useAppDispatch'
import { useGetControlPlans } from '@hooks/useGetControlPlans'
import { Button, Icon } from '@mtes-mct/monitor-ui'
Expand All @@ -20,7 +21,7 @@ export function ReportingsList() {
}

return (
<StyledReportingsContainer>
<SideWindowContent>
<StyledHeader>
<Title data-cy="SideWindowHeader-title">Signalements</Title>
<StyledButton Icon={Icon.Plus} onClick={createReporting}>
Expand All @@ -34,18 +35,10 @@ export function ReportingsList() {
) : (
<ReportingsTable isLoading={isLoading || isFetching} reportings={reportings} />
)}
</StyledReportingsContainer>
</SideWindowContent>
)
}

const StyledReportingsContainer = styled.div`
display: flex;
flex: 1;
flex-direction: column;
padding: 40px;
overflow: auto;
`

const StyledHeader = styled.div`
display: flex;
flex-direction: row;
Expand Down
18 changes: 17 additions & 1 deletion frontend/src/features/SideWindow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { DashboardForm } from '@features/Dashboard/components/DashboardForm'
import { DashboardsList } from '@features/Dashboard/components/DashboardsList'
import { DashboardsNavBar } from '@features/Dashboard/components/DashboardsNavBar'
import { REPORTING_EVENT_UNSYNCHRONIZED_PROPERTIES } from '@features/Reportings/components/ReportingForm/constants'
import { useListenReportingEventUpdates } from '@features/Reportings/components/ReportingForm/hooks/useListenReportingEventUpdates'
import { ReportingsList } from '@features/Reportings/components/ReportingsList'
Expand All @@ -18,7 +21,7 @@ import { ReportingContext } from '../../domain/shared_slices/Global'
import { switchTab } from '../../domain/use_cases/missions/switchTab'
import { useAppDispatch } from '../../hooks/useAppDispatch'
import { useAppSelector } from '../../hooks/useAppSelector'
import { isMissionOrMissionsPage, isMissionPage, isReportingsPage } from '../../utils/routes'
import { isDashboardsPage, isMissionOrMissionsPage, isMissionPage, isReportingsPage } from '../../utils/routes'
import { MissionFormWrapper } from '../missions/MissionForm'
import { MISSION_EVENT_UNSYNCHRONIZED_PROPERTIES } from '../missions/MissionForm/constants'
import { useListenMissionEventUpdates } from '../missions/MissionForm/hooks/useListenMissionEventUpdates'
Expand All @@ -37,6 +40,7 @@ export function SideWindow() {

const isMissionButtonIsActive = useMemo(() => isMissionOrMissionsPage(currentPath), [currentPath])
const isReportingsButtonIsActive = useMemo(() => isReportingsPage(currentPath), [currentPath])
const isDashboardsButtonIsActive = useMemo(() => isDashboardsPage(currentPath), [currentPath])

/**
* Use to update mission opened in the side window but not actives
Expand Down Expand Up @@ -106,13 +110,25 @@ export function SideWindow() {
onClick={() => navigate(generatePath(sideWindowPaths.REPORTINGS))}
title="Signalements"
/>
<SideMenu.Button
Icon={Icon.Bullseye}
isActive={isDashboardsButtonIsActive}
onClick={() => navigate(generatePath(sideWindowPaths.DASHBOARDS))}
title="Tableaux de bord"
/>
</SideMenu>

<StyledRouteContainer>
<Route element={<ReportingsList />} path={sideWindowPaths.REPORTINGS} />
<Route element={<MissionsNavBar />} path={[sideWindowPaths.MISSIONS, sideWindowPaths.MISSION]} />
<Route element={<Missions />} path={sideWindowPaths.MISSIONS} />
<Route element={<MissionFormWrapper />} path={sideWindowPaths.MISSION} />
<Route
element={<DashboardsNavBar />}
path={[sideWindowPaths.DASHBOARDS, sideWindowPaths.DASHBOARD]}
/>
<Route element={<DashboardsList />} path={sideWindowPaths.DASHBOARDS} />
<Route element={<DashboardForm />} path={sideWindowPaths.DASHBOARD} />
</StyledRouteContainer>
{isReportingsButtonIsActive && (
<Reportings key="reportings-on-side-window" context={ReportingContext.SIDE_WINDOW} />
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/features/SideWindow/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ export const StyledRouteContainer = styled.section`
flex-direction: column;
width: calc(100vw - 64px);
`

export const SideWindowContent = styled.div`
display: flex;
flex: 1;
flex-direction: column;
padding: 40px;
overflow: auto;
`
13 changes: 3 additions & 10 deletions frontend/src/features/missions/MissionsList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SideWindowContent } from '@features/SideWindow/style'
import { Button, Icon } from '@mtes-mct/monitor-ui'
import styled from 'styled-components'

Expand All @@ -17,7 +18,7 @@ export function Missions() {
}

return (
<StyledMissionsContainer>
<SideWindowContent>
<StyledHeader>
<Title data-cy="SideWindowHeader-title">Missions et contrôles</Title>
<StyledButton data-cy="add-mission" Icon={Icon.Plus} onClick={createMission}>
Expand All @@ -34,18 +35,10 @@ export function Missions() {
) : (
<MissionsTable isLoading={isLoading || isFetching} missions={missions} />
)}
</StyledMissionsContainer>
</SideWindowContent>
)
}

const StyledMissionsContainer = styled.div`
display: flex;
flex: 1;
flex-direction: column;
padding: 40px;
overflow: auto;
`

const StyledHeader = styled.div`
display: flex;
flex-direction: row;
Expand Down
Loading