diff --git a/application/frontend/src/app/core/actions/map.actions.ts b/application/frontend/src/app/core/actions/map.actions.ts index 37e74b23..479d6e41 100644 --- a/application/frontend/src/app/core/actions/map.actions.ts +++ b/application/frontend/src/app/core/actions/map.actions.ts @@ -54,7 +54,7 @@ export const editPreSolveVehicle = createAction( export const editVisit = createAction('[Map] Edit Visit', props<{ visitId: number }>()); -export const setPostSolveLayerVisible = createAction( - '[Map] Set Post Solve Layer Visible', +export const setLayerVisible = createAction( + '[Map] Set Layer Visible', props<{ layerId: MapLayerId; visible: boolean }>() ); diff --git a/application/frontend/src/app/core/components/map-add-buttons/map-add-buttons.component.scss b/application/frontend/src/app/core/components/map-add-buttons/map-add-buttons.component.scss index dcf2a63d..24d90706 100644 --- a/application/frontend/src/app/core/components/map-add-buttons/map-add-buttons.component.scss +++ b/application/frontend/src/app/core/components/map-add-buttons/map-add-buttons.component.scss @@ -6,10 +6,6 @@ border: none; box-shadow: none; gap: 1rem; - position: absolute; - top: 0; - left: 50px; - margin: 10px; } .add-button { diff --git a/application/frontend/src/app/core/containers/map/map.component.css b/application/frontend/src/app/core/containers/map/map.component.css index 0dbd9511..7dcccc29 100644 --- a/application/frontend/src/app/core/containers/map/map.component.css +++ b/application/frontend/src/app/core/containers/map/map.component.css @@ -2,11 +2,13 @@ position: relative; } -app-post-solve-map-legend { +.map-controls { position: absolute; z-index: 1; top: 10px; left: 50px; + display: flex; + gap: 1rem; } app-map-type-button { diff --git a/application/frontend/src/app/core/containers/map/map.component.html b/application/frontend/src/app/core/containers/map/map.component.html index 98870deb..31b2b68e 100644 --- a/application/frontend/src/app/core/containers/map/map.component.html +++ b/application/frontend/src/app/core/containers/map/map.component.html @@ -1,14 +1,15 @@ - - - +
+ + + +
{ + this.store.pipe(select(fromMap.selectUsedMapLayers)), + ]).subscribe(([preSolve, postSolve, hasMap, visibleMapLayers]) => { this.routeLayer.visible = hasMap && postSolve; this.preSolveVehicleLayer.visible = hasMap && preSolve; - this.preSolveVisitRequestLayer.visible = hasMap && preSolve; + this.preSolveVisitRequestLayer.visible = + hasMap && preSolve && visibleMapLayers[MapLayerId.VisitRequests].visible; this.postSolveVehicleLayer.visible = hasMap && postSolve; this.postSolveVisitRequestLayer.visible = - hasMap && postSolve && postSolveMapLayers[MapLayerId.PostSolveVisitRequests].visible; + hasMap && postSolve && visibleMapLayers[MapLayerId.VisitRequests].visible; this.depotLayer.visible = hasMap; }), @@ -262,7 +263,7 @@ export class MapComponent implements OnInit, OnDestroy { onSetLayerVisibility(event: { layerId: MapLayerId; visible: boolean }): void { this.store.dispatch( - MapActions.setPostSolveLayerVisible({ layerId: event.layerId, visible: event.visible }) + MapActions.setLayerVisible({ layerId: event.layerId, visible: event.visible }) ); } } diff --git a/application/frontend/src/app/core/models/map.ts b/application/frontend/src/app/core/models/map.ts index 36341f4d..ea72a5b6 100644 --- a/application/frontend/src/app/core/models/map.ts +++ b/application/frontend/src/app/core/models/map.ts @@ -17,9 +17,9 @@ limitations under the License. import { TravelMode } from './dispatcher.model'; export enum MapLayerId { - PostSolveVisitRequests, - PostSolveFourWheel, - PostSolveWalking, + VisitRequests, + FourWheel, + Walking, } export interface MapLayer { diff --git a/application/frontend/src/app/core/reducers/map.reducer.ts b/application/frontend/src/app/core/reducers/map.reducer.ts index 9acbee12..c377be63 100644 --- a/application/frontend/src/app/core/reducers/map.reducer.ts +++ b/application/frontend/src/app/core/reducers/map.reducer.ts @@ -22,23 +22,23 @@ import { TravelMode } from '../models'; export const mapFeatureKey = 'map'; export interface State { - postSolveMapLayers: { [id in MapLayerId]: MapLayer }; + visibleMapLayers: { [id in MapLayerId]: MapLayer }; } export const initialState: State = { - postSolveMapLayers: { - [MapLayerId.PostSolveVisitRequests]: { + visibleMapLayers: { + [MapLayerId.VisitRequests]: { name: 'Shipments', icon: 'pickup', visible: true, }, - [MapLayerId.PostSolveFourWheel]: { + [MapLayerId.FourWheel]: { name: 'Driving', icon: 'vehicle_icon', visible: true, travelMode: TravelMode.DRIVING, }, - [MapLayerId.PostSolveWalking]: { + [MapLayerId.Walking]: { name: 'Walking', icon: 'walking', visible: true, @@ -49,17 +49,17 @@ export const initialState: State = { export const reducer = createReducer( initialState, - on(MapActions.setPostSolveLayerVisible, (state, { layerId, visible }) => ({ + on(MapActions.setLayerVisible, (state, { layerId, visible }) => ({ ...state, - postSolveMapLayers: { - ...state.postSolveMapLayers, + visibleMapLayers: { + ...state.visibleMapLayers, [layerId]: { - ...state.postSolveMapLayers[layerId], + ...state.visibleMapLayers[layerId], visible, }, }, })) ); -export const selectPostSolveMapLayers = (state: State): { [id in MapLayerId]: MapLayer } => - state.postSolveMapLayers; +export const selectVisibleMapLayers = (state: State): { [id in MapLayerId]: MapLayer } => + state.visibleMapLayers; diff --git a/application/frontend/src/app/core/selectors/map.selectors.ts b/application/frontend/src/app/core/selectors/map.selectors.ts index b6b1f598..060a58d0 100644 --- a/application/frontend/src/app/core/selectors/map.selectors.ts +++ b/application/frontend/src/app/core/selectors/map.selectors.ts @@ -324,9 +324,9 @@ export const selectSelectionFilterActive = createSelector( } ); -export const selectAllMapLayers = createSelector(selectMapState, fromMap.selectPostSolveMapLayers); +export const selectAllMapLayers = createSelector(selectMapState, fromMap.selectVisibleMapLayers); -export const selectPostSolveMapLayers = createSelector( +export const selectUsedMapLayers = createSelector( selectAllMapLayers, fromVehicle.selectAll, (layers, vehicles) => { diff --git a/application/frontend/src/app/core/selectors/post-solve-vehicle-layer.selectors.ts b/application/frontend/src/app/core/selectors/post-solve-vehicle-layer.selectors.ts index 4f2ad910..065b0f51 100644 --- a/application/frontend/src/app/core/selectors/post-solve-vehicle-layer.selectors.ts +++ b/application/frontend/src/app/core/selectors/post-solve-vehicle-layer.selectors.ts @@ -15,10 +15,7 @@ limitations under the License. */ import { createSelector } from '@ngrx/store'; -import { - selectPostSolveMapLayers, - selectVehicleLocationsOnRouteWithHeadings, -} from './map.selectors'; +import { selectUsedMapLayers, selectVehicleLocationsOnRouteWithHeadings } from './map.selectors'; import { vehicleToDeckGL } from './pre-solve-vehicle-layer.selectors'; import RoutesChartSelectors from './routes-chart.selectors'; import * as fromVehicle from './vehicle.selectors'; @@ -33,7 +30,7 @@ export const selectFilteredVehicles = createSelector( selectVehicleLocationsOnRouteWithHeadings, RoutesChartSelectors.selectFilteredRoutesWithTransitionsLookup, RoutesMetadataSelectors.selectFilteredRouteLookup, - selectPostSolveMapLayers, + selectUsedMapLayers, ( vehicles, currentPage, @@ -50,8 +47,8 @@ export const selectFilteredVehicles = createSelector( (v) => lookup.has(v.id) && ((v.travelMode ?? TravelMode.DRIVING) === TravelMode.DRIVING - ? mapLayers[MapLayerId.PostSolveFourWheel].visible - : mapLayers[MapLayerId.PostSolveWalking].visible) + ? mapLayers[MapLayerId.FourWheel].visible + : mapLayers[MapLayerId.Walking].visible) ) : []; return filteredVehicles.map((vehicle) => @@ -67,7 +64,7 @@ export const selectFilteredVehiclesSelected = createSelector( RoutesChartSelectors.selectFilteredRoutesSelectedWithTransitionsLookup, RoutesMetadataSelectors.selectFilteredRoutesSelectedLookup, RoutesChartSelectors.selectSelectedRoutesColors, - selectPostSolveMapLayers, + selectUsedMapLayers, ( vehicles, currentPage, @@ -83,8 +80,8 @@ export const selectFilteredVehiclesSelected = createSelector( (v) => lookup.has(v.id) && ((v.travelMode ?? TravelMode.DRIVING) === TravelMode.DRIVING - ? mapLayers[MapLayerId.PostSolveFourWheel].visible - : mapLayers[MapLayerId.PostSolveWalking].visible) + ? mapLayers[MapLayerId.FourWheel].visible + : mapLayers[MapLayerId.Walking].visible) ); return selectedVehicles.map((vehicle) => ({ ...vehicleToDeckGL(vehicle, locations[vehicle.id].location, locations[vehicle.id].heading), diff --git a/application/frontend/src/app/core/selectors/pre-solve-vehicle-layer.selectors.ts b/application/frontend/src/app/core/selectors/pre-solve-vehicle-layer.selectors.ts index 4e8920da..04a5bad3 100644 --- a/application/frontend/src/app/core/selectors/pre-solve-vehicle-layer.selectors.ts +++ b/application/frontend/src/app/core/selectors/pre-solve-vehicle-layer.selectors.ts @@ -18,10 +18,11 @@ import { createSelector } from '@ngrx/store'; import { Feature, Point } from '@turf/helpers'; import { fromDispatcherLatLng, fromDispatcherToTurfPoint } from 'src/app/util'; import * as fromLinearReferencing from '../../util/linear-referencing'; -import { MapVehicle, Vehicle } from '../models'; +import { MapVehicle, TravelMode, Vehicle } from '../models'; import * as fromDepot from './depot.selectors'; -import { selectVehicleInitialHeadings } from './map.selectors'; +import { selectUsedMapLayers, selectVehicleInitialHeadings } from './map.selectors'; import PreSolveVehicleSelectors from './pre-solve-vehicle.selectors'; +import { MapLayerId } from '../models/map'; export const vehicleToDeckGL = ( vehicle: Vehicle, @@ -66,17 +67,24 @@ export const selectFilteredVehiclesSelected = createSelector( PreSolveVehicleSelectors.selectFilteredVehiclesSelected, selectVehicleInitialHeadings, fromDepot.selectDepot, - (vehicles, headings, depot) => { + selectUsedMapLayers, + (vehicles, headings, depot, visibleMapLayers) => { const selectedVehicles: MapVehicle[] = []; - vehicles.forEach((vehicle) => { - if (vehicle.startWaypoint?.location?.latLng) { - const position = fromDispatcherLatLng(vehicle.startWaypoint.location.latLng); - const atDepot = depot - ? fromLinearReferencing.pointsAreCoincident(position, fromDispatcherLatLng(depot)) - : false; - selectedVehicles.push(vehicleToDeckGL(vehicle, position, headings[vehicle.id], atDepot)); - } - }); + vehicles + .filter((vehicle) => + vehicle.travelMode ?? TravelMode.DRIVING + ? visibleMapLayers[MapLayerId.FourWheel].visible + : visibleMapLayers[MapLayerId.Walking].visible + ) + .forEach((vehicle) => { + if (vehicle.startWaypoint?.location?.latLng) { + const position = fromDispatcherLatLng(vehicle.startWaypoint.location.latLng); + const atDepot = depot + ? fromLinearReferencing.pointsAreCoincident(position, fromDispatcherLatLng(depot)) + : false; + selectedVehicles.push(vehicleToDeckGL(vehicle, position, headings[vehicle.id], atDepot)); + } + }); return selectedVehicles; } ); diff --git a/application/frontend/src/app/core/selectors/route-layer.selectors.ts b/application/frontend/src/app/core/selectors/route-layer.selectors.ts index 2f7455a3..af533a10 100644 --- a/application/frontend/src/app/core/selectors/route-layer.selectors.ts +++ b/application/frontend/src/app/core/selectors/route-layer.selectors.ts @@ -20,7 +20,7 @@ import RoutesChartSelectors from './routes-chart.selectors'; import { Page, ShipmentRoute, TravelMode } from '../models'; import { Feature, LineString } from '@turf/helpers'; import { toTurfLineString } from 'src/app/util'; -import { selectPostSolveMapLayers } from './map.selectors'; +import { selectUsedMapLayers } from './map.selectors'; import * as fromVehicle from './vehicle.selectors'; import { MapLayerId } from '../models/map'; import RoutesMetadataSelectors from './routes-metadata.selectors'; @@ -50,7 +50,7 @@ export const selectFilteredRoutes = createSelector( RoutesMetadataSelectors.selectFilteredRouteIds, fromUi.selectPage, fromVehicle.selectAll, - selectPostSolveMapLayers, + selectUsedMapLayers, (paths, chartFilteredRouteIds, tableFilteredRouteIds, page, vehicles, mapLayers) => { const filteredRouteIds = page === Page.RoutesChart ? chartFilteredRouteIds : new Set(tableFilteredRouteIds); @@ -58,8 +58,8 @@ export const selectFilteredRoutes = createSelector( (route) => { return (vehicles[route.vehicleIndex]?.travelMode ?? TravelMode.DRIVING) === TravelMode.DRIVING - ? mapLayers[MapLayerId.PostSolveFourWheel].visible - : mapLayers[MapLayerId.PostSolveWalking].visible; + ? mapLayers[MapLayerId.FourWheel].visible + : mapLayers[MapLayerId.Walking].visible; } ); } @@ -72,7 +72,7 @@ export const selectFilteredRoutesSelected = createSelector( fromUi.selectPage, RoutesChartSelectors.selectSelectedRoutesColors, fromVehicle.selectAll, - selectPostSolveMapLayers, + selectUsedMapLayers, ( paths, chartSelectedRoutesLookup, @@ -88,8 +88,8 @@ export const selectFilteredRoutesSelected = createSelector( (p) => lookupSet.has(p.id) && ((vehicles[p.vehicleIndex]?.travelMode ?? TravelMode.DRIVING) === TravelMode.DRIVING - ? mapLayers[MapLayerId.PostSolveFourWheel].visible - : mapLayers[MapLayerId.PostSolveWalking].visible) + ? mapLayers[MapLayerId.FourWheel].visible + : mapLayers[MapLayerId.Walking].visible) ); return selectedRoutes.map((route) => ({ ...route,