@fleetbase/fleetops-engine 0.6.45 → 0.6.47

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 (148) 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/layout/fleet-ops-sidebar/driver-listing.js +5 -5
  10. package/addon/components/layout/fleet-ops-sidebar/fleet-listing.js +5 -5
  11. package/addon/components/layout/fleet-ops-sidebar.js +8 -0
  12. package/addon/components/maintenance-schedule/form.js +2 -1
  13. package/addon/components/map/drawer/driver-listing.js +5 -5
  14. package/addon/components/map/drawer/place-listing.js +5 -5
  15. package/addon/components/map/drawer/position-listing.js +102 -21
  16. package/addon/components/map/drawer/vehicle-listing.js +5 -5
  17. package/addon/components/map/google-live-map.hbs +9 -0
  18. package/addon/components/map/google-live-map.js +445 -0
  19. package/addon/components/map/leaflet-live-map.hbs +186 -142
  20. package/addon/components/map/leaflet-live-map.js +121 -41
  21. package/addon/components/map/toolbar/visibility-control-panel.js +2 -2
  22. package/addon/components/map/toolbar/zones-panel.hbs +9 -9
  23. package/addon/components/map/toolbar.hbs +3 -3
  24. package/addon/components/map/toolbar.js +9 -1
  25. package/addon/components/modals/map-layer-form.hbs +132 -63
  26. package/addon/components/modals/orchestrator-import.hbs +4 -11
  27. package/addon/components/modals/orchestrator-import.js +17 -1
  28. package/addon/components/modals/update-order-activity.hbs +1 -1
  29. package/addon/components/orchestrator/order-pool.js +3 -2
  30. package/addon/components/orchestrator-workbench.js +29 -41
  31. package/addon/components/order/details/detail.js +2 -2
  32. package/addon/components/order/details/payload.hbs +5 -5
  33. package/addon/components/order/details/payload.js +18 -1
  34. package/addon/components/order/details/route.hbs +2 -2
  35. package/addon/components/order/details/route.js +76 -3
  36. package/addon/components/order/form/details.hbs +1 -2
  37. package/addon/components/order/form/details.js +6 -0
  38. package/addon/components/order/form/payload.hbs +33 -0
  39. package/addon/components/order/form/payload.js +1 -0
  40. package/addon/components/order/form/route.hbs +8 -8
  41. package/addon/components/order/form/route.js +86 -18
  42. package/addon/components/order/form.js +2 -2
  43. package/addon/components/order/route-editor.hbs +209 -147
  44. package/addon/components/order/route-editor.js +143 -102
  45. package/addon/components/place/address.hbs +1 -0
  46. package/addon/components/place/address.js +12 -0
  47. package/addon/components/route-list.hbs +43 -55
  48. package/addon/components/route-list.js +47 -0
  49. package/addon/components/route-optimization-wizard-panel.js +3 -4
  50. package/addon/components/vehicle/card.hbs +4 -4
  51. package/addon/controllers/maintenance/schedules/index.js +2 -1
  52. package/addon/controllers/operations/orders/index/details.js +110 -37
  53. package/addon/controllers/operations/orders/index/new.js +1 -1
  54. package/addon/controllers/operations/orders/index.js +8 -1
  55. package/addon/controllers/settings/map.js +97 -0
  56. package/addon/controllers/settings/payments/index.js +1 -1
  57. package/addon/controllers/settings/routing.js +47 -12
  58. package/addon/extension.js +11 -0
  59. package/addon/helpers/place-address-html.js +6 -0
  60. package/addon/instance-initializers/register-google-routes.js +17 -0
  61. package/addon/instance-initializers/register-osrm.js +5 -0
  62. package/addon/routes/application.js +6 -0
  63. package/addon/routes/operations/orchestrator.js +13 -0
  64. package/addon/routes/operations/orders/index/details.js +29 -22
  65. package/addon/routes/operations/orders/index/new.js +9 -0
  66. package/addon/routes/operations/orders/index.js +0 -1
  67. package/addon/routes/settings/map.js +3 -0
  68. package/addon/routes.js +1 -0
  69. package/addon/services/entity-actions.js +1 -1
  70. package/addon/services/geofence-event-bus.js +2 -1
  71. package/addon/services/geofence.js +204 -168
  72. package/addon/services/google-routes.js +300 -0
  73. package/addon/services/leaflet-draw-restriction.js +2 -1
  74. package/addon/services/leaflet-map-manager.js +17 -0
  75. package/addon/services/map-adapter/google.js +2205 -0
  76. package/addon/services/map-adapter/leaflet.js +1042 -0
  77. package/addon/services/map-adapter-interface.js +551 -0
  78. package/addon/services/map-manager.js +768 -0
  79. package/addon/services/map-settings.js +75 -0
  80. package/addon/services/movement-tracker.js +83 -32
  81. package/addon/services/order-actions.js +11 -1
  82. package/addon/services/osrm.js +79 -6
  83. package/addon/services/position-playback.js +135 -62
  84. package/addon/services/route-engine.js +83 -0
  85. package/addon/services/service-areas.js +8 -1
  86. package/addon/styles/fleetops-engine.css +555 -0
  87. package/addon/templates/management/vehicles/index.hbs +0 -1
  88. package/addon/templates/operations/orders/index/details.hbs +0 -1
  89. package/addon/templates/settings/map.hbs +53 -0
  90. package/addon/templates/settings/routing.hbs +15 -4
  91. package/addon/utils/fleet-ops-options.js +1 -0
  92. package/addon/utils/has-valid-coordinates.js +6 -0
  93. package/addon/utils/map-provider-options.js +6 -0
  94. package/addon/utils/order-route-editing.js +86 -0
  95. package/addon/utils/order-route-summary.js +20 -0
  96. package/addon/utils/place-address-html.js +41 -0
  97. package/addon/utils/route-colors.js +43 -12
  98. package/addon/utils/route-visualization.js +93 -0
  99. package/addon/utils/vendor-integration.js +2 -1
  100. package/app/components/admin/map-settings.js +1 -0
  101. package/app/components/admin/routing-settings.js +1 -0
  102. package/app/components/cell/order-route-type.js +1 -0
  103. package/app/components/cell/place-address.js +1 -0
  104. package/app/components/map/google-live-map.js +1 -0
  105. package/app/components/place/address.js +1 -0
  106. package/app/controllers/settings/map.js +1 -0
  107. package/app/helpers/place-address-html.js +1 -0
  108. package/app/routes/settings/map.js +1 -0
  109. package/app/services/map-adapter/google.js +1 -0
  110. package/app/services/map-adapter/leaflet.js +1 -0
  111. package/app/services/map-adapter-interface.js +1 -0
  112. package/app/services/map-manager.js +1 -0
  113. package/app/services/map-settings.js +1 -0
  114. package/app/templates/settings/map.js +1 -0
  115. package/app/utils/has-valid-coordinates.js +1 -0
  116. package/app/utils/order-route-editing.js +2 -0
  117. package/app/utils/order-route-summary.js +1 -0
  118. package/app/utils/place-address-html.js +1 -0
  119. package/app/utils/route-colors.js +1 -1
  120. package/app/utils/route-visualization.js +1 -0
  121. package/assets/images/drawing-controls-spritesheet.svg +156 -0
  122. package/composer.json +1 -1
  123. package/extension.json +1 -1
  124. package/package.json +4 -4
  125. package/pnpm-workspace.yaml +7 -0
  126. package/server/src/Auth/Schemas/FleetOps.php +5 -0
  127. package/server/src/Http/Controllers/Api/v1/OrderController.php +31 -3
  128. package/server/src/Http/Controllers/Api/v1/PayloadController.php +14 -1
  129. package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +2 -0
  130. package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +3 -2
  131. package/server/src/Http/Controllers/Api/v1/ZoneController.php +2 -0
  132. package/server/src/Http/Controllers/Internal/v1/LiveController.php +2 -1
  133. package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +7 -4
  134. package/server/src/Http/Controllers/Internal/v1/OrderController.php +90 -34
  135. package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +3 -2
  136. package/server/src/Http/Controllers/Internal/v1/SettingController.php +106 -3
  137. package/server/src/Http/Filter/OrderFilter.php +2 -1
  138. package/server/src/Http/Resources/v1/Index/Payload.php +9 -7
  139. package/server/src/Http/Resources/v1/Order.php +20 -1
  140. package/server/src/Models/Order.php +42 -1
  141. package/server/src/Models/OrderConfig.php +15 -0
  142. package/server/src/Models/Payload.php +131 -27
  143. package/server/src/Models/Place.php +182 -48
  144. package/server/src/Models/ServiceRate.php +4 -3
  145. package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +59 -23
  146. package/server/src/Support/Utils.php +36 -2
  147. package/server/src/routes.php +4 -0
  148. package/translations/en-us.yaml +1937 -1916
@@ -0,0 +1,86 @@
1
+ import { isArray } from '@ember/array';
2
+ import { Point } from '@fleetbase/fleetops-data/utils/geojson';
3
+ import { buildRoutePointsFromPayload, waypointToPlace } from './route-visualization';
4
+
5
+ export function routePointsToCoordinates(routePoints = []) {
6
+ return routePoints
7
+ .map(({ place }) => place)
8
+ .filter((place) => place?.hasValidCoordinates)
9
+ .map((place) => [place.latitude, place.longitude]);
10
+ }
11
+
12
+ export function getPayloadRouteCoordinates(payload) {
13
+ return routePointsToCoordinates(buildRoutePointsFromPayload(payload));
14
+ }
15
+
16
+ export function getPayloadIntermediateWaypoints(payload) {
17
+ const waypoints = payload?.waypoints;
18
+
19
+ if (typeof waypoints?.toArray === 'function') {
20
+ return waypoints.toArray();
21
+ }
22
+
23
+ return isArray(waypoints) ? waypoints : Array.from(waypoints ?? []);
24
+ }
25
+
26
+ export function hasRouteEndpoints(payload) {
27
+ return Boolean(payload?.pickup || payload?.dropoff);
28
+ }
29
+
30
+ export function canOptimizeIntermediateWaypoints(payload) {
31
+ return getPayloadIntermediateWaypoints(payload).length >= 2;
32
+ }
33
+
34
+ export function buildRouteOptimizationInput(order) {
35
+ const payload = order?.payload;
36
+ const routePoints = buildRoutePointsFromPayload(payload);
37
+ const coordinates = routePointsToCoordinates(routePoints).map(([lat, lng]) => [lng, lat]);
38
+ const waypoints = getPayloadIntermediateWaypoints(payload);
39
+
40
+ return {
41
+ order,
42
+ payload,
43
+ coordinates,
44
+ routePoints,
45
+ waypoints,
46
+ preserveEndpoints: hasRouteEndpoints(payload),
47
+ };
48
+ }
49
+
50
+ export function applyOptimizedIntermediateWaypoints(payload, sortedWaypoints = []) {
51
+ if (!payload) {
52
+ return;
53
+ }
54
+
55
+ if (typeof payload.setWaypoints === 'function') {
56
+ payload.setWaypoints(sortedWaypoints);
57
+ return;
58
+ }
59
+
60
+ payload.waypoints = sortedWaypoints;
61
+ }
62
+
63
+ export function createWaypointRecord(store, properties = {}) {
64
+ const place = properties.place ? waypointToPlace(properties.place) : null;
65
+ const serializedPlace = typeof place?.serialize === 'function' ? place.serialize() : {};
66
+
67
+ return store.createRecord('waypoint', {
68
+ type: 'dropoff',
69
+ ...serializedPlace,
70
+ ...properties,
71
+ place: place ?? null,
72
+ place_uuid: properties.place_uuid ?? place?.id ?? null,
73
+ location: properties.location ?? place?.location ?? new Point(0, 0),
74
+ });
75
+ }
76
+
77
+ export default {
78
+ routePointsToCoordinates,
79
+ getPayloadRouteCoordinates,
80
+ getPayloadIntermediateWaypoints,
81
+ hasRouteEndpoints,
82
+ canOptimizeIntermediateWaypoints,
83
+ buildRouteOptimizationInput,
84
+ applyOptimizedIntermediateWaypoints,
85
+ createWaypointRecord,
86
+ };
@@ -0,0 +1,20 @@
1
+ export function buildRouteTypeSummary({ hasIntermediateWaypoints = false, intermediateStopCount = 0, hasPickup = false, hasDropoff = false } = {}) {
2
+ const count = Math.max(Number(intermediateStopCount) || 0, 0);
3
+ const hasIntermediateStops = count > 0 || Boolean(hasIntermediateWaypoints);
4
+ const hasEndpoints = Boolean(hasPickup || hasDropoff);
5
+ const kind = hasIntermediateStops ? (hasEndpoints ? 'pickup_dropoff_stops' : 'multi_stop') : 'pickup_dropoff';
6
+
7
+ return {
8
+ kind,
9
+ intermediateStopCount: count,
10
+ icon: hasIntermediateStops ? 'route' : 'exchange-alt',
11
+ badgeClass: hasIntermediateStops ? 'import-preview-badge import-preview-badge--blue' : 'import-preview-badge import-preview-badge--gray',
12
+ translationKey:
13
+ kind === 'pickup_dropoff_stops'
14
+ ? 'orchestrator.col-preview-pickup-dropoff-stops'
15
+ : kind === 'multi_stop'
16
+ ? 'orchestrator.col-preview-multi-stop'
17
+ : 'orchestrator.col-preview-pickup-dropoff',
18
+ translationOptions: hasIntermediateStops ? { count } : {},
19
+ };
20
+ }
@@ -0,0 +1,41 @@
1
+ import { htmlSafe } from '@ember/template';
2
+ import { isBlank } from '@ember/utils';
3
+
4
+ function escapeHtml(value) {
5
+ return String(value).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
6
+ }
7
+
8
+ function line(content, className = '') {
9
+ const classAttribute = className ? ` class="${className}"` : '';
10
+
11
+ return `<div${classAttribute}>${escapeHtml(content)}</div>`;
12
+ }
13
+
14
+ export default function placeAddressHtml(place) {
15
+ if (!place) {
16
+ return htmlSafe('');
17
+ }
18
+
19
+ const name = place.name === place.street1 ? null : place.name;
20
+ const cityStatePostalCode = [place.city, place.province, place.postal_code].filter((value) => !isBlank(value)).join(', ');
21
+ const lines = [];
22
+
23
+ if (name) {
24
+ lines.push(line(name, 'font-semibold'));
25
+ lines.push(line(place.street1));
26
+ } else if (place.street1) {
27
+ lines.push(line(place.street1, 'font-semibold'));
28
+ }
29
+
30
+ if (place.street2) {
31
+ lines.push(line(place.street2));
32
+ }
33
+
34
+ lines.push(line(cityStatePostalCode));
35
+
36
+ if (place.country) {
37
+ lines.push(line(place.country_name));
38
+ }
39
+
40
+ return htmlSafe(`<address class="uppercase truncate w-full">${lines.join('')}</address>`);
41
+ }
@@ -10,6 +10,15 @@
10
10
  * Colors are chosen for high contrast against both light and dark CartoDB tile layers.
11
11
  */
12
12
  export const ROUTE_COLOR_PALETTE = ['#0EA5E9', '#8B5CF6', '#F59E0B', '#10B981', '#F97316', '#EC4899', '#06B6D4', '#EF4444', '#84CC16', '#6366F1'];
13
+ export const ORDER_ROUTE_STATUS_COLORS = {
14
+ created: '#2563EB',
15
+ dispatched: '#4F46E5',
16
+ started: '#0891B2',
17
+ enroute: '#CA8A04',
18
+ driver_enroute: '#CA8A04',
19
+ completed: '#16A34A',
20
+ canceled: '#DC2626',
21
+ };
13
22
 
14
23
  /**
15
24
  * Darken a hex color by a given integer amount (0-255 per channel).
@@ -43,6 +52,23 @@ export function colorForId(id = '') {
43
52
  return ROUTE_COLOR_PALETTE[Math.abs(hash) % ROUTE_COLOR_PALETTE.length];
44
53
  }
45
54
 
55
+ export function normalizeOrderRouteStatus(status = 'created') {
56
+ switch (status) {
57
+ case 'pending':
58
+ return 'created';
59
+ case 'driver-enroute':
60
+ return 'driver_enroute';
61
+ case 'cancelled':
62
+ return 'canceled';
63
+ default:
64
+ return status && ORDER_ROUTE_STATUS_COLORS[status] ? status : 'created';
65
+ }
66
+ }
67
+
68
+ export function routeColorForStatus(status = 'created') {
69
+ return ORDER_ROUTE_STATUS_COLORS[normalizeOrderRouteStatus(status)] ?? ORDER_ROUTE_STATUS_COLORS.created;
70
+ }
71
+
46
72
  /**
47
73
  * Return a Leaflet Path options `styles` array for a route polyline
48
74
  * based on the order status. Uses a two-layer "cased" approach:
@@ -52,28 +78,33 @@ export function colorForId(id = '') {
52
78
  * @param {string} color - The base hex color for this route
53
79
  * @returns {Array<Object>} Array of Leaflet Path options objects
54
80
  */
55
- export function routeStyleForStatus(status, color) {
56
- const darker = darkenColor(color, 40);
57
-
58
- switch (status) {
59
- case 'pending':
60
- return [{ color: '#9CA3AF', weight: 5, opacity: 0.65, dashArray: '8 14', lineCap: 'round', lineJoin: 'round' }];
81
+ export function routeStyleForStatus(status, fallbackColor = null) {
82
+ const normalizedStatus = normalizeOrderRouteStatus(status);
83
+ const color = routeColorForStatus(normalizedStatus) ?? fallbackColor ?? ORDER_ROUTE_STATUS_COLORS.created;
84
+ const darker = darkenColor(color, 36);
61
85
 
86
+ switch (normalizedStatus) {
62
87
  case 'canceled':
63
- return [{ color: '#EF4444', weight: 4, opacity: 0.4, dashArray: '6 10', lineCap: 'round', lineJoin: 'round' }];
88
+ return [
89
+ { color: darkenColor(color, 18), weight: 5, opacity: 0.16, lineCap: 'round', lineJoin: 'round' },
90
+ { color, weight: 3, opacity: 0.52, lineCap: 'round', lineJoin: 'round' },
91
+ ];
64
92
 
65
93
  case 'completed':
66
94
  return [
67
- { color: darkenColor('#14B8A6', 30), weight: 7, opacity: 0.5, lineCap: 'round', lineJoin: 'round' },
68
- { color: '#14B8A6', weight: 4, opacity: 0.5, lineCap: 'round', lineJoin: 'round' },
95
+ { color: darker, weight: 6, opacity: 0.4, lineCap: 'round', lineJoin: 'round' },
96
+ { color, weight: 3, opacity: 0.8, lineCap: 'round', lineJoin: 'round' },
69
97
  ];
70
98
 
71
- case 'in_progress':
99
+ case 'created':
72
100
  case 'dispatched':
101
+ case 'started':
102
+ case 'enroute':
103
+ case 'driver_enroute':
73
104
  default:
74
105
  return [
75
- { color: darker, weight: 9, opacity: 0.9, lineCap: 'round', lineJoin: 'round' },
76
- { color: color, weight: 5, opacity: 1.0, lineCap: 'round', lineJoin: 'round' },
106
+ { color: darker, weight: 7, opacity: 0.82, lineCap: 'round', lineJoin: 'round' },
107
+ { color, weight: 4, opacity: 1, lineCap: 'round', lineJoin: 'round' },
77
108
  ];
78
109
  }
79
110
  }
@@ -0,0 +1,93 @@
1
+ import hasValidCoordinates from './has-valid-coordinates';
2
+
3
+ export function waypointToPlace(waypoint) {
4
+ if (!waypoint) {
5
+ return null;
6
+ }
7
+
8
+ return waypoint.place ?? waypoint;
9
+ }
10
+
11
+ export function buildPlaceAddressTooltip(title, place) {
12
+ if (!place) {
13
+ return title;
14
+ }
15
+
16
+ const name = place.name && place.name !== place.street1 ? place.name : null;
17
+ const cityStatePostalCode = [place.city, place.province, place.postal_code].filter(Boolean).join(', ');
18
+ const lines = [
19
+ name ? `<div class="fleetops-google-hover-tooltip__meta">${name}</div>` : '',
20
+ place.street1 ? `<div class="fleetops-google-hover-tooltip__meta">${place.street1}</div>` : '',
21
+ place.street2 ? `<div class="fleetops-google-hover-tooltip__meta">${place.street2}</div>` : '',
22
+ cityStatePostalCode ? `<div class="fleetops-google-hover-tooltip__meta">${cityStatePostalCode}</div>` : '',
23
+ place.country_name ? `<div class="fleetops-google-hover-tooltip__meta">${place.country_name}</div>` : '',
24
+ ].filter(Boolean);
25
+
26
+ return `
27
+ <div class="fleetops-google-hover-tooltip__title">${title}</div>
28
+ ${lines.join('')}
29
+ `;
30
+ }
31
+
32
+ export function buildRoutePointsFromPayload(payload) {
33
+ if (!payload) {
34
+ return [];
35
+ }
36
+
37
+ const points = [];
38
+ const waypoints = payload.waypoints ?? [];
39
+
40
+ if (hasValidCoordinates(payload.pickup)) {
41
+ points.push({ role: 'pickup', place: payload.pickup });
42
+ }
43
+
44
+ waypoints.forEach((waypoint, index) => {
45
+ const place = waypointToPlace(waypoint);
46
+
47
+ if (hasValidCoordinates(place)) {
48
+ points.push({ role: 'waypoint', place, stopNumber: index + 1 });
49
+ }
50
+ });
51
+
52
+ if (hasValidCoordinates(payload.dropoff)) {
53
+ points.push({ role: 'dropoff', place: payload.dropoff });
54
+ }
55
+
56
+ return points;
57
+ }
58
+
59
+ export function describeRoutePoint(routePoint, routeColor) {
60
+ const role = routePoint?.role;
61
+ const stopNumber = routePoint?.stopNumber ?? 1;
62
+ const label = role === 'pickup' ? 'P' : role === 'dropoff' ? 'D' : String(stopNumber);
63
+ const markerColor = role === 'pickup' ? '#22C55E' : role === 'dropoff' ? '#EF4444' : routeColor;
64
+ const title = role === 'pickup' ? 'Pickup' : role === 'dropoff' ? 'Dropoff' : `Stop ${stopNumber}`;
65
+
66
+ return {
67
+ label,
68
+ markerColor,
69
+ title,
70
+ };
71
+ }
72
+
73
+ export function buildRoutePointMarkerPresentation(routePoint, routeColor, options = {}) {
74
+ const role = routePoint?.role;
75
+ const place = routePoint?.place;
76
+ const { label, markerColor, title } = describeRoutePoint(routePoint, routeColor);
77
+ const zIndexOffset = role === 'pickup' ? 2200 : role === 'dropoff' ? 2100 : 1800;
78
+
79
+ return {
80
+ waypointLabel: label,
81
+ waypointColor: markerColor,
82
+ title,
83
+ zIndexOffset: options.zIndexOffset ?? zIndexOffset,
84
+ tooltip: buildPlaceAddressTooltip(title, place),
85
+ tooltipOptions: {
86
+ direction: 'top',
87
+ offset: [0, -20],
88
+ className: 'fleetops-waypoint-tooltip',
89
+ html: true,
90
+ ...(options.tooltipOptions ?? {}),
91
+ },
92
+ };
93
+ }
@@ -1,4 +1,5 @@
1
1
  import apiUrl from '@fleetbase/ember-core/utils/api-url';
2
+ import { isArray } from '@ember/array';
2
3
 
3
4
  /**
4
5
  * Normalize any array-like (EmberArray, Set, arguments) into a plain array.
@@ -8,7 +9,7 @@ import apiUrl from '@fleetbase/ember-core/utils/api-url';
8
9
  */
9
10
  export function normalizeToArray(input) {
10
11
  if (!input) return [];
11
- if (Array.isArray(input)) return input;
12
+ if (isArray(input)) return input;
12
13
  if (typeof input.toArray === 'function') return input.toArray();
13
14
  try {
14
15
  return Array.from(input);
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/admin/map-settings';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/admin/routing-settings';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/cell/order-route-type';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/cell/place-address';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/map/google-live-map';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/place/address';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/controllers/settings/map';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/helpers/place-address-html';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/settings/map';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/map-adapter/google';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/map-adapter/leaflet';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/map-adapter-interface';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/map-manager';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/map-settings';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/templates/settings/map';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/utils/has-valid-coordinates';
@@ -0,0 +1,2 @@
1
+ export { default } from '@fleetbase/fleetops/utils/order-route-editing';
2
+ export * from '@fleetbase/fleetops/utils/order-route-editing';
@@ -0,0 +1 @@
1
+ export * from '@fleetbase/fleetops-engine/utils/order-route-summary';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/utils/place-address-html';
@@ -1 +1 @@
1
- export { default, ROUTE_COLOR_PALETTE, colorForId, darkenColor, routeStyleForStatus, waypointIconHtml } from '@fleetbase/fleetops-engine/utils/route-colors';
1
+ export * from '@fleetbase/fleetops-engine/utils/route-colors';
@@ -0,0 +1 @@
1
+ export * from '@fleetbase/fleetops-engine/utils/route-visualization';
@@ -0,0 +1,156 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg
3
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+ xmlns:cc="http://creativecommons.org/ns#"
5
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6
+ xmlns:svg="http://www.w3.org/2000/svg"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ xmlns:xlink="http://www.w3.org/1999/xlink"
9
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11
+ viewBox="0 0 600 60"
12
+ height="60"
13
+ width="600"
14
+ id="svg4225"
15
+ version="1.1"
16
+ inkscape:version="0.91 r13725"
17
+ sodipodi:docname="spritesheet.svg"
18
+ inkscape:export-filename="/home/fpuga/development/upstream/icarto.Leaflet.draw/src/images/spritesheet-2x.png"
19
+ inkscape:export-xdpi="90"
20
+ inkscape:export-ydpi="90">
21
+ <metadata
22
+ id="metadata4258">
23
+ <rdf:RDF>
24
+ <cc:Work
25
+ rdf:about="">
26
+ <dc:format>image/svg+xml</dc:format>
27
+ <dc:type
28
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
29
+ <dc:title />
30
+ </cc:Work>
31
+ </rdf:RDF>
32
+ </metadata>
33
+ <defs
34
+ id="defs4256" />
35
+ <sodipodi:namedview
36
+ pagecolor="#ffffff"
37
+ bordercolor="#666666"
38
+ borderopacity="1"
39
+ objecttolerance="10"
40
+ gridtolerance="10"
41
+ guidetolerance="10"
42
+ inkscape:pageopacity="0"
43
+ inkscape:pageshadow="2"
44
+ inkscape:window-width="1920"
45
+ inkscape:window-height="1056"
46
+ id="namedview4254"
47
+ showgrid="false"
48
+ inkscape:zoom="1.3101852"
49
+ inkscape:cx="237.56928"
50
+ inkscape:cy="7.2419621"
51
+ inkscape:window-x="1920"
52
+ inkscape:window-y="24"
53
+ inkscape:window-maximized="1"
54
+ inkscape:current-layer="svg4225" />
55
+ <g
56
+ id="enabled"
57
+ style="fill:#464646;fill-opacity:1">
58
+ <g
59
+ id="polyline"
60
+ style="fill:#464646;fill-opacity:1">
61
+ <path
62
+ d="m 18,36 0,6 6,0 0,-6 -6,0 z m 4,4 -2,0 0,-2 2,0 0,2 z"
63
+ id="path4229"
64
+ inkscape:connector-curvature="0"
65
+ style="fill:#464646;fill-opacity:1" />
66
+ <path
67
+ d="m 36,18 0,6 6,0 0,-6 -6,0 z m 4,4 -2,0 0,-2 2,0 0,2 z"
68
+ id="path4231"
69
+ inkscape:connector-curvature="0"
70
+ style="fill:#464646;fill-opacity:1" />
71
+ <path
72
+ d="m 23.142,39.145 -2.285,-2.29 16,-15.998 2.285,2.285 z"
73
+ id="path4233"
74
+ inkscape:connector-curvature="0"
75
+ style="fill:#464646;fill-opacity:1" />
76
+ </g>
77
+ <path
78
+ id="polygon"
79
+ d="M 100,24.565 97.904,39.395 83.07,42 76,28.773 86.463,18 Z"
80
+ inkscape:connector-curvature="0"
81
+ style="fill:#464646;fill-opacity:1" />
82
+ <path
83
+ id="rectangle"
84
+ d="m 140,20 20,0 0,20 -20,0 z"
85
+ inkscape:connector-curvature="0"
86
+ style="fill:#464646;fill-opacity:1" />
87
+ <path
88
+ id="circle"
89
+ d="m 221,30 c 0,6.078 -4.926,11 -11,11 -6.074,0 -11,-4.922 -11,-11 0,-6.074 4.926,-11 11,-11 6.074,0 11,4.926 11,11 z"
90
+ inkscape:connector-curvature="0"
91
+ style="fill:#464646;fill-opacity:1" />
92
+ <path
93
+ id="marker"
94
+ d="m 270,19 c -4.971,0 -9,4.029 -9,9 0,4.971 5.001,12 9,14 4.001,-2 9,-9.029 9,-14 0,-4.971 -4.029,-9 -9,-9 z m 0,12.5 c -2.484,0 -4.5,-2.014 -4.5,-4.5 0,-2.484 2.016,-4.5 4.5,-4.5 2.485,0 4.5,2.016 4.5,4.5 0,2.486 -2.015,4.5 -4.5,4.5 z"
95
+ inkscape:connector-curvature="0"
96
+ style="fill:#464646;fill-opacity:1" />
97
+ <g
98
+ id="edit"
99
+ style="fill:#464646;fill-opacity:1">
100
+ <path
101
+ d="m 337,30.156 0,0.407 0,5.604 c 0,1.658 -1.344,3 -3,3 l -10,0 c -1.655,0 -3,-1.342 -3,-3 l 0,-10 c 0,-1.657 1.345,-3 3,-3 l 6.345,0 3.19,-3.17 -9.535,0 c -3.313,0 -6,2.687 -6,6 l 0,10 c 0,3.313 2.687,6 6,6 l 10,0 c 3.314,0 6,-2.687 6,-6 l 0,-8.809 -3,2.968"
102
+ id="path4240"
103
+ inkscape:connector-curvature="0"
104
+ style="fill:#464646;fill-opacity:1" />
105
+ <path
106
+ d="m 338.72,24.637 -8.892,8.892 -2.828,0 0,-2.829 8.89,-8.89 z"
107
+ id="path4242"
108
+ inkscape:connector-curvature="0"
109
+ style="fill:#464646;fill-opacity:1" />
110
+ <path
111
+ d="m 338.697,17.826 4,0 0,4 -4,0 z"
112
+ transform="matrix(-0.70698336,-0.70723018,0.70723018,-0.70698336,567.55917,274.78273)"
113
+ id="path4244"
114
+ inkscape:connector-curvature="0"
115
+ style="fill:#464646;fill-opacity:1" />
116
+ </g>
117
+ <g
118
+ id="remove"
119
+ style="fill:#464646;fill-opacity:1">
120
+ <path
121
+ d="m 381,42 18,0 0,-18 -18,0 0,18 z m 14,-16 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z"
122
+ id="path4247"
123
+ inkscape:connector-curvature="0"
124
+ style="fill:#464646;fill-opacity:1" />
125
+ <path
126
+ d="m 395,20 0,-4 -10,0 0,4 -6,0 0,2 22,0 0,-2 -6,0 z m -2,0 -6,0 0,-2 6,0 0,2 z"
127
+ id="path4249"
128
+ inkscape:connector-curvature="0"
129
+ style="fill:#464646;fill-opacity:1" />
130
+ </g>
131
+ </g>
132
+ <g
133
+ id="disabled"
134
+ transform="translate(120,0)"
135
+ style="fill:#bbbbbb">
136
+ <use
137
+ xlink:href="#edit"
138
+ id="edit-disabled"
139
+ x="0"
140
+ y="0"
141
+ width="100%"
142
+ height="100%" />
143
+ <use
144
+ xlink:href="#remove"
145
+ id="remove-disabled"
146
+ x="0"
147
+ y="0"
148
+ width="100%"
149
+ height="100%" />
150
+ </g>
151
+ <path
152
+ style="fill:none;stroke:#464646;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
153
+ id="circle-3"
154
+ d="m 581.65725,30 c 0,6.078 -4.926,11 -11,11 -6.074,0 -11,-4.922 -11,-11 0,-6.074 4.926,-11 11,-11 6.074,0 11,4.926 11,11 z"
155
+ inkscape:connector-curvature="0" />
156
+ </svg>
package/composer.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbase/fleetops-api",
3
- "version": "0.6.45",
3
+ "version": "0.6.47",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "keywords": [
6
6
  "fleetbase-extension",
package/extension.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Fleet-Ops",
3
- "version": "0.6.45",
3
+ "version": "0.6.47",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "repository": "https://github.com/fleetbase/fleetops",
6
6
  "license": "AGPL-3.0-or-later",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/fleetops-engine",
3
- "version": "0.6.45",
3
+ "version": "0.6.47",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "fleetbase": {
6
6
  "route": "fleet-ops"
@@ -42,9 +42,9 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@babel/core": "^7.23.2",
45
- "@fleetbase/ember-core": "^0.3.18",
46
- "@fleetbase/ember-ui": "^0.3.26",
47
- "@fleetbase/fleetops-data": "^0.1.30",
45
+ "@fleetbase/ember-core": "^0.3.19",
46
+ "@fleetbase/ember-ui": "^0.3.29",
47
+ "@fleetbase/fleetops-data": "^0.1.32",
48
48
  "@fleetbase/leaflet-routing-machine": "^3.2.17",
49
49
  "@fortawesome/ember-fontawesome": "^2.0.0",
50
50
  "@fortawesome/fontawesome-svg-core": "6.4.0",
@@ -0,0 +1,7 @@
1
+ allowBuilds:
2
+ '@fortawesome/fontawesome-common-types': false
3
+ '@fortawesome/fontawesome-svg-core': false
4
+ '@fortawesome/free-brands-svg-icons': false
5
+ '@fortawesome/free-solid-svg-icons': false
6
+ core-js: false
7
+ fsevents: false
@@ -157,6 +157,11 @@ class FleetOps
157
157
  'action' => [],
158
158
  'remove_actions' => ['export', 'create'],
159
159
  ],
160
+ [
161
+ 'name' => 'map-settings',
162
+ 'action' => [],
163
+ 'remove_actions' => ['export', 'create'],
164
+ ],
160
165
  ];
161
166
 
162
167
  /**