From 6e428caacd9da1db702a04072fa64924737d6748 Mon Sep 17 00:00:00 2001 From: Jason McCollum Date: Tue, 23 Jul 2024 14:03:13 -0700 Subject: [PATCH] Only show labeled stops on selected routes --- ...ost-solve-visit-request-layer.selectors.ts | 21 ++++++++ .../base-visit-request-layer.service.ts | 18 +++---- .../post-solve-visit-request-layer.service.ts | 49 ++++++++++++++----- 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/application/frontend/src/app/core/selectors/post-solve-visit-request-layer.selectors.ts b/application/frontend/src/app/core/selectors/post-solve-visit-request-layer.selectors.ts index bae59ae8..c113e42e 100644 --- a/application/frontend/src/app/core/selectors/post-solve-visit-request-layer.selectors.ts +++ b/application/frontend/src/app/core/selectors/post-solve-visit-request-layer.selectors.ts @@ -120,6 +120,27 @@ export const selectFilteredVisitRequests = createSelector( } ); +export const selectFilteredVisitRequestsWithStopOrderAndSelectionStatus = createSelector( + selectFilteredVisitRequests, + selectFilteredRouteVisitRequestsSelected, + selectVisitRequestStopOrder, + fromVisit.selectEntities, + RoutesChartSelectors.selectSelectedRoutesColors, + (visitRequests, selectedVisitRequests, stopOrder, visits, colors) => { + const visitRequestsWithOrder = []; + visitRequests.forEach((vr) => { + const made = !!visits[vr.id]; + visitRequestsWithOrder.push({ + ...vr, + color: made ? colors[visits[vr.id].shipmentRouteId] : null, + stopOrder: stopOrder[vr.id], + selected: selectedVisitRequests.some((svr) => svr.id === vr.id), + }); + }); + return visitRequestsWithOrder; + } +); + export const selectFilteredVisitRequestsWithStopOrder = createSelector( selectFilteredVisitRequests, selectVisitRequestStopOrder, diff --git a/application/frontend/src/app/core/services/base-visit-request-layer.service.ts b/application/frontend/src/app/core/services/base-visit-request-layer.service.ts index 8c99df49..3617fffc 100644 --- a/application/frontend/src/app/core/services/base-visit-request-layer.service.ts +++ b/application/frontend/src/app/core/services/base-visit-request-layer.service.ts @@ -139,6 +139,12 @@ export abstract class BaseVisitRequestLayer { : `dropoff-${this.defaultSelectedColor}`; } + protected updateLayers(): void { + this.gLayer.setProps({ + layers: [this.layer, this.selectedDataLayer, this.mouseOverLayer], + }); + } + abstract getDefaultIconFn(data): string; protected onDataFiltered(data): void { this.layer = new IconLayer({ @@ -160,9 +166,7 @@ export abstract class BaseVisitRequestLayer { }); }, }); - this.gLayer.setProps({ - layers: [this.layer, this.selectedDataLayer, this.mouseOverLayer], - }); + this.updateLayers(); } protected onDataSelected(data): void { @@ -177,9 +181,7 @@ export abstract class BaseVisitRequestLayer { getPosition: (d) => d.arrivalPosition, pickable: false, }); - this.gLayer.setProps({ - layers: [this.layer, this.selectedDataLayer, this.mouseOverLayer], - }); + this.updateLayers(); } protected onDataMouseOver(data): void { @@ -194,8 +196,6 @@ export abstract class BaseVisitRequestLayer { getPosition: (d) => d.arrivalPosition, pickable: false, }); - this.gLayer.setProps({ - layers: [this.layer, this.selectedDataLayer, this.mouseOverLayer], - }); + this.updateLayers(); } } diff --git a/application/frontend/src/app/core/services/post-solve-visit-request-layer.service.ts b/application/frontend/src/app/core/services/post-solve-visit-request-layer.service.ts index e6c2b8c6..ea0c48fe 100644 --- a/application/frontend/src/app/core/services/post-solve-visit-request-layer.service.ts +++ b/application/frontend/src/app/core/services/post-solve-visit-request-layer.service.ts @@ -18,13 +18,14 @@ import { Injectable, NgZone } from '@angular/core'; import { select, Store } from '@ngrx/store'; import { State } from 'src/app/reducers'; import { - selectFilteredVisitRequestsSelectedWithStopOrder, - selectFilteredVisitRequestsWithStopOrder, + selectFilteredVisitRequestsWithStopOrderAndSelectionStatus, selectMouseOverVisitRequest, } from '../selectors/post-solve-visit-request-layer.selectors'; import { BaseVisitRequestLayer } from './base-visit-request-layer.service'; import { MapService } from './map.service'; import { combineLatest } from 'rxjs'; +import { IconLayer } from '@deck.gl/layers'; +import { UIActions } from '../actions'; @Injectable({ providedIn: 'root', @@ -38,6 +39,7 @@ export class PostSolveVisitRequestLayer extends BaseVisitRequestLayer { readonly capsuleIconSize: [number, number] = [78, 24.85714285714285]; private capsuleIconMapping = {}; + private unselectedLayer: IconLayer = new IconLayer({}); constructor(mapService: MapService, store: Store, zone: NgZone) { super(mapService, store, zone); @@ -45,19 +47,12 @@ export class PostSolveVisitRequestLayer extends BaseVisitRequestLayer { this.createLabeledIconMapping(); combineLatest([ - this.store.pipe(select(selectFilteredVisitRequestsWithStopOrder)), + this.store.pipe(select(selectFilteredVisitRequestsWithStopOrderAndSelectionStatus)), this.mapService.zoomChanged$, ]).subscribe(([visitRequests, zoom]) => { this.canShowTextLayer = zoom >= this.minZoom; this.onDataFiltered(visitRequests); - }); - - combineLatest([ - this.store.pipe(select(selectFilteredVisitRequestsSelectedWithStopOrder)), - this.mapService.zoomChanged$, - ]).subscribe(([visitRequests, zoom]) => { - this.canShowTextLayer = zoom >= this.minZoom; - this.onDataSelected(visitRequests); + this.onDataSelected(visitRequests.filter((vr) => vr.selected)); }); combineLatest([ @@ -102,6 +97,36 @@ export class PostSolveVisitRequestLayer extends BaseVisitRequestLayer { : `dropoff-${this.defaultColor}-${stopOrder}`; } + protected onDataFiltered(data): void { + this.unselectedLayer = new IconLayer({ + id: this.layerId + '-unselected', + data: data.filter((d) => !d.selected), + iconAtlas: super.getIconAtlas(), + iconMapping: this.iconMapping, + getIcon: (d) => (d.pickup ? `pickup-${this.defaultColor}` : `dropoff-${this.defaultColor}`), + getSize: 10, + sizeScale: super.getSizeScale(), + getPosition: (d) => d.arrivalPosition, + pickable: true, + onHover: ({ object }) => { + this.mapService.map.setOptions({ draggableCursor: object ? 'pointer' : 'grab' }); + }, + onClick: ({ object }) => { + this.zone.run(() => { + this.store.dispatch(UIActions.mapVisitRequestClicked({ id: object.id })); + }); + }, + }); + + super.onDataFiltered(data.filter((d) => d.selected)); + } + + protected updateLayers(): void { + this.gLayer.setProps({ + layers: [this.layer, this.unselectedLayer, this.selectedDataLayer, this.mouseOverLayer], + }); + } + protected getIconAtlas(): string { return this.canShowTextLayer ? './assets/images/labeled_dropoffs_pickups.png' @@ -109,7 +134,7 @@ export class PostSolveVisitRequestLayer extends BaseVisitRequestLayer { } protected getSizeScale(): number { - return this.canShowTextLayer ? 2.0 : super.getSizeScale(); + return this.canShowTextLayer ? 1.8 : super.getSizeScale(); } protected getIconMapping(): any {