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 & brief] Ajout du bouton et du feature flag #1708

Merged
merged 16 commits into from
Sep 18, 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
1 change: 1 addition & 0 deletions .env.dev.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ FRONTEND_MISSION_FORM_AUTO_UPDATE=true
FRONTEND_MISSION_FORM_AUTO_SAVE_ENABLED=true
FRONTEND_REPORTING_FORM_AUTO_SAVE_ENABLED=true
FRONTEND_REPORTING_FORM_AUTO_UPDATE=true
FRONTEND_DASHBOARD_ENABLED=true

################################################################################
# Version
Expand Down
1 change: 1 addition & 0 deletions .env.infra.example
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ FRONTEND_MISSION_FORM_AUTO_UPDATE=
FRONTEND_MISSION_FORM_AUTO_SAVE_ENABLED=
FRONTEND_REPORTING_FORM_AUTO_SAVE_ENABLED=
FRONTEND_REPORTING_FORM_AUTO_UPDATE=
FRONTEND_DASHBOARD_ENABLED=

################################################################################
# Version
Expand Down
1 change: 1 addition & 0 deletions .env.test.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ FRONTEND_MISSION_FORM_AUTO_UPDATE=true
FRONTEND_MISSION_FORM_AUTO_SAVE_ENABLED=true
FRONTEND_REPORTING_FORM_AUTO_SAVE_ENABLED=true
FRONTEND_REPORTING_FORM_AUTO_UPDATE=true
FRONTEND_DASHBOARD_ENABLED=true

################################################################################
# Version
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ services:
- FRONTEND_MISSION_FORM_AUTO_SAVE_ENABLED=${FRONTEND_MISSION_FORM_AUTO_SAVE_ENABLED}
- FRONTEND_REPORTING_FORM_AUTO_SAVE_ENABLED=${FRONTEND_REPORTING_FORM_AUTO_SAVE_ENABLED}
- FRONTEND_REPORTING_FORM_AUTO_UPDATE=${FRONTEND_REPORTING_FORM_AUTO_UPDATE}
- FRONTEND_DASHBOARD_ENABLED=${FRONTEND_DASHBOARD_ENABLED}
- FRONTEND_OIDC_AUTHORITY=${MONITORENV_OIDC_ISSUER_URI}
- FRONTEND_OIDC_CLIENT_ID=${MONITORENV_OIDC_CLIENT_ID}
- FRONTEND_OIDC_ENABLED=${MONITORENV_OIDC_ENABLED}
Expand Down
1 change: 1 addition & 0 deletions frontend/.env.frontend.example
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ FRONTEND_MISSION_FORM_AUTO_UPDATE=
FRONTEND_MISSION_FORM_AUTO_SAVE_ENABLED=
FRONTEND_REPORTING_FORM_AUTO_SAVE_ENABLED=
FRONTEND_REPORTING_FORM_AUTO_UPDATE=
FRONTEND_DASHBOARD_ENABLED=

################################################################################
# Version
Expand Down
12 changes: 0 additions & 12 deletions frontend/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,3 @@ Cypress.on('uncaught:exception', err => {

return undefined
})

// Run before each spec
beforeEach(() => {
// We use a Cypress session to inject inject a Local Storage key
// so that we can detect when the browser app is running in Cypress.
// https://docs.cypress.io/faq/questions/using-cypress-faq#How-do-I-preserve-cookies--localStorage-in-between-my-tests
cy.session('cypress', () => {
cy.window().then(window => {
window.localStorage.setItem('IS_CYPRESS', 'true')
})
})
})
705 changes: 316 additions & 389 deletions frontend/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
"test:unit:watch": "npm run test:unit -- --watch"
},
"dependencies": {
"@mtes-mct/monitor-ui": "21.2.0",
"@mtes-mct/monitor-ui": "22.1.0",
"@reduxjs/toolkit": "2.0.0",
"@rsuite/responsive-nav": "5.0.2",
"@sentry/browser": "7.73.0",
"@sentry/react": "7.73.0",
"@sentry/tracing": "7.114.0",
"@svgr/webpack": "8.1.0",
"@tanstack/react-table": "8.20.1",
"@tanstack/react-table": "8.20.5",
"@tanstack/react-virtual": "beta",
"classnames": "2.5.1",
"dayjs": "1.11.12",
Expand Down
102 changes: 102 additions & 0 deletions frontend/src/components/Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { Account } from '@features/Account/components/Account'
import { ControlUnitListButton } from '@features/ControlUnit/components/ControlUnitListButton'
import { DashboardMapButton } from '@features/Dashboard/components/DashboardMapButton'
import { InterestPointMapButton } from '@features/InterestPoint/components/InterestPointMapButton'
import { MeasurementMapButton } from '@features/map/tools/measurements/MeasurementMapButton'
import { MissionsMenu } from '@features/missions/MissionsButton'
import { ReportingsButton } from '@features/Reportings/components/ReportingsButton'
import { SearchSemaphoreButton } from '@features/Semaphore/components/SearchSemaphoreButton'
import { useAppSelector } from '@hooks/useAppSelector'
import styled from 'styled-components'

type MenuProps = {
isSuperUser: boolean
}

export function Menu({ isSuperUser }: MenuProps) {
const displaySearchSemaphoreButton = useAppSelector(state => state.global.displaySearchSemaphoreButton)

const displayInterestPoint = useAppSelector(state => state.global.displayInterestPoint)
const displayMeasurement = useAppSelector(state => state.global.displayMeasurement)
const displayMissionMenuButton = useAppSelector(state => state.global.displayMissionMenuButton)
const displayReportingsButton = useAppSelector(state => state.global.displayReportingsButton)
const displayAccountButton = useAppSelector(state => state.global.displayAccountButton)
const displayDashboard = useAppSelector(state => state.global.displayDashboard)
const isRightMenuControlUnitListButtonVisible = useAppSelector(
state => state.global.displayRightMenuControlUnitListButton
)
const hasFullHeightRightDialogOpen = useAppSelector(state => state.mainWindow.hasFullHeightRightDialogOpen)
const isRightMenuOpened = useAppSelector(state => state.mainWindow.isRightMenuOpened)

return (
<ButtonsWrapper $hasFullHeightRightDialogOpen={hasFullHeightRightDialogOpen} $isRightMenuOpened={isRightMenuOpened}>
{displayMissionMenuButton && isSuperUser && (
<li>
<MissionsMenu />
</li>
)}
{displayReportingsButton && isSuperUser && (
<li>
<ReportingsButton />
</li>
)}
{displaySearchSemaphoreButton && (
<li>
<SearchSemaphoreButton />
</li>
)}
{isRightMenuControlUnitListButtonVisible && isSuperUser && (
<li>
<ControlUnitListButton />
</li>
)}
{displayDashboard && isSuperUser && (
<li>
<DashboardMapButton />
</li>
)}

<ToolWrapper>
<ToolButtons>
{displayMeasurement && isSuperUser && <MeasurementMapButton />}
{displayInterestPoint && isSuperUser && (
<li>
<InterestPointMapButton />
</li>
)}
{displayAccountButton && (
<li>
<Account />
</li>
)}
</ToolButtons>
</ToolWrapper>
</ButtonsWrapper>
)
}

const ButtonsWrapper = styled.menu<{
$hasFullHeightRightDialogOpen: boolean
$isRightMenuOpened: boolean
}>`
position: absolute;
display: flex;
flex-direction: column;
row-gap: 8px;
top: 82px;
right: ${p => (!p.$hasFullHeightRightDialogOpen || p.$isRightMenuOpened ? 10 : 0)}px;
transition: right 0.3s ease-out;
list-style: none;
`

const ToolWrapper = styled.li`
margin-top: 24px;
`

const ToolButtons = styled.ul`
display: flex;
flex-direction: column;
row-gap: 8px;
list-style: none;
padding: 0;
`
20 changes: 20 additions & 0 deletions frontend/src/components/style.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Button, MapMenuDialog } from '@mtes-mct/monitor-ui'
import styled from 'styled-components'

export const Italic = styled.div`
Expand All @@ -7,3 +8,22 @@ export const Italic = styled.div`
export const Bold = styled.span`
font-weight: 700;
`

export const StyledMapMenuDialogContainer = styled(MapMenuDialog.Container)`
position: absolute;
transform: translateX(-100%);
margin-left: -6px;
display: block;
`

// TODO delete when Monitor-ui component have good padding
export const DialogButton = styled(Button)`
padding: 4px 12px;
`

export const DialogSeparator = styled.div`
height: 1px;
border-top: 1px solid ${p => p.theme.color.gainsboro};
margin-left: -12px;
margin-right: -12px;
`
4 changes: 1 addition & 3 deletions frontend/src/domain/entities/map/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ export enum MapToolType {
FILTERS = 'FILTERS',
INTEREST_POINT = 'INTEREST_POINT',
MEASUREMENT = 'MEASUREMENT',
MEASUREMENT_MENU = 'MEASUREMENT_MENU',
VESSEL_LABELS = 'VESSEL_LABELS',
VESSEL_VISIBILITY = 'VESSEL_VISIBILITY'
MEASUREMENT_MENU = 'MEASUREMENT_MENU'
}

export enum OLGeometryType {
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/domain/shared_slices/Global.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// TODO This slice should disappear in favor of `features/MainWindow/slice.ts` and "Map" feature should have its own slice.
// TODO "Map" feature should have its own slice where we would transfer the related `display...` props.

import { isDashboardEnabled } from '@features/Dashboard/utils'
import { createSelector, createSlice, type PayloadAction } from '@reduxjs/toolkit'

import type { MapToolType } from '../entities/map/constants'
Expand Down Expand Up @@ -42,6 +43,7 @@ type GlobalStateType = {
displayLocateOnMap: boolean
displayMeasurement: boolean
displayInterestPoint: boolean
displayDashboard: boolean
displaySearchSemaphoreButton: boolean
displayReportingsButton: boolean
displayRightMenuControlUnitListButton: boolean
Expand Down Expand Up @@ -76,6 +78,8 @@ type GlobalStateType = {

displayStationLayer: boolean

isDashboardDialogVisible: boolean

isLayersSidebarVisible: boolean

isMapToolVisible?: MapToolType
Expand All @@ -97,6 +101,7 @@ const initialState: GlobalStateType = {
displayLocateOnMap: true,
displayMeasurement: true,
displayInterestPoint: true,
displayDashboard: true && isDashboardEnabled(),
displaySearchSemaphoreButton: true,
displayReportingsButton: true,
displayRightMenuControlUnitListButton: true,
Expand Down Expand Up @@ -135,6 +140,8 @@ const initialState: GlobalStateType = {

displayStationLayer: false,

isDashboardDialogVisible: false,

isMapToolVisible: undefined,

healthcheckTextWarning: undefined,
Expand Down Expand Up @@ -164,6 +171,7 @@ const globalSlice = createSlice({
state.isSearchSemaphoreVisible = false
state.isSearchMissionsVisible = false
state.isMapToolVisible = undefined
state.isDashboardDialogVisible = false
},

removeOverlayStroke(state) {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/// <reference types="vite/client" />

interface ImportMetaEnv {
readonly FRONTEND_DASHBOARD_ENABLED: string
readonly FRONTEND_GEOSERVER_NAMESPACE: string
readonly FRONTEND_GEOSERVER_REMOTE_URL: string
readonly FRONTEND_GOOGLEMAPS_API_KEY: string
Expand Down
17 changes: 5 additions & 12 deletions frontend/src/features/Account/components/Account.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { StyledMapMenuDialogContainer } from '@components/style'
import { MenuWithCloseButton } from '@features/commonStyles/map/MenuWithCloseButton'
import { ButtonWrapper } from '@features/MainWindow/components/RightMenu/ButtonWrapper'
import { useAppDispatch } from '@hooks/useAppDispatch'
import { useAppSelector } from '@hooks/useAppSelector'
import { Accent, Button, Icon, MapMenuDialog, Size } from '@mtes-mct/monitor-ui'
import { getOIDCConfig } from 'auth/getOIDCConfig'
import { globalActions } from 'domain/shared_slices/Global'
import { useAuth } from 'react-oidc-context'
import styled from 'styled-components'

const MARGIN_TOP = 388

export function Account() {
const dispatch = useAppDispatch()
Expand All @@ -30,9 +27,9 @@ export function Account() {
}

return (
<ButtonWrapper topPosition={MARGIN_TOP}>
<>
{isAccountVisible && (
<StyledContainer>
<StyledMapMenuDialogContainer>
<MapMenuDialog.Header>
<MapMenuDialog.Title>Déconnexion</MapMenuDialog.Title>
</MapMenuDialog.Header>
Expand All @@ -46,7 +43,7 @@ export function Account() {
</Button>
</MapMenuDialog.Footer>
)}
</StyledContainer>
</StyledMapMenuDialogContainer>
)}

<MenuWithCloseButton.ButtonOnMap
Expand All @@ -57,10 +54,6 @@ export function Account() {
size={Size.LARGE}
title="Mon compte"
/>
</ButtonWrapper>
</>
)
}

const StyledContainer = styled(MapMenuDialog.Container)`
margin-right: unset;
`
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Icon, Size } from '@mtes-mct/monitor-ui'
import { useCallback } from 'react'

import { ButtonWrapper } from './ButtonWrapper'
import { globalActions } from '../../../../domain/shared_slices/Global'
import { reduceReportingFormOnMap } from '../../../../domain/use_cases/reporting/reduceReportingFormOnMap'
import { useAppDispatch } from '../../../../hooks/useAppDispatch'
import { useAppSelector } from '../../../../hooks/useAppSelector'
import { MenuWithCloseButton } from '../../../commonStyles/map/MenuWithCloseButton'
import { ControlUnitListDialog } from '../../../ControlUnit/components/ControlUnitListDialog'
import { ControlUnitListDialog } from './ControlUnitListDialog'
import { globalActions } from '../../../domain/shared_slices/Global'
import { reduceReportingFormOnMap } from '../../../domain/use_cases/reporting/reduceReportingFormOnMap'
import { useAppDispatch } from '../../../hooks/useAppDispatch'
import { useAppSelector } from '../../../hooks/useAppSelector'
import { MenuWithCloseButton } from '../../commonStyles/map/MenuWithCloseButton'

export function ControlUnitListButton() {
const dispatch = useAppDispatch()
Expand All @@ -20,7 +19,7 @@ export function ControlUnitListButton() {
}, [dispatch, isControlUnitListDialogVisible])

return (
<ButtonWrapper topPosition={226}>
<>
{/* TODO The right menu should be a full `MainWindow` feature component by itself. */}
{/* We should positition related dialogs independantly, not include them here. */}
{isControlUnitListDialogVisible && <ControlUnitListDialog onClose={toggleDialog} />}
Expand All @@ -32,6 +31,6 @@ export function ControlUnitListButton() {
size={Size.LARGE}
title="Liste des unités de contrôle"
/>
</ButtonWrapper>
</>
)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { StyledMapMenuDialogContainer } from '@components/style'
import { Accent, Icon, MapMenuDialog } from '@mtes-mct/monitor-ui'
import { useCallback, useMemo } from 'react'

Expand Down Expand Up @@ -46,7 +47,7 @@ export function ControlUnitListDialog({ onClose }: ControlUnitListDialogProps) {
}, [dispatch, displayBaseLayer])

return (
<MapMenuDialog.Container style={{ height: 480 }}>
<StyledMapMenuDialogContainer style={{ height: 480 }}>
<MapMenuDialog.Header>
<MapMenuDialog.CloseButton Icon={Icon.Close} onClick={onClose} />
<MapMenuDialog.Title>Unités de contrôle</MapMenuDialog.Title>
Expand All @@ -63,11 +64,6 @@ export function ControlUnitListDialog({ onClose }: ControlUnitListDialogProps) {
{filteredControlUnits &&
filteredControlUnits.map(controlUnit => <Item key={controlUnit.id} controlUnit={controlUnit} />)}
</MapMenuDialog.Body>
{/* <MapMenuDialog.Footer>
<Button accent={Accent.SECONDARY} Icon={Icon.Expand} isFullWidth onClick={noop}>
Voir la vue détaillée des unités
</Button>
</MapMenuDialog.Footer> */}
</MapMenuDialog.Container>
</StyledMapMenuDialogContainer>
)
}
Loading