@fleetbase/fleetops-engine 0.6.48 → 0.6.50
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.
- package/addon/components/customer/create-order-form.hbs +2 -2
- package/addon/components/customer/form.hbs +2 -2
- package/addon/components/customer/order-form.hbs +2 -2
- package/addon/components/customer/orders.hbs +2 -2
- package/addon/components/display-place.hbs +2 -2
- package/addon/components/driver/details.hbs +5 -1
- package/addon/components/driver/form.hbs +11 -1
- package/addon/components/fleet-listing-panel.hbs +2 -2
- package/addon/components/fleet-listing-panel.js +10 -0
- package/addon/components/map/google-live-map.js +18 -75
- package/addon/components/map/leaflet-live-map.hbs +187 -37
- package/addon/components/map/leaflet-live-map.js +184 -20
- package/addon/components/modals/order-change-destination.hbs +46 -0
- package/addon/components/modals/order-change-destination.js +106 -0
- package/addon/components/modals/stop-activity.hbs +28 -0
- package/addon/components/modals/stop-activity.js +52 -0
- package/addon/components/modals/update-order-activity.hbs +45 -3
- package/addon/components/modals/update-order-activity.js +143 -5
- package/addon/components/orchestrator/phase-builder.hbs +21 -0
- package/addon/components/orchestrator/phase-builder.js +13 -0
- package/addon/components/orchestrator/resource-panel.hbs +0 -10
- package/addon/components/orchestrator/resource-panel.js +2 -4
- package/addon/components/orchestrator-workbench.js +1 -0
- package/addon/components/order/activity-list.hbs +2 -2
- package/addon/components/order/activity-timeline.hbs +31 -29
- package/addon/components/order/details/activity.hbs +3 -3
- package/addon/components/order/details/activity.js +11 -0
- package/addon/components/order/details/documents.js +2 -0
- package/addon/components/order/details/purchase-rate.hbs +2 -2
- package/addon/components/order/details/route.hbs +11 -3
- package/addon/components/order/details/route.js +91 -14
- package/addon/components/order/details/tracking.hbs +101 -72
- package/addon/components/order/details/tracking.js +149 -2
- package/addon/components/order/form/details.hbs +3 -3
- package/addon/components/order/form/documents.js +11 -4
- package/addon/components/order/form/route.hbs +108 -104
- package/addon/components/order/form/route.js +37 -1
- package/addon/components/order/form/service-rate.hbs +2 -2
- package/addon/components/order/form.hbs +2 -2
- package/addon/components/order-config-manager/activity-flow.hbs +4 -1
- package/addon/components/order-config-manager/activity-flow.js +178 -12
- package/addon/components/place/address.js +1 -1
- package/addon/components/route-list.hbs +17 -17
- package/addon/components/route-list.js +42 -10
- package/addon/components/service-rate/details.hbs +41 -0
- package/addon/components/service-rate/form.hbs +118 -0
- package/addon/components/service-rate/form.js +55 -0
- package/addon/components/vehicle/form.js +1 -1
- package/addon/components/vehicle/pill.hbs +1 -1
- package/addon/components/widget/fleet-ops-key-metrics.hbs +19 -17
- package/addon/components/widget/fleet-ops-key-metrics.js +26 -0
- package/addon/components/widget/fuel-efficiency.hbs +26 -0
- package/addon/components/widget/fuel-efficiency.js +43 -0
- package/addon/components/widget/geofence-violations.hbs +44 -0
- package/addon/components/widget/geofence-violations.js +55 -0
- package/addon/components/widget/issues-insights.hbs +43 -0
- package/addon/components/widget/issues-insights.js +62 -0
- package/addon/components/widget/kpi-active-orders.hbs +10 -0
- package/addon/components/widget/kpi-active-orders.js +5 -0
- package/addon/components/widget/kpi-aov.hbs +10 -0
- package/addon/components/widget/kpi-aov.js +5 -0
- package/addon/components/widget/kpi-distance.hbs +10 -0
- package/addon/components/widget/kpi-distance.js +5 -0
- package/addon/components/widget/kpi-drivers-online.hbs +10 -0
- package/addon/components/widget/kpi-drivers-online.js +5 -0
- package/addon/components/widget/kpi-earnings.hbs +10 -0
- package/addon/components/widget/kpi-earnings.js +5 -0
- package/addon/components/widget/kpi-open-issues.hbs +11 -0
- package/addon/components/widget/kpi-open-issues.js +5 -0
- package/addon/components/widget/kpi-tile.hbs +59 -0
- package/addon/components/widget/kpi-tile.js +168 -0
- package/addon/components/widget/live-fleet.hbs +122 -0
- package/addon/components/widget/live-fleet.js +365 -0
- package/addon/components/widget/maintenance-overview.hbs +45 -0
- package/addon/components/widget/maintenance-overview.js +40 -0
- package/addon/components/widget/on-time-delivery.hbs +27 -0
- package/addon/components/widget/on-time-delivery.js +73 -0
- package/addon/components/widget/operations-pulse.hbs +51 -0
- package/addon/components/widget/operations-pulse.js +173 -0
- package/addon/components/widget/orders-by-status.hbs +26 -0
- package/addon/components/widget/orders-by-status.js +54 -0
- package/addon/components/widget/revenue-trend.hbs +34 -0
- package/addon/components/widget/revenue-trend.js +67 -0
- package/addon/components/widget/top-drivers.hbs +44 -0
- package/addon/components/widget/top-drivers.js +54 -0
- package/addon/controllers/management/vehicles/index/new.js +1 -1
- package/addon/controllers/operations/orders/index/details.js +4 -4
- package/addon/controllers/operations/orders/index.js +14 -0
- package/addon/controllers/settings/routing.js +26 -0
- package/addon/extension.js +172 -3
- package/addon/helpers/place-address-html.js +2 -2
- package/addon/routes/operations/service-rates/index.js +1 -1
- package/addon/services/geofence.js +163 -19
- package/addon/services/leaflet-contextmenu-manager.js +27 -0
- package/addon/services/map-adapter/google.js +13 -2
- package/addon/services/vehicle-actions.js +1 -1
- package/addon/styles/fleetops-engine.css +205 -88
- package/addon/templates/maintenance/equipment/index.hbs +1 -1
- package/addon/templates/maintenance/parts/index.hbs +1 -1
- package/addon/templates/maintenance/schedules/index.hbs +1 -1
- package/addon/templates/management/vehicles/index.hbs +1 -1
- package/addon/templates/settings/avatars.hbs +1 -1
- package/addon/templates/settings/custom-fields.hbs +1 -1
- package/addon/templates/settings/map.hbs +1 -1
- package/addon/templates/settings/navigator-app.hbs +1 -1
- package/addon/templates/settings/notifications.hbs +1 -1
- package/addon/templates/settings/orchestrator.hbs +1 -1
- package/addon/templates/settings/payments/index.hbs +1 -1
- package/addon/templates/settings/payments/onboard.hbs +1 -1
- package/addon/templates/settings/routing.hbs +22 -2
- package/addon/templates/settings/scheduling.hbs +1 -1
- package/addon/utils/fleet-ops-options.js +2 -1
- package/addon/utils/live-map-card-content.js +171 -0
- package/addon/utils/normalize-order-config-flow.js +41 -0
- package/addon/utils/place-address-html.js +3 -2
- package/addon/utils/route-visualization.js +54 -7
- package/app/components/modals/order-change-destination.js +1 -0
- package/app/components/modals/stop-activity.js +1 -0
- package/app/components/widget/fuel-efficiency.js +1 -0
- package/app/components/widget/geofence-violations.js +1 -0
- package/app/components/widget/issues-insights.js +1 -0
- package/app/components/widget/kpi-active-orders.js +1 -0
- package/app/components/widget/kpi-aov.js +1 -0
- package/app/components/widget/kpi-distance.js +1 -0
- package/app/components/widget/kpi-drivers-online.js +1 -0
- package/app/components/widget/kpi-earnings.js +1 -0
- package/app/components/widget/kpi-open-issues.js +1 -0
- package/app/components/widget/kpi-tile.js +1 -0
- package/app/components/widget/live-fleet.js +1 -0
- package/app/components/widget/maintenance-overview.js +1 -0
- package/app/components/widget/on-time-delivery.js +1 -0
- package/app/components/widget/operations-pulse.js +1 -0
- package/app/components/widget/orders-by-status.js +1 -0
- package/app/components/widget/revenue-trend.js +1 -0
- package/app/components/widget/top-drivers.js +1 -0
- package/app/utils/live-map-card-content.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +3 -3
- package/pnpm-workspace.yaml +1 -0
- package/server/config/telematics.php +111 -1
- package/server/migrations/2026_05_18_000001_add_license_expiry_to_drivers_table.php +25 -0
- package/server/migrations/2026_05_21_000001_add_geographic_rules_to_service_rate_fees_table.php +37 -0
- package/server/migrations/2026_05_25_000001_add_endpoint_tracking_refs_to_payloads_table.php +50 -0
- package/server/migrations/2026_05_27_000001_default_driver_vehicle_statuses_to_available.php +48 -0
- package/server/resources/views/labels/default.php +57 -49
- package/server/resources/views/labels/waypoint-label.php +27 -20
- package/server/seeders/Testing/Concerns/SeedsTestingData.php +183 -0
- package/server/seeders/Testing/ConnectivitySeeder.php +213 -0
- package/server/seeders/Testing/FleetSeeder.php +341 -0
- package/server/seeders/Testing/MaintenanceSeeder.php +238 -0
- package/server/seeders/Testing/NetworkSeeder.php +250 -0
- package/server/seeders/Testing/OrdersSeeder.php +198 -0
- package/server/seeders/Testing/TestingSeeder.php +40 -0
- package/server/seeders/{VroomOrchestrationSeeder.php → Testing/VroomOrchestrationSeeder.php} +29 -22
- package/server/src/Console/Commands/AuditCustomerUserConflicts.php +75 -0
- package/server/src/Console/Commands/ProcessOperationalAlerts.php +279 -0
- package/server/src/Exceptions/CustomerUserConflictException.php +13 -0
- package/server/src/Http/Controllers/Api/v1/ContactController.php +17 -2
- package/server/src/Http/Controllers/Api/v1/CustomerController.php +876 -0
- package/server/src/Http/Controllers/Api/v1/DriverController.php +1 -1
- package/server/src/Http/Controllers/Api/v1/OrderConfigController.php +54 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +98 -70
- package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +2 -2
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +20 -3
- package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +119 -0
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +19 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +101 -66
- package/server/src/Http/Controllers/Internal/v1/MetricsController.php +82 -3
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +441 -32
- package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +46 -1
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +54 -1
- package/server/src/Http/Middleware/AuthenticateCustomerToken.php +34 -0
- package/server/src/Http/Requests/CreateCustomerOrderRequest.php +63 -0
- package/server/src/Http/Requests/CreateCustomerRequest.php +48 -0
- package/server/src/Http/Requests/CreateDriverRequest.php +1 -1
- package/server/src/Http/Requests/CreateVehicleRequest.php +25 -1
- package/server/src/Http/Requests/Internal/CreateDriverRequest.php +1 -1
- package/server/src/Http/Requests/VerifyCreateCustomerRequest.php +29 -0
- package/server/src/Http/Resources/Internal/v1/OrderConfig.php +41 -0
- package/server/src/Http/Resources/v1/Customer.php +79 -0
- package/server/src/Http/Resources/v1/Driver.php +2 -0
- package/server/src/Http/Resources/v1/Fleet.php +4 -0
- package/server/src/Http/Resources/v1/Index/Driver.php +48 -0
- package/server/src/Http/Resources/v1/Index/Vehicle.php +74 -1
- package/server/src/Http/Resources/v1/OrderConfig.php +74 -0
- package/server/src/Http/Resources/v1/Payload.php +23 -20
- package/server/src/Http/Resources/v1/ServiceArea.php +33 -19
- package/server/src/Http/Resources/v1/ServiceRateFee.php +7 -0
- package/server/src/Listeners/HandleOrderDispatched.php +2 -2
- package/server/src/Models/Contact.php +92 -15
- package/server/src/Models/Customer.php +64 -0
- package/server/src/Models/Driver.php +14 -3
- package/server/src/Models/Entity.php +2 -2
- package/server/src/Models/Order.php +29 -4
- package/server/src/Models/OrderConfig.php +14 -11
- package/server/src/Models/Payload.php +17 -1
- package/server/src/Models/ServiceRate.php +273 -1
- package/server/src/Models/ServiceRateFee.php +39 -9
- package/server/src/Models/TrackingNumber.php +8 -2
- package/server/src/Models/Vehicle.php +18 -2
- package/server/src/Models/Waypoint.php +2 -2
- package/server/src/Notifications/LateDeparture.php +48 -0
- package/server/src/Notifications/ProlongedStoppage.php +48 -0
- package/server/src/Notifications/RouteDeviation.php +48 -0
- package/server/src/Observers/ContactObserver.php +2 -0
- package/server/src/Observers/ServiceRateObserver.php +6 -6
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +29 -2
- package/server/src/Providers/FleetOpsServiceProvider.php +6 -0
- package/server/src/Providers/NotificationServiceProvider.php +3 -0
- package/server/src/Support/Analytics/AbstractAnalytics.php +77 -0
- package/server/src/Support/Analytics/FuelEfficiency.php +83 -0
- package/server/src/Support/Analytics/GeofenceViolations.php +63 -0
- package/server/src/Support/Analytics/IssuesInsights.php +67 -0
- package/server/src/Support/Analytics/LiveFleet.php +127 -0
- package/server/src/Support/Analytics/MaintenanceOverview.php +70 -0
- package/server/src/Support/Analytics/OnTimeDelivery.php +75 -0
- package/server/src/Support/Analytics/OperationsPulse.php +86 -0
- package/server/src/Support/Analytics/OrdersByStatus.php +64 -0
- package/server/src/Support/Analytics/RevenueTrend.php +78 -0
- package/server/src/Support/Analytics/TopDrivers.php +92 -0
- package/server/src/Support/CustomerAuth.php +98 -0
- package/server/src/Support/LabelPdf.php +52 -0
- package/server/src/Support/Metrics/AbstractMetric.php +170 -0
- package/server/src/Support/Metrics/ActiveLiveOrdersMetric.php +28 -0
- package/server/src/Support/Metrics/AvgOrderValueMetric.php +53 -0
- package/server/src/Support/Metrics/DriversOnlineMetric.php +30 -0
- package/server/src/Support/Metrics/EarningsMetric.php +30 -0
- package/server/src/Support/Metrics/FuelCostsMetric.php +30 -0
- package/server/src/Support/Metrics/MoneyMetric.php +30 -0
- package/server/src/Support/Metrics/OpenIssuesMetric.php +35 -0
- package/server/src/Support/Metrics/OrdersCanceledMetric.php +35 -0
- package/server/src/Support/Metrics/OrdersCompletedMetric.php +35 -0
- package/server/src/Support/Metrics/OrdersInProgressMetric.php +51 -0
- package/server/src/Support/Metrics/OrdersScheduledMetric.php +37 -0
- package/server/src/Support/Metrics/Registry.php +46 -0
- package/server/src/Support/Metrics/ResolvedIssuesMetric.php +35 -0
- package/server/src/Support/Metrics/TotalCustomersMetric.php +29 -0
- package/server/src/Support/Metrics/TotalDistanceTraveledMetric.php +35 -0
- package/server/src/Support/Metrics/TotalDriversMetric.php +28 -0
- package/server/src/Support/Metrics/TotalTimeTraveledMetric.php +35 -0
- package/server/src/Support/Metrics.php +46 -249
- package/server/src/Support/ResolvesOrderServiceStops.php +512 -0
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +290 -0
- package/server/src/Support/Telematics/Providers/SafeeProvider.php +333 -0
- package/server/src/Tracking/TrackingContextBuilder.php +41 -38
- package/server/src/Tracking/TrackingIntelligenceService.php +109 -9
- package/server/src/Tracking/TrackingStop.php +13 -11
- package/server/src/routes.php +50 -0
- package/server/tests/AnalyticsRoutesTest.php +41 -0
- package/server/tests/CapacityAllocationEngineTest.php +10 -10
- package/server/tests/CustomerContactIdentitySafetyTest.php +54 -0
- package/server/tests/CustomerEndpointTest.php +199 -0
- package/server/tests/DriverVehicleStatusDefaultTest.php +39 -0
- package/server/tests/LabelPdfRenderingTest.php +23 -0
- package/server/tests/LiveControllerViewportTest.php +60 -0
- package/server/tests/MetricsRegistryTest.php +84 -0
- package/server/tests/OrchestrationPayloadBuilderTest.php +2 -2
- package/server/tests/OrderConfigEndpointTest.php +86 -0
- package/server/tests/OrderFileAttachmentTest.php +20 -0
- package/server/tests/ServiceAreaZoneApiShapeTest.php +34 -0
- package/server/tests/VehicleDriverAssignmentTest.php +18 -0
- package/server/tests/VroomOrchestrationEngineTest.php +91 -0
- package/translations/en-us.yaml +38 -0
- package/server/migrations/2026_05_13_000001_repair_customer_contact_user_types.php +0 -86
|
@@ -335,7 +335,7 @@
|
|
|
335
335
|
{{#each serviceQuote.items as |item|}}
|
|
336
336
|
<tr>
|
|
337
337
|
<td>
|
|
338
|
-
<span class="font-semibold">{{
|
|
338
|
+
<span class="font-semibold">{{item.details}}</span>
|
|
339
339
|
</td>
|
|
340
340
|
<td>
|
|
341
341
|
<span>{{format-currency item.amount serviceQuote.currency}}</span>
|
|
@@ -449,4 +449,4 @@
|
|
|
449
449
|
|
|
450
450
|
<Spacer @height="300px" />
|
|
451
451
|
</Overlay::Body>
|
|
452
|
-
</Overlay>
|
|
452
|
+
</Overlay>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
@modelName="user"
|
|
7
7
|
@selectedModel={{@resource.user}}
|
|
8
8
|
@placeholder={{t "customer.fields.select-user"}}
|
|
9
|
-
@query={{hash doesnt_have_contact=true}}
|
|
9
|
+
@query={{hash doesnt_have_contact=true is_customer=true}}
|
|
10
10
|
@triggerClass="form-select form-input"
|
|
11
11
|
@infiniteScroll={{false}}
|
|
12
12
|
@renderInPlace={{true}}
|
|
@@ -141,4 +141,4 @@
|
|
|
141
141
|
<RegistryYield @registry="fleet-ops:component:customer:form" as |RegistryComponent|>
|
|
142
142
|
<RegistryComponent @resource={{@resource}} @controller={{@controller}} @permission={{get-write-permission @resource}} />
|
|
143
143
|
</RegistryYield>
|
|
144
|
-
</div>
|
|
144
|
+
</div>
|
|
@@ -351,7 +351,7 @@
|
|
|
351
351
|
{{#each serviceQuote.items as |item|}}
|
|
352
352
|
<tr>
|
|
353
353
|
<td>
|
|
354
|
-
<span class="font-semibold">{{
|
|
354
|
+
<span class="font-semibold">{{item.details}}</span>
|
|
355
355
|
</td>
|
|
356
356
|
<td>
|
|
357
357
|
<span>{{format-currency item.amount serviceQuote.currency}}</span>
|
|
@@ -473,4 +473,4 @@
|
|
|
473
473
|
|
|
474
474
|
<Spacer @height="300px" />
|
|
475
475
|
</Overlay::Body>
|
|
476
|
-
</Overlay>
|
|
476
|
+
</Overlay>
|
|
@@ -274,7 +274,7 @@
|
|
|
274
274
|
{{#each order.purchase_rate.service_quote.items as |item|}}
|
|
275
275
|
<tr>
|
|
276
276
|
<td>
|
|
277
|
-
<span class="font-semibold">{{
|
|
277
|
+
<span class="font-semibold">{{item.details}}</span>
|
|
278
278
|
</td>
|
|
279
279
|
<td>
|
|
280
280
|
<div class="flex flex-row items-center justify-end">{{format-currency
|
|
@@ -320,4 +320,4 @@
|
|
|
320
320
|
</div>
|
|
321
321
|
<div id="customer-portal-content-wormhole"></div>
|
|
322
322
|
{{/let}}
|
|
323
|
-
</div>
|
|
323
|
+
</div>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<div class="next-dd-menu-seperator"></div>
|
|
32
32
|
{{#each-in @waypointActions as |actionId action|}}
|
|
33
33
|
<div class="px-1">
|
|
34
|
-
<a href="javascript:;" class="next-dd-item" disabled={{cannot "fleet-ops view order"}} {{on "click" (dropdown-fn dd action.fn this.place)}}>
|
|
34
|
+
<a href="javascript:;" class="next-dd-item" disabled={{cannot "fleet-ops view order"}} {{on "click" (dropdown-fn dd action.fn (or @waypointActionContext this.place))}}>
|
|
35
35
|
{{action.label}}
|
|
36
36
|
</a>
|
|
37
37
|
</div>
|
|
@@ -65,4 +65,4 @@
|
|
|
65
65
|
{{/if}}
|
|
66
66
|
</address>
|
|
67
67
|
{{/if}}
|
|
68
|
-
</div>
|
|
68
|
+
</div>
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
<div class="field-name">{{t "driver.fields.driver-license"}}</div>
|
|
31
31
|
<div class="field-value">{{n-a @resource.drivers_license_number}}</div>
|
|
32
32
|
</div>
|
|
33
|
+
<div class="field-info-container">
|
|
34
|
+
<div class="field-name">{{t "driver.fields.license-expiry"}}</div>
|
|
35
|
+
<div class="field-value">{{n-a @resource.license_expiry}}</div>
|
|
36
|
+
</div>
|
|
33
37
|
<div class="field-info-container">
|
|
34
38
|
<div class="field-name">{{t "resource.vendor"}}</div>
|
|
35
39
|
<div class="field-value">{{n-a @resource.vendor_name}}</div>
|
|
@@ -92,4 +96,4 @@
|
|
|
92
96
|
>
|
|
93
97
|
<MetadataViewer @metadata={{@resource.meta}} />
|
|
94
98
|
</ContentPanel>
|
|
95
|
-
</div>
|
|
99
|
+
</div>
|
|
@@ -93,6 +93,16 @@
|
|
|
93
93
|
/>
|
|
94
94
|
</InputGroup>
|
|
95
95
|
|
|
96
|
+
<InputGroup @name={{t "driver.fields.license-expiry"}}>
|
|
97
|
+
<DatePicker
|
|
98
|
+
@value={{@resource.license_expiry}}
|
|
99
|
+
@onChange={{fn (mut @resource.license_expiry)}}
|
|
100
|
+
@placeholder={{t "driver.fields.license-expiry"}}
|
|
101
|
+
@disabled={{cannot-write @resource}}
|
|
102
|
+
class="w-full form-input"
|
|
103
|
+
/>
|
|
104
|
+
</InputGroup>
|
|
105
|
+
|
|
96
106
|
<InputGroup @name={{t "driver.fields.vendor"}}>
|
|
97
107
|
<ModelSelect
|
|
98
108
|
@modelName="vendor"
|
|
@@ -221,4 +231,4 @@
|
|
|
221
231
|
<ContentPanel @title={{t "common.metadata"}} @open={{true}} @wrapperClass="bordered-top">
|
|
222
232
|
<MetadataEditor @value={{@resource.meta}} @onChange={{fn (mut @resource.meta)}} />
|
|
223
233
|
</ContentPanel>
|
|
224
|
-
</div>
|
|
234
|
+
</div>
|
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
@dropdownButtonIcon={{@itemDropdownButtonIcon}}
|
|
37
37
|
@dropdownButtonIconPrefix={{@itemDropdownButtonIconPrefix}}
|
|
38
38
|
@dropdownButtonText={{@itemDropdownButtonText}}
|
|
39
|
-
@dropdownButtonCalculatePosition={{
|
|
39
|
+
@dropdownButtonCalculatePosition={{this.calculateDropdownItemPosition}}
|
|
40
40
|
@dropdownButtonMenuLabel={{vehicle.displayName}}
|
|
41
41
|
@dropdownButtonWrapperClass={{@itemDropdownButtonWrapperClass}}
|
|
42
42
|
@dropdownButtonTriggerClass={{@itemDropdownButtonTriggerClass}}
|
|
43
43
|
@registerDropdownButtonAPI={{@itemRegisterDropdownButtonAPI}}
|
|
44
|
-
@permission="fleet-ops view vehicle"
|
|
45
44
|
@dropdownButtonRenderInPlace={{false}}
|
|
45
|
+
@permission="fleet-ops view vehicle"
|
|
46
46
|
>{{vehicle.displayName}}</Layout::Sidebar::Item>
|
|
47
47
|
{{/each}}
|
|
48
48
|
</Layout::Sidebar::Panel>
|
|
@@ -31,4 +31,14 @@ export default class FleetListingPanelComponent extends Component {
|
|
|
31
31
|
this.args.onVehicleClicked(vehicle);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
@action calculateDropdownItemPosition(trigger) {
|
|
36
|
+
let { top, left, width } = trigger.getBoundingClientRect();
|
|
37
|
+
let style = {
|
|
38
|
+
left: 11 + left + width,
|
|
39
|
+
top: top + 2,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return { style };
|
|
43
|
+
}
|
|
34
44
|
}
|
|
@@ -6,73 +6,7 @@ import { action } from '@ember/object';
|
|
|
6
6
|
import { isArray } from '@ember/array';
|
|
7
7
|
import { debug } from '@ember/debug';
|
|
8
8
|
import { guidFor } from '@ember/object/internals';
|
|
9
|
-
|
|
10
|
-
function buildDriverInfoWindowContent(driver) {
|
|
11
|
-
return `
|
|
12
|
-
<div class="fleetops-google-popover fleetops-google-popover--compact">
|
|
13
|
-
<div class="fleetops-google-popover__row">
|
|
14
|
-
<img src="${driver.photoUrl ?? ''}" alt="${driver.name ?? ''}" class="fleetops-google-popover__avatar" />
|
|
15
|
-
<div class="fleetops-google-popover__body">
|
|
16
|
-
<div class="fleetops-google-popover__title">${driver.name ?? '-'}</div>
|
|
17
|
-
<div class="fleetops-google-popover__meta">Phone: ${driver.phone ?? '-'}</div>
|
|
18
|
-
<div class="fleetops-google-popover__meta">Vehicle: ${driver.vehicle_name ?? '-'}</div>
|
|
19
|
-
<div class="fleetops-google-popover__meta">Status:
|
|
20
|
-
<span class="${driver.online ? 'text-green-500' : 'text-red-400'}">${driver.online ? 'Online' : 'Offline'}</span>
|
|
21
|
-
</div>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
</div>`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function buildDriverTooltipContent(driver) {
|
|
28
|
-
return `
|
|
29
|
-
<div class="fleetops-google-hover-tooltip__title">${driver.name ?? '-'}</div>
|
|
30
|
-
<div class="fleetops-google-hover-tooltip__meta ${driver.online ? 'text-green-400' : 'text-red-400'}">${driver.online ? 'Online' : 'Offline'}</div>
|
|
31
|
-
`;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function buildVehicleInfoWindowContent(vehicle) {
|
|
35
|
-
return `
|
|
36
|
-
<div class="fleetops-google-popover">
|
|
37
|
-
<div class="fleetops-google-popover__row">
|
|
38
|
-
<img src="${vehicle.photo_url ?? ''}" alt="${vehicle.display_name ?? ''}" class="fleetops-google-popover__vehicle" />
|
|
39
|
-
<div class="fleetops-google-popover__body">
|
|
40
|
-
<div class="fleetops-google-popover__title">${vehicle.displayName ?? '-'}</div>
|
|
41
|
-
<div class="fleetops-google-popover__meta">ID: ${vehicle.public_id ?? '-'}</div>
|
|
42
|
-
<div class="fleetops-google-popover__meta">Serial: ${vehicle.serial_number ?? vehicle.vin ?? '-'}</div>
|
|
43
|
-
<div class="fleetops-google-popover__meta">Driver: ${vehicle.driver_name ?? '-'}</div>
|
|
44
|
-
<div class="fleetops-google-popover__meta">Status:
|
|
45
|
-
<span class="${vehicle.online ? 'text-green-500' : 'text-red-400'}">${vehicle.online ? 'Online' : 'Offline'}</span>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
</div>`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function buildVehicleTooltipContent(vehicle) {
|
|
53
|
-
return `
|
|
54
|
-
<div class="fleetops-google-hover-tooltip__title">${vehicle.displayName ?? '-'}</div>
|
|
55
|
-
<div class="fleetops-google-hover-tooltip__meta">ID: ${vehicle.public_id ?? '-'}</div>
|
|
56
|
-
<div class="fleetops-google-hover-tooltip__meta ${vehicle.online ? 'text-green-400' : 'text-red-400'}">${vehicle.online ? 'Online' : 'Offline'}</div>
|
|
57
|
-
`;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function buildPlaceInfoWindowContent(place) {
|
|
61
|
-
return `
|
|
62
|
-
<div class="fleetops-google-popover fleetops-google-popover--compact">
|
|
63
|
-
<div class="fleetops-google-popover__body">
|
|
64
|
-
<div class="fleetops-google-popover__title">${place.name ?? place.address ?? '-'}</div>
|
|
65
|
-
<div class="fleetops-google-popover__meta">${place.address ?? ''}</div>
|
|
66
|
-
</div>
|
|
67
|
-
</div>`;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function buildPlaceTooltipContent(place) {
|
|
71
|
-
return `
|
|
72
|
-
<div class="fleetops-google-hover-tooltip__title">${place.name ?? place.address ?? '-'}</div>
|
|
73
|
-
<div class="fleetops-google-hover-tooltip__meta">${place.address ?? ''}</div>
|
|
74
|
-
`;
|
|
75
|
-
}
|
|
9
|
+
import { buildDriverLiveMapContent, buildPlaceInfoWindowContent, buildPlaceTooltipContent, buildVehicleLiveMapContent } from '../../utils/live-map-card-content';
|
|
76
10
|
|
|
77
11
|
export default class MapGoogleLiveMapComponent extends Component {
|
|
78
12
|
@service mapManager;
|
|
@@ -100,6 +34,7 @@ export default class MapGoogleLiveMapComponent extends Component {
|
|
|
100
34
|
|
|
101
35
|
this.map = map;
|
|
102
36
|
this.mapManager.on('moveend', () => this.args.onViewportChanged?.());
|
|
37
|
+
this.mapManager.on('click', () => this._closeAllInfoWindows());
|
|
103
38
|
this.mapManager.on('rightclick', (event) => this._showMapContextMenu(event));
|
|
104
39
|
this.args.onLoad?.({ target: map });
|
|
105
40
|
this.syncResources();
|
|
@@ -125,12 +60,12 @@ export default class MapGoogleLiveMapComponent extends Component {
|
|
|
125
60
|
if (!marker) {
|
|
126
61
|
const createdMarker = await this.mapManager.addMarker(driver.id, coords.lat, coords.lng, {
|
|
127
62
|
iconUrl: driver.vehicle_avatar ?? '/engines-dist/images/driver-marker.png',
|
|
128
|
-
iconSize: [
|
|
63
|
+
iconSize: [20, 20],
|
|
129
64
|
title: driver.name,
|
|
130
|
-
tooltip:
|
|
65
|
+
tooltip: buildDriverLiveMapContent(driver),
|
|
131
66
|
tooltipOptions: { html: true },
|
|
132
67
|
rotationAngle: driver.heading,
|
|
133
|
-
onClick: () => this.#openInfoWindow(`driver:${driver.id}`,
|
|
68
|
+
onClick: () => this.#openInfoWindow(`driver:${driver.id}`, buildDriverLiveMapContent(driver, true), driver.id, () => this.args.onDriverClicked?.(driver)),
|
|
134
69
|
onRightClick: (event) => this._showDriverContextMenu(driver, event),
|
|
135
70
|
});
|
|
136
71
|
|
|
@@ -155,12 +90,12 @@ export default class MapGoogleLiveMapComponent extends Component {
|
|
|
155
90
|
if (!marker) {
|
|
156
91
|
const createdMarker = await this.mapManager.addMarker(vehicle.id, coords.lat, coords.lng, {
|
|
157
92
|
iconUrl: vehicle.avatar_url ?? '/engines-dist/images/vehicle-marker.png',
|
|
158
|
-
iconSize: [
|
|
93
|
+
iconSize: [20, 20],
|
|
159
94
|
title: vehicle.displayName,
|
|
160
|
-
tooltip:
|
|
95
|
+
tooltip: buildVehicleLiveMapContent(vehicle),
|
|
161
96
|
tooltipOptions: { html: true },
|
|
162
97
|
rotationAngle: vehicle.heading,
|
|
163
|
-
onClick: () => this.#openInfoWindow(`vehicle:${vehicle.id}`,
|
|
98
|
+
onClick: () => this.#openInfoWindow(`vehicle:${vehicle.id}`, buildVehicleLiveMapContent(vehicle, true), vehicle.id, () => this.args.onVehicleClicked?.(vehicle)),
|
|
164
99
|
onRightClick: (event) => this._showVehicleContextMenu(vehicle, event),
|
|
165
100
|
});
|
|
166
101
|
|
|
@@ -308,6 +243,10 @@ export default class MapGoogleLiveMapComponent extends Component {
|
|
|
308
243
|
if (!infoWindow) {
|
|
309
244
|
infoWindow = new google.maps.InfoWindow({ content });
|
|
310
245
|
this._infoWindows.set(infoId, infoWindow);
|
|
246
|
+
|
|
247
|
+
infoWindow.addListener('domready', () => {
|
|
248
|
+
document.querySelector('[data-fleetops-google-popover-close]')?.addEventListener('click', () => infoWindow.close(), { once: true });
|
|
249
|
+
});
|
|
311
250
|
} else {
|
|
312
251
|
infoWindow.setContent(content);
|
|
313
252
|
}
|
|
@@ -337,15 +276,19 @@ export default class MapGoogleLiveMapComponent extends Component {
|
|
|
337
276
|
}
|
|
338
277
|
|
|
339
278
|
_showServiceAreaContextMenu(serviceArea, event) {
|
|
340
|
-
const items = this.mapManager.getComposedContextMenuItems(
|
|
279
|
+
const items = this.mapManager.getComposedContextMenuItems(this._resourceContextKey('service-area', serviceArea));
|
|
341
280
|
this.mapManager.showContextMenu(event, items);
|
|
342
281
|
}
|
|
343
282
|
|
|
344
283
|
_showZoneContextMenu(zone, event) {
|
|
345
|
-
const items = this.mapManager.getComposedContextMenuItems(
|
|
284
|
+
const items = this.mapManager.getComposedContextMenuItems(this._resourceContextKey('zone', zone));
|
|
346
285
|
this.mapManager.showContextMenu(event, items);
|
|
347
286
|
}
|
|
348
287
|
|
|
288
|
+
_resourceContextKey(type, resource) {
|
|
289
|
+
return `${type}:${resource?.public_id ?? resource?.id}`;
|
|
290
|
+
}
|
|
291
|
+
|
|
349
292
|
_closeAllInfoWindows() {
|
|
350
293
|
this._infoWindows.forEach((iw) => iw.close());
|
|
351
294
|
this.mapManager.closeContextMenu();
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
through the provider-agnostic MapManagerService.
|
|
14
14
|
}}
|
|
15
15
|
|
|
16
|
-
<div class="live-map-component {{@wrapperClass}}">
|
|
16
|
+
<div class="live-map-component {{@wrapperClass}}" {{did-update this.syncServiceAreaContextMenus this.serviceAreaActions.serviceAreas this.serviceAreaActions.serviceAreas.length}}>
|
|
17
17
|
|
|
18
18
|
{{#if this.shouldUseGoogleMaps}}
|
|
19
19
|
{{! ─── Google Maps branch ──────────────────────────────────────────── }}
|
|
@@ -83,27 +83,108 @@
|
|
|
83
83
|
as |marker|
|
|
84
84
|
>
|
|
85
85
|
<marker.popup @maxWidth="500" @minWidth="225">
|
|
86
|
-
<div class="
|
|
87
|
-
<div class="
|
|
88
|
-
<
|
|
86
|
+
<div class="w-[280px] max-w-[calc(100vw-2rem)] rounded-lg bg-gray-900 shadow-lg p-1.5 text-white">
|
|
87
|
+
<div class="flex items-center gap-1.5 text-xs font-semibold mb-1.5">
|
|
88
|
+
<span class="inline-block w-2 h-2 rounded-full {{if driver.online 'bg-green-400' 'bg-red-500'}}"></span>
|
|
89
|
+
<span>{{driver.name}}</span>
|
|
90
|
+
<div
|
|
91
|
+
class="status-badge
|
|
92
|
+
{{if driver.status (dasherize driver.status) 'default'}}-status-badge status-badge-{{if driver.status (dasherize driver.status) 'default'}}
|
|
93
|
+
shadow-none ml-auto"
|
|
94
|
+
>
|
|
95
|
+
<span class="rounded-full text-[9px] px-1.5 py-0.5">{{n-a driver.meta.status_label (smart-humanize driver.status)}}</span>
|
|
96
|
+
</div>
|
|
89
97
|
</div>
|
|
90
|
-
<div class="
|
|
91
|
-
<div class="
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
<div class="grid grid-cols-2 gap-1">
|
|
99
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
100
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">ID</div>
|
|
101
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.public_id driver.id}}</div>
|
|
102
|
+
</div>
|
|
103
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
104
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Phone</div>
|
|
105
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.phone}}</div>
|
|
106
|
+
</div>
|
|
107
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
108
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Vehicle</div>
|
|
109
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.vehicle_name}}</div>
|
|
110
|
+
</div>
|
|
111
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
112
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Email</div>
|
|
113
|
+
<div class="text-[11px] text-white leading-tight truncate min-w-0 w-full">{{n-a driver.email}}</div>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
116
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Order</div>
|
|
117
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.meta.current_order_reference}}</div>
|
|
118
|
+
</div>
|
|
119
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
120
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Speed</div>
|
|
121
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.meta.speed_label}}</div>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
124
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Heading</div>
|
|
125
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.meta.heading_label}}</div>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
128
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Location</div>
|
|
129
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a
|
|
130
|
+
driver.meta.location_coordinates
|
|
131
|
+
(point-coordinates driver.location)
|
|
132
|
+
}}</div>
|
|
133
|
+
</div>
|
|
97
134
|
</div>
|
|
98
135
|
</div>
|
|
99
136
|
</marker.popup>
|
|
100
137
|
<marker.tooltip @permanent={{false}} @sticky={{true}}>
|
|
101
|
-
<div class="
|
|
102
|
-
<div class="text-xs font-semibold">
|
|
103
|
-
|
|
104
|
-
|
|
138
|
+
<div class="w-[280px] max-w-[calc(100vw-2rem)]">
|
|
139
|
+
<div class="flex items-center gap-1.5 text-xs font-semibold mb-1.5">
|
|
140
|
+
<span class="inline-block w-2 h-2 rounded-full {{if driver.online 'bg-green-400' 'bg-red-500'}}"></span>
|
|
141
|
+
<span>{{driver.name}}</span>
|
|
142
|
+
<div
|
|
143
|
+
class="status-badge
|
|
144
|
+
{{if driver.status (dasherize driver.status) 'default'}}-status-badge status-badge-{{if driver.status (dasherize driver.status) 'default'}}
|
|
145
|
+
shadow-none ml-auto"
|
|
146
|
+
>
|
|
147
|
+
<span class="rounded-full text-[9px] px-1.5 py-0.5">{{n-a driver.meta.status_label (smart-humanize driver.status)}}</span>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
<div class="grid grid-cols-2 gap-1">
|
|
151
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
152
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">ID</div>
|
|
153
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.public_id driver.id}}</div>
|
|
154
|
+
</div>
|
|
155
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
156
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Phone</div>
|
|
157
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.phone}}</div>
|
|
158
|
+
</div>
|
|
159
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
160
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Vehicle</div>
|
|
161
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.vehicle_name}}</div>
|
|
162
|
+
</div>
|
|
163
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
164
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Email</div>
|
|
165
|
+
<div class="text-[11px] text-white leading-tight truncate min-w-0 w-full">{{n-a driver.email}}</div>
|
|
166
|
+
</div>
|
|
167
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
168
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Order</div>
|
|
169
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.meta.current_order_reference}}</div>
|
|
170
|
+
</div>
|
|
171
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
172
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Speed</div>
|
|
173
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.meta.speed_label}}</div>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
176
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Heading</div>
|
|
177
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a driver.meta.heading_label}}</div>
|
|
178
|
+
</div>
|
|
179
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
180
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Location</div>
|
|
181
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a
|
|
182
|
+
driver.meta.location_coordinates
|
|
183
|
+
(point-coordinates driver.location)
|
|
184
|
+
}}</div>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
105
187
|
</div>
|
|
106
|
-
<div class="text-xs truncate"><FaIcon @icon="location-dot" @size="xs" class="mr-0.5" />{{point-coordinates driver.location}}</div>
|
|
107
188
|
</marker.tooltip>
|
|
108
189
|
</layers.tracking-marker>
|
|
109
190
|
{{/each}}
|
|
@@ -121,29 +202,98 @@
|
|
|
121
202
|
as |marker|
|
|
122
203
|
>
|
|
123
204
|
<marker.popup @permanent={{false}} @sticky={{true}}>
|
|
124
|
-
<div class="
|
|
125
|
-
<div class="
|
|
126
|
-
<
|
|
205
|
+
<div class="w-[280px] max-w-[calc(100vw-2rem)] rounded-lg bg-gray-900 shadow-lg p-1.5 text-white">
|
|
206
|
+
<div class="flex items-center gap-1.5 text-xs font-semibold mb-1.5">
|
|
207
|
+
<span class="inline-block w-2 h-2 rounded-full {{if vehicle.online 'bg-green-400' 'bg-red-500'}}"></span>
|
|
208
|
+
<span>{{vehicle.displayName}}</span>
|
|
209
|
+
<div
|
|
210
|
+
class="status-badge
|
|
211
|
+
{{if vehicle.status (dasherize vehicle.status) 'default'}}-status-badge status-badge-{{if vehicle.status (dasherize vehicle.status) 'default'}}
|
|
212
|
+
shadow-none ml-auto"
|
|
213
|
+
>
|
|
214
|
+
<span class="rounded-full text-[9px] px-1.5 py-0.5">{{n-a vehicle.meta.status_label}}</span>
|
|
215
|
+
</div>
|
|
127
216
|
</div>
|
|
128
|
-
<div class="
|
|
129
|
-
<div class="
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
217
|
+
<div class="grid grid-cols-2 gap-1">
|
|
218
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
219
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Vehicle #</div>
|
|
220
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a
|
|
221
|
+
vehicle.internal_id
|
|
222
|
+
vehicle.public_id
|
|
223
|
+
vehicle.plate_number
|
|
224
|
+
vehicle.serial_number
|
|
225
|
+
vehicle.vin
|
|
226
|
+
}}</div>
|
|
227
|
+
</div>
|
|
228
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
229
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Driver</div>
|
|
230
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.driver_name}}</div>
|
|
231
|
+
</div>
|
|
232
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
233
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Order</div>
|
|
234
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.current_order_reference}}</div>
|
|
235
|
+
</div>
|
|
236
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
237
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Speed</div>
|
|
238
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.speed_label}}</div>
|
|
239
|
+
</div>
|
|
240
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
241
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Heading</div>
|
|
242
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.heading_label}}</div>
|
|
243
|
+
</div>
|
|
244
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
245
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Location</div>
|
|
246
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.location_coordinates}}</div>
|
|
247
|
+
</div>
|
|
135
248
|
</div>
|
|
136
249
|
</div>
|
|
137
250
|
</marker.popup>
|
|
138
251
|
<marker.tooltip @permanent={{false}} @sticky={{true}}>
|
|
139
|
-
<div class="
|
|
140
|
-
<div class="text-xs font-semibold">
|
|
141
|
-
|
|
142
|
-
|
|
252
|
+
<div class="w-[280px] max-w-[calc(100vw-2rem)]">
|
|
253
|
+
<div class="flex items-center gap-1.5 text-xs font-semibold mb-1.5">
|
|
254
|
+
<span class="inline-block w-2 h-2 rounded-full {{if vehicle.online 'bg-green-400' 'bg-red-500'}}"></span>
|
|
255
|
+
<span>{{vehicle.displayName}}</span>
|
|
256
|
+
<div
|
|
257
|
+
class="status-badge
|
|
258
|
+
{{if vehicle.status (dasherize vehicle.status) 'default'}}-status-badge status-badge-{{if vehicle.status (dasherize vehicle.status) 'default'}}
|
|
259
|
+
shadow-none ml-auto"
|
|
260
|
+
>
|
|
261
|
+
<span class="rounded-full text-[9px] px-1.5 py-0.5">{{n-a vehicle.meta.status_label}}</span>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
<div class="grid grid-cols-2 gap-1">
|
|
265
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
266
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Vehicle #</div>
|
|
267
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a
|
|
268
|
+
vehicle.internal_id
|
|
269
|
+
vehicle.public_id
|
|
270
|
+
vehicle.plate_number
|
|
271
|
+
vehicle.serial_number
|
|
272
|
+
vehicle.vin
|
|
273
|
+
}}</div>
|
|
274
|
+
</div>
|
|
275
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
276
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Driver</div>
|
|
277
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.driver_name}}</div>
|
|
278
|
+
</div>
|
|
279
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
280
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Order</div>
|
|
281
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.current_order_reference}}</div>
|
|
282
|
+
</div>
|
|
283
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
284
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Speed</div>
|
|
285
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.speed_label}}</div>
|
|
286
|
+
</div>
|
|
287
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
288
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Heading</div>
|
|
289
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.heading_label}}</div>
|
|
290
|
+
</div>
|
|
291
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
292
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Location</div>
|
|
293
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.location_coordinates}}</div>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
143
296
|
</div>
|
|
144
|
-
<div class="text-xs">ID: {{n-a vehicle.public_id}}</div>
|
|
145
|
-
<div class="text-xs">Serial No: {{or vehicle.serial_number vehicle.vin vehicle.internal_id vehicle.id "-"}}</div>
|
|
146
|
-
<div class="text-xs truncate"><FaIcon @icon="location-dot" @size="xs" class="mr-0.5" />{{point-coordinates vehicle.location}}</div>
|
|
147
297
|
</marker.tooltip>
|
|
148
298
|
</layers.tracking-marker>
|
|
149
299
|
{{/each}}
|
|
@@ -175,8 +325,8 @@
|
|
|
175
325
|
@id={{serviceArea.id}}
|
|
176
326
|
@record={{serviceArea}}
|
|
177
327
|
@locations={{unwrap-coordinates serviceArea.leafletCoordinates}}
|
|
178
|
-
@fillColor={{serviceArea.color}}
|
|
179
|
-
@color={{serviceArea.stroke_color}}
|
|
328
|
+
@fillColor={{or serviceArea.color "#3388ff"}}
|
|
329
|
+
@color={{or serviceArea.stroke_color serviceArea.color "#3388ff"}}
|
|
180
330
|
@onAdd={{fn this.trigger "onServiceAreaLayerAdded" serviceArea}}
|
|
181
331
|
as |polygon|
|
|
182
332
|
>
|
|
@@ -188,8 +338,8 @@
|
|
|
188
338
|
@id={{zone.id}}
|
|
189
339
|
@record={{zone}}
|
|
190
340
|
@locations={{unwrap-coordinates zone.leafletCoordinates}}
|
|
191
|
-
@fillColor={{zone.color}}
|
|
192
|
-
@color={{zone.stroke_color}}
|
|
341
|
+
@fillColor={{or zone.color "#3388ff"}}
|
|
342
|
+
@color={{or zone.stroke_color zone.color "#3388ff"}}
|
|
193
343
|
@onAdd={{fn this.trigger "onZoneLayerAdd" zone}}
|
|
194
344
|
as |polygon|
|
|
195
345
|
>
|