@fleetbase/fleetops-engine 0.6.51 → 0.6.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (396) hide show
  1. package/README.md +0 -2
  2. package/addon/components/cell/telematic-provider.hbs +16 -0
  3. package/addon/components/cell/telematic-provider.js +36 -0
  4. package/addon/components/cell/telematic-status.hbs +1 -0
  5. package/addon/components/cell/telematic-status.js +39 -0
  6. package/addon/components/device/manager.hbs +5 -6
  7. package/addon/components/device/manager.js +12 -15
  8. package/addon/components/driver/details.hbs +1 -1
  9. package/addon/components/fleet/vehicle-listing.js +1 -0
  10. package/addon/components/fuel-integration/form.hbs +200 -0
  11. package/addon/components/fuel-integration/form.js +242 -0
  12. package/addon/components/fuel-integration/hub.hbs +154 -0
  13. package/addon/components/fuel-integration/hub.js +165 -0
  14. package/addon/components/fuel-integration/matching-priority.hbs +76 -0
  15. package/addon/components/fuel-integration/matching-priority.js +145 -0
  16. package/addon/components/fuel-report/details.hbs +13 -1
  17. package/addon/components/issue/details.hbs +3 -57
  18. package/addon/components/issue/details.js +0 -96
  19. package/addon/components/layout/fleet-ops-sidebar/operations-monitor.hbs +201 -0
  20. package/addon/components/layout/fleet-ops-sidebar/operations-monitor.js +589 -0
  21. package/addon/components/layout/fleet-ops-sidebar.hbs +19 -233
  22. package/addon/components/layout/fleet-ops-sidebar.js +287 -376
  23. package/addon/components/maintenance-schedule/form.js +1 -0
  24. package/addon/components/map/drawer/device-event-listing.hbs +12 -2
  25. package/addon/components/map/drawer/driver-listing.hbs +14 -1
  26. package/addon/components/map/drawer/place-listing.hbs +14 -1
  27. package/addon/components/map/drawer/position-listing.hbs +12 -2
  28. package/addon/components/map/drawer/vehicle-listing.hbs +14 -1
  29. package/addon/components/modals/assigned-orders.hbs +40 -0
  30. package/addon/components/modals/attach-device.hbs +4 -3
  31. package/addon/components/modals/attach-telematic-device.hbs +25 -0
  32. package/addon/components/modals/attach-telematic-device.js +3 -0
  33. package/addon/components/modals/driver-assign-order.hbs +7 -58
  34. package/addon/components/modals/driver-assign-vehicle.hbs +10 -2
  35. package/addon/components/modals/fleet-assign-driver.hbs +18 -0
  36. package/addon/components/modals/fleet-assign-driver.js +3 -0
  37. package/addon/components/modals/fleet-assign-vehicle.hbs +18 -0
  38. package/addon/components/modals/fleet-assign-vehicle.js +3 -0
  39. package/addon/components/modals/telematic-connection-diagnostics.hbs +75 -0
  40. package/addon/components/modals/telematic-connection-diagnostics.js +287 -0
  41. package/addon/components/modals/vehicle-details.hbs +6 -1
  42. package/addon/components/modals/vehicle-form.hbs +8 -1
  43. package/addon/components/order/card.hbs +106 -0
  44. package/addon/components/order/card.js +257 -0
  45. package/addon/components/order/form/payload.js +3 -1
  46. package/addon/components/order/form/service-rate.hbs +2 -0
  47. package/addon/components/service-rate/form.hbs +3 -2
  48. package/addon/components/telematic/details.hbs +98 -87
  49. package/addon/components/telematic/details.js +230 -1
  50. package/addon/components/telematic/form.hbs +303 -72
  51. package/addon/components/telematic/form.js +519 -3
  52. package/addon/components/telematic/hub.hbs +149 -0
  53. package/addon/components/telematic/hub.js +142 -0
  54. package/addon/components/telematic/settings.hbs +152 -0
  55. package/addon/components/telematic/settings.js +45 -0
  56. package/addon/components/telematic/tab-empty-state.hbs +29 -0
  57. package/addon/components/telematic/tab-empty-state.js +33 -0
  58. package/addon/components/vehicle/details.hbs +6 -1
  59. package/addon/components/vehicle/form.hbs +2 -1
  60. package/addon/components/widget/fuel-providers.hbs +43 -0
  61. package/addon/components/widget/fuel-providers.js +27 -0
  62. package/addon/controllers/connectivity/devices/index/details.js +27 -1
  63. package/addon/controllers/connectivity/devices/index.js +18 -1
  64. package/addon/controllers/connectivity/fuel-providers/details/sync.js +18 -0
  65. package/addon/controllers/connectivity/fuel-providers/details/transactions.js +24 -0
  66. package/addon/controllers/connectivity/fuel-providers/details.js +69 -0
  67. package/addon/controllers/connectivity/fuel-providers/edit.js +24 -0
  68. package/addon/controllers/connectivity/fuel-providers/index.js +177 -0
  69. package/addon/controllers/connectivity/fuel-providers/new.js +37 -0
  70. package/addon/controllers/connectivity/telematics/details/attachments.js +247 -0
  71. package/addon/controllers/connectivity/telematics/details/devices.js +368 -0
  72. package/addon/controllers/connectivity/telematics/details/events.js +244 -0
  73. package/addon/controllers/connectivity/telematics/details/index.js +3 -0
  74. package/addon/controllers/connectivity/telematics/details/logs.js +43 -0
  75. package/addon/controllers/connectivity/telematics/details/sensors.js +270 -0
  76. package/addon/controllers/connectivity/telematics/details.js +149 -0
  77. package/addon/controllers/connectivity/telematics/{index/edit.js → edit.js} +15 -4
  78. package/addon/controllers/connectivity/telematics/index.js +25 -5
  79. package/addon/controllers/connectivity/telematics/{index/new.js → new.js} +8 -2
  80. package/addon/controllers/maintenance/index.js +100 -0
  81. package/addon/controllers/management/drivers/index/details.js +78 -1
  82. package/addon/controllers/management/drivers/index.js +39 -0
  83. package/addon/controllers/management/fleets/index/details.js +23 -1
  84. package/addon/controllers/management/fleets/index.js +6 -1
  85. package/addon/controllers/management/fuel-reports/index.js +37 -1
  86. package/addon/controllers/management/fuel-transactions/index/details.js +70 -0
  87. package/addon/controllers/management/fuel-transactions/index.js +240 -0
  88. package/addon/controllers/management/index.js +88 -0
  89. package/addon/controllers/management/vehicles/index/details.js +32 -0
  90. package/addon/controllers/management/vehicles/index.js +26 -0
  91. package/addon/controllers/operations/orders/index.js +4 -0
  92. package/addon/controllers/settings/index.js +142 -0
  93. package/addon/controllers/settings/payments/index.js +5 -0
  94. package/addon/extension.js +31 -0
  95. package/addon/routes/analytics/index.js +3 -0
  96. package/addon/routes/connectivity/devices/index.js +3 -0
  97. package/addon/routes/connectivity/fuel-providers/details/index.js +7 -0
  98. package/addon/routes/connectivity/fuel-providers/details/matching.js +7 -0
  99. package/addon/routes/connectivity/fuel-providers/details/settings.js +7 -0
  100. package/addon/routes/connectivity/fuel-providers/details/sync.js +18 -0
  101. package/addon/routes/connectivity/fuel-providers/details/transactions.js +14 -0
  102. package/addon/routes/connectivity/fuel-providers/details.js +18 -0
  103. package/addon/routes/connectivity/fuel-providers/edit.js +18 -0
  104. package/addon/routes/connectivity/fuel-providers/index.js +20 -0
  105. package/addon/routes/connectivity/fuel-providers/new.js +3 -0
  106. package/addon/routes/connectivity/fuel-providers.js +3 -0
  107. package/addon/routes/connectivity/telematics/details/attachments.js +28 -0
  108. package/addon/routes/connectivity/telematics/details/devices.js +30 -0
  109. package/addon/routes/connectivity/telematics/details/events.js +33 -0
  110. package/addon/routes/connectivity/telematics/details/index.js +3 -0
  111. package/addon/routes/connectivity/telematics/details/logs.js +17 -0
  112. package/addon/routes/connectivity/telematics/details/sensors.js +29 -0
  113. package/addon/routes/connectivity/telematics/{index/details.js → details.js} +1 -1
  114. package/addon/routes/connectivity/telematics/{index/edit.js → edit.js} +1 -1
  115. package/addon/routes/connectivity/telematics/new.js +3 -0
  116. package/addon/routes/maintenance/index.js +3 -0
  117. package/addon/routes/maintenance/work-orders/index.js +2 -0
  118. package/addon/routes/management/drivers/index/details/activity.js +3 -0
  119. package/addon/routes/management/fuel-reports/index.js +2 -0
  120. package/addon/routes/management/fuel-transactions/index/details.js +18 -0
  121. package/addon/routes/management/fuel-transactions/index.js +21 -0
  122. package/addon/routes/management/fuel-transactions.js +3 -0
  123. package/addon/routes/settings/index.js +3 -0
  124. package/addon/routes.js +28 -9
  125. package/addon/services/device-actions.js +64 -1
  126. package/addon/services/device-event-actions.js +12 -1
  127. package/addon/services/driver-actions.js +147 -11
  128. package/addon/services/fleet-actions.js +66 -1
  129. package/addon/services/fuel-integration-actions.js +31 -0
  130. package/addon/services/issue-actions.js +1 -1
  131. package/addon/services/telematic-actions.js +9 -3
  132. package/addon/services/vehicle-actions.js +125 -0
  133. package/addon/styles/fleetops-engine.css +2237 -162
  134. package/addon/templates/analytics/index.hbs +14 -0
  135. package/addon/templates/analytics/reports/index.hbs +19 -1
  136. package/addon/templates/connectivity/devices/index.hbs +19 -1
  137. package/addon/templates/connectivity/events/index.hbs +16 -1
  138. package/addon/templates/connectivity/fuel-providers/details/index.hbs +38 -0
  139. package/addon/templates/connectivity/fuel-providers/details/matching.hbs +13 -0
  140. package/addon/templates/connectivity/fuel-providers/details/settings.hbs +11 -0
  141. package/addon/templates/connectivity/fuel-providers/details/sync.hbs +48 -0
  142. package/addon/templates/connectivity/fuel-providers/details/transactions.hbs +21 -0
  143. package/addon/templates/connectivity/fuel-providers/details.hbs +51 -0
  144. package/addon/templates/connectivity/fuel-providers/edit.hbs +24 -0
  145. package/addon/templates/connectivity/fuel-providers/index.hbs +12 -0
  146. package/addon/templates/connectivity/fuel-providers/new.hbs +22 -0
  147. package/addon/templates/connectivity/fuel-providers.hbs +1 -0
  148. package/addon/templates/connectivity/sensors/index.hbs +19 -1
  149. package/addon/templates/connectivity/telematics/details/attachments.hbs +163 -0
  150. package/addon/templates/connectivity/telematics/details/devices.hbs +88 -0
  151. package/addon/templates/connectivity/telematics/details/events.hbs +101 -0
  152. package/addon/templates/connectivity/telematics/{index/details → details}/index.hbs +0 -1
  153. package/addon/templates/connectivity/telematics/details/logs.hbs +69 -0
  154. package/addon/templates/connectivity/telematics/details/sensors.hbs +88 -0
  155. package/addon/templates/connectivity/telematics/details.hbs +53 -0
  156. package/addon/templates/connectivity/telematics/edit.hbs +27 -0
  157. package/addon/templates/connectivity/telematics/index.hbs +6 -8
  158. package/addon/templates/connectivity/telematics/new.hbs +24 -0
  159. package/addon/templates/maintenance/equipment/index.hbs +19 -1
  160. package/addon/templates/maintenance/index.hbs +113 -0
  161. package/addon/templates/maintenance/maintenances/index.hbs +15 -1
  162. package/addon/templates/maintenance/parts/index.hbs +19 -1
  163. package/addon/templates/maintenance/schedules/index.hbs +19 -1
  164. package/addon/templates/maintenance/work-orders/index.hbs +19 -1
  165. package/addon/templates/management/contacts/customers.hbs +15 -1
  166. package/addon/templates/management/contacts/index.hbs +19 -1
  167. package/addon/templates/management/drivers/index/details/activity.hbs +1 -0
  168. package/addon/templates/management/drivers/index.hbs +19 -1
  169. package/addon/templates/management/fleets/index.hbs +19 -1
  170. package/addon/templates/management/fuel-reports/index.hbs +19 -1
  171. package/addon/templates/management/fuel-transactions/index/details.hbs +73 -0
  172. package/addon/templates/management/fuel-transactions/index.hbs +58 -0
  173. package/addon/templates/management/fuel-transactions.hbs +1 -0
  174. package/addon/templates/management/index.hbs +109 -73
  175. package/addon/templates/management/issues/index.hbs +19 -1
  176. package/addon/templates/management/places/index.hbs +19 -1
  177. package/addon/templates/management/vehicles/index.hbs +19 -1
  178. package/addon/templates/management/vendors/index.hbs +19 -1
  179. package/addon/templates/management/vendors/integrated.hbs +13 -1
  180. package/addon/templates/operations/orders/index.hbs +19 -1
  181. package/addon/templates/operations/service-rates/index.hbs +19 -1
  182. package/addon/templates/settings/index.hbs +83 -0
  183. package/addon/templates/settings/payments/index.hbs +15 -1
  184. package/addon/templates/settings/routing.hbs +2 -2
  185. package/addon/utils/fleet-ops-options.js +3 -0
  186. package/app/components/cell/telematic-provider.js +1 -0
  187. package/app/components/cell/telematic-status.js +1 -0
  188. package/app/components/fuel-integration/form.js +1 -0
  189. package/app/components/fuel-integration/hub.js +1 -0
  190. package/app/components/fuel-integration/matching-priority.js +1 -0
  191. package/app/components/modals/assigned-orders.js +1 -0
  192. package/app/components/modals/attach-telematic-device.js +1 -0
  193. package/app/components/modals/fleet-assign-driver.js +1 -0
  194. package/app/components/modals/fleet-assign-vehicle.js +1 -0
  195. package/app/components/modals/telematic-connection-diagnostics.js +1 -0
  196. package/app/components/order/card.js +1 -0
  197. package/app/components/telematic/hub.js +1 -0
  198. package/app/components/telematic/settings.js +1 -0
  199. package/app/components/telematic/tab-empty-state.js +1 -0
  200. package/app/components/widget/fuel-providers.js +1 -0
  201. package/app/controllers/connectivity/fuel-providers/details/sync.js +1 -0
  202. package/app/controllers/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  203. package/app/controllers/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  204. package/app/controllers/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  205. package/app/controllers/connectivity/{telematics/index/details → fuel-providers}/index.js +1 -1
  206. package/app/controllers/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  207. package/app/controllers/connectivity/telematics/details/attachments.js +1 -0
  208. package/app/controllers/connectivity/telematics/details/devices.js +1 -0
  209. package/app/controllers/connectivity/telematics/details/events.js +1 -0
  210. package/app/controllers/connectivity/telematics/details/index.js +1 -0
  211. package/app/controllers/connectivity/telematics/details/logs.js +1 -0
  212. package/app/controllers/connectivity/telematics/details/sensors.js +1 -0
  213. package/app/controllers/connectivity/telematics/details.js +1 -0
  214. package/app/controllers/connectivity/telematics/edit.js +1 -0
  215. package/app/controllers/connectivity/telematics/new.js +1 -0
  216. package/app/controllers/maintenance/index.js +1 -0
  217. package/app/controllers/management/fuel-transactions/index/details.js +1 -0
  218. package/app/controllers/management/fuel-transactions/index.js +1 -0
  219. package/app/controllers/management/index.js +1 -0
  220. package/app/controllers/settings/index.js +1 -0
  221. package/app/routes/analytics/index.js +1 -0
  222. package/app/routes/connectivity/{telematics/index → fuel-providers}/details/index.js +1 -1
  223. package/app/routes/connectivity/{telematics/index/details/events.js → fuel-providers/details/matching.js} +1 -1
  224. package/app/routes/connectivity/fuel-providers/details/settings.js +1 -0
  225. package/app/routes/connectivity/fuel-providers/details/sync.js +1 -0
  226. package/app/routes/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  227. package/app/routes/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  228. package/app/routes/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  229. package/app/routes/connectivity/fuel-providers/index.js +1 -0
  230. package/app/routes/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  231. package/app/routes/connectivity/fuel-providers.js +1 -0
  232. package/app/routes/connectivity/telematics/details/attachments.js +1 -0
  233. package/app/routes/connectivity/telematics/details/devices.js +1 -0
  234. package/app/routes/connectivity/telematics/details/events.js +1 -0
  235. package/app/routes/connectivity/telematics/details/index.js +1 -0
  236. package/app/routes/connectivity/telematics/details/logs.js +1 -0
  237. package/app/routes/connectivity/telematics/details/sensors.js +1 -0
  238. package/app/routes/connectivity/telematics/details.js +1 -0
  239. package/app/routes/connectivity/telematics/edit.js +1 -0
  240. package/app/routes/connectivity/telematics/new.js +1 -0
  241. package/app/routes/maintenance/index.js +1 -0
  242. package/app/routes/management/drivers/index/details/activity.js +1 -0
  243. package/app/routes/management/fuel-transactions/index/details.js +1 -0
  244. package/app/routes/management/fuel-transactions/index.js +1 -0
  245. package/app/routes/management/fuel-transactions.js +1 -0
  246. package/app/routes/settings/index.js +1 -0
  247. package/app/services/fuel-integration-actions.js +1 -0
  248. package/app/templates/analytics/index.js +1 -0
  249. package/app/templates/connectivity/{telematics/index → fuel-providers}/details/index.js +1 -1
  250. package/app/templates/connectivity/{telematics/index/details/events.js → fuel-providers/details/matching.js} +1 -1
  251. package/app/templates/connectivity/fuel-providers/details/settings.js +1 -0
  252. package/app/templates/connectivity/fuel-providers/details/sync.js +1 -0
  253. package/app/templates/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  254. package/app/templates/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  255. package/app/templates/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  256. package/app/templates/connectivity/fuel-providers/index.js +1 -0
  257. package/app/templates/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  258. package/app/templates/connectivity/fuel-providers.js +1 -0
  259. package/app/templates/connectivity/telematics/details/attachments.js +1 -0
  260. package/app/templates/connectivity/telematics/details/devices.js +1 -0
  261. package/app/templates/connectivity/telematics/details/events.js +1 -0
  262. package/app/templates/connectivity/telematics/details/index.js +1 -0
  263. package/app/templates/connectivity/telematics/details/logs.js +1 -0
  264. package/app/templates/connectivity/telematics/details/sensors.js +1 -0
  265. package/app/templates/connectivity/telematics/details.js +1 -0
  266. package/app/templates/connectivity/telematics/edit.js +1 -0
  267. package/app/templates/connectivity/telematics/new.js +1 -0
  268. package/app/templates/maintenance/index.js +1 -0
  269. package/app/templates/management/drivers/index/details/activity.js +1 -0
  270. package/app/templates/management/fuel-transactions/index/details.js +1 -0
  271. package/app/templates/management/fuel-transactions/index.js +1 -0
  272. package/app/templates/management/fuel-transactions.js +1 -0
  273. package/app/templates/management/index.js +1 -0
  274. package/app/templates/settings/index.js +1 -0
  275. package/assets/images/telematics/providers/afaqy.webp +0 -0
  276. package/assets/images/telematics/providers/default.webp +0 -0
  277. package/assets/images/telematics/providers/flespi.webp +0 -0
  278. package/assets/images/telematics/providers/geotab.webp +0 -0
  279. package/assets/images/telematics/providers/safee.webp +0 -0
  280. package/assets/images/telematics/providers/samsara.webp +0 -0
  281. package/composer.json +1 -1
  282. package/extension.json +1 -1
  283. package/package.json +4 -4
  284. package/server/config/fuel-providers.php +42 -0
  285. package/server/config/telematics.php +139 -130
  286. package/server/migrations/2026_06_06_000001_harden_device_events_telematics_contract.php +59 -0
  287. package/server/migrations/2026_06_08_000001_create_fuel_provider_connections_table.php +37 -0
  288. package/server/migrations/2026_06_08_000002_create_fuel_provider_transactions_table.php +53 -0
  289. package/server/migrations/2026_06_08_000003_create_fuel_provider_sync_runs_table.php +40 -0
  290. package/server/migrations/2026_06_10_000001_add_fuel_card_number_to_vehicles_table.php +25 -0
  291. package/server/migrations/2026_06_10_000002_add_vehicle_identity_columns_to_fuel_provider_transactions_table.php +39 -0
  292. package/server/migrations/2026_06_15_000001_normalize_device_attachable_vehicle_morph_types.php +30 -0
  293. package/server/src/Console/Commands/FixInvalidPolymorphicRelationTypeNamespaces.php +1 -0
  294. package/server/src/Contracts/FuelProvider.php +30 -0
  295. package/server/src/Contracts/TelematicProviderDescriptor.php +3 -1
  296. package/server/src/Events/FuelProviderTransactionImported.php +17 -0
  297. package/server/src/Events/FuelProviderTransactionMatched.php +17 -0
  298. package/server/src/Events/FuelProviderTransactionUnmatched.php +17 -0
  299. package/server/src/Events/FuelReportCreatedFromProvider.php +18 -0
  300. package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +6 -0
  301. package/server/src/Http/Controllers/Internal/v1/DeviceController.php +140 -2
  302. package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +44 -0
  303. package/server/src/Http/Controllers/Internal/v1/DriverController.php +158 -7
  304. package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +124 -0
  305. package/server/src/Http/Controllers/Internal/v1/FuelProviderSyncRunController.php +10 -0
  306. package/server/src/Http/Controllers/Internal/v1/FuelProviderTransactionController.php +76 -0
  307. package/server/src/Http/Controllers/Internal/v1/HubController.php +300 -0
  308. package/server/src/Http/Controllers/Internal/v1/SearchController.php +506 -0
  309. package/server/src/Http/Controllers/Internal/v1/SensorController.php +1 -1
  310. package/server/src/Http/Controllers/Internal/v1/TelematicController.php +179 -16
  311. package/server/src/Http/Controllers/Internal/v1/VehicleController.php +249 -0
  312. package/server/src/Http/Controllers/TelematicWebhookController.php +103 -19
  313. package/server/src/Http/Filter/DeviceFilter.php +74 -0
  314. package/server/src/Http/Filter/DriverFilter.php +6 -0
  315. package/server/src/Http/Filter/FuelProviderConnectionFilter.php +33 -0
  316. package/server/src/Http/Filter/FuelProviderSyncRunFilter.php +28 -0
  317. package/server/src/Http/Filter/FuelProviderTransactionFilter.php +59 -0
  318. package/server/src/Http/Filter/FuelReportFilter.php +10 -0
  319. package/server/src/Http/Filter/VehicleFilter.php +6 -0
  320. package/server/src/Http/Resources/v1/Driver.php +15 -0
  321. package/server/src/Http/Resources/v1/FuelProviderConnection.php +30 -0
  322. package/server/src/Http/Resources/v1/FuelProviderSyncRun.php +36 -0
  323. package/server/src/Http/Resources/v1/FuelProviderTransaction.php +54 -0
  324. package/server/src/Http/Resources/v1/FuelReport.php +28 -22
  325. package/server/src/Http/Resources/v1/Index/Driver.php +26 -20
  326. package/server/src/Http/Resources/v1/Index/Vehicle.php +29 -22
  327. package/server/src/Http/Resources/v1/Vehicle.php +17 -0
  328. package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +2 -0
  329. package/server/src/Jobs/SyncFuelProviderTransactionsJob.php +57 -0
  330. package/server/src/Jobs/SyncTelematicDevicesJob.php +105 -17
  331. package/server/src/Jobs/TestTelematicConnectionJob.php +9 -22
  332. package/server/src/Models/Asset.php +2 -1
  333. package/server/src/Models/Contact.php +2 -1
  334. package/server/src/Models/Device.php +27 -4
  335. package/server/src/Models/DeviceEvent.php +40 -3
  336. package/server/src/Models/Driver.php +3 -2
  337. package/server/src/Models/Equipment.php +2 -1
  338. package/server/src/Models/Fleet.php +2 -1
  339. package/server/src/Models/FuelProviderConnection.php +60 -0
  340. package/server/src/Models/FuelProviderSyncRun.php +58 -0
  341. package/server/src/Models/FuelProviderTransaction.php +119 -0
  342. package/server/src/Models/FuelReport.php +16 -1
  343. package/server/src/Models/Part.php +2 -1
  344. package/server/src/Models/Sensor.php +21 -4
  345. package/server/src/Models/ServiceRate.php +39 -2
  346. package/server/src/Models/Vehicle.php +14 -2
  347. package/server/src/Models/Vendor.php +2 -1
  348. package/server/src/Providers/FleetOpsServiceProvider.php +20 -0
  349. package/server/src/Support/Analytics/FuelProviderSummary.php +42 -0
  350. package/server/src/Support/FuelProviders/FuelProviderDescriptor.php +55 -0
  351. package/server/src/Support/FuelProviders/FuelProviderRegistry.php +75 -0
  352. package/server/src/Support/FuelProviders/FuelProviderService.php +447 -0
  353. package/server/src/Support/FuelProviders/Providers/AbstractFuelProvider.php +98 -0
  354. package/server/src/Support/FuelProviders/Providers/PetroAppFuelProvider.php +167 -0
  355. package/server/src/Support/Telematics/Providers/AbstractProvider.php +27 -6
  356. package/server/src/Support/Telematics/Providers/AfaqyProvider.php +105 -38
  357. package/server/src/Support/Telematics/Providers/FlespiProvider.php +1 -0
  358. package/server/src/Support/Telematics/Providers/GeotabProvider.php +1 -0
  359. package/server/src/Support/Telematics/Providers/SafeeProvider.php +32 -22
  360. package/server/src/Support/Telematics/Providers/SamsaraProvider.php +3 -1
  361. package/server/src/Support/Telematics/TelematicService.php +340 -21
  362. package/server/src/routes.php +50 -4
  363. package/server/tests/FuelProviderRegistryTest.php +416 -0
  364. package/server/tests/HubRoutesTest.php +62 -0
  365. package/server/tests/ServiceRateAlgorithmWeightVariablesTest.php +44 -0
  366. package/server/tests/TelematicsHardeningTest.php +359 -0
  367. package/server/tests/VehicleDriverAssignmentTest.php +51 -0
  368. package/translations/ar-ae.yml +23 -1
  369. package/translations/bg-bg.yaml +72 -0
  370. package/translations/en-us.yaml +83 -0
  371. package/translations/es-pa.yaml +72 -0
  372. package/translations/fr-fr.yaml +72 -0
  373. package/translations/mn-mn.yaml +72 -0
  374. package/translations/pt-br.yaml +72 -0
  375. package/translations/ru-ru.yaml +72 -0
  376. package/translations/vi-vn.yaml +98 -1
  377. package/addon/controllers/connectivity/telematics/index/details/devices.js +0 -3
  378. package/addon/controllers/connectivity/telematics/index/details/events.js +0 -3
  379. package/addon/controllers/connectivity/telematics/index/details/index.js +0 -3
  380. package/addon/controllers/connectivity/telematics/index/details/sensors.js +0 -3
  381. package/addon/controllers/connectivity/telematics/index/details.js +0 -24
  382. package/addon/routes/connectivity/telematics/index/details/devices.js +0 -3
  383. package/addon/routes/connectivity/telematics/index/details/events.js +0 -3
  384. package/addon/routes/connectivity/telematics/index/details/index.js +0 -3
  385. package/addon/routes/connectivity/telematics/index/details/sensors.js +0 -3
  386. package/addon/routes/connectivity/telematics/index/new.js +0 -3
  387. package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
  388. package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
  389. package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
  390. package/addon/templates/connectivity/telematics/index/details.hbs +0 -14
  391. package/addon/templates/connectivity/telematics/index/edit.hbs +0 -12
  392. package/addon/templates/connectivity/telematics/index/new.hbs +0 -12
  393. package/app/controllers/connectivity/telematics/index/details/events.js +0 -1
  394. package/app/controllers/connectivity/telematics/index/details/sensors.js +0 -1
  395. package/app/routes/connectivity/telematics/index/details/sensors.js +0 -1
  396. package/app/templates/connectivity/telematics/index/details/sensors.js +0 -1
@@ -11,6 +11,20 @@
11
11
  @actionButtons={{this.actionButtons}}
12
12
  @bulkActions={{this.bulkActions}}
13
13
  @controller={{this}}
14
+ @emptyStateComponent={{component
15
+ "table/empty-state"
16
+ icon="user-group"
17
+ title="Add your first customer"
18
+ description="Customers give orders an owner, contact details, and account context for service history."
19
+ filteredTitle="No customers match your filters"
20
+ filteredDescription="Adjust the search or filters to find another customer."
21
+ primaryText="New customer"
22
+ primaryIcon="plus"
23
+ primaryAction=this.customerActions.transition.create
24
+ secondaryText="Import"
25
+ secondaryIcon="upload"
26
+ secondaryAction=this.customerActions.import
27
+ }}
14
28
  @withoutHeader={{true}}
15
29
  />
16
- {{outlet}}
30
+ {{outlet}}
@@ -11,6 +11,24 @@
11
11
  @actionButtons={{this.actionButtons}}
12
12
  @bulkActions={{this.bulkActions}}
13
13
  @controller={{this}}
14
+ @emptyStateComponent={{component
15
+ "table/empty-state"
16
+ icon="address-book"
17
+ title="Add your first contact"
18
+ description="Contacts keep customer, vendor, and internal stakeholder details ready for orders and communication."
19
+ filteredTitle="No contacts match your filters"
20
+ filteredDescription="Adjust the search or filters to find another contact."
21
+ primaryText="New contact"
22
+ primaryIcon="plus"
23
+ primaryAction=this.contactActions.transition.create
24
+ secondaryText="Import"
25
+ secondaryIcon="upload"
26
+ secondaryAction=this.contactActions.import
27
+ docsSlug="fleet-ops/resources/contacts/overview"
28
+ docsTitle="Contacts guide"
29
+ docsText="Contacts guide"
30
+ docsSource="fleet-ops-empty-contacts"
31
+ }}
14
32
  @withoutHeader={{true}}
15
33
  />
16
- {{outlet}}
34
+ {{outlet}}
@@ -0,0 +1 @@
1
+ <ActivityLog @subjectId={{@model.id}} class="p-3" />
@@ -11,5 +11,23 @@
11
11
  @actionButtons={{this.actionButtons}}
12
12
  @bulkActions={{this.bulkActions}}
13
13
  @controller={{this}}
14
+ @emptyStateComponent={{component
15
+ "table/empty-state"
16
+ icon="id-card"
17
+ title="Add your first driver"
18
+ description="Drivers power dispatching, live fleet visibility, assignments, and delivery activity."
19
+ filteredTitle="No drivers match your search"
20
+ filteredDescription="Adjust the search or filters to find another driver."
21
+ primaryText="New driver"
22
+ primaryIcon="plus"
23
+ primaryAction=this.driverActions.transition.create
24
+ secondaryText="Import"
25
+ secondaryIcon="upload"
26
+ secondaryAction=this.driverActions.import
27
+ docsSlug="fleet-ops/resources/drivers/overview"
28
+ docsTitle="Drivers guide"
29
+ docsText="Driver guide"
30
+ docsSource="fleet-ops-empty-drivers"
31
+ }}
14
32
  />
15
- {{outlet}}
33
+ {{outlet}}
@@ -11,5 +11,23 @@
11
11
  @actionButtons={{this.actionButtons}}
12
12
  @bulkActions={{this.bulkActions}}
13
13
  @controller={{this}}
14
+ @emptyStateComponent={{component
15
+ "table/empty-state"
16
+ icon="layer-group"
17
+ title="Create your first fleet"
18
+ description="Fleets help group vehicles and drivers for dispatching, reporting, and operational coverage."
19
+ filteredTitle="No fleets match your filters"
20
+ filteredDescription="Adjust the search or filters to find another fleet."
21
+ primaryText="New fleet"
22
+ primaryIcon="plus"
23
+ primaryAction=this.fleetActions.transition.create
24
+ secondaryText="Import"
25
+ secondaryIcon="upload"
26
+ secondaryAction=this.fleetActions.import
27
+ docsSlug="fleet-ops/resources/fleets/overview"
28
+ docsTitle="Fleets guide"
29
+ docsText="Fleet guide"
30
+ docsSource="fleet-ops-empty-fleets"
31
+ }}
14
32
  />
15
- {{outlet}}
33
+ {{outlet}}
@@ -11,5 +11,23 @@
11
11
  @actionButtons={{this.actionButtons}}
12
12
  @bulkActions={{this.bulkActions}}
13
13
  @controller={{this}}
14
+ @emptyStateComponent={{component
15
+ "table/empty-state"
16
+ icon="gas-pump"
17
+ title="No fuel reports yet"
18
+ description="Create fuel reports to track vehicle fuel usage, cost, and supporting transaction records."
19
+ filteredTitle="No fuel reports match your filters"
20
+ filteredDescription="Adjust the search or filters to find another fuel report."
21
+ primaryText="New fuel report"
22
+ primaryIcon="plus"
23
+ primaryAction=this.fuelReportActions.transition.create
24
+ secondaryText="Import"
25
+ secondaryIcon="upload"
26
+ secondaryAction=this.fuelReportActions.import
27
+ docsSlug="fleet-ops/resources/fuel-reports/overview"
28
+ docsTitle="Fuel reports guide"
29
+ docsText="Fuel reports guide"
30
+ docsSource="fleet-ops-empty-fuel-reports"
31
+ }}
14
32
  />
15
- {{outlet}}
33
+ {{outlet}}
@@ -0,0 +1,73 @@
1
+ <div class="flex h-full flex-col bg-gray-50 dark:bg-gray-900">
2
+ <section class="flex-shrink-0 border-b border-gray-200 bg-white px-4 py-4 shadow-sm dark:border-gray-700 dark:bg-gray-900 md:px-6">
3
+ <div class="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
4
+ <div class="min-w-0">
5
+ <div class="text-xs font-semibold uppercase text-gray-400 dark:text-gray-500">Fuel transaction review</div>
6
+ <h1 class="truncate text-lg font-bold text-gray-900 dark:text-gray-100">{{@model.provider_transaction_id}}</h1>
7
+ <div class="mt-2 flex flex-wrap gap-2 text-xs text-gray-500 dark:text-gray-300">
8
+ <Badge @status={{@model.sync_status}}>{{@model.sync_status}}</Badge>
9
+ <span>{{@model.provider}}</span>
10
+ <span>{{n-a (format-date-fns @model.transaction_at "dd MMM yyyy HH:mm")}}</span>
11
+ <span>{{n-a @model.station_name}}</span>
12
+ </div>
13
+ </div>
14
+ <div class="flex flex-wrap items-center gap-2">
15
+ <Button @icon="arrow-left" @text="Back" @size="sm" @onClick={{transition-to "management.fuel-transactions.index"}} />
16
+ <Button @icon="rotate" @text="Reprocess" @type="primary" @size="sm" @isLoading={{this.reprocess.isRunning}} @onClick={{perform this.reprocess}} />
17
+ </div>
18
+ </div>
19
+ </section>
20
+
21
+ <div class="min-h-0 flex-1 overflow-y-auto p-4 md:p-6">
22
+ <div class="mx-auto grid w-full max-w-7xl grid-cols-1 gap-4 lg:grid-cols-3">
23
+ <section class="rounded-md border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800 lg:col-span-2">
24
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Provider Bill Data</h2>
25
+ <div class="mt-4 grid grid-cols-1 gap-3 md:grid-cols-3">
26
+ <div class="rounded-md border border-gray-200 p-3 dark:border-gray-700"><div class="text-xs text-gray-500">Vehicle/Card</div><div class="mt-1 font-semibold text-gray-900 dark:text-gray-100">{{n-a @model.vehicle_card_id}}</div></div>
27
+ <div class="rounded-md border border-gray-200 p-3 dark:border-gray-700"><div class="text-xs text-gray-500">Liters</div><div class="mt-1 font-semibold text-gray-900 dark:text-gray-100">{{n-a @model.volume}}</div></div>
28
+ <div class="rounded-md border border-gray-200 p-3 dark:border-gray-700"><div class="text-xs text-gray-500">Amount</div><div class="mt-1 font-semibold text-gray-900 dark:text-gray-100">{{n-a @model.amount}} {{@model.currency}}</div></div>
29
+ <div class="rounded-md border border-gray-200 p-3 dark:border-gray-700"><div class="text-xs text-gray-500">Vehicle</div><div class="mt-1 font-semibold text-gray-900 dark:text-gray-100">{{n-a @model.vehicle_name}}</div></div>
30
+ <div class="rounded-md border border-gray-200 p-3 dark:border-gray-700"><div class="text-xs text-gray-500">Trip</div><div class="mt-1 font-semibold text-gray-900 dark:text-gray-100">{{n-a @model.trip_number}}</div></div>
31
+ <div class="rounded-md border border-gray-200 p-3 dark:border-gray-700"><div class="text-xs text-gray-500">Fuel Report</div><div class="mt-1 font-semibold text-gray-900 dark:text-gray-100">{{n-a @model.fuel_report_id}}</div></div>
32
+ </div>
33
+
34
+ <div class="mt-4 grid grid-cols-1 gap-4 lg:grid-cols-2">
35
+ <div>
36
+ <h3 class="text-xs font-bold uppercase text-gray-400">Normalized Payload</h3>
37
+ <pre class="mt-2 max-h-80 overflow-auto rounded-md bg-gray-900 p-3 text-[11px] leading-5 text-gray-100">{{this.normalizedPayloadJson}}</pre>
38
+ </div>
39
+ <div>
40
+ <h3 class="text-xs font-bold uppercase text-gray-400">Raw Payload</h3>
41
+ <pre class="mt-2 max-h-80 overflow-auto rounded-md bg-gray-900 p-3 text-[11px] leading-5 text-gray-100">{{this.rawPayloadJson}}</pre>
42
+ </div>
43
+ </div>
44
+ </section>
45
+
46
+ <aside class="space-y-4">
47
+ <section class="rounded-md border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
48
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Manual Match</h2>
49
+ <p class="mt-1 text-xs leading-5 text-gray-500 dark:text-gray-300">Use a Fleet-Ops UUID or public ID when automatic matching cannot identify the vehicle or order.</p>
50
+ <div class="mt-3 space-y-3 no-input-group-padding">
51
+ <InputGroup @name="Vehicle ID">
52
+ <Input class="form-input w-full" @value={{this.vehicleId}} {{on "input" this.setVehicleId}} />
53
+ </InputGroup>
54
+ <Button @icon="truck" @text="Match Vehicle" @type="primary" @size="sm" @isLoading={{this.matchVehicle.isRunning}} @disabled={{not this.vehicleId}} @onClick={{perform this.matchVehicle}} />
55
+ <InputGroup @name="Order / Trip ID">
56
+ <Input class="form-input w-full" @value={{this.orderId}} {{on "input" this.setOrderId}} />
57
+ </InputGroup>
58
+ <Button @icon="route" @text="Match Order" @size="sm" @isLoading={{this.matchOrder.isRunning}} @disabled={{not this.orderId}} @onClick={{perform this.matchOrder}} />
59
+ </div>
60
+ </section>
61
+
62
+ <section class="rounded-md border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
63
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Review State</h2>
64
+ <p class="mt-1 text-xs leading-5 text-gray-500 dark:text-gray-300">Mark noisy provider records as reviewed or ignored without deleting the audit ledger.</p>
65
+ <div class="mt-3 flex flex-wrap gap-2">
66
+ <Button @icon="check" @text="Mark Reviewed" @size="sm" @isLoading={{this.review.isRunning}} @onClick={{perform this.review "reviewed"}} />
67
+ <Button @icon="ban" @text="Ignore" @type="danger" @size="sm" @isLoading={{this.review.isRunning}} @onClick={{perform this.review "ignored"}} />
68
+ </div>
69
+ </section>
70
+ </aside>
71
+ </div>
72
+ </div>
73
+ </div>
@@ -0,0 +1,58 @@
1
+ <div class="flex h-full flex-col bg-gray-50 dark:bg-gray-900">
2
+ <section class="flex-shrink-0 border-b border-gray-200 bg-white px-4 py-4 shadow-sm dark:border-gray-700 dark:bg-gray-900 md:px-6">
3
+ <div class="flex flex-col gap-2 md:flex-row md:items-start md:justify-between">
4
+ <div>
5
+ <div class="text-xs font-semibold uppercase text-gray-400 dark:text-gray-500">Fuel transaction ledger</div>
6
+ <h1 class="text-lg font-bold text-gray-900 dark:text-gray-100">{{t "menu.fuel-transactions"}}</h1>
7
+ <p class="mt-1 max-w-4xl text-sm leading-5 text-gray-500 dark:text-gray-300">
8
+ Imported fuel card bills and provider purchase records are reviewed here before, during, and after they match to vehicles, trips, and linked Fuel Reports.
9
+ </p>
10
+ </div>
11
+ </div>
12
+ </section>
13
+
14
+ <div class="min-h-0 flex-1 overflow-y-auto p-4 md:p-6">
15
+ {{#if this.hasRecords}}
16
+ <Layout::Resource::Tabular
17
+ @resource="fuel-provider-transaction"
18
+ @title={{t "menu.fuel-transactions"}}
19
+ @searchQuery={{this.query}}
20
+ @data={{@model}}
21
+ @columns={{this.columns}}
22
+ @page={{this.page}}
23
+ @onPageChange={{fn (mut this.page)}}
24
+ @setupTable={{fn (mut this.table)}}
25
+ @actionButtons={{this.actionButtons}}
26
+ @bulkActions={{this.bulkActions}}
27
+ @controller={{this}}
28
+ @emptyStateComponent={{component
29
+ "table/empty-state"
30
+ icon="receipt"
31
+ title="No fuel transactions"
32
+ description="Imported fuel card bills and provider purchase records appear here after provider syncs complete."
33
+ filteredTitle="No transactions match your filters"
34
+ filteredDescription="Adjust the search or filters to review other imported transactions."
35
+ primaryText="Refresh"
36
+ primaryIcon="refresh"
37
+ primaryAction=this.refresh
38
+ docsSlug="fleet-ops/resources/fuel-reports/overview"
39
+ docsTitle="Fuel reports guide"
40
+ docsText="Fuel reports guide"
41
+ }}
42
+ />
43
+ {{else}}
44
+ <section class="rounded-md border border-dashed border-gray-300 bg-white p-8 text-center shadow-sm dark:border-gray-700 dark:bg-gray-800">
45
+ <div class="mx-auto flex h-11 w-11 items-center justify-center rounded-md bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-300">
46
+ <FaIcon @icon="receipt" />
47
+ </div>
48
+ <h2 class="mt-3 text-sm font-bold text-gray-900 dark:text-gray-100">{{this.emptyStateTitle}}</h2>
49
+ <p class="mx-auto mt-1 max-w-2xl text-xs leading-5 text-gray-500 dark:text-gray-300">{{this.emptyStateMessage}}</p>
50
+ <div class="mt-4 flex flex-wrap items-center justify-center gap-2">
51
+ <Button @icon="gas-pump" @text="Open Fuel Integrations" @type="primary" @size="sm" @onClick={{transition-to "connectivity.fuel-providers.index"}} />
52
+ <Button @icon="refresh" @text="Refresh" @size="sm" @onClick={{this.refresh}} />
53
+ </div>
54
+ </section>
55
+ {{/if}}
56
+ </div>
57
+ </div>
58
+ {{outlet}}
@@ -0,0 +1 @@
1
+ {{outlet}}
@@ -1,77 +1,113 @@
1
- <div class="content">
2
- <div class="row">
3
- <div class="col-12 col-lg-3 col-xl-3">
4
- <LinkTo
5
- @route="dashboard.fleet-ops.management.vendors"
6
- class="group hover:bg-flb-blue p-4 cursor-pointer bg-white rounded max-w-xs w-full shadow-lg select-none overflow-hidden mx-auto mb-6"
7
- >
8
- <p class="font-semibold text-lg mb-1 text-black group-hover:text-white">{{t "fleet-ops.management.vendors.index.title"}}</p>
9
- <p class="text-grey-darker group-hover:text-white mb-2">{{t "fleet-ops.common.manage-message"}}</p>
10
- </LinkTo>
1
+ <div class="fleet-ops-control-hub" data-test-fleet-ops-resources-hub>
2
+ <section class="fleet-ops-control-hub-header">
3
+ <div class="fleet-ops-control-hub-header-copy">
4
+ <div class="fleet-ops-control-hub-eyebrow">Resources</div>
5
+ <h1 class="fleet-ops-control-hub-title">Resources Hub</h1>
6
+ <p class="fleet-ops-control-hub-subtitle">Manage the people, vehicles, places, partners, and operating records that keep dispatch grounded.</p>
11
7
  </div>
12
- <div class="col-12 col-lg-3 col-xl-3">
13
- <LinkTo
14
- @route="dashboard.fleet-ops.management.fleets"
15
- class="group hover:bg-flb-blue p-4 cursor-pointer bg-white rounded max-w-xs w-full shadow-lg select-none overflow-hidden mx-auto mb-6"
16
- >
17
- <p class="font-semibold text-lg mb-1 text-black group-hover:text-white">{{t "fleet-ops.management.fleets.index.title"}}</p>
18
- <p class="text-grey-darker group-hover:text-white mb-2">{{t "fleet-ops.common.manage-message"}}</p>
19
- </LinkTo>
20
- </div>
21
- <div class="col-12 col-lg-3 col-xl-3">
22
- <LinkTo
23
- @route="dashboard.fleet-ops.management.drivers"
24
- class="group hover:bg-flb-blue p-4 cursor-pointer bg-white rounded max-w-xs w-full shadow-lg select-none overflow-hidden mx-auto mb-6"
25
- >
26
- <p class="font-semibold text-lg mb-1 text-black group-hover:text-white">{{t "fleet-ops.management.drivers.index.title"}}</p>
27
- <p class="text-grey-darker group-hover:text-white mb-2">{{t "fleet-ops.common.manage-message"}}</p>
28
- </LinkTo>
29
- </div>
30
- <div class="col-12 col-lg-3 col-xl-3">
31
- <LinkTo
32
- @route="dashboard.fleet-ops.management.vehicles"
33
- class="group hover:bg-flb-blue p-4 cursor-pointer bg-white rounded max-w-xs w-full shadow-lg select-none overflow-hidden mx-auto mb-6"
34
- >
35
- <p class="font-semibold text-lg mb-1 text-black group-hover:text-white">{{t "fleet-ops.management.vehicles.index.title"}}</p>
36
- <p class="text-grey-darker group-hover:text-white mb-2">{{t "fleet-ops.common.manage-message"}}</p>
37
- </LinkTo>
38
- </div>
39
- <div class="col-12 col-lg-3 col-xl-3">
40
- <LinkTo
41
- @route="dashboard.fleet-ops.management.places"
42
- class="group hover:bg-flb-blue p-4 cursor-pointer bg-white rounded max-w-xs w-full shadow-lg select-none overflow-hidden mx-auto mb-6"
43
- >
44
- <p class="font-semibold text-lg mb-1 text-black group-hover:text-white">{{t "fleet-ops.management.places.index.title"}}</p>
45
- <p class="text-grey-darker group-hover:text-white mb-2">{{t "fleet-ops.common.manage-message"}}</p>
46
- </LinkTo>
47
- </div>
48
- <div class="col-12 col-lg-3 col-xl-3">
49
- <LinkTo
50
- @route="dashboard.fleet-ops.management.contacts."
51
- class="group hover:bg-flb-blue p-4 cursor-pointer bg-white rounded max-w-xs w-full shadow-lg select-none overflow-hidden mx-auto mb-6"
52
- >
53
- <p class="font-semibold text-lg mb-1 text-black group-hover:text-white">{{t "fleet-ops.management.contacts.index.title"}}</p>
54
- <p class="text-grey-darker group-hover:text-white mb-2">{{t "fleet-ops.common.manage-message"}}</p>
55
- </LinkTo>
56
- </div>
57
- <div class="col-12 col-lg-3 col-xl-3">
58
- <LinkTo
59
- @route="dashboard.fleet-ops.management.issues"
60
- class="group hover:bg-flb-blue p-4 cursor-pointer bg-white rounded max-w-xs w-full shadow-lg select-none overflow-hidden mx-auto mb-6"
61
- >
62
- <p class="font-semibold text-lg mb-1 text-black group-hover:text-white">{{t "fleet-ops.management.issues.index.title"}}</p>
63
- <p class="text-grey-darker group-hover:text-white mb-2">{{t "fleet-ops.common.manage-message"}}</p>
64
- </LinkTo>
65
- </div>
66
- <div class="col-12 col-lg-3 col-xl-3">
67
- <LinkTo
68
- @route="dashboard.fleet-ops.management.fuel-reports"
69
- class="group hover:bg-flb-blue p-4 cursor-pointer bg-white rounded max-w-xs w-full shadow-lg select-none overflow-hidden mx-auto mb-6"
70
- >
71
- <p class="font-semibold text-lg mb-1 text-black group-hover:text-white">{{t "fleet-ops.management.fuel-reports.index.title"}}</p>
72
- <p class="text-grey-darker group-hover:text-white mb-2">{{t "fleet-ops.common.manage-message"}}</p>
73
- </LinkTo>
8
+ <div class="fleet-ops-control-hub-header-actions">
9
+ <Button @icon="refresh" @size="sm" @helpText={{t "common.reload"}} @onClick={{perform this.loadHub}} />
74
10
  </div>
11
+ </section>
12
+
13
+ <div class="fleet-ops-control-hub-body">
14
+ <section class="fleet-ops-control-hub-kpis">
15
+ {{#each this.kpis as |kpi|}}
16
+ <LinkTo @route={{kpi.route}} class="fleet-ops-control-hub-kpi fleet-ops-control-hub-tone-{{kpi.tone}}" data-test-fleet-ops-resources-kpi={{kpi.key}}>
17
+ <div class="fleet-ops-control-hub-kpi-copy">
18
+ <div class="fleet-ops-control-hub-kpi-label">{{kpi.label}}</div>
19
+ <div class="fleet-ops-control-hub-kpi-value">{{kpi.value}}</div>
20
+ <div class="fleet-ops-control-hub-kpi-caption">{{kpi.caption}}</div>
21
+ <div class="fleet-ops-control-hub-kpi-action">
22
+ <span>{{kpi.actionLabel}}</span>
23
+ <FaIcon @icon="arrow-right" />
24
+ </div>
25
+ </div>
26
+ <div class="fleet-ops-control-hub-kpi-icon"><FaIcon @icon={{kpi.icon}} /></div>
27
+ </LinkTo>
28
+ {{/each}}
29
+ </section>
30
+
31
+ <section class="fleet-ops-control-hub-grid">
32
+ <div class="fleet-ops-control-hub-main">
33
+ {{#each this.sections as |section|}}
34
+ <div class="fleet-ops-control-hub-panel" data-test-fleet-ops-resources-section={{section.key}}>
35
+ <div class="fleet-ops-control-hub-panel-header">
36
+ <div>
37
+ <h2>{{section.title}}</h2>
38
+ <p>{{section.description}}</p>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="fleet-ops-control-hub-link-grid">
43
+ {{#each section.links as |link|}}
44
+ <LinkTo @route={{link.route}} class="fleet-ops-control-hub-link" data-test-fleet-ops-hub-card={{link.label}}>
45
+ <span class="fleet-ops-control-hub-link-icon"><FaIcon @icon={{link.icon}} /></span>
46
+ <span class="fleet-ops-control-hub-link-copy">
47
+ <span class="fleet-ops-control-hub-link-title">{{link.label}}</span>
48
+ <span class="fleet-ops-control-hub-link-description">{{link.description}}</span>
49
+ </span>
50
+ <span class="fleet-ops-control-hub-link-count">{{link.count}}</span>
51
+ </LinkTo>
52
+ {{/each}}
53
+ </div>
54
+ </div>
55
+ {{/each}}
56
+ </div>
57
+
58
+ <aside class="fleet-ops-control-hub-side">
59
+ <div class="fleet-ops-control-hub-panel">
60
+ <div class="fleet-ops-control-hub-panel-header">
61
+ <div>
62
+ <h2>Action Queue</h2>
63
+ <p>Prioritized from current resource readiness.</p>
64
+ </div>
65
+ </div>
66
+
67
+ <div class="fleet-ops-control-hub-action-list">
68
+ {{#each this.actions as |action|}}
69
+ {{#if action.route}}
70
+ <LinkTo @route={{action.route}} @query={{action.query}} class="fleet-ops-control-hub-action fleet-ops-control-hub-tone-{{action.tone}}">
71
+ <FaIcon @icon={{action.icon}} />
72
+ <span>
73
+ <strong>{{action.label}}</strong>
74
+ <small>{{action.description}}</small>
75
+ </span>
76
+ </LinkTo>
77
+ {{else}}
78
+ <div class="fleet-ops-control-hub-action fleet-ops-control-hub-tone-{{action.tone}}">
79
+ <FaIcon @icon={{action.icon}} />
80
+ <span>
81
+ <strong>{{action.label}}</strong>
82
+ <small>{{action.description}}</small>
83
+ </span>
84
+ </div>
85
+ {{/if}}
86
+ {{/each}}
87
+ </div>
88
+ </div>
89
+
90
+ <div class="fleet-ops-control-hub-doc-note">
91
+ <div class="fleet-ops-control-hub-doc-note-heading">
92
+ <FaIcon @icon="lightbulb" />
93
+ <span>Guides</span>
94
+ </div>
95
+ <p class="fleet-ops-control-hub-doc-note-copy">Read the guide before changing resource setup.</p>
96
+ <div class="fleet-ops-control-hub-doc-grid">
97
+ {{#each this.docs as |doc|}}
98
+ <button type="button" class="fleet-ops-control-hub-doc-link" {{on "click" (fn this.openDocs doc)}}>
99
+ <FaIcon @icon={{doc.icon}} />
100
+ <span class="fleet-ops-control-hub-doc-copy">
101
+ <strong>Read the guide on {{doc.label}}</strong>
102
+ <small>{{doc.description}}</small>
103
+ </span>
104
+ </button>
105
+ {{/each}}
106
+ </div>
107
+ </div>
108
+ </aside>
109
+ </section>
75
110
  </div>
76
111
  </div>
77
- {{outlet}}
112
+
113
+ {{outlet}}
@@ -11,5 +11,23 @@
11
11
  @actionButtons={{this.actionButtons}}
12
12
  @bulkActions={{this.bulkActions}}
13
13
  @controller={{this}}
14
+ @emptyStateComponent={{component
15
+ "table/empty-state"
16
+ icon="triangle-exclamation"
17
+ title="No issues reported"
18
+ description="Track vehicle, driver, facility, and service issues here so follow-up work stays visible."
19
+ filteredTitle="No issues match your filters"
20
+ filteredDescription="Clear the search or filters to review other reported issues."
21
+ primaryText="New issue"
22
+ primaryIcon="plus"
23
+ primaryAction=this.issueActions.transition.create
24
+ secondaryText="Import"
25
+ secondaryIcon="upload"
26
+ secondaryAction=this.issueActions.import
27
+ docsSlug="fleet-ops/resources/issues/overview"
28
+ docsTitle="Issues guide"
29
+ docsText="Issues guide"
30
+ docsSource="fleet-ops-empty-issues"
31
+ }}
14
32
  />
15
- {{outlet}}
33
+ {{outlet}}
@@ -10,5 +10,23 @@
10
10
  @actionButtons={{this.actionButtons}}
11
11
  @bulkActions={{this.bulkActions}}
12
12
  @controller={{this}}
13
+ @emptyStateComponent={{component
14
+ "table/empty-state"
15
+ icon="location-dot"
16
+ title="Add your first place"
17
+ description="Places keep frequent pickup, dropoff, facility, and service locations ready for orders and routing."
18
+ filteredTitle="No places match your filters"
19
+ filteredDescription="Adjust the search or filters to find another saved location."
20
+ primaryText="New place"
21
+ primaryIcon="plus"
22
+ primaryAction=this.placeActions.transition.create
23
+ secondaryText="Import"
24
+ secondaryIcon="upload"
25
+ secondaryAction=this.placeActions.import
26
+ docsSlug="fleet-ops/resources/places/overview"
27
+ docsTitle="Places guide"
28
+ docsText="Places guide"
29
+ docsSource="fleet-ops-empty-places"
30
+ }}
13
31
  />
14
- {{outlet}}
32
+ {{outlet}}
@@ -12,6 +12,24 @@
12
12
  @actionButtons={{this.actionButtons}}
13
13
  @bulkActions={{this.bulkActions}}
14
14
  @controller={{this}}
15
+ @emptyStateComponent={{component
16
+ "table/empty-state"
17
+ icon="truck"
18
+ title="Add your first vehicle"
19
+ description="Vehicles connect assignments, live tracking, fleet capacity, maintenance, and compliance history."
20
+ filteredTitle="No vehicles match your filters"
21
+ filteredDescription="Adjust the search or filters to find another vehicle."
22
+ primaryText="New vehicle"
23
+ primaryIcon="plus"
24
+ primaryAction=this.vehicleActions.transition.create
25
+ secondaryText="Import"
26
+ secondaryIcon="upload"
27
+ secondaryAction=this.vehicleActions.import
28
+ docsSlug="fleet-ops/resources/vehicles/overview"
29
+ docsTitle="Vehicles guide"
30
+ docsText="Vehicle guide"
31
+ docsSource="fleet-ops-empty-vehicles"
32
+ }}
15
33
  />
16
34
  {{else}}
17
35
  <Layout::Section::Header @title={{t "resource.vehicles"}} @actionsWrapperClass="space-x-1">
@@ -46,4 +64,4 @@
46
64
  </Layout::Resource::CardsGrid>
47
65
  </Layout::Section::Body>
48
66
  {{/if}}
49
- {{outlet}}
67
+ {{outlet}}
@@ -11,5 +11,23 @@
11
11
  @actionButtons={{this.actionButtons}}
12
12
  @bulkActions={{this.bulkActions}}
13
13
  @controller={{this}}
14
+ @emptyStateComponent={{component
15
+ "table/empty-state"
16
+ icon="building"
17
+ title="Add your first vendor"
18
+ description="Vendors let your team manage external carriers, service providers, and operational partners."
19
+ filteredTitle="No vendors match your filters"
20
+ filteredDescription="Adjust the search or filters to find another vendor."
21
+ primaryText="New vendor"
22
+ primaryIcon="plus"
23
+ primaryAction=this.vendorActions.transition.create
24
+ secondaryText="Import"
25
+ secondaryIcon="upload"
26
+ secondaryAction=this.vendorActions.import
27
+ docsSlug="fleet-ops/resources/vendors/overview"
28
+ docsTitle="Vendors guide"
29
+ docsText="Vendor guide"
30
+ docsSource="fleet-ops-empty-vendors"
31
+ }}
14
32
  />
15
- {{outlet}}
33
+ {{outlet}}
@@ -11,5 +11,17 @@
11
11
  @actionButtons={{this.actionButtons}}
12
12
  @bulkActions={{this.bulkActions}}
13
13
  @controller={{this}}
14
+ @emptyStateComponent={{component
15
+ "table/empty-state"
16
+ icon="plug"
17
+ title="No integrated vendors yet"
18
+ description="Integrated vendor records appear here after vendor integrations are connected and synchronized."
19
+ filteredTitle="No integrated vendors match your filters"
20
+ filteredDescription="Adjust the search or filters to find another integrated vendor."
21
+ docsSlug="fleet-ops/resources/vendors/integrated-vendors"
22
+ docsTitle="Integrated vendors guide"
23
+ docsText="Integrated vendors guide"
24
+ docsSource="fleet-ops-empty-integrated-vendors"
25
+ }}
14
26
  />
15
- {{outlet}}
27
+ {{outlet}}
@@ -47,6 +47,24 @@
47
47
  @filterPickerGridCols="3"
48
48
  @filterPickerWidth="700px"
49
49
  @controller={{this}}
50
+ @emptyStateComponent={{component
51
+ "table/empty-state"
52
+ icon="paper-plane"
53
+ title="Create your first order"
54
+ description="Orders are the center of Fleet-Ops: plan routes, assign drivers and vehicles, track progress, and collect proof."
55
+ filteredTitle="No orders match your filters"
56
+ filteredDescription="Adjust the search, bulk search, or filters to find another order."
57
+ primaryText="New order"
58
+ primaryIcon="plus"
59
+ primaryAction=this.orderActions.transition.create
60
+ secondaryText="Import"
61
+ secondaryIcon="upload"
62
+ secondaryAction=this.importOrders
63
+ docsSlug="fleet-ops/operations/orders/overview"
64
+ docsTitle="Orders guide"
65
+ docsText="Order guide"
66
+ docsSource="fleet-ops-empty-orders"
67
+ }}
50
68
  @tfootVerticalOffset="7"
51
69
  @tfootVerticalOffsetElements="#next-view-section-subheader,.next-table-wrapper > table > thead,.next-map-container-topbar"
52
70
  />
@@ -88,4 +106,4 @@
88
106
  </Layout::Section::Body>
89
107
  {{/if}}
90
108
 
91
- {{outlet}}
109
+ {{outlet}}
@@ -10,5 +10,23 @@
10
10
  @actionButtons={{this.actionButtons}}
11
11
  @bulkActions={{this.bulkActions}}
12
12
  @controller={{this}}
13
+ @emptyStateComponent={{component
14
+ "table/empty-state"
15
+ icon="route"
16
+ title="Set up your first service rate"
17
+ description="Service rates define how Fleet-Ops prices routes, zones, distance, and other service rules."
18
+ filteredTitle="No service rates match your filters"
19
+ filteredDescription="Adjust the search or filters to find another service rate."
20
+ primaryText="New service rate"
21
+ primaryIcon="plus"
22
+ primaryAction=this.serviceRateActions.transition.create
23
+ secondaryText="Refresh"
24
+ secondaryIcon="refresh"
25
+ secondaryAction=this.serviceRateActions.refresh
26
+ docsSlug="fleet-ops/operations/service-rates/overview"
27
+ docsTitle="Service rates guide"
28
+ docsText="Service rates guide"
29
+ docsSource="fleet-ops-empty-service-rates"
30
+ }}
13
31
  />
14
- {{outlet}}
32
+ {{outlet}}