@fleetbase/fleetops-engine 0.6.44 → 0.6.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/addon/components/admin/map-settings.hbs +26 -0
  2. package/addon/components/admin/map-settings.js +46 -0
  3. package/addon/components/admin/routing-settings.hbs +11 -0
  4. package/addon/components/cell/order-route-type.hbs +46 -0
  5. package/addon/components/cell/order-route-type.js +90 -0
  6. package/addon/components/cell/place-address.hbs +1 -0
  7. package/addon/components/display-place.hbs +45 -56
  8. package/addon/components/display-place.js +21 -0
  9. package/addon/components/entity/form.hbs +24 -0
  10. package/addon/components/entity/form.js +30 -0
  11. package/addon/components/layout/fleet-ops-sidebar/driver-listing.js +5 -5
  12. package/addon/components/layout/fleet-ops-sidebar/fleet-listing.js +5 -5
  13. package/addon/components/layout/fleet-ops-sidebar.js +8 -0
  14. package/addon/components/leaflet-draw-control.js +1 -1
  15. package/addon/components/maintenance-schedule/form.js +2 -1
  16. package/addon/components/map/drawer/driver-listing.js +5 -5
  17. package/addon/components/map/drawer/geofence-event-listing.js +5 -2
  18. package/addon/components/map/drawer/place-listing.js +5 -5
  19. package/addon/components/map/drawer/position-listing.js +102 -21
  20. package/addon/components/map/drawer/vehicle-listing.js +5 -5
  21. package/addon/components/map/google-live-map.hbs +9 -0
  22. package/addon/components/map/google-live-map.js +445 -0
  23. package/addon/components/map/leaflet-live-map.hbs +186 -142
  24. package/addon/components/map/leaflet-live-map.js +121 -41
  25. package/addon/components/map/toolbar/visibility-control-panel.js +2 -2
  26. package/addon/components/map/toolbar/zones-panel.hbs +9 -9
  27. package/addon/components/map/toolbar.hbs +3 -3
  28. package/addon/components/map/toolbar.js +9 -1
  29. package/addon/components/modals/map-layer-form.hbs +132 -63
  30. package/addon/components/modals/orchestrator-import.hbs +4 -11
  31. package/addon/components/modals/orchestrator-import.js +17 -1
  32. package/addon/components/modals/update-order-activity.hbs +1 -1
  33. package/addon/components/orchestrator/order-pool.js +3 -2
  34. package/addon/components/orchestrator-workbench.js +29 -41
  35. package/addon/components/order/details/detail.js +2 -2
  36. package/addon/components/order/details/payload.hbs +5 -5
  37. package/addon/components/order/details/payload.js +18 -1
  38. package/addon/components/order/details/route.hbs +2 -2
  39. package/addon/components/order/details/route.js +76 -3
  40. package/addon/components/order/form/payload.hbs +33 -0
  41. package/addon/components/order/form/payload.js +1 -0
  42. package/addon/components/order/form/route.hbs +8 -8
  43. package/addon/components/order/form/route.js +78 -18
  44. package/addon/components/order/form/service-rate.hbs +1 -1
  45. package/addon/components/order/form.js +2 -2
  46. package/addon/components/order/route-editor.hbs +209 -147
  47. package/addon/components/order/route-editor.js +143 -102
  48. package/addon/components/place/address.hbs +1 -0
  49. package/addon/components/place/address.js +12 -0
  50. package/addon/components/route-list.hbs +43 -55
  51. package/addon/components/route-list.js +47 -0
  52. package/addon/components/route-optimization-wizard-panel.js +3 -4
  53. package/addon/components/service-rate/details.hbs +6 -6
  54. package/addon/components/service-rate/form.hbs +28 -15
  55. package/addon/components/vehicle/card.hbs +4 -4
  56. package/addon/controllers/maintenance/schedules/index.js +2 -1
  57. package/addon/controllers/operations/orders/index/details/virtual.js +5 -0
  58. package/addon/controllers/operations/orders/index/details.js +113 -15
  59. package/addon/controllers/operations/orders/index/new.js +1 -1
  60. package/addon/controllers/operations/orders/index.js +8 -1
  61. package/addon/controllers/operations/service-rates/index/edit.js +1 -0
  62. package/addon/controllers/operations/service-rates/index/new.js +1 -0
  63. package/addon/controllers/settings/map.js +97 -0
  64. package/addon/controllers/settings/routing.js +47 -12
  65. package/addon/extension.js +11 -0
  66. package/addon/helpers/f-to-int.js +6 -0
  67. package/addon/helpers/place-address-html.js +6 -0
  68. package/addon/instance-initializers/register-google-routes.js +17 -0
  69. package/addon/instance-initializers/register-osrm.js +5 -0
  70. package/addon/routes/application.js +9 -3
  71. package/addon/routes/operations/orchestrator.js +13 -0
  72. package/addon/routes/operations/orders/index/details/virtual.js +1 -0
  73. package/addon/routes/operations/orders/index/details.js +47 -24
  74. package/addon/routes/operations/orders/index/new.js +9 -0
  75. package/addon/routes/operations/orders/index.js +0 -1
  76. package/addon/routes/settings/map.js +3 -0
  77. package/addon/routes.js +1 -0
  78. package/addon/services/entity-actions.js +1 -1
  79. package/addon/services/equipment-actions.js +4 -6
  80. package/addon/services/geofence-event-bus.js +2 -1
  81. package/addon/services/geofence.js +204 -168
  82. package/addon/services/google-routes.js +300 -0
  83. package/addon/services/leaflet-draw-restriction.js +2 -1
  84. package/addon/services/leaflet-map-manager.js +21 -0
  85. package/addon/services/maintenance-actions.js +4 -6
  86. package/addon/services/map-adapter/google.js +2205 -0
  87. package/addon/services/map-adapter/leaflet.js +1042 -0
  88. package/addon/services/map-adapter-interface.js +551 -0
  89. package/addon/services/map-manager.js +768 -0
  90. package/addon/services/map-settings.js +75 -0
  91. package/addon/services/movement-tracker.js +83 -32
  92. package/addon/services/order-actions.js +11 -1
  93. package/addon/services/osrm.js +79 -6
  94. package/addon/services/part-actions.js +4 -6
  95. package/addon/services/position-playback.js +135 -62
  96. package/addon/services/route-engine.js +83 -0
  97. package/addon/services/service-areas.js +8 -1
  98. package/addon/services/service-rate-actions.js +8 -3
  99. package/addon/styles/fleetops-engine.css +555 -0
  100. package/addon/templates/management/vehicles/index.hbs +0 -1
  101. package/addon/templates/operations/orders/index/details/virtual.hbs +7 -1
  102. package/addon/templates/operations/orders/index/details.hbs +0 -1
  103. package/addon/templates/settings/map.hbs +53 -0
  104. package/addon/templates/settings/routing.hbs +15 -4
  105. package/addon/utils/fleet-ops-options.js +34 -0
  106. package/addon/utils/has-valid-coordinates.js +6 -0
  107. package/addon/utils/map-provider-options.js +6 -0
  108. package/addon/utils/order-route-editing.js +86 -0
  109. package/addon/utils/order-route-summary.js +20 -0
  110. package/addon/utils/place-address-html.js +41 -0
  111. package/addon/utils/route-colors.js +43 -12
  112. package/addon/utils/route-visualization.js +93 -0
  113. package/addon/utils/serialize-payload.js +1 -1
  114. package/addon/utils/vendor-integration.js +2 -1
  115. package/app/components/admin/map-settings.js +1 -0
  116. package/app/components/admin/routing-settings.js +1 -0
  117. package/app/components/cell/order-route-type.js +1 -0
  118. package/app/components/cell/place-address.js +1 -0
  119. package/app/components/map/google-live-map.js +1 -0
  120. package/app/components/place/address.js +1 -0
  121. package/app/controllers/operations/orders/index/details/virtual.js +1 -0
  122. package/app/controllers/settings/map.js +1 -0
  123. package/app/helpers/f-to-int.js +1 -0
  124. package/app/helpers/place-address-html.js +1 -0
  125. package/app/routes/settings/map.js +1 -0
  126. package/app/services/map-adapter/google.js +1 -0
  127. package/app/services/map-adapter/leaflet.js +1 -0
  128. package/app/services/map-adapter-interface.js +1 -0
  129. package/app/services/map-manager.js +1 -0
  130. package/app/services/map-settings.js +1 -0
  131. package/app/templates/settings/map.js +1 -0
  132. package/app/utils/has-valid-coordinates.js +1 -0
  133. package/app/utils/order-route-editing.js +2 -0
  134. package/app/utils/order-route-summary.js +1 -0
  135. package/app/utils/place-address-html.js +1 -0
  136. package/app/utils/route-colors.js +1 -1
  137. package/app/utils/route-visualization.js +1 -0
  138. package/assets/images/drawing-controls-spritesheet.svg +156 -0
  139. package/composer.json +1 -1
  140. package/extension.json +1 -1
  141. package/package.json +3 -3
  142. package/server/src/Auth/Schemas/FleetOps.php +5 -0
  143. package/server/src/Http/Controllers/Api/v1/OrderController.php +36 -8
  144. package/server/src/Http/Controllers/Api/v1/PayloadController.php +14 -1
  145. package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +11 -3
  146. package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +2 -0
  147. package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +7 -2
  148. package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +6 -1
  149. package/server/src/Http/Controllers/Api/v1/ZoneController.php +2 -0
  150. package/server/src/Http/Controllers/Internal/v1/LiveController.php +2 -1
  151. package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +7 -4
  152. package/server/src/Http/Controllers/Internal/v1/OrderController.php +61 -34
  153. package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +3 -2
  154. package/server/src/Http/Controllers/Internal/v1/SettingController.php +106 -3
  155. package/server/src/Http/Filter/OrderFilter.php +2 -1
  156. package/server/src/Http/Requests/CreateServiceRateRequest.php +2 -2
  157. package/server/src/Http/Resources/v1/Index/Payload.php +9 -7
  158. package/server/src/Http/Resources/v1/Order.php +20 -2
  159. package/server/src/Http/Resources/v1/ServiceQuote.php +2 -2
  160. package/server/src/Models/Entity.php +7 -0
  161. package/server/src/Models/Order.php +81 -8
  162. package/server/src/Models/OrderConfig.php +15 -0
  163. package/server/src/Models/Payload.php +131 -27
  164. package/server/src/Models/Place.php +182 -48
  165. package/server/src/Models/ServiceRate.php +125 -32
  166. package/server/src/Observers/PurchaseRateObserver.php +3 -5
  167. package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +59 -23
  168. package/server/src/Rules/ComputableAlgo.php +1 -3
  169. package/server/src/Support/Algo.php +87 -1
  170. package/server/src/Support/Utils.php +69 -0
  171. package/server/src/routes.php +4 -0
  172. package/translations/en-us.yaml +1937 -1916
@@ -0,0 +1,300 @@
1
+ /* global google */
2
+ import RouteOptimizationInterfaceService from './route-optimization-interface';
3
+ import { isArray } from '@ember/array';
4
+ import { inject as service } from '@ember/service';
5
+
6
+ export default class GoogleRoutesService extends RouteOptimizationInterfaceService {
7
+ @service mapSettings;
8
+
9
+ name = 'Google';
10
+ _apiLoadPromise = null;
11
+
12
+ async computeRoute(waypoints = [], options = {}) {
13
+ const normalizedWaypoints = this.#normalizeWaypoints(waypoints);
14
+ if (normalizedWaypoints.length < 2) {
15
+ throw new Error('At least 2 waypoints are required to compute a route.');
16
+ }
17
+
18
+ await this.#ensureApiLoaded(options);
19
+ const { Route, TravelMode, RoutingPreference } = await google.maps.importLibrary('routes');
20
+ const optimizeWaypointOrder = options.optimizeWaypointOrder === true;
21
+ const request = {
22
+ origin: normalizedWaypoints[0],
23
+ destination: normalizedWaypoints[normalizedWaypoints.length - 1],
24
+ travelMode: TravelMode.DRIVING,
25
+ routingPreference: optimizeWaypointOrder ? RoutingPreference.TRAFFIC_AWARE : RoutingPreference.TRAFFIC_AWARE_OPTIMAL,
26
+ fields: ['path', 'viewport', 'distanceMeters', 'durationMillis', 'legs', 'optimizedIntermediateWaypointIndices'],
27
+ };
28
+
29
+ if (normalizedWaypoints.length > 2) {
30
+ request.intermediates = normalizedWaypoints.slice(1, -1).map((waypoint) => ({ location: waypoint, via: false }));
31
+ }
32
+
33
+ if (optimizeWaypointOrder) {
34
+ request.optimizeWaypointOrder = true;
35
+ }
36
+
37
+ const response = await Route.computeRoutes(request);
38
+ const route = response?.routes?.[0];
39
+
40
+ if (!route?.path?.length) {
41
+ throw new Error('Google route computation returned no path.');
42
+ }
43
+
44
+ const coordinates = route.path.map((point) => [typeof point.lat === 'function' ? point.lat() : point.lat, typeof point.lng === 'function' ? point.lng() : point.lng]);
45
+ const optimizedIndices = isArray(route.optimizedIntermediateWaypointIndices) ? route.optimizedIntermediateWaypointIndices : [];
46
+ const bounds = this.#extractBounds(route.viewport) ?? this.#boundsFromCoordinates(coordinates);
47
+
48
+ return {
49
+ engine: 'google',
50
+ waypoints: this.#reorderWaypoints(waypoints, optimizedIndices),
51
+ coordinates,
52
+ bounds,
53
+ summary: {
54
+ totalDistance: route.distanceMeters ?? 0,
55
+ totalTime: route.durationMillis ? route.durationMillis / 1000 : 0,
56
+ },
57
+ legs: isArray(route.legs)
58
+ ? route.legs.map((leg) => ({
59
+ distanceMeters: leg.distanceMeters ?? 0,
60
+ durationMillis: leg.durationMillis ?? 0,
61
+ startLocation: leg.startLocation,
62
+ endLocation: leg.endLocation,
63
+ }))
64
+ : [],
65
+ raw: route,
66
+ optimizedIntermediateWaypointIndices: optimizedIndices,
67
+ };
68
+ }
69
+
70
+ async optimize({ order, waypoints, coordinates, preserveEndpoints = false }, options = {}) {
71
+ const route = await this.computeRoute(this.#normalizeOptimizationCoordinates(order, coordinates), {
72
+ ...options,
73
+ optimizeWaypointOrder: true,
74
+ });
75
+ let sortedWaypoints = waypoints;
76
+
77
+ if (isArray(route.waypoints) && route.waypoints.length > 0) {
78
+ sortedWaypoints = this.#reorderModelsByRouteWaypoints(waypoints, route.waypoints, preserveEndpoints);
79
+ } else if (isArray(route.optimizedIntermediateWaypointIndices) && route.optimizedIntermediateWaypointIndices.length > 0) {
80
+ sortedWaypoints = this.#reorderModelWaypoints(waypoints, route.optimizedIntermediateWaypointIndices, preserveEndpoints);
81
+ }
82
+
83
+ return {
84
+ sortedWaypoints,
85
+ route: route.coordinates,
86
+ trip: {
87
+ distance: route.summary.totalDistance,
88
+ duration: route.summary.totalTime,
89
+ legs: route.legs,
90
+ },
91
+ result: route.raw,
92
+ engine: 'google',
93
+ };
94
+ }
95
+
96
+ #normalizeOptimizationCoordinates(order, coordinates = []) {
97
+ const driverPosition = order?.driver_assigned?.location?.coordinates;
98
+ const normalized = (isArray(coordinates) ? coordinates : []).map(([lng, lat]) => [lat, lng]);
99
+
100
+ if (this.#isValidDriverPosition(driverPosition)) {
101
+ return [[driverPosition[1], driverPosition[0]], ...normalized];
102
+ }
103
+
104
+ return normalized;
105
+ }
106
+
107
+ #isValidDriverPosition(driverPosition) {
108
+ if (!isArray(driverPosition) || driverPosition.length < 2) {
109
+ return false;
110
+ }
111
+
112
+ const [lng, lat] = driverPosition.map(Number);
113
+
114
+ if (!Number.isFinite(lat) || !Number.isFinite(lng)) {
115
+ return false;
116
+ }
117
+
118
+ return lat !== 0 && lng !== 0;
119
+ }
120
+
121
+ #normalizeWaypoints(waypoints = []) {
122
+ return (isArray(waypoints) ? waypoints : [])
123
+ .map((waypoint) => {
124
+ if (isArray(waypoint) && waypoint.length >= 2) {
125
+ return { lat: Number(waypoint[0]), lng: Number(waypoint[1]) };
126
+ }
127
+
128
+ if (Number.isFinite(waypoint?.lat) && Number.isFinite(waypoint?.lng)) {
129
+ return { lat: Number(waypoint.lat), lng: Number(waypoint.lng) };
130
+ }
131
+
132
+ return null;
133
+ })
134
+ .filter((waypoint) => Number.isFinite(waypoint?.lat) && Number.isFinite(waypoint?.lng));
135
+ }
136
+
137
+ #reorderWaypoints(waypoints = [], optimizedIndices = []) {
138
+ if (!isArray(optimizedIndices) || optimizedIndices.length === 0 || waypoints.length < 3) {
139
+ return waypoints;
140
+ }
141
+
142
+ const start = waypoints[0];
143
+ const end = waypoints[waypoints.length - 1];
144
+ const intermediates = waypoints.slice(1, -1);
145
+ const orderedIntermediates = optimizedIndices.map((index) => intermediates[index]).filter(Boolean);
146
+
147
+ return [start, ...orderedIntermediates, end];
148
+ }
149
+
150
+ #reorderModelWaypoints(waypoints = [], optimizedIndices = [], preserveEndpoints = false) {
151
+ if (!isArray(optimizedIndices) || optimizedIndices.length === 0 || !isArray(waypoints) || waypoints.length < 3) {
152
+ return waypoints;
153
+ }
154
+
155
+ if (!preserveEndpoints) {
156
+ const start = waypoints[0];
157
+ const end = waypoints[waypoints.length - 1];
158
+ const intermediates = waypoints.slice(1, -1);
159
+ const orderedIntermediates = optimizedIndices.map((index) => intermediates[index]).filter(Boolean);
160
+
161
+ return [start, ...orderedIntermediates, end];
162
+ }
163
+
164
+ const start = waypoints[0];
165
+ const end = waypoints[waypoints.length - 1];
166
+ const intermediates = waypoints.slice(1, -1);
167
+ const orderedIntermediates = optimizedIndices.map((index) => intermediates[index]).filter(Boolean);
168
+
169
+ return [start, ...orderedIntermediates, end];
170
+ }
171
+
172
+ #reorderModelsByRouteWaypoints(waypoints = [], routeWaypoints = [], preserveEndpoints = false) {
173
+ if (!isArray(waypoints) || !waypoints.length || !isArray(routeWaypoints) || !routeWaypoints.length) {
174
+ return waypoints;
175
+ }
176
+
177
+ const waypointOrder = preserveEndpoints ? routeWaypoints.slice(1, -1) : routeWaypoints;
178
+ const buckets = new Map();
179
+
180
+ for (const waypoint of waypoints) {
181
+ const key = this.#modelCoordinateKey(waypoint);
182
+
183
+ if (!key) {
184
+ continue;
185
+ }
186
+
187
+ if (!buckets.has(key)) {
188
+ buckets.set(key, []);
189
+ }
190
+
191
+ buckets.get(key).push(waypoint);
192
+ }
193
+
194
+ const orderedWaypoints = [];
195
+ for (const routeWaypoint of waypointOrder) {
196
+ const key = this.#coordinateKey(routeWaypoint?.lat, routeWaypoint?.lng);
197
+ const bucket = buckets.get(key);
198
+
199
+ if (bucket?.length) {
200
+ orderedWaypoints.push(bucket.shift());
201
+ }
202
+ }
203
+
204
+ if (orderedWaypoints.length === waypoints.length) {
205
+ return orderedWaypoints;
206
+ }
207
+
208
+ return waypoints;
209
+ }
210
+
211
+ #modelCoordinateKey(waypoint) {
212
+ const place = waypoint?.place ?? waypoint;
213
+ return this.#coordinateKey(place?.latitude ?? waypoint?.latitude, place?.longitude ?? waypoint?.longitude);
214
+ }
215
+
216
+ #coordinateKey(lat, lng) {
217
+ const normalizedLat = Number(lat);
218
+ const normalizedLng = Number(lng);
219
+
220
+ if (!Number.isFinite(normalizedLat) || !Number.isFinite(normalizedLng)) {
221
+ return null;
222
+ }
223
+
224
+ return `${normalizedLat.toFixed(6)}:${normalizedLng.toFixed(6)}`;
225
+ }
226
+
227
+ #boundsFromCoordinates(coordinates = []) {
228
+ if (!coordinates.length) {
229
+ return [
230
+ [0, 0],
231
+ [0, 0],
232
+ ];
233
+ }
234
+
235
+ const lats = coordinates.map(([lat]) => lat);
236
+ const lngs = coordinates.map(([, lng]) => lng);
237
+
238
+ return [
239
+ [Math.min(...lats), Math.min(...lngs)],
240
+ [Math.max(...lats), Math.max(...lngs)],
241
+ ];
242
+ }
243
+
244
+ #extractBounds(viewport) {
245
+ if (!viewport) return null;
246
+
247
+ if (typeof viewport.getSouthWest === 'function' && typeof viewport.getNorthEast === 'function') {
248
+ const sw = viewport.getSouthWest();
249
+ const ne = viewport.getNorthEast();
250
+ return [
251
+ [sw.lat(), sw.lng()],
252
+ [ne.lat(), ne.lng()],
253
+ ];
254
+ }
255
+
256
+ if (Number.isFinite(viewport.south) && Number.isFinite(viewport.west) && Number.isFinite(viewport.north) && Number.isFinite(viewport.east)) {
257
+ return [
258
+ [viewport.south, viewport.west],
259
+ [viewport.north, viewport.east],
260
+ ];
261
+ }
262
+
263
+ return null;
264
+ }
265
+
266
+ async #ensureApiLoaded(options = {}) {
267
+ if (window.google?.maps?.importLibrary) {
268
+ return true;
269
+ }
270
+
271
+ if (this._apiLoadPromise) {
272
+ return this._apiLoadPromise;
273
+ }
274
+
275
+ const apiKey = options.apiKey ?? this.mapSettings.googleMapsApiKey;
276
+ if (!apiKey) {
277
+ throw new Error('Google Maps API key is required for Google route computation.');
278
+ }
279
+
280
+ this._apiLoadPromise = new Promise((resolve, reject) => {
281
+ const callbackName = `__fleetopsGoogleRoutesInit_${Date.now().toString(36)}`;
282
+ window[callbackName] = () => {
283
+ delete window[callbackName];
284
+ resolve(true);
285
+ };
286
+
287
+ const script = document.createElement('script');
288
+ script.async = true;
289
+ script.defer = true;
290
+ script.onerror = (error) => {
291
+ delete window[callbackName];
292
+ reject(error);
293
+ };
294
+ script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=routes,geometry,marker&callback=${callbackName}&loading=async`;
295
+ document.head.appendChild(script);
296
+ });
297
+
298
+ return this._apiLoadPromise;
299
+ }
300
+ }
@@ -1,4 +1,5 @@
1
1
  import Service from '@ember/service';
2
+ import { isArray } from '@ember/array';
2
3
  import booleanPointInPolygon from '@turf/boolean-point-in-polygon';
3
4
  import { point as turfPoint, polygon as turfPolygon } from '@turf/helpers';
4
5
 
@@ -124,7 +125,7 @@ export default class LeafletMapManagerService extends Service {
124
125
  #everyVertexInside(latlngs) {
125
126
  // latlngs can be nested (poly: [ring], multi: [[ring]...])
126
127
  const walk = (arr) => {
127
- if (!Array.isArray(arr)) return true;
128
+ if (!isArray(arr)) return true;
128
129
  if (arr.length && arr[0]?.lat != null) {
129
130
  return arr.every((ll) => this.#isInside(ll));
130
131
  }
@@ -10,6 +10,7 @@ import isUuid from '@fleetbase/ember-core/utils/is-uuid';
10
10
 
11
11
  export default class LeafletMapManagerService extends Service {
12
12
  @service leafletRoutingControl;
13
+ @service mapManager;
13
14
  @service notifications;
14
15
  @tracked map;
15
16
  @tracked _livemap;
@@ -222,6 +223,10 @@ export default class LeafletMapManagerService extends Service {
222
223
  /** routing methods */
223
224
  /* eslint-disable no-empty */
224
225
  async addRoutingControl(waypoints, options = {}) {
226
+ if (this.mapManager?.providerName && this.mapManager.providerName !== 'leaflet') {
227
+ return this.mapManager.addRoutingControl(waypoints, options);
228
+ }
229
+
225
230
  if (!isArray(waypoints) || waypoints.length === 0) return;
226
231
 
227
232
  const map = await this.ensureInteractive({ timeoutMs: 8000 });
@@ -270,12 +275,20 @@ export default class LeafletMapManagerService extends Service {
270
275
  this.route = routes[0];
271
276
  });
272
277
 
278
+ routingControl.on('routingerror', (event) => {
279
+ options?.onRoutingError?.(event);
280
+ });
281
+
273
282
  this.positionWaypoints(waypoints);
274
283
 
275
284
  return routingControl;
276
285
  }
277
286
 
278
287
  positionWaypoints(waypoints) {
288
+ if (this.mapManager?.providerName && this.mapManager.providerName !== 'leaflet') {
289
+ return this.mapManager.positionWaypoints(waypoints);
290
+ }
291
+
279
292
  if (waypoints.length === 1) {
280
293
  this.map.flyTo(waypoints[0], 18);
281
294
  this.map.once('moveend', () => this.map.panBy([200, 0]));
@@ -294,6 +307,10 @@ export default class LeafletMapManagerService extends Service {
294
307
  }
295
308
 
296
309
  async replaceRoutingControl(waypoints, routingControl, options = {}) {
310
+ if (this.mapManager?.providerName && this.mapManager.providerName !== 'leaflet') {
311
+ return this.mapManager.replaceRoutingControl(waypoints, routingControl, options);
312
+ }
313
+
297
314
  const removeOptions = options.removeOptions ?? {};
298
315
  if (routingControl) {
299
316
  await this.removeRoutingControl(routingControl, removeOptions);
@@ -307,6 +324,10 @@ export default class LeafletMapManagerService extends Service {
307
324
 
308
325
  /* eslint-disable no-empty */
309
326
  removeRoutingControl(routingControl, options = {}) {
327
+ if (this.mapManager?.providerName && this.mapManager.providerName !== 'leaflet') {
328
+ return Promise.resolve(this.mapManager.removeRoutingControl(routingControl, options));
329
+ }
330
+
310
331
  return new Promise((resolve) => {
311
332
  let removed = false;
312
333
 
@@ -1,7 +1,9 @@
1
- import ResourceActionService, { inject as service } from '@fleetbase/ember-core/services/resource-action';
1
+ import ResourceActionService from '@fleetbase/ember-core/services/resource-action';
2
2
 
3
3
  export default class MaintenanceActionsService extends ResourceActionService {
4
- @service currentUser;
4
+ get defaultCurrency() {
5
+ return this.currentUser?.company?.currency || this.currentUser.currency || 'USD';
6
+ }
5
7
 
6
8
  constructor() {
7
9
  super(...arguments);
@@ -12,10 +14,6 @@ export default class MaintenanceActionsService extends ResourceActionService {
12
14
  });
13
15
  }
14
16
 
15
- get defaultCurrency() {
16
- return this.currentUser?.company?.currency || 'USD';
17
- }
18
-
19
17
  transition = {
20
18
  view: (maintenance) => this.transitionTo('maintenance.maintenances.index.details', maintenance),
21
19
  edit: (maintenance) => this.transitionTo('maintenance.maintenances.index.edit', maintenance),