@fleetbase/fleetops-engine 0.6.69 → 0.6.71
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/RELEASE.md +21 -14
- package/addon/components/admin/telematics-settings.hbs +143 -0
- package/addon/components/admin/telematics-settings.js +145 -0
- package/addon/components/fuel-integration/hub.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +37 -17
- package/addon/components/map/leaflet-live-map.hbs +4 -242
- package/addon/components/map/leaflet-live-map.js +2 -1
- package/addon/components/map/marker-card/driver.hbs +57 -0
- package/addon/components/map/marker-card/driver.js +3 -0
- package/addon/components/map/marker-card/vehicle.hbs +78 -0
- package/addon/components/map/marker-card/vehicle.js +3 -0
- package/addon/components/order/details/activity.hbs +8 -6
- package/addon/components/order/details/activity.js +9 -0
- package/addon/components/order/details.hbs +29 -0
- package/addon/components/order/details.js +26 -0
- package/addon/components/order/form/details.hbs +30 -4
- package/addon/components/order/form/details.js +46 -0
- package/addon/components/order/form/route.hbs +4 -2
- package/addon/components/order/form/route.js +11 -0
- package/addon/components/order/form.hbs +12 -0
- package/addon/components/order/form.js +21 -1
- package/addon/components/order/kanban.js +72 -0
- package/addon/components/order-config-manager/activity-flow.js +45 -10
- package/addon/components/order-config-manager/lifecycle.hbs +250 -0
- package/addon/components/order-config-manager/lifecycle.js +358 -0
- package/addon/components/order-config-manager.js +5 -1
- package/addon/components/telematic/hub.hbs +1 -1
- package/addon/components/widget/live-fleet.hbs +8 -40
- package/addon/controllers/analytics/reports/index.js +15 -1
- package/addon/controllers/connectivity/devices/index/details.js +1 -0
- package/addon/controllers/connectivity/devices/index.js +12 -2
- package/addon/controllers/connectivity/events/index.js +31 -1
- package/addon/controllers/connectivity/fuel-providers/index.js +6 -4
- package/addon/controllers/connectivity/sensors/index/details.js +1 -1
- package/addon/controllers/connectivity/sensors/index.js +41 -1
- package/addon/controllers/connectivity/telematics/index.js +4 -0
- package/addon/controllers/maintenance/equipment/index/details.js +2 -2
- package/addon/controllers/maintenance/equipment/index.js +36 -10
- package/addon/controllers/maintenance/inspection-forms/index.js +32 -12
- package/addon/controllers/maintenance/inspection-submissions/index/details.js +2 -1
- package/addon/controllers/maintenance/inspection-submissions/index.js +56 -10
- package/addon/controllers/maintenance/maintenances/index/details.js +2 -0
- package/addon/controllers/maintenance/maintenances/index.js +24 -1
- package/addon/controllers/maintenance/parts/index/details.js +2 -2
- package/addon/controllers/maintenance/parts/index.js +36 -9
- package/addon/controllers/maintenance/schedules/index.js +48 -6
- package/addon/controllers/maintenance/work-orders/index/details.js +3 -3
- package/addon/controllers/maintenance/work-orders/index.js +47 -9
- package/addon/controllers/management/contacts/customers.js +13 -0
- package/addon/controllers/management/contacts/index.js +47 -1
- package/addon/controllers/management/drivers/index/details.js +1 -0
- package/addon/controllers/management/drivers/index.js +36 -2
- package/addon/controllers/management/fleets/index/details.js +1 -0
- package/addon/controllers/management/fleets/index.js +43 -1
- package/addon/controllers/management/fuel-reports/index.js +26 -2
- package/addon/controllers/management/fuel-transactions/index.js +45 -7
- package/addon/controllers/management/issues/index/details.js +1 -0
- package/addon/controllers/management/issues/index.js +26 -2
- package/addon/controllers/management/places/index.js +40 -1
- package/addon/controllers/management/trailers/index/details.js +1 -0
- package/addon/controllers/management/trailers/index.js +50 -2
- package/addon/controllers/management/vehicles/index/details.js +1 -0
- package/addon/controllers/management/vehicles/index.js +37 -2
- package/addon/controllers/management/vendors/index.js +30 -2
- package/addon/controllers/operations/orders/index/details.js +61 -5
- package/addon/controllers/operations/orders/index.js +66 -4
- package/addon/controllers/operations/service-rates/index.js +18 -1
- package/addon/controllers/settings/index.js +13 -0
- package/addon/controllers/settings/telematics.js +113 -0
- package/addon/extension.js +70 -6
- package/addon/routes/analytics/index.js +14 -1
- package/addon/routes/analytics/reports/index/details.js +1 -1
- package/addon/routes/analytics/reports/index/edit.js +1 -1
- package/addon/routes/analytics/reports/index/new.js +14 -1
- package/addon/routes/analytics/reports.js +14 -1
- package/addon/routes/connectivity/devices/index/new.js +14 -1
- package/addon/routes/connectivity/devices.js +14 -1
- package/addon/routes/connectivity/events.js +14 -1
- package/addon/routes/connectivity/fuel-providers/details/transactions.js +12 -0
- package/addon/routes/connectivity/fuel-providers/details.js +9 -0
- package/addon/routes/connectivity/fuel-providers/edit.js +9 -0
- package/addon/routes/connectivity/fuel-providers/new.js +14 -1
- package/addon/routes/connectivity/fuel-providers.js +14 -1
- package/addon/routes/connectivity/sensors/index/new.js +14 -1
- package/addon/routes/connectivity/sensors.js +14 -1
- package/addon/routes/connectivity/telematics/new.js +14 -1
- package/addon/routes/connectivity/telematics.js +14 -1
- package/addon/routes/connectivity/tracking.js +14 -1
- package/addon/routes/maintenance/equipment/index/details.js +2 -2
- package/addon/routes/maintenance/equipment/index/edit.js +2 -2
- package/addon/routes/maintenance/equipment/index/new.js +14 -1
- package/addon/routes/maintenance/equipment.js +14 -1
- package/addon/routes/maintenance/index.js +14 -1
- package/addon/routes/maintenance/inspection-forms/index/details.js +10 -1
- package/addon/routes/maintenance/inspection-forms/index/edit.js +10 -1
- package/addon/routes/maintenance/inspection-forms/index/new.js +14 -1
- package/addon/routes/maintenance/inspection-forms.js +14 -1
- package/addon/routes/maintenance/inspection-submissions/index/details.js +10 -1
- package/addon/routes/maintenance/inspection-submissions/index/edit.js +10 -1
- package/addon/routes/maintenance/inspection-submissions/index/new.js +14 -1
- package/addon/routes/maintenance/inspection-submissions.js +14 -1
- package/addon/routes/maintenance/maintenances/index/details.js +2 -2
- package/addon/routes/maintenance/maintenances/index/edit.js +2 -2
- package/addon/routes/maintenance/maintenances/index/new.js +14 -1
- package/addon/routes/maintenance/maintenances.js +14 -1
- package/addon/routes/maintenance/parts/index/details.js +2 -2
- package/addon/routes/maintenance/parts/index/edit.js +2 -2
- package/addon/routes/maintenance/parts/index/new.js +14 -1
- package/addon/routes/maintenance/parts.js +14 -1
- package/addon/routes/maintenance/schedules/index/details.js +2 -2
- package/addon/routes/maintenance/schedules/index/edit.js +2 -2
- package/addon/routes/maintenance/schedules/index/new.js +15 -1
- package/addon/routes/maintenance/schedules.js +15 -1
- package/addon/routes/maintenance/work-orders/index/details.js +2 -2
- package/addon/routes/maintenance/work-orders/index/edit.js +2 -2
- package/addon/routes/maintenance/work-orders/index/new.js +14 -1
- package/addon/routes/maintenance/work-orders.js +14 -1
- package/addon/routes/management/fuel-transactions/index/details.js +9 -0
- package/addon/routes/management/fuel-transactions.js +14 -1
- package/addon/routes/management/index.js +13 -0
- package/addon/routes/management/trailers.js +16 -0
- package/addon/routes/management/vendors/integrated/details.js +14 -1
- package/addon/routes/management/vendors/integrated/edit.js +14 -1
- package/addon/routes/management/vendors/integrated/new.js +14 -1
- package/addon/routes/management/vendors/integrated.js +14 -1
- package/addon/routes/operations/orders/index/details.js +1 -0
- package/addon/routes/operations/orders.js +40 -1
- package/addon/routes/operations/routes/index/details.js +14 -1
- package/addon/routes/operations/routes/index/new.js +13 -0
- package/addon/routes/operations/routes.js +14 -1
- package/addon/routes/operations/service-rates/index/new.js +11 -0
- package/addon/routes/operations/service-rates.js +14 -1
- package/addon/routes/settings/avatars.js +14 -1
- package/addon/routes/settings/custom-fields.js +14 -1
- package/addon/routes/settings/map.js +14 -1
- package/addon/routes/settings/notifications.js +11 -0
- package/addon/routes/settings/orchestrator.js +1 -1
- package/addon/routes/settings/payments/index.js +1 -1
- package/addon/routes/settings/routing.js +14 -1
- package/addon/routes/settings/scheduling.js +14 -1
- package/addon/routes/settings/telematics.js +21 -0
- package/addon/routes/virtual.js +11 -0
- package/addon/routes.js +1 -0
- package/addon/services/contact-actions.js +1 -0
- package/addon/services/customer-actions.js +2 -1
- package/addon/services/device-actions.js +1 -0
- package/addon/services/device-event-actions.js +1 -0
- package/addon/services/driver-actions.js +4 -13
- package/addon/services/equipment-actions.js +1 -0
- package/addon/services/fleet-actions.js +1 -0
- package/addon/services/fuel-report-actions.js +1 -0
- package/addon/services/inspection-form-actions.js +1 -0
- package/addon/services/inspection-submission-actions.js +1 -0
- package/addon/services/integrated-vendor-actions.js +1 -0
- package/addon/services/issue-actions.js +1 -0
- package/addon/services/maintenance-actions.js +1 -0
- package/addon/services/maintenance-schedule-actions.js +2 -1
- package/addon/services/order-actions.js +7 -0
- package/addon/services/order-presentation.js +129 -0
- package/addon/services/part-actions.js +1 -0
- package/addon/services/place-actions.js +1 -0
- package/addon/services/sensor-actions.js +1 -0
- package/addon/services/service-area-actions.js +1 -0
- package/addon/services/service-rate-actions.js +1 -0
- package/addon/services/telematic-actions.js +1 -0
- package/addon/services/trailer-actions.js +4 -14
- package/addon/services/vehicle-actions.js +4 -13
- package/addon/services/vendor-actions.js +1 -0
- package/addon/services/work-order-actions.js +1 -0
- package/addon/services/zone-actions.js +1 -0
- package/addon/templates/analytics/reports/index/details.hbs +1 -0
- package/addon/templates/analytics/reports/index.hbs +1 -0
- package/addon/templates/connectivity/devices/index/details.hbs +1 -0
- package/addon/templates/connectivity/devices/index.hbs +1 -0
- package/addon/templates/connectivity/events/index.hbs +1 -0
- package/addon/templates/connectivity/sensors/index/details.hbs +1 -0
- package/addon/templates/connectivity/sensors/index.hbs +1 -0
- package/addon/templates/maintenance/equipment/index/details.hbs +1 -0
- package/addon/templates/maintenance/equipment/index.hbs +2 -0
- package/addon/templates/maintenance/inspection-forms/index/details.hbs +1 -0
- package/addon/templates/maintenance/inspection-forms/index.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index/details.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index.hbs +1 -0
- package/addon/templates/maintenance/maintenances/index/details.hbs +1 -0
- package/addon/templates/maintenance/maintenances/index.hbs +1 -0
- package/addon/templates/maintenance/parts/index/details.hbs +1 -0
- package/addon/templates/maintenance/parts/index.hbs +2 -0
- package/addon/templates/maintenance/schedules/index/details.hbs +1 -0
- package/addon/templates/maintenance/schedules/index.hbs +2 -0
- package/addon/templates/maintenance/work-orders/index/details.hbs +1 -0
- package/addon/templates/maintenance/work-orders/index.hbs +1 -0
- package/addon/templates/management/contacts/customers/details.hbs +1 -0
- package/addon/templates/management/contacts/customers.hbs +1 -0
- package/addon/templates/management/contacts/index/details.hbs +1 -0
- package/addon/templates/management/contacts/index.hbs +1 -0
- package/addon/templates/management/contacts.hbs +1 -0
- package/addon/templates/management/drivers/index/details.hbs +1 -0
- package/addon/templates/management/drivers/index.hbs +2 -0
- package/addon/templates/management/fleets/index/details.hbs +1 -0
- package/addon/templates/management/fleets/index.hbs +1 -0
- package/addon/templates/management/fuel-reports/index/details.hbs +1 -0
- package/addon/templates/management/fuel-reports/index.hbs +1 -0
- package/addon/templates/management/fuel-transactions/index.hbs +1 -0
- package/addon/templates/management/issues/index/details.hbs +1 -0
- package/addon/templates/management/issues/index.hbs +1 -0
- package/addon/templates/management/places/index/details.hbs +1 -0
- package/addon/templates/management/places/index.hbs +1 -0
- package/addon/templates/management/trailers/index/details.hbs +1 -0
- package/addon/templates/management/trailers/index.hbs +2 -0
- package/addon/templates/management/vehicles/index/details.hbs +1 -0
- package/addon/templates/management/vehicles/index.hbs +2 -0
- package/addon/templates/management/vendors/index/details.hbs +1 -0
- package/addon/templates/management/vendors/index.hbs +2 -0
- package/addon/templates/management/vendors/integrated.hbs +1 -0
- package/addon/templates/operations/orders/index/details.hbs +1 -0
- package/addon/templates/operations/orders/index.hbs +1 -0
- package/addon/templates/operations/service-rates/index/details.hbs +1 -0
- package/addon/templates/operations/service-rates/index.hbs +1 -0
- package/addon/templates/settings/telematics.hbs +70 -0
- package/addon/utils/normalize-order-config-flow.js +6 -1
- package/app/components/admin/telematics-settings.js +1 -0
- package/app/components/map/marker-card/driver.js +1 -0
- package/app/components/map/marker-card/vehicle.js +1 -0
- package/app/controllers/settings/telematics.js +1 -0
- package/app/routes/settings/telematics.js +1 -0
- package/app/services/order-presentation.js +1 -0
- package/app/templates/settings/telematics.js +1 -0
- package/composer.json +2 -2
- package/docs/AFAQY.md +1 -1
- package/docs/TELEMATICS_QUEUES.md +1 -1
- package/docs/TELEMETRY_ARCHITECTURE.md +72 -1
- package/extension.json +1 -1
- package/package.json +3 -3
- package/server/config/telemetry.php +12 -0
- package/server/migrations/2026_09_23_000001_add_retention_index_to_device_events.php +40 -0
- package/server/migrations/2026_09_23_000002_add_retention_index_to_positions.php +40 -0
- package/server/migrations/2026_09_23_000003_add_retention_index_to_telematic_sync_runs.php +40 -0
- package/server/src/Auth/Schemas/FleetOps.php +104 -5
- package/server/src/Console/Commands/DrainTelematicInbox.php +3 -13
- package/server/src/Console/Commands/ProcessOperationalAlerts.php +3 -3
- package/server/src/Console/Commands/PruneTelematicsData.php +318 -0
- package/server/src/Http/Controllers/Api/v1/OrchestrationController.php +9 -0
- package/server/src/Http/Controllers/FleetOpsController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/CustomerController.php +14 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +22 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderTransactionController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/FuelReportController.php +9 -3
- package/server/src/Http/Controllers/Internal/v1/InspectionFormController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +16 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/ManifestController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/MetricsController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +42 -1
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +12 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +56 -4
- package/server/src/Http/Controllers/Internal/v1/PaymentController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/RadarController.php +19 -0
- package/server/src/Http/Controllers/Internal/v1/ServiceAreaController.php +9 -3
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +465 -14
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/TrailerController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/VendorController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +11 -0
- package/server/src/Jobs/DispatchTelematicsRetentionJobs.php +70 -0
- package/server/src/Jobs/PruneTelematicsDataJob.php +74 -0
- package/server/src/Listeners/NotifyDriverOnShiftChange.php +3 -3
- package/server/src/Mail/CustomerCredentialsMail.php +1 -1
- package/server/src/Models/Order.php +35 -3
- package/server/src/Models/OrderConfig.php +129 -0
- package/server/src/Models/TrackingNumber.php +8 -4
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +9 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +3 -0
- package/server/src/Support/Analytics/LiveFleet.php +18 -2
- package/server/src/Support/Authorization.php +103 -0
- package/server/src/Support/Database/TableIndexes.php +66 -0
- package/server/src/Support/OrderTracker.php +2 -2
- package/server/src/Support/Reporting/FleetOpsReportSchema.php +476 -116
- package/server/src/Support/Telematics/Retention/RetentionPolicy.php +300 -0
- package/server/src/Support/Telematics/Retention/TelemetryActivity.php +40 -0
- package/server/src/Support/Telematics/TelematicService.php +12 -2
- package/server/src/Support/Telematics/Telemetry/Ingestor.php +4 -2
- package/server/src/Tracking/TrackingIntelligenceService.php +1 -1
- package/server/src/Tracking/TrackingOptions.php +2 -2
- package/server/src/Traits/AuthorizesMethods.php +37 -0
- package/server/src/routes.php +9 -1
- package/server/tests/AnalyticsRoutesTest.php +29 -2
- package/server/tests/Feature/Http/AfaqyRealtimeIngestionTest.php +16 -1
- package/server/tests/Feature/Http/Api/TelematicsRetentionIndexMigrationTest.php +115 -0
- package/server/tests/Feature/Http/Internal/OrderControllerActivityFlowsTest.php +72 -0
- package/server/tests/Feature/Http/Internal/OrderControllerCreateRecordTest.php +26 -0
- package/server/tests/Feature/Http/Internal/SettingControllerHelpersTest.php +71 -0
- package/server/tests/Feature/Http/Internal/TelematicsStorageDeadlinesTest.php +119 -0
- package/server/tests/InternalImportExportControllerContractsTest.php +5 -8
- package/server/tests/NavigatorControllerContractsTest.php +36 -4
- package/server/tests/NotificationAndMailContractsTest.php +31 -0
- package/server/tests/ObserverContractsTest.php +1 -1
- package/server/tests/OrchestratorConsumableApiTest.php +42 -0
- package/server/tests/OrderConfigLifecycleTest.php +120 -0
- package/server/tests/ProviderContractsTest.php +10 -0
- package/server/tests/ReportSchemaContractsTest.php +120 -6
- package/server/tests/SettingControllerContractsTest.php +429 -18
- package/server/tests/SmallControllerContractsTest.php +8 -5
- package/server/tests/Support/PruneTelematicsDataProbe.php +55 -0
- package/server/tests/Unit/Console/Commands/ProcessOperationalAlertsCommandTest.php +2 -2
- package/server/tests/Unit/Console/PruneTelematicsDataCommandTest.php +353 -0
- package/server/tests/Unit/Events/OrderDispatchFailedTest.php +2 -1
- package/server/tests/Unit/Jobs/DispatchTelematicsRetentionJobsTest.php +114 -0
- package/server/tests/Unit/Jobs/PruneTelematicsDataJobTest.php +60 -0
- package/server/tests/Unit/Orchestration/VroomEngineTransportAndSettingsTest.php +20 -0
- package/server/tests/Unit/Support/Analytics/LiveFleetTest.php +6 -0
- package/server/tests/Unit/Support/AuthorizationTest.php +142 -0
- package/server/tests/Unit/Support/MaintainableAndOperationalAlertsTest.php +12 -1
- package/server/tests/Unit/Support/MoreQuerySeamsTest.php +11 -2
- package/server/tests/Unit/Support/Telematics/Retention/RetentionPolicyTest.php +190 -0
- package/server/tests/Unit/Support/Telematics/Retention/TelemetryActivityTest.php +68 -0
- package/server/tests/Unit/Tracking/TrackingOptionsCompanySettingsTest.php +109 -0
- package/translations/en-us.yaml +108 -0
|
@@ -83,108 +83,10 @@
|
|
|
83
83
|
as |marker|
|
|
84
84
|
>
|
|
85
85
|
<marker.popup @maxWidth="500" @minWidth="225">
|
|
86
|
-
<
|
|
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>
|
|
97
|
-
</div>
|
|
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>
|
|
134
|
-
</div>
|
|
135
|
-
</div>
|
|
86
|
+
<Map::MarkerCard::Driver @driver={{driver}} />
|
|
136
87
|
</marker.popup>
|
|
137
88
|
<marker.tooltip @permanent={{false}} @sticky={{true}}>
|
|
138
|
-
<
|
|
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>
|
|
187
|
-
</div>
|
|
89
|
+
<Map::MarkerCard::Driver @driver={{driver}} @variant="tooltip" />
|
|
188
90
|
</marker.tooltip>
|
|
189
91
|
</layers.tracking-marker>
|
|
190
92
|
{{/each}}
|
|
@@ -202,150 +104,10 @@
|
|
|
202
104
|
as |marker|
|
|
203
105
|
>
|
|
204
106
|
<marker.popup @permanent={{false}} @sticky={{true}}>
|
|
205
|
-
<
|
|
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>
|
|
216
|
-
</div>
|
|
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">{{t "resource.trailers"}}</div>
|
|
234
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">
|
|
235
|
-
{{#each vehicle.trailers as |trailer|}}
|
|
236
|
-
<div class="flex items-center gap-1 min-w-0">
|
|
237
|
-
<span class="inline-block w-1.5 h-1.5 rounded-full shrink-0 {{if trailer.online 'bg-green-400' 'bg-gray-500'}}"></span>
|
|
238
|
-
<span class="truncate">{{or trailer.displayName trailer.display_name trailer.name trailer.public_id}}</span>
|
|
239
|
-
</div>
|
|
240
|
-
{{else}}
|
|
241
|
-
-
|
|
242
|
-
{{/each}}
|
|
243
|
-
</div>
|
|
244
|
-
</div>
|
|
245
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
246
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">{{t "resource.devices"}}</div>
|
|
247
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">
|
|
248
|
-
{{#each vehicle.devices as |device|}}
|
|
249
|
-
<div class="flex items-center gap-1 min-w-0">
|
|
250
|
-
<span class="inline-block w-1.5 h-1.5 rounded-full shrink-0 {{if device.online 'bg-green-400' 'bg-gray-500'}}"></span>
|
|
251
|
-
<span class="truncate">{{or device.displayName device.display_name device.name device.device_id device.public_id}}</span>
|
|
252
|
-
</div>
|
|
253
|
-
{{else}}
|
|
254
|
-
-
|
|
255
|
-
{{/each}}
|
|
256
|
-
</div>
|
|
257
|
-
</div>
|
|
258
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
259
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Order</div>
|
|
260
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.current_order_reference}}</div>
|
|
261
|
-
</div>
|
|
262
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
263
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Speed</div>
|
|
264
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.speed_label}}</div>
|
|
265
|
-
</div>
|
|
266
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
267
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Heading</div>
|
|
268
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.heading_label}}</div>
|
|
269
|
-
</div>
|
|
270
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
271
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Location</div>
|
|
272
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.location_coordinates}}</div>
|
|
273
|
-
</div>
|
|
274
|
-
</div>
|
|
275
|
-
</div>
|
|
107
|
+
<Map::MarkerCard::Vehicle @vehicle={{vehicle}} />
|
|
276
108
|
</marker.popup>
|
|
277
109
|
<marker.tooltip @permanent={{false}} @sticky={{true}}>
|
|
278
|
-
<
|
|
279
|
-
<div class="flex items-center gap-1.5 text-xs font-semibold mb-1.5">
|
|
280
|
-
<span class="inline-block w-2 h-2 rounded-full {{if vehicle.online 'bg-green-400' 'bg-red-500'}}"></span>
|
|
281
|
-
<span>{{vehicle.displayName}}</span>
|
|
282
|
-
<div
|
|
283
|
-
class="status-badge
|
|
284
|
-
{{if vehicle.status (dasherize vehicle.status) 'default'}}-status-badge status-badge-{{if vehicle.status (dasherize vehicle.status) 'default'}}
|
|
285
|
-
shadow-none ml-auto"
|
|
286
|
-
>
|
|
287
|
-
<span class="rounded-full text-[9px] px-1.5 py-0.5">{{n-a vehicle.meta.status_label}}</span>
|
|
288
|
-
</div>
|
|
289
|
-
</div>
|
|
290
|
-
<div class="grid grid-cols-2 gap-1">
|
|
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">Vehicle #</div>
|
|
293
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a
|
|
294
|
-
vehicle.internal_id
|
|
295
|
-
vehicle.public_id
|
|
296
|
-
vehicle.plate_number
|
|
297
|
-
vehicle.serial_number
|
|
298
|
-
vehicle.vin
|
|
299
|
-
}}</div>
|
|
300
|
-
</div>
|
|
301
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
302
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Driver</div>
|
|
303
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.driver_name}}</div>
|
|
304
|
-
</div>
|
|
305
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
306
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">{{t "resource.trailers"}}</div>
|
|
307
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">
|
|
308
|
-
{{#each vehicle.trailers as |trailer|}}
|
|
309
|
-
<div class="flex items-center gap-1 min-w-0">
|
|
310
|
-
<span class="inline-block w-1.5 h-1.5 rounded-full shrink-0 {{if trailer.online 'bg-green-400' 'bg-gray-500'}}"></span>
|
|
311
|
-
<span class="truncate">{{or trailer.displayName trailer.display_name trailer.name trailer.public_id}}</span>
|
|
312
|
-
</div>
|
|
313
|
-
{{else}}
|
|
314
|
-
-
|
|
315
|
-
{{/each}}
|
|
316
|
-
</div>
|
|
317
|
-
</div>
|
|
318
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
319
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">{{t "resource.devices"}}</div>
|
|
320
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">
|
|
321
|
-
{{#each vehicle.devices as |device|}}
|
|
322
|
-
<div class="flex items-center gap-1 min-w-0">
|
|
323
|
-
<span class="inline-block w-1.5 h-1.5 rounded-full shrink-0 {{if device.online 'bg-green-400' 'bg-gray-500'}}"></span>
|
|
324
|
-
<span class="truncate">{{or device.displayName device.display_name device.name device.device_id device.public_id}}</span>
|
|
325
|
-
</div>
|
|
326
|
-
{{else}}
|
|
327
|
-
-
|
|
328
|
-
{{/each}}
|
|
329
|
-
</div>
|
|
330
|
-
</div>
|
|
331
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
332
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Order</div>
|
|
333
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.current_order_reference}}</div>
|
|
334
|
-
</div>
|
|
335
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
336
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Speed</div>
|
|
337
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.speed_label}}</div>
|
|
338
|
-
</div>
|
|
339
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
340
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Heading</div>
|
|
341
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.heading_label}}</div>
|
|
342
|
-
</div>
|
|
343
|
-
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
344
|
-
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Location</div>
|
|
345
|
-
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a vehicle.meta.location_coordinates}}</div>
|
|
346
|
-
</div>
|
|
347
|
-
</div>
|
|
348
|
-
</div>
|
|
110
|
+
<Map::MarkerCard::Vehicle @vehicle={{vehicle}} @variant="tooltip" />
|
|
349
111
|
</marker.tooltip>
|
|
350
112
|
</layers.tracking-marker>
|
|
351
113
|
{{/each}}
|
|
@@ -298,7 +298,8 @@ export default class MapLeafletLiveMapComponent extends Component {
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
@task *loadResource(path, options = {}) {
|
|
301
|
-
|
|
301
|
+
// Permissions use the singular resource name (e.g. `fleet-ops list vehicle`), not the plural endpoint path.
|
|
302
|
+
if (this.abilities.cannot(`fleet-ops list ${singularize(path)}`)) return [];
|
|
302
303
|
|
|
303
304
|
if (path === 'service-areas') {
|
|
304
305
|
const serviceAreas = yield this.serviceAreaActions.loadAll.perform();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{{!
|
|
2
|
+
The driver card the fleet-ops live map shows in a marker's popup and hover tooltip.
|
|
3
|
+
Shared with the dashboard's Live Fleet widget so both look the same. @driver is a driver
|
|
4
|
+
model or its index resource payload (the same attributes, plain JSON).
|
|
5
|
+
@variant: "popup" (default, a dark panel) or "tooltip" (inherits the tooltip's panel).
|
|
6
|
+
}}
|
|
7
|
+
<div class="w-[280px] max-w-[calc(100vw-2rem)] {{unless (eq @variant 'tooltip') 'rounded-lg bg-gray-900 shadow-lg p-1.5 text-white'}}" ...attributes>
|
|
8
|
+
<div class="flex items-center gap-1.5 text-xs font-semibold mb-1.5">
|
|
9
|
+
<span class="inline-block w-2 h-2 rounded-full {{if @driver.online 'bg-green-400' 'bg-red-500'}}"></span>
|
|
10
|
+
<span>{{@driver.name}}</span>
|
|
11
|
+
<div
|
|
12
|
+
class="status-badge
|
|
13
|
+
{{if @driver.status (dasherize @driver.status) 'default'}}-status-badge status-badge-{{if @driver.status (dasherize @driver.status) 'default'}}
|
|
14
|
+
shadow-none ml-auto"
|
|
15
|
+
>
|
|
16
|
+
<span class="rounded-full text-[9px] px-1.5 py-0.5">{{n-a @driver.meta.status_label (smart-humanize @driver.status)}}</span>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="grid grid-cols-2 gap-1">
|
|
20
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
21
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">ID</div>
|
|
22
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @driver.public_id @driver.id}}</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
25
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Phone</div>
|
|
26
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @driver.phone}}</div>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
29
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Vehicle</div>
|
|
30
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @driver.vehicle_name}}</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
33
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Email</div>
|
|
34
|
+
<div class="text-[11px] text-white leading-tight truncate min-w-0 w-full">{{n-a @driver.email}}</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
37
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Order</div>
|
|
38
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @driver.meta.current_order_reference}}</div>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
41
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Speed</div>
|
|
42
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @driver.meta.speed_label}}</div>
|
|
43
|
+
</div>
|
|
44
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
45
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Heading</div>
|
|
46
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @driver.meta.heading_label}}</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
49
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Location</div>
|
|
50
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a
|
|
51
|
+
@driver.meta.location_coordinates
|
|
52
|
+
(point-coordinates @driver.location)
|
|
53
|
+
}}</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{{!
|
|
2
|
+
The vehicle card the fleet-ops live map shows in a marker's popup and hover tooltip.
|
|
3
|
+
Shared with the dashboard's Live Fleet widget so both look the same. @vehicle is a vehicle
|
|
4
|
+
model or its index resource payload (the same attributes, plain JSON).
|
|
5
|
+
@variant: "popup" (default, a dark panel) or "tooltip" (inherits the tooltip's panel).
|
|
6
|
+
}}
|
|
7
|
+
<div class="w-[280px] max-w-[calc(100vw-2rem)] {{unless (eq @variant 'tooltip') 'rounded-lg bg-gray-900 shadow-lg p-1.5 text-white'}}" ...attributes>
|
|
8
|
+
<div class="flex items-center gap-1.5 text-xs font-semibold mb-1.5">
|
|
9
|
+
<span class="inline-block w-2 h-2 rounded-full {{if @vehicle.online 'bg-green-400' 'bg-red-500'}}"></span>
|
|
10
|
+
<span>{{or @vehicle.displayName @vehicle.display_name @vehicle.name}}</span>
|
|
11
|
+
<div
|
|
12
|
+
class="status-badge
|
|
13
|
+
{{if @vehicle.status (dasherize @vehicle.status) 'default'}}-status-badge status-badge-{{if @vehicle.status (dasherize @vehicle.status) 'default'}}
|
|
14
|
+
shadow-none ml-auto"
|
|
15
|
+
>
|
|
16
|
+
<span class="rounded-full text-[9px] px-1.5 py-0.5">{{n-a @vehicle.meta.status_label}}</span>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="grid grid-cols-2 gap-1">
|
|
20
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
21
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Vehicle #</div>
|
|
22
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a
|
|
23
|
+
@vehicle.internal_id
|
|
24
|
+
@vehicle.public_id
|
|
25
|
+
@vehicle.plate_number
|
|
26
|
+
@vehicle.serial_number
|
|
27
|
+
@vehicle.vin
|
|
28
|
+
}}</div>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
31
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Driver</div>
|
|
32
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @vehicle.driver_name}}</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
35
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">{{t "resource.trailers"}}</div>
|
|
36
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">
|
|
37
|
+
{{#each @vehicle.trailers as |trailer|}}
|
|
38
|
+
<div class="flex items-center gap-1 min-w-0">
|
|
39
|
+
<span class="inline-block w-1.5 h-1.5 rounded-full shrink-0 {{if trailer.online 'bg-green-400' 'bg-gray-500'}}"></span>
|
|
40
|
+
<span class="truncate">{{or trailer.displayName trailer.display_name trailer.name trailer.public_id}}</span>
|
|
41
|
+
</div>
|
|
42
|
+
{{else}}
|
|
43
|
+
-
|
|
44
|
+
{{/each}}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
48
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">{{t "resource.devices"}}</div>
|
|
49
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">
|
|
50
|
+
{{#each @vehicle.devices as |device|}}
|
|
51
|
+
<div class="flex items-center gap-1 min-w-0">
|
|
52
|
+
<span class="inline-block w-1.5 h-1.5 rounded-full shrink-0 {{if device.online 'bg-green-400' 'bg-gray-500'}}"></span>
|
|
53
|
+
<span class="truncate">{{or device.displayName device.display_name device.name device.device_id device.public_id}}</span>
|
|
54
|
+
</div>
|
|
55
|
+
{{else}}
|
|
56
|
+
-
|
|
57
|
+
{{/each}}
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
61
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Order</div>
|
|
62
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @vehicle.meta.current_order_reference}}</div>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
65
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Speed</div>
|
|
66
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @vehicle.meta.speed_label}}</div>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
69
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Heading</div>
|
|
70
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @vehicle.meta.heading_label}}</div>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="rounded bg-gray-900 shadow-md px-1.5 py-1 min-w-0">
|
|
73
|
+
<div class="text-[9px] font-semibold uppercase text-gray-400 leading-none">Location</div>
|
|
74
|
+
<div class="text-[11px] text-white leading-tight whitespace-normal break-words">{{n-a @vehicle.meta.location_coordinates}}</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
@isLoading={{or @isLoadingActivity this.loadActivity.isRunning @isLoading}}
|
|
6
6
|
@wrapperClass="bordered-top"
|
|
7
7
|
>
|
|
8
|
-
{{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
<div {{did-update this.onStatusChanged @resource.status}}>
|
|
9
|
+
{{#if (eq this.layout "timeline")}}
|
|
10
|
+
<Order::ActivityTimeline @resource={{@resource}} @activity={{this.parentOrderActivity}} />
|
|
11
|
+
{{else}}
|
|
12
|
+
<Order::ActivityList @resource={{@resource}} @activity={{this.parentOrderActivity}} />
|
|
13
|
+
{{/if}}
|
|
14
|
+
</div>
|
|
15
|
+
</ContentPanel>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
|
+
import { action } from '@ember/object';
|
|
4
5
|
import { task } from 'ember-concurrency';
|
|
5
6
|
|
|
6
7
|
export default class OrderDetailsActivityComponent extends Component {
|
|
@@ -64,6 +65,14 @@ export default class OrderDetailsActivityComponent extends Component {
|
|
|
64
65
|
];
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
/**
|
|
69
|
+
* A status change recorded outside this panel (a configured lifecycle advancing on save, an
|
|
70
|
+
* extension action, a realtime update) means new tracking statuses exist server-side.
|
|
71
|
+
*/
|
|
72
|
+
@action onStatusChanged() {
|
|
73
|
+
this.loadActivity.perform();
|
|
74
|
+
}
|
|
75
|
+
|
|
67
76
|
@task *loadActivity() {
|
|
68
77
|
if (!this.args.resource) {
|
|
69
78
|
return;
|
|
@@ -44,6 +44,35 @@
|
|
|
44
44
|
)
|
|
45
45
|
)
|
|
46
46
|
}}
|
|
47
|
+
{{else if this.profile}}
|
|
48
|
+
{{#each this.profileSections key="key" as |section|}}
|
|
49
|
+
{{#if section.native}}
|
|
50
|
+
{{#let
|
|
51
|
+
(component
|
|
52
|
+
section.componentName
|
|
53
|
+
resource=@resource
|
|
54
|
+
onChange=section.onChange
|
|
55
|
+
isLoading=@isLoading
|
|
56
|
+
isLoadingActivity=@isLoadingActivity
|
|
57
|
+
reloadToken=this.effectiveProofReloadToken
|
|
58
|
+
)
|
|
59
|
+
as |NativeSection|
|
|
60
|
+
}}
|
|
61
|
+
<NativeSection />
|
|
62
|
+
{{/let}}
|
|
63
|
+
{{else}}
|
|
64
|
+
<LazyEngineComponent @component={{section.component}} as |ProfileSection|>
|
|
65
|
+
<ProfileSection
|
|
66
|
+
@resource={{@resource}}
|
|
67
|
+
@controller={{@controller}}
|
|
68
|
+
@permission={{get-write-permission @resource}}
|
|
69
|
+
@isLoading={{@isLoading}}
|
|
70
|
+
@profile={{this.profile}}
|
|
71
|
+
@onChange={{@onDetailsChanged}}
|
|
72
|
+
/>
|
|
73
|
+
</LazyEngineComponent>
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{/each}}
|
|
47
76
|
{{else}}
|
|
48
77
|
<RegistryYield @registry="fleet-ops:component:order:details:start" as |RegistryComponent|>
|
|
49
78
|
<RegistryComponent @resource={{@resource}} @controller={{@controller}} @permission={{get-write-permission @resource}} @isLoading={{@isLoading}} />
|
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import { action } from '@ember/object';
|
|
3
3
|
import { tracked } from '@glimmer/tracking';
|
|
4
|
+
import { inject as service } from '@ember/service';
|
|
4
5
|
|
|
5
6
|
export default class OrderDetailsComponent extends Component {
|
|
7
|
+
@service orderPresentation;
|
|
6
8
|
@tracked proofReloadToken = 0;
|
|
7
9
|
|
|
8
10
|
get effectiveProofReloadToken() {
|
|
9
11
|
return `${this.args.proofReloadToken ?? 0}:${this.proofReloadToken}`;
|
|
10
12
|
}
|
|
11
13
|
|
|
14
|
+
/** The extension presentation profile applying to this order's config, if any. */
|
|
15
|
+
get profile() {
|
|
16
|
+
return this.orderPresentation.profileFor(this.args.resource);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Profile sections with the change handler each native section expects. */
|
|
20
|
+
get profileSections() {
|
|
21
|
+
const handlers = {
|
|
22
|
+
activity: this.handleActivityChanged,
|
|
23
|
+
detail: this.args.onDetailsChanged,
|
|
24
|
+
'custom-fields': this.args.onCustomFieldsChanged,
|
|
25
|
+
notes: this.args.onNotesChanged,
|
|
26
|
+
route: this.args.onRouteChanged,
|
|
27
|
+
payload: this.args.onPayloadChanged,
|
|
28
|
+
documents: this.args.onDocumentsChanged,
|
|
29
|
+
comments: this.args.onCommentsChanged,
|
|
30
|
+
metadata: this.args.onMetadataChanged,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return this.orderPresentation.renderableSectionsFor(this.profile, 'details').map((section) => {
|
|
34
|
+
return section.native ? { ...section, onChange: handlers[section.name] } : section;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
12
38
|
@action handleActivityChanged(optionsOrActivity) {
|
|
13
39
|
if (typeof this.args.onActivityChanged === 'function') {
|
|
14
40
|
this.args.onActivityChanged(optionsOrActivity?.activityCreated ?? optionsOrActivity);
|