@fleetbase/fleetops-engine 0.6.69 → 0.6.70
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 +41 -8
- 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/telematic/hub.hbs +1 -1
- package/addon/components/widget/live-fleet.hbs +8 -40
- package/addon/controllers/analytics/reports/index.js +5 -0
- package/addon/controllers/connectivity/devices/index.js +4 -0
- package/addon/controllers/connectivity/fuel-providers/index.js +6 -4
- package/addon/controllers/connectivity/sensors/index.js +4 -0
- package/addon/controllers/connectivity/telematics/index.js +4 -0
- package/addon/controllers/maintenance/equipment/index.js +11 -4
- package/addon/controllers/maintenance/inspection-forms/index.js +2 -2
- package/addon/controllers/maintenance/inspection-submissions/index.js +8 -2
- package/addon/controllers/maintenance/maintenances/index.js +4 -0
- package/addon/controllers/maintenance/parts/index.js +11 -4
- package/addon/controllers/maintenance/schedules/index.js +17 -4
- package/addon/controllers/maintenance/work-orders/index.js +11 -4
- package/addon/controllers/management/contacts/index.js +4 -0
- package/addon/controllers/management/drivers/index.js +4 -0
- package/addon/controllers/management/fleets/index.js +4 -0
- package/addon/controllers/management/fuel-reports/index.js +4 -0
- package/addon/controllers/management/fuel-transactions/index.js +9 -7
- package/addon/controllers/management/issues/index.js +4 -0
- package/addon/controllers/management/places/index.js +4 -0
- package/addon/controllers/management/vehicles/index.js +4 -0
- package/addon/controllers/management/vendors/index.js +4 -0
- package/addon/controllers/operations/orders/index/details.js +30 -1
- package/addon/controllers/operations/orders/index.js +7 -0
- package/addon/controllers/operations/service-rates/index.js +3 -0
- package/addon/controllers/settings/index.js +13 -0
- package/addon/controllers/settings/telematics.js +113 -0
- package/addon/extension.js +38 -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.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/templates/settings/telematics.hbs +70 -0
- 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/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 +1 -1
- 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 +22 -0
- 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/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/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/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/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 +48 -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
|
+
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</div>
|
|
16
16
|
<div class="flex flex-shrink-0 items-center gap-2 whitespace-nowrap">
|
|
17
17
|
<Button @icon="refresh" @size="sm" @helpText={{t "common.reload"}} @onClick={{this.refresh}} />
|
|
18
|
-
<Button @icon="plus" @text="Connect Provider" @type="primary" @size="sm" @onClick={{this.telematicActions.transition.create}} />
|
|
18
|
+
<Button @icon="plus" @text="Connect Provider" @type="primary" @size="sm" @permission="fleet-ops create telematic" @onClick={{this.telematicActions.transition.create}} />
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
21
|
</section>
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
|
|
29
29
|
{{#if this.load.isIdle}}
|
|
30
30
|
{{! Drivers — fleetops' rotating tracking-marker matches the operational
|
|
31
|
-
live-map's look and animates on heading changes.
|
|
31
|
+
live-map's look and animates on heading changes. The popup and tooltip
|
|
32
|
+
are the live map's own cards, fed from each marker's index-resource card. }}
|
|
32
33
|
{{#each this.drivers as |driver|}}
|
|
33
34
|
<layers.tracking-marker
|
|
34
35
|
@id={{driver.uuid}}
|
|
@@ -39,28 +40,11 @@
|
|
|
39
40
|
@draggable={{false}}
|
|
40
41
|
as |marker|
|
|
41
42
|
>
|
|
42
|
-
<marker.popup @maxWidth="
|
|
43
|
-
<
|
|
44
|
-
<div class="w-9 h-9 flex-shrink-0">
|
|
45
|
-
<img src={{or driver.avatar_url driver.vehicle_avatar}} alt={{driver.name}} class="rounded-md w-9 h-9 object-cover shadow-sm" />
|
|
46
|
-
</div>
|
|
47
|
-
<div class="flex-1 min-w-0">
|
|
48
|
-
<div class="text-xs font-semibold truncate">{{or driver.name "Driver"}}</div>
|
|
49
|
-
<div class="text-[11px]">
|
|
50
|
-
{{#if driver.current_order_uuid}}
|
|
51
|
-
<span class="text-blue-500"><FaIcon @icon="bolt" class="mr-1" />On order</span>
|
|
52
|
-
{{else if driver.online}}
|
|
53
|
-
<span class="text-green-500"><FaIcon @icon="circle" @size="2xs" class="mr-1" />Online</span>
|
|
54
|
-
{{else}}
|
|
55
|
-
<span class="text-gray-400"><FaIcon @icon="circle" @size="2xs" class="mr-1" />Offline</span>
|
|
56
|
-
{{/if}}
|
|
57
|
-
</div>
|
|
58
|
-
<div class="text-[10px] text-gray-400 mt-0.5 truncate">{{driver.lat}}, {{driver.lng}}</div>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
43
|
+
<marker.popup @maxWidth="500" @minWidth="225">
|
|
44
|
+
<Map::MarkerCard::Driver @driver={{or driver.card driver}} />
|
|
61
45
|
</marker.popup>
|
|
62
46
|
<marker.tooltip @permanent={{false}} @sticky={{true}} @direction="top">
|
|
63
|
-
<
|
|
47
|
+
<Map::MarkerCard::Driver @driver={{or driver.card driver}} @variant="tooltip" />
|
|
64
48
|
</marker.tooltip>
|
|
65
49
|
</layers.tracking-marker>
|
|
66
50
|
{{/each}}
|
|
@@ -77,27 +61,11 @@
|
|
|
77
61
|
@draggable={{false}}
|
|
78
62
|
as |marker|
|
|
79
63
|
>
|
|
80
|
-
<marker.popup @maxWidth="
|
|
81
|
-
<
|
|
82
|
-
<div class="w-9 h-9 flex-shrink-0">
|
|
83
|
-
<img src={{or vehicle.photo_url vehicle.avatar_url}} alt={{vehicle.name}} class="rounded-md w-9 h-9 object-cover shadow-sm" />
|
|
84
|
-
</div>
|
|
85
|
-
<div class="flex-1 min-w-0">
|
|
86
|
-
<div class="text-xs font-semibold truncate">{{or vehicle.name "Vehicle"}}</div>
|
|
87
|
-
{{#if vehicle.plate_number}}
|
|
88
|
-
<div class="text-[10px] text-gray-500 truncate">{{vehicle.plate_number}}</div>
|
|
89
|
-
{{/if}}
|
|
90
|
-
{{#if vehicle.driver_name}}
|
|
91
|
-
<div class="text-[11px] text-gray-600 dark:text-gray-300 truncate">
|
|
92
|
-
<FaIcon @icon="id-card" class="mr-1 text-gray-400" />{{vehicle.driver_name}}
|
|
93
|
-
</div>
|
|
94
|
-
{{/if}}
|
|
95
|
-
<div class="text-[10px] text-gray-400 mt-0.5 truncate">{{vehicle.lat}}, {{vehicle.lng}}</div>
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
64
|
+
<marker.popup @maxWidth="500" @minWidth="225">
|
|
65
|
+
<Map::MarkerCard::Vehicle @vehicle={{or vehicle.card vehicle}} />
|
|
98
66
|
</marker.popup>
|
|
99
67
|
<marker.tooltip @permanent={{false}} @sticky={{true}} @direction="top">
|
|
100
|
-
<
|
|
68
|
+
<Map::MarkerCard::Vehicle @vehicle={{or vehicle.card vehicle}} @variant="tooltip" />
|
|
101
69
|
</marker.tooltip>
|
|
102
70
|
</layers.tracking-marker>
|
|
103
71
|
{{/each}}
|
|
@@ -29,6 +29,7 @@ export default class AnalyticsReportsIndexController extends Controller {
|
|
|
29
29
|
type: 'primary',
|
|
30
30
|
icon: 'plus',
|
|
31
31
|
onClick: this.reportActions.transition.create,
|
|
32
|
+
permission: 'iam create report',
|
|
32
33
|
},
|
|
33
34
|
];
|
|
34
35
|
}
|
|
@@ -39,6 +40,7 @@ export default class AnalyticsReportsIndexController extends Controller {
|
|
|
39
40
|
label: 'Delete selected...',
|
|
40
41
|
class: 'text-red-500',
|
|
41
42
|
fn: this.reportActions.bulkDelete,
|
|
43
|
+
permission: 'iam delete report',
|
|
42
44
|
},
|
|
43
45
|
];
|
|
44
46
|
}
|
|
@@ -81,10 +83,12 @@ export default class AnalyticsReportsIndexController extends Controller {
|
|
|
81
83
|
{
|
|
82
84
|
label: 'View report...',
|
|
83
85
|
fn: this.reportActions.transition.view,
|
|
86
|
+
permission: 'iam view report',
|
|
84
87
|
},
|
|
85
88
|
{
|
|
86
89
|
label: 'Edit report...',
|
|
87
90
|
fn: this.reportActions.transition.edit,
|
|
91
|
+
permission: 'iam update report',
|
|
88
92
|
},
|
|
89
93
|
{
|
|
90
94
|
separator: true,
|
|
@@ -92,6 +96,7 @@ export default class AnalyticsReportsIndexController extends Controller {
|
|
|
92
96
|
{
|
|
93
97
|
label: 'Delete report...',
|
|
94
98
|
fn: this.reportActions.delete,
|
|
99
|
+
permission: 'iam delete report',
|
|
95
100
|
},
|
|
96
101
|
],
|
|
97
102
|
sortable: false,
|
|
@@ -65,12 +65,14 @@ export default class ConnectivityDevicesIndexController extends Controller {
|
|
|
65
65
|
type: 'primary',
|
|
66
66
|
icon: 'plus',
|
|
67
67
|
onClick: this.deviceActions.transition.create,
|
|
68
|
+
permission: 'fleet-ops create device',
|
|
68
69
|
},
|
|
69
70
|
{
|
|
70
71
|
text: this.intl.t('common.import'),
|
|
71
72
|
type: 'magic',
|
|
72
73
|
icon: 'upload',
|
|
73
74
|
onClick: this.deviceActions.import,
|
|
75
|
+
permission: 'fleet-ops import device',
|
|
74
76
|
},
|
|
75
77
|
{
|
|
76
78
|
text: this.intl.t('common.export'),
|
|
@@ -78,6 +80,7 @@ export default class ConnectivityDevicesIndexController extends Controller {
|
|
|
78
80
|
iconClass: 'rotate-icon-45',
|
|
79
81
|
wrapperClass: 'hidden md:flex',
|
|
80
82
|
onClick: this.deviceActions.export,
|
|
83
|
+
permission: 'fleet-ops export device',
|
|
81
84
|
},
|
|
82
85
|
];
|
|
83
86
|
|
|
@@ -87,6 +90,7 @@ export default class ConnectivityDevicesIndexController extends Controller {
|
|
|
87
90
|
label: 'Delete selected...',
|
|
88
91
|
class: 'text-red-500',
|
|
89
92
|
fn: this.deviceActions.bulkDelete,
|
|
93
|
+
permission: 'fleet-ops delete device',
|
|
90
94
|
},
|
|
91
95
|
];
|
|
92
96
|
|
|
@@ -40,6 +40,7 @@ export default class ConnectivityFuelProvidersIndexController extends Controller
|
|
|
40
40
|
text: 'Connect Integration',
|
|
41
41
|
type: 'primary',
|
|
42
42
|
onClick: () => this.fuelIntegrationActions.transition.create(),
|
|
43
|
+
permission: 'fleet-ops create fuel-provider-connection',
|
|
43
44
|
},
|
|
44
45
|
];
|
|
45
46
|
}
|
|
@@ -51,6 +52,7 @@ export default class ConnectivityFuelProvidersIndexController extends Controller
|
|
|
51
52
|
{
|
|
52
53
|
label: `Sync ${selected.length} selected`,
|
|
53
54
|
fn: () => selected.forEach((connection) => this.syncConnection(connection)),
|
|
55
|
+
permission: 'fleet-ops sync fuel-provider-connection',
|
|
54
56
|
},
|
|
55
57
|
];
|
|
56
58
|
}
|
|
@@ -125,11 +127,11 @@ export default class ConnectivityFuelProvidersIndexController extends Controller
|
|
|
125
127
|
sticky: 'right',
|
|
126
128
|
width: 60,
|
|
127
129
|
actions: [
|
|
128
|
-
{ label: 'Open Integration', fn: this.openConnection },
|
|
129
|
-
{ label: 'Edit Settings', fn: this.editConnection },
|
|
130
|
+
{ label: 'Open Integration', fn: this.openConnection, permission: 'fleet-ops view fuel-provider-connection' },
|
|
131
|
+
{ label: 'Edit Settings', fn: this.editConnection, permission: 'fleet-ops update fuel-provider-connection' },
|
|
130
132
|
{ separator: true },
|
|
131
|
-
{ label: 'Test Connection', fn: this.testConnection },
|
|
132
|
-
{ label: 'Sync Transactions', fn: this.syncConnection },
|
|
133
|
+
{ label: 'Test Connection', fn: this.testConnection, permission: 'fleet-ops update fuel-provider-connection' },
|
|
134
|
+
{ label: 'Sync Transactions', fn: this.syncConnection, permission: 'fleet-ops sync fuel-provider-connection' },
|
|
133
135
|
],
|
|
134
136
|
sortable: false,
|
|
135
137
|
filterable: false,
|