@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
@@ -13,6 +13,19 @@ export default class OperationsAllocationRoute extends Route {
13
13
  @service hostRouter;
14
14
  @service abilities;
15
15
  @service intl;
16
+ @service sidebar;
17
+ @service mapManager;
18
+
19
+ activate() {
20
+ this.sidebar.hide();
21
+ }
22
+
23
+ deactivate() {
24
+ this.sidebar.show();
25
+ this.mapManager.setMapInstance?.(null);
26
+ this.mapManager.setLivemap?.(null);
27
+ this.mapManager.setActiveProvider?.(this.mapManager.getConfiguredProvider?.() ?? 'leaflet');
28
+ }
16
29
 
17
30
  beforeModel() {
18
31
  if (this.abilities.cannot('fleet-ops list order')) {
@@ -19,5 +19,6 @@ export default class OperationsOrdersIndexDetailsVirtualRoute extends Route {
19
19
  setupController(controller) {
20
20
  super.setupController(...arguments);
21
21
  controller.resource = this.modelFor('operations.orders.index.details');
22
+ controller.detailsController = this.controllerFor('operations.orders.index.details');
22
23
  }
23
24
  }
@@ -7,33 +7,27 @@ export default class OperationsOrdersIndexDetailsRoute extends Route {
7
7
  @service store;
8
8
  @service hostRouter;
9
9
  @service orderSocketEvents;
10
- @service leafletMapManager;
10
+ @service mapManager;
11
11
  @service abilities;
12
- @service universe;
13
12
  @service intl;
13
+ @service sidebar;
14
14
 
15
15
  @action willTransition(transition) {
16
16
  const fromName = transition.from?.name;
17
17
  const toName = transition.to?.name;
18
+ const orderDetailsRoute = 'console.fleet-ops.operations.orders.index.details';
19
+ const isRefreshWithinSameDetailsRoute = fromName?.startsWith(orderDetailsRoute) && toName?.startsWith(orderDetailsRoute) && fromName === toName;
18
20
 
19
- // only cleanup when actually leaving this route (not intra-route changes)
20
- if (fromName && fromName !== toName) {
21
- const controller = this.controllerFor('operations.orders.index.details');
22
- const rc = controller.routingControl;
23
-
24
- // Put back sidebar
25
- if (this.universe.sidebarContext) {
26
- this.universe.sidebarContext.show();
27
- }
28
-
29
- // stop listening for events
30
- this.orderSocketEvents.stop(controller.model);
21
+ if (isRefreshWithinSameDetailsRoute) {
22
+ return true;
23
+ }
31
24
 
32
- // cleanup guards
33
- if (rc) {
34
- this.leafletMapManager.removeRoutingControl(rc);
35
- controller.routingControl = undefined;
36
- }
25
+ // only cleanup when leaving the order details route tree entirely
26
+ const isLeavingOrderDetails = fromName?.startsWith(orderDetailsRoute) && !toName?.startsWith(orderDetailsRoute);
27
+ if (isLeavingOrderDetails) {
28
+ const controller = this.controllerFor('operations.orders.index.details');
29
+ controller.teardownRealtime();
30
+ controller.teardownRoutingControls();
37
31
  }
38
32
 
39
33
  return true;
@@ -44,6 +38,14 @@ export default class OperationsOrdersIndexDetailsRoute extends Route {
44
38
  return this.hostRouter.transitionTo('console.fleet-ops.operations.orders.index');
45
39
  }
46
40
 
41
+ activate() {
42
+ this.sidebar.hide();
43
+ }
44
+
45
+ deactivate() {
46
+ this.sidebar.show();
47
+ }
48
+
47
49
  beforeModel() {
48
50
  if (this.abilities.cannot('fleet-ops view order')) {
49
51
  this.notifications.warning(this.intl.t('common.unauthorized-access'));
@@ -55,14 +57,35 @@ export default class OperationsOrdersIndexDetailsRoute extends Route {
55
57
  return this.store.queryRecord('order', {
56
58
  public_id,
57
59
  single: true,
58
- with: ['payload', 'driverAssigned', 'orderConfig', 'customer', 'facilitator', 'trackingStatuses', 'trackingNumber', 'purchaseRate', 'comments', 'files'],
60
+ with: [
61
+ 'payload',
62
+ 'driverAssigned',
63
+ 'orderConfig',
64
+ 'customer',
65
+ 'facilitator',
66
+ 'trackingStatuses',
67
+ 'trackingNumber',
68
+ 'purchaseRate',
69
+ 'purchaseRate.serviceQuote',
70
+ 'purchaseRate.serviceQuote.items',
71
+ 'comments',
72
+ 'files',
73
+ ],
59
74
  });
60
75
  }
61
76
 
62
- async afterModel(order) {
63
- await order.loadTrackingActivity();
64
- if (order.meta?._index_resource) {
65
- await order.reload();
77
+ async setupController(controller, model) {
78
+ super.setupController(...arguments);
79
+
80
+ // Change layout to map
81
+ controller.index?.changeLayout?.('map');
82
+
83
+ // load activity and reload order if lightweight payload
84
+ await model.loadTrackingActivity();
85
+ if (model.meta?._index_resource) {
86
+ await model.reload();
66
87
  }
88
+
89
+ await controller.setupDetailsSession();
67
90
  }
68
91
  }
@@ -7,6 +7,7 @@ export default class OperationsOrdersIndexNewRoute extends Route {
7
7
  @service hostRouter;
8
8
  @service abilities;
9
9
  @service intl;
10
+ @service sidebar;
10
11
 
11
12
  @action willTransition() {
12
13
  if (this.controller) {
@@ -14,6 +15,14 @@ export default class OperationsOrdersIndexNewRoute extends Route {
14
15
  }
15
16
  }
16
17
 
18
+ activate() {
19
+ this.sidebar.hide();
20
+ }
21
+
22
+ deactivate() {
23
+ this.sidebar.show();
24
+ }
25
+
17
26
  beforeModel() {
18
27
  if (this.abilities.cannot('fleet-ops create order')) {
19
28
  this.notifications.warning(this.intl.t('common.unauthorized-access'));
@@ -3,7 +3,6 @@ import { inject as service } from '@ember/service';
3
3
 
4
4
  export default class OperationsOrdersIndexRoute extends Route {
5
5
  @service store;
6
- @service leafletMapManager;
7
6
 
8
7
  queryParams = {
9
8
  page: { refreshModel: true },
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class SettingsMapRoute extends Route {}
package/addon/routes.js CHANGED
@@ -257,6 +257,7 @@ export default buildRoutes(function () {
257
257
  this.route('custom-fields');
258
258
  this.route('avatars');
259
259
  this.route('routing');
260
+ this.route('map');
260
261
  this.route('orchestrator');
261
262
  this.route('scheduling');
262
263
  this.route('payments', function () {
@@ -3,7 +3,7 @@ import ResourceActionService from '@fleetbase/ember-core/services/resource-actio
3
3
  export default class EntityActionsService extends ResourceActionService {
4
4
  constructor() {
5
5
  super(...arguments);
6
- this.initialize('entity', { defaultAttributes: {} });
6
+ this.initialize('entity', { defaultAttributes: { type: 'entity' } });
7
7
  }
8
8
 
9
9
  modal = {
@@ -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 EquipmentActionsService 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 EquipmentActionsService 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: (equipment) => this.transitionTo('maintenance.equipment.index.details', equipment),
21
19
  edit: (equipment) => this.transitionTo('maintenance.equipment.index.edit', equipment),
@@ -1,4 +1,5 @@
1
1
  import Service from '@ember/service';
2
+ import { isArray } from '@ember/array';
2
3
  import { inject as service } from '@ember/service';
3
4
  import { tracked } from '@glimmer/tracking';
4
5
  import { action } from '@ember/object';
@@ -154,7 +155,7 @@ export default class GeofenceEventBusService extends Service {
154
155
 
155
156
  @action
156
157
  seedEvents(events = []) {
157
- this.events = Array.isArray(events) ? events.slice(0, this.MAX_EVENTS).map((event) => ({ ...event, isNew: false })) : [];
158
+ this.events = isArray(events) ? events.slice(0, this.MAX_EVENTS).map((event) => ({ ...event, isNew: false })) : [];
158
159
  }
159
160
 
160
161
  /**