@ducna01120/fleetops-engine
Version:
Fleet & Transport Management Extension for Fleetbase
209 lines (182 loc) • 6.73 kB
JavaScript
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { isArray } from '@ember/array';
import { getOwner } from '@ember/application';
import { later } from '@ember/runloop';
import { debug } from '@ember/debug';
import { task } from 'ember-concurrency';
import { OSRMv1, Control as RoutingControl } from '@fleetbase/leaflet-routing-machine';
import getRoutingHost from '@fleetbase/ember-core/utils/get-routing-host';
import engineService from '@fleetbase/ember-core/decorators/engine-service';
export default class OrderTrackingLookupComponent extends Component {
urlSearchParams;
fetch;
notifications;
socket;
currentUser;
universe;
location;
movementTracker;
trackingNumber;
order;
zoom = 12;
map;
mapReady = false;
latitude;
longitude;
route;
tileSourceUrl = 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png';
constructor() {
super(...arguments);
this.movementTracker.registerTrackingMarker();
const trackingNumber = this.urlSearchParams.get('order');
if (trackingNumber) {
this.trackingNumber = trackingNumber;
this.lookupOrder.perform();
}
this.location.getUserLocation().then(({ latitude, longitude }) => {
this.latitude = latitude;
this.longitude = longitude;
this.mapReady = true;
});
}
*lookupOrder() {
try {
this.order = yield this.fetch.get('fleet-ops/lookup', { tracking: this.trackingNumber }, { normalizeToEmberData: true, normalizeModelType: 'order' });
this.urlSearchParams.addParamToCurrentUrl('order', this.order.tracking);
const driverCurrentLocation = this.order.get('tracker_data.driver_current_location');
if (driverCurrentLocation) {
this.latitude = driverCurrentLocation.coordinates[1];
this.longitude = driverCurrentLocation.coordinates[0];
this.mapReady = true;
}
} catch (error) {
this.notifications.serverError(error);
}
}
lookupAnother() {
this.urlSearchParams.removeParamFromCurrentUrl('order');
this.trackingNumber = null;
this.order = null;
}
/* eslint-disable ember/no-private-routing-service */
transitionToConsole() {
const owner = getOwner(this);
const router = owner.lookup('router:main');
return router.transitionTo('console');
}
setupMap({ target }) {
this.map = target;
this.map.whenReady(() => {
this.resetOrderRoute();
});
}
startTrackingDriverPosition(event) {
const { target } = event;
const driver = this.order.driver_assigned;
if (driver) {
driver.set('_layer', target);
this.movementTracker.track(driver);
}
}
locateDriver() {
const driver = this.order.driver_assigned;
if (driver) {
this.map.flyTo(driver.coordinates, 14, {
maxZoom: 14,
animate: true,
});
}
}
locateOrderRoute() {
if (this.order) {
const waypoints = this.getRouteCoordinatesFromOrder(this.order);
this.map.flyToBounds(waypoints, {
maxZoom: waypoints.length === 2 ? 12 : 11,
animate: true,
});
}
}
displayOrderRoute() {
const waypoints = this.getRouteCoordinatesFromOrder(this.order);
const routingHost = getRoutingHost();
if (this.cannotRouteWaypoints(waypoints)) {
return;
}
// center on first coordinate
try {
this.map.stop();
this.map.flyTo(waypoints.firstObject);
} catch (error) {
// unable to stop map
debug(`Leaflet Map Error: ${error.message}`);
}
const router = new OSRMv1({
serviceUrl: `${routingHost}/route/v1`,
profile: 'driving',
});
this.routeControl = new RoutingControl({
fitSelectedRoutes: false,
router,
waypoints,
alternativeClassName: 'hidden',
addWaypoints: false,
markerOptions: {
draggable: false,
icon: L.icon({
iconUrl: '/assets/images/marker-icon.png',
iconRetinaUrl: '/assets/images/marker-icon-2x.png',
shadowUrl: '/assets/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
}),
},
}).addTo(this.map);
this.routeControl.on('routingerror', (error) => {
debug(`Routing Control Error: ${error.error.message}`);
});
this.routeControl.on('routesfound', (event) => {
const { routes } = event;
this.route = routes.firstObject;
later(
this,
() => {
this.map.flyToBounds(waypoints, {
maxZoom: waypoints.length === 2 ? 12 : 11,
animate: true,
});
},
100
);
});
}
resetOrderRoute() {
this.removeRouteControl();
this.displayOrderRoute();
}
cannotRouteWaypoints(waypoints = []) {
return !this.map || !isArray(waypoints) || waypoints.length < 2;
}
getRouteCoordinatesFromOrder(order) {
const payload = order.payload;
const waypoints = [];
const coordinates = [];
waypoints.pushObjects([payload.pickup, ...payload.waypoints.toArray(), payload.dropoff]);
waypoints.forEach((place) => {
if (place && place.get('longitude') && place.get('latitude')) {
if (place.hasInvalidCoordinates) {
return;
}
coordinates.pushObject([place.get('latitude'), place.get('longitude')]);
}
});
return coordinates;
}
removeRouteControl() {
if (this.routeControl && this.routeControl instanceof RoutingControl) {
this.routeControl.remove();
}
}
}