diff --git a/frontend/src/components/NavBar.tsx b/frontend/src/components/NavBar.tsx
new file mode 100644
index 000000000..9455a6f21
--- /dev/null
+++ b/frontend/src/components/NavBar.tsx
@@ -0,0 +1,99 @@
+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'
+
+export function NavBar({ children, onClose, onSelect }) {
+ const currentPath = useAppSelector(state => state.sideWindow.currentPath)
+
+ return (
+ }
+ onItemRemove={onClose}
+ onSelect={onSelect}
+ removable
+ >
+ {children}
+
+ )
+}
+
+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;
+ }
+`
diff --git a/frontend/src/domain/entities/sideWindow.ts b/frontend/src/domain/entities/sideWindow.ts
index 6a55d1910..52aa203d2 100644
--- a/frontend/src/domain/entities/sideWindow.ts
+++ b/frontend/src/domain/entities/sideWindow.ts
@@ -10,6 +10,8 @@ export const sideWindowMenu = {
}
export const sideWindowPaths = {
+ DASHBOARD: '/dashboard/:id',
+ DASHBOARDS: '/dashboards',
HOME: '/',
MISSION: '/mission/:id',
MISSIONS: '/missions',
diff --git a/frontend/src/features/Dashboard/components/DashboardMapButton.tsx b/frontend/src/features/Dashboard/components/DashboardMapButton.tsx
index b65e34608..6c1354364 100644
--- a/frontend/src/features/Dashboard/components/DashboardMapButton.tsx
+++ b/frontend/src/features/Dashboard/components/DashboardMapButton.tsx
@@ -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'
@@ -21,6 +23,7 @@ export function DashboardMapButton() {
)
dispatch(reduceReportingFormOnMap())
}
+ const gotToDashboardsList = () => dispatch(sideWindowActions.focusAndGoTo(sideWindowPaths.DASHBOARDS))
return (
<>
@@ -35,7 +38,7 @@ export function DashboardMapButton() {
Créer un tableau de bord
- {}}>
+
Voir les briefs déjà créés
diff --git a/frontend/src/features/Dashboard/components/DashboardsList/index.tsx b/frontend/src/features/Dashboard/components/DashboardsList/index.tsx
new file mode 100644
index 000000000..400d29744
--- /dev/null
+++ b/frontend/src/features/Dashboard/components/DashboardsList/index.tsx
@@ -0,0 +1,16 @@
+import { SideWindowContent } from '@features/SideWindow/style'
+import styled from 'styled-components'
+
+export function DashboardsList() {
+ return (
+
+ Tableaux de bord
+
+ )
+}
+
+const Title = styled.h1`
+ color: ${p => p.theme.color.gunMetal};
+ font-size: 22px;
+ line-height: 50px;
+`
diff --git a/frontend/src/features/Dashboard/components/DashboardsNavBar.tsx b/frontend/src/features/Dashboard/components/DashboardsNavBar.tsx
new file mode 100644
index 000000000..9453626b2
--- /dev/null
+++ b/frontend/src/features/Dashboard/components/DashboardsNavBar.tsx
@@ -0,0 +1,44 @@
+import { NavBar } from '@components/NavBar'
+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 tabs = useMemo(() => {
+ const dashboardsList = {
+ icon: ,
+ label: 'Liste des tableaux de bords',
+ nextPath: sideWindowPaths.DASHBOARDS
+ }
+
+ // TODO 19/09 : replace with real data
+ const openDashboards = {
+ icon: ,
+ label: Tab XX/XX/XX,
+ nextPath: generatePath(sideWindowPaths.MISSION, { id: 1 })
+ }
+
+ return [dashboardsList, openDashboards]
+ }, [])
+
+ const selectDashboard = () => {}
+
+ const closeDashboard = () => {}
+
+ return (
+
+ {tabs.map((item, index) => (
+
+ {item.label}
+
+ ))}
+
+ )
+}
diff --git a/frontend/src/features/Reportings/components/ReportingsList/index.tsx b/frontend/src/features/Reportings/components/ReportingsList/index.tsx
index 54b2323aa..48914222c 100644
--- a/frontend/src/features/Reportings/components/ReportingsList/index.tsx
+++ b/frontend/src/features/Reportings/components/ReportingsList/index.tsx
@@ -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'
@@ -20,7 +21,7 @@ export function ReportingsList() {
}
return (
-
+
Signalements
@@ -34,18 +35,10 @@ export function ReportingsList() {
) : (
)}
-
+
)
}
-const StyledReportingsContainer = styled.div`
- display: flex;
- flex: 1;
- flex-direction: column;
- padding: 40px;
- overflow: auto;
-`
-
const StyledHeader = styled.div`
display: flex;
flex-direction: row;
diff --git a/frontend/src/features/SideWindow/index.tsx b/frontend/src/features/SideWindow/index.tsx
index 11c3372be..e1212b196 100644
--- a/frontend/src/features/SideWindow/index.tsx
+++ b/frontend/src/features/SideWindow/index.tsx
@@ -1,3 +1,5 @@
+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'
@@ -18,7 +20,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'
@@ -37,6 +39,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
@@ -106,6 +109,12 @@ export function SideWindow() {
onClick={() => navigate(generatePath(sideWindowPaths.REPORTINGS))}
title="Signalements"
/>
+ navigate(generatePath(sideWindowPaths.DASHBOARDS))}
+ title="Tableaux de bord"
+ />
@@ -113,6 +122,11 @@ export function SideWindow() {
} path={[sideWindowPaths.MISSIONS, sideWindowPaths.MISSION]} />
} path={sideWindowPaths.MISSIONS} />
} path={sideWindowPaths.MISSION} />
+ }
+ path={[sideWindowPaths.DASHBOARDS, sideWindowPaths.DASHBOARD]}
+ />
+ } path={sideWindowPaths.DASHBOARDS} />
{isReportingsButtonIsActive && (
diff --git a/frontend/src/features/SideWindow/style.ts b/frontend/src/features/SideWindow/style.ts
index 5fc656d7e..aa1cb717c 100644
--- a/frontend/src/features/SideWindow/style.ts
+++ b/frontend/src/features/SideWindow/style.ts
@@ -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;
+`
diff --git a/frontend/src/features/missions/MissionsList/index.tsx b/frontend/src/features/missions/MissionsList/index.tsx
index 939df2d20..d9d6b265a 100644
--- a/frontend/src/features/missions/MissionsList/index.tsx
+++ b/frontend/src/features/missions/MissionsList/index.tsx
@@ -1,3 +1,4 @@
+import { SideWindowContent } from '@features/SideWindow/style'
import { Button, Icon } from '@mtes-mct/monitor-ui'
import styled from 'styled-components'
@@ -17,7 +18,7 @@ export function Missions() {
}
return (
-
+
Missions et contrôles
@@ -34,18 +35,10 @@ export function Missions() {
) : (
)}
-
+
)
}
-const StyledMissionsContainer = styled.div`
- display: flex;
- flex: 1;
- flex-direction: column;
- padding: 40px;
- overflow: auto;
-`
-
const StyledHeader = styled.div`
display: flex;
flex-direction: row;
diff --git a/frontend/src/features/missions/MissionsNavBar.tsx b/frontend/src/features/missions/MissionsNavBar.tsx
index 0bb21bf0c..b23a6a86f 100644
--- a/frontend/src/features/missions/MissionsNavBar.tsx
+++ b/frontend/src/features/missions/MissionsNavBar.tsx
@@ -1,4 +1,5 @@
-import { Accent, Icon, IconButton } from '@mtes-mct/monitor-ui'
+import { NavBar } from '@components/NavBar'
+import { Icon } from '@mtes-mct/monitor-ui'
import ResponsiveNav from '@rsuite/responsive-nav'
import { useMemo } from 'react'
import { generatePath } from 'react-router-dom'
@@ -24,7 +25,6 @@ function MissionStatus({ mission }) {
}
export function MissionsNavBar() {
- const currentPath = useAppSelector(state => state.sideWindow.currentPath)
const selectedMissions = useAppSelector(state => state.missionForms.missions)
const dispatch = useAppDispatch()
@@ -65,101 +65,16 @@ export function MissionsNavBar() {
}
return (
- }
- onItemRemove={removeTab}
- onSelect={selectTab}
- removable
- >
+
{tabs.map((item, index) => (
{item.label}
))}
-
+
)
}
-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;
- }
-`
-
export const StyledStatus = styled.div<{ borderColor: string | undefined; color: string }>`
height: 12px;
width: 12px;
diff --git a/frontend/src/utils/routes.ts b/frontend/src/utils/routes.ts
index 57a0b2db7..4e0b0b8a3 100644
--- a/frontend/src/utils/routes.ts
+++ b/frontend/src/utils/routes.ts
@@ -42,3 +42,13 @@ export function isReportingsPage(path: string) {
path as string
)
}
+
+export function isDashboardsPage(path: string) {
+ return !!matchPath(
+ {
+ end: true,
+ path: sideWindowPaths.DASHBOARDS
+ },
+ path as string
+ )
+}