@fleetbase/fleetops-engine 0.6.51 → 0.6.52

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 (360) 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.js +20 -2
  20. package/addon/components/map/drawer/device-event-listing.hbs +12 -2
  21. package/addon/components/map/drawer/driver-listing.hbs +14 -1
  22. package/addon/components/map/drawer/place-listing.hbs +14 -1
  23. package/addon/components/map/drawer/position-listing.hbs +12 -2
  24. package/addon/components/map/drawer/vehicle-listing.hbs +14 -1
  25. package/addon/components/modals/assigned-orders.hbs +40 -0
  26. package/addon/components/modals/attach-device.hbs +4 -3
  27. package/addon/components/modals/attach-telematic-device.hbs +25 -0
  28. package/addon/components/modals/attach-telematic-device.js +3 -0
  29. package/addon/components/modals/driver-assign-order.hbs +7 -58
  30. package/addon/components/modals/driver-assign-vehicle.hbs +10 -2
  31. package/addon/components/modals/fleet-assign-driver.hbs +18 -0
  32. package/addon/components/modals/fleet-assign-driver.js +3 -0
  33. package/addon/components/modals/fleet-assign-vehicle.hbs +18 -0
  34. package/addon/components/modals/fleet-assign-vehicle.js +3 -0
  35. package/addon/components/modals/telematic-connection-diagnostics.hbs +75 -0
  36. package/addon/components/modals/telematic-connection-diagnostics.js +287 -0
  37. package/addon/components/modals/vehicle-details.hbs +6 -1
  38. package/addon/components/modals/vehicle-form.hbs +8 -1
  39. package/addon/components/order/card.hbs +106 -0
  40. package/addon/components/order/card.js +257 -0
  41. package/addon/components/order/form/service-rate.hbs +2 -0
  42. package/addon/components/service-rate/form.hbs +3 -2
  43. package/addon/components/telematic/details.hbs +98 -87
  44. package/addon/components/telematic/details.js +230 -1
  45. package/addon/components/telematic/form.hbs +303 -72
  46. package/addon/components/telematic/form.js +519 -3
  47. package/addon/components/telematic/hub.hbs +149 -0
  48. package/addon/components/telematic/hub.js +142 -0
  49. package/addon/components/telematic/settings.hbs +152 -0
  50. package/addon/components/telematic/settings.js +45 -0
  51. package/addon/components/telematic/tab-empty-state.hbs +29 -0
  52. package/addon/components/telematic/tab-empty-state.js +33 -0
  53. package/addon/components/vehicle/details.hbs +6 -1
  54. package/addon/components/vehicle/form.hbs +2 -1
  55. package/addon/components/widget/fuel-providers.hbs +43 -0
  56. package/addon/components/widget/fuel-providers.js +27 -0
  57. package/addon/controllers/connectivity/devices/index/details.js +27 -1
  58. package/addon/controllers/connectivity/devices/index.js +14 -0
  59. package/addon/controllers/connectivity/fuel-providers/details/sync.js +18 -0
  60. package/addon/controllers/connectivity/fuel-providers/details/transactions.js +24 -0
  61. package/addon/controllers/connectivity/fuel-providers/details.js +69 -0
  62. package/addon/controllers/connectivity/fuel-providers/edit.js +24 -0
  63. package/addon/controllers/connectivity/fuel-providers/index.js +177 -0
  64. package/addon/controllers/connectivity/fuel-providers/new.js +37 -0
  65. package/addon/controllers/connectivity/telematics/details/attachments.js +247 -0
  66. package/addon/controllers/connectivity/telematics/details/devices.js +368 -0
  67. package/addon/controllers/connectivity/telematics/details/events.js +244 -0
  68. package/addon/controllers/connectivity/telematics/details/index.js +3 -0
  69. package/addon/controllers/connectivity/telematics/details/logs.js +43 -0
  70. package/addon/controllers/connectivity/telematics/details/sensors.js +270 -0
  71. package/addon/controllers/connectivity/telematics/details.js +149 -0
  72. package/addon/controllers/connectivity/telematics/{index/edit.js → edit.js} +15 -4
  73. package/addon/controllers/connectivity/telematics/index.js +25 -5
  74. package/addon/controllers/connectivity/telematics/{index/new.js → new.js} +8 -2
  75. package/addon/controllers/management/drivers/index/details.js +78 -1
  76. package/addon/controllers/management/drivers/index.js +39 -0
  77. package/addon/controllers/management/fleets/index/details.js +23 -1
  78. package/addon/controllers/management/fleets/index.js +6 -1
  79. package/addon/controllers/management/fuel-reports/index.js +37 -1
  80. package/addon/controllers/management/fuel-transactions/index/details.js +70 -0
  81. package/addon/controllers/management/fuel-transactions/index.js +240 -0
  82. package/addon/controllers/management/vehicles/index/details.js +32 -0
  83. package/addon/controllers/management/vehicles/index.js +26 -0
  84. package/addon/controllers/operations/orders/index.js +4 -0
  85. package/addon/controllers/settings/payments/index.js +5 -0
  86. package/addon/extension.js +10 -0
  87. package/addon/routes/connectivity/fuel-providers/details/index.js +7 -0
  88. package/addon/routes/connectivity/fuel-providers/details/matching.js +7 -0
  89. package/addon/routes/connectivity/fuel-providers/details/settings.js +7 -0
  90. package/addon/routes/connectivity/fuel-providers/details/sync.js +18 -0
  91. package/addon/routes/connectivity/fuel-providers/details/transactions.js +14 -0
  92. package/addon/routes/connectivity/fuel-providers/details.js +18 -0
  93. package/addon/routes/connectivity/fuel-providers/edit.js +18 -0
  94. package/addon/routes/connectivity/fuel-providers/index.js +20 -0
  95. package/addon/routes/connectivity/fuel-providers/new.js +3 -0
  96. package/addon/routes/connectivity/fuel-providers.js +3 -0
  97. package/addon/routes/connectivity/telematics/details/attachments.js +28 -0
  98. package/addon/routes/connectivity/telematics/details/devices.js +30 -0
  99. package/addon/routes/connectivity/telematics/details/events.js +33 -0
  100. package/addon/routes/connectivity/telematics/details/index.js +3 -0
  101. package/addon/routes/connectivity/telematics/details/logs.js +17 -0
  102. package/addon/routes/connectivity/telematics/details/sensors.js +29 -0
  103. package/addon/routes/connectivity/telematics/{index/details.js → details.js} +1 -1
  104. package/addon/routes/connectivity/telematics/{index/edit.js → edit.js} +1 -1
  105. package/addon/routes/connectivity/telematics/new.js +3 -0
  106. package/addon/routes/management/drivers/index/details/activity.js +3 -0
  107. package/addon/routes/management/fuel-reports/index.js +2 -0
  108. package/addon/routes/management/fuel-transactions/index/details.js +18 -0
  109. package/addon/routes/management/fuel-transactions/index.js +21 -0
  110. package/addon/routes/management/fuel-transactions.js +3 -0
  111. package/addon/routes.js +28 -9
  112. package/addon/services/device-actions.js +64 -1
  113. package/addon/services/device-event-actions.js +12 -1
  114. package/addon/services/driver-actions.js +147 -11
  115. package/addon/services/fleet-actions.js +66 -1
  116. package/addon/services/fuel-integration-actions.js +31 -0
  117. package/addon/services/issue-actions.js +1 -1
  118. package/addon/services/telematic-actions.js +9 -3
  119. package/addon/services/vehicle-actions.js +125 -0
  120. package/addon/styles/fleetops-engine.css +310 -34
  121. package/addon/templates/analytics/reports/index.hbs +19 -1
  122. package/addon/templates/connectivity/devices/index.hbs +19 -1
  123. package/addon/templates/connectivity/events/index.hbs +16 -1
  124. package/addon/templates/connectivity/fuel-providers/details/index.hbs +38 -0
  125. package/addon/templates/connectivity/fuel-providers/details/matching.hbs +13 -0
  126. package/addon/templates/connectivity/fuel-providers/details/settings.hbs +11 -0
  127. package/addon/templates/connectivity/fuel-providers/details/sync.hbs +48 -0
  128. package/addon/templates/connectivity/fuel-providers/details/transactions.hbs +21 -0
  129. package/addon/templates/connectivity/fuel-providers/details.hbs +51 -0
  130. package/addon/templates/connectivity/fuel-providers/edit.hbs +24 -0
  131. package/addon/templates/connectivity/fuel-providers/index.hbs +12 -0
  132. package/addon/templates/connectivity/fuel-providers/new.hbs +22 -0
  133. package/addon/templates/connectivity/fuel-providers.hbs +1 -0
  134. package/addon/templates/connectivity/sensors/index.hbs +19 -1
  135. package/addon/templates/connectivity/telematics/details/attachments.hbs +163 -0
  136. package/addon/templates/connectivity/telematics/details/devices.hbs +88 -0
  137. package/addon/templates/connectivity/telematics/details/events.hbs +101 -0
  138. package/addon/templates/connectivity/telematics/{index/details → details}/index.hbs +0 -1
  139. package/addon/templates/connectivity/telematics/details/logs.hbs +69 -0
  140. package/addon/templates/connectivity/telematics/details/sensors.hbs +88 -0
  141. package/addon/templates/connectivity/telematics/details.hbs +53 -0
  142. package/addon/templates/connectivity/telematics/edit.hbs +27 -0
  143. package/addon/templates/connectivity/telematics/index.hbs +6 -8
  144. package/addon/templates/connectivity/telematics/new.hbs +24 -0
  145. package/addon/templates/maintenance/equipment/index.hbs +19 -1
  146. package/addon/templates/maintenance/maintenances/index.hbs +15 -1
  147. package/addon/templates/maintenance/parts/index.hbs +19 -1
  148. package/addon/templates/maintenance/schedules/index.hbs +19 -1
  149. package/addon/templates/maintenance/work-orders/index.hbs +19 -1
  150. package/addon/templates/management/contacts/customers.hbs +15 -1
  151. package/addon/templates/management/contacts/index.hbs +19 -1
  152. package/addon/templates/management/drivers/index/details/activity.hbs +1 -0
  153. package/addon/templates/management/drivers/index.hbs +19 -1
  154. package/addon/templates/management/fleets/index.hbs +19 -1
  155. package/addon/templates/management/fuel-reports/index.hbs +19 -1
  156. package/addon/templates/management/fuel-transactions/index/details.hbs +73 -0
  157. package/addon/templates/management/fuel-transactions/index.hbs +58 -0
  158. package/addon/templates/management/fuel-transactions.hbs +1 -0
  159. package/addon/templates/management/issues/index.hbs +19 -1
  160. package/addon/templates/management/places/index.hbs +19 -1
  161. package/addon/templates/management/vehicles/index.hbs +19 -1
  162. package/addon/templates/management/vendors/index.hbs +19 -1
  163. package/addon/templates/management/vendors/integrated.hbs +13 -1
  164. package/addon/templates/operations/orders/index.hbs +19 -1
  165. package/addon/templates/operations/service-rates/index.hbs +19 -1
  166. package/addon/templates/settings/payments/index.hbs +15 -1
  167. package/addon/utils/fleet-ops-options.js +3 -0
  168. package/app/components/cell/telematic-provider.js +1 -0
  169. package/app/components/cell/telematic-status.js +1 -0
  170. package/app/components/fuel-integration/form.js +1 -0
  171. package/app/components/fuel-integration/hub.js +1 -0
  172. package/app/components/fuel-integration/matching-priority.js +1 -0
  173. package/app/components/modals/assigned-orders.js +1 -0
  174. package/app/components/modals/attach-telematic-device.js +1 -0
  175. package/app/components/modals/fleet-assign-driver.js +1 -0
  176. package/app/components/modals/fleet-assign-vehicle.js +1 -0
  177. package/app/components/modals/telematic-connection-diagnostics.js +1 -0
  178. package/app/components/order/card.js +1 -0
  179. package/app/components/telematic/hub.js +1 -0
  180. package/app/components/telematic/settings.js +1 -0
  181. package/app/components/telematic/tab-empty-state.js +1 -0
  182. package/app/components/widget/fuel-providers.js +1 -0
  183. package/app/controllers/connectivity/fuel-providers/details/sync.js +1 -0
  184. package/app/controllers/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  185. package/app/controllers/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  186. package/app/controllers/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  187. package/app/controllers/connectivity/{telematics/index/details → fuel-providers}/index.js +1 -1
  188. package/app/controllers/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  189. package/app/controllers/connectivity/telematics/details/attachments.js +1 -0
  190. package/app/controllers/connectivity/telematics/details/devices.js +1 -0
  191. package/app/controllers/connectivity/telematics/details/events.js +1 -0
  192. package/app/controllers/connectivity/telematics/details/index.js +1 -0
  193. package/app/controllers/connectivity/telematics/details/logs.js +1 -0
  194. package/app/controllers/connectivity/telematics/details/sensors.js +1 -0
  195. package/app/controllers/connectivity/telematics/details.js +1 -0
  196. package/app/controllers/connectivity/telematics/edit.js +1 -0
  197. package/app/controllers/connectivity/telematics/new.js +1 -0
  198. package/app/controllers/management/fuel-transactions/index/details.js +1 -0
  199. package/app/controllers/management/fuel-transactions/index.js +1 -0
  200. package/app/routes/connectivity/{telematics/index → fuel-providers}/details/index.js +1 -1
  201. package/app/routes/connectivity/{telematics/index/details/events.js → fuel-providers/details/matching.js} +1 -1
  202. package/app/routes/connectivity/fuel-providers/details/settings.js +1 -0
  203. package/app/routes/connectivity/fuel-providers/details/sync.js +1 -0
  204. package/app/routes/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  205. package/app/routes/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  206. package/app/routes/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  207. package/app/routes/connectivity/fuel-providers/index.js +1 -0
  208. package/app/routes/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  209. package/app/routes/connectivity/fuel-providers.js +1 -0
  210. package/app/routes/connectivity/telematics/details/attachments.js +1 -0
  211. package/app/routes/connectivity/telematics/details/devices.js +1 -0
  212. package/app/routes/connectivity/telematics/details/events.js +1 -0
  213. package/app/routes/connectivity/telematics/details/index.js +1 -0
  214. package/app/routes/connectivity/telematics/details/logs.js +1 -0
  215. package/app/routes/connectivity/telematics/details/sensors.js +1 -0
  216. package/app/routes/connectivity/telematics/details.js +1 -0
  217. package/app/routes/connectivity/telematics/edit.js +1 -0
  218. package/app/routes/connectivity/telematics/new.js +1 -0
  219. package/app/routes/management/drivers/index/details/activity.js +1 -0
  220. package/app/routes/management/fuel-transactions/index/details.js +1 -0
  221. package/app/routes/management/fuel-transactions/index.js +1 -0
  222. package/app/routes/management/fuel-transactions.js +1 -0
  223. package/app/services/fuel-integration-actions.js +1 -0
  224. package/app/templates/connectivity/{telematics/index → fuel-providers}/details/index.js +1 -1
  225. package/app/templates/connectivity/{telematics/index/details/events.js → fuel-providers/details/matching.js} +1 -1
  226. package/app/templates/connectivity/fuel-providers/details/settings.js +1 -0
  227. package/app/templates/connectivity/fuel-providers/details/sync.js +1 -0
  228. package/app/templates/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  229. package/app/templates/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  230. package/app/templates/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  231. package/app/templates/connectivity/fuel-providers/index.js +1 -0
  232. package/app/templates/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  233. package/app/templates/connectivity/fuel-providers.js +1 -0
  234. package/app/templates/connectivity/telematics/details/attachments.js +1 -0
  235. package/app/templates/connectivity/telematics/details/devices.js +1 -0
  236. package/app/templates/connectivity/telematics/details/events.js +1 -0
  237. package/app/templates/connectivity/telematics/details/index.js +1 -0
  238. package/app/templates/connectivity/telematics/details/logs.js +1 -0
  239. package/app/templates/connectivity/telematics/details/sensors.js +1 -0
  240. package/app/templates/connectivity/telematics/details.js +1 -0
  241. package/app/templates/connectivity/telematics/edit.js +1 -0
  242. package/app/templates/connectivity/telematics/new.js +1 -0
  243. package/app/templates/management/drivers/index/details/activity.js +1 -0
  244. package/app/templates/management/fuel-transactions/index/details.js +1 -0
  245. package/app/templates/management/fuel-transactions/index.js +1 -0
  246. package/app/templates/management/fuel-transactions.js +1 -0
  247. package/assets/images/telematics/providers/afaqy.webp +0 -0
  248. package/assets/images/telematics/providers/default.webp +0 -0
  249. package/assets/images/telematics/providers/flespi.webp +0 -0
  250. package/assets/images/telematics/providers/geotab.webp +0 -0
  251. package/assets/images/telematics/providers/safee.webp +0 -0
  252. package/assets/images/telematics/providers/samsara.webp +0 -0
  253. package/composer.json +1 -1
  254. package/extension.json +1 -1
  255. package/package.json +4 -4
  256. package/server/config/fuel-providers.php +42 -0
  257. package/server/config/telematics.php +139 -130
  258. package/server/migrations/2026_06_06_000001_harden_device_events_telematics_contract.php +59 -0
  259. package/server/migrations/2026_06_08_000001_create_fuel_provider_connections_table.php +37 -0
  260. package/server/migrations/2026_06_08_000002_create_fuel_provider_transactions_table.php +53 -0
  261. package/server/migrations/2026_06_08_000003_create_fuel_provider_sync_runs_table.php +40 -0
  262. package/server/migrations/2026_06_10_000001_add_fuel_card_number_to_vehicles_table.php +25 -0
  263. package/server/migrations/2026_06_10_000002_add_vehicle_identity_columns_to_fuel_provider_transactions_table.php +39 -0
  264. package/server/src/Contracts/FuelProvider.php +30 -0
  265. package/server/src/Contracts/TelematicProviderDescriptor.php +3 -1
  266. package/server/src/Events/FuelProviderTransactionImported.php +17 -0
  267. package/server/src/Events/FuelProviderTransactionMatched.php +17 -0
  268. package/server/src/Events/FuelProviderTransactionUnmatched.php +17 -0
  269. package/server/src/Events/FuelReportCreatedFromProvider.php +18 -0
  270. package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +6 -0
  271. package/server/src/Http/Controllers/Internal/v1/DeviceController.php +76 -2
  272. package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +44 -0
  273. package/server/src/Http/Controllers/Internal/v1/DriverController.php +158 -7
  274. package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +124 -0
  275. package/server/src/Http/Controllers/Internal/v1/FuelProviderSyncRunController.php +10 -0
  276. package/server/src/Http/Controllers/Internal/v1/FuelProviderTransactionController.php +76 -0
  277. package/server/src/Http/Controllers/Internal/v1/SensorController.php +1 -1
  278. package/server/src/Http/Controllers/Internal/v1/TelematicController.php +178 -15
  279. package/server/src/Http/Controllers/Internal/v1/VehicleController.php +165 -0
  280. package/server/src/Http/Controllers/TelematicWebhookController.php +103 -19
  281. package/server/src/Http/Filter/FuelProviderConnectionFilter.php +33 -0
  282. package/server/src/Http/Filter/FuelProviderSyncRunFilter.php +28 -0
  283. package/server/src/Http/Filter/FuelProviderTransactionFilter.php +59 -0
  284. package/server/src/Http/Filter/FuelReportFilter.php +10 -0
  285. package/server/src/Http/Resources/v1/Driver.php +15 -0
  286. package/server/src/Http/Resources/v1/FuelProviderConnection.php +30 -0
  287. package/server/src/Http/Resources/v1/FuelProviderSyncRun.php +36 -0
  288. package/server/src/Http/Resources/v1/FuelProviderTransaction.php +54 -0
  289. package/server/src/Http/Resources/v1/FuelReport.php +28 -22
  290. package/server/src/Http/Resources/v1/Index/Driver.php +26 -20
  291. package/server/src/Http/Resources/v1/Index/Vehicle.php +29 -22
  292. package/server/src/Http/Resources/v1/Vehicle.php +17 -0
  293. package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +2 -0
  294. package/server/src/Jobs/SyncFuelProviderTransactionsJob.php +57 -0
  295. package/server/src/Jobs/SyncTelematicDevicesJob.php +36 -6
  296. package/server/src/Jobs/TestTelematicConnectionJob.php +9 -22
  297. package/server/src/Models/Asset.php +2 -1
  298. package/server/src/Models/Contact.php +2 -1
  299. package/server/src/Models/Device.php +27 -4
  300. package/server/src/Models/DeviceEvent.php +40 -3
  301. package/server/src/Models/Driver.php +2 -1
  302. package/server/src/Models/Equipment.php +2 -1
  303. package/server/src/Models/Fleet.php +2 -1
  304. package/server/src/Models/FuelProviderConnection.php +60 -0
  305. package/server/src/Models/FuelProviderSyncRun.php +58 -0
  306. package/server/src/Models/FuelProviderTransaction.php +119 -0
  307. package/server/src/Models/FuelReport.php +16 -1
  308. package/server/src/Models/Part.php +2 -1
  309. package/server/src/Models/Sensor.php +21 -4
  310. package/server/src/Models/ServiceRate.php +39 -2
  311. package/server/src/Models/Vehicle.php +14 -2
  312. package/server/src/Models/Vendor.php +2 -1
  313. package/server/src/Providers/FleetOpsServiceProvider.php +10 -0
  314. package/server/src/Support/Analytics/FuelProviderSummary.php +42 -0
  315. package/server/src/Support/FuelProviders/FuelProviderDescriptor.php +55 -0
  316. package/server/src/Support/FuelProviders/FuelProviderRegistry.php +75 -0
  317. package/server/src/Support/FuelProviders/FuelProviderService.php +447 -0
  318. package/server/src/Support/FuelProviders/Providers/AbstractFuelProvider.php +98 -0
  319. package/server/src/Support/FuelProviders/Providers/PetroAppFuelProvider.php +167 -0
  320. package/server/src/Support/Telematics/Providers/AbstractProvider.php +27 -6
  321. package/server/src/Support/Telematics/Providers/AfaqyProvider.php +55 -26
  322. package/server/src/Support/Telematics/Providers/FlespiProvider.php +1 -0
  323. package/server/src/Support/Telematics/Providers/GeotabProvider.php +1 -0
  324. package/server/src/Support/Telematics/Providers/SafeeProvider.php +32 -22
  325. package/server/src/Support/Telematics/Providers/SamsaraProvider.php +3 -1
  326. package/server/src/Support/Telematics/TelematicService.php +340 -21
  327. package/server/src/routes.php +41 -4
  328. package/server/tests/FuelProviderRegistryTest.php +416 -0
  329. package/server/tests/ServiceRateAlgorithmWeightVariablesTest.php +44 -0
  330. package/server/tests/TelematicsHardeningTest.php +268 -0
  331. package/server/tests/VehicleDriverAssignmentTest.php +51 -0
  332. package/translations/ar-ae.yml +22 -0
  333. package/translations/bg-bg.yaml +72 -0
  334. package/translations/en-us.yaml +83 -0
  335. package/translations/es-pa.yaml +72 -0
  336. package/translations/fr-fr.yaml +72 -0
  337. package/translations/mn-mn.yaml +72 -0
  338. package/translations/pt-br.yaml +72 -0
  339. package/translations/ru-ru.yaml +72 -0
  340. package/translations/vi-vn.yaml +97 -0
  341. package/addon/controllers/connectivity/telematics/index/details/devices.js +0 -3
  342. package/addon/controllers/connectivity/telematics/index/details/events.js +0 -3
  343. package/addon/controllers/connectivity/telematics/index/details/index.js +0 -3
  344. package/addon/controllers/connectivity/telematics/index/details/sensors.js +0 -3
  345. package/addon/controllers/connectivity/telematics/index/details.js +0 -24
  346. package/addon/routes/connectivity/telematics/index/details/devices.js +0 -3
  347. package/addon/routes/connectivity/telematics/index/details/events.js +0 -3
  348. package/addon/routes/connectivity/telematics/index/details/index.js +0 -3
  349. package/addon/routes/connectivity/telematics/index/details/sensors.js +0 -3
  350. package/addon/routes/connectivity/telematics/index/new.js +0 -3
  351. package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
  352. package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
  353. package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
  354. package/addon/templates/connectivity/telematics/index/details.hbs +0 -14
  355. package/addon/templates/connectivity/telematics/index/edit.hbs +0 -12
  356. package/addon/templates/connectivity/telematics/index/new.hbs +0 -12
  357. package/app/controllers/connectivity/telematics/index/details/events.js +0 -1
  358. package/app/controllers/connectivity/telematics/index/details/sensors.js +0 -1
  359. package/app/routes/connectivity/telematics/index/details/sensors.js +0 -1
  360. package/app/templates/connectivity/telematics/index/details/sensors.js +0 -1
@@ -0,0 +1,145 @@
1
+ import Component from '@glimmer/component';
2
+ import { action } from '@ember/object';
3
+
4
+ const MATCHING_FIELDS = [
5
+ {
6
+ key: 'plate_number',
7
+ label: 'Plate number',
8
+ source: 'Provider plate number',
9
+ target: 'Vehicle plate number',
10
+ description: 'Best default for fuel card imports. Matches license plates with normalized spacing and casing.',
11
+ },
12
+ {
13
+ key: 'internal_id',
14
+ label: 'Internal ID',
15
+ source: 'Provider internal fleet number',
16
+ target: 'Vehicle internal ID',
17
+ description: 'Use when the provider fleet number is the same identifier operators maintain on the vehicle.',
18
+ },
19
+ {
20
+ key: 'vin',
21
+ label: 'VIN',
22
+ source: 'Provider VIN',
23
+ target: 'Vehicle VIN',
24
+ description: 'Matches the vehicle identification number when the provider sends it with the transaction.',
25
+ },
26
+ {
27
+ key: 'serial_number',
28
+ label: 'Serial number',
29
+ source: 'Provider serial number',
30
+ target: 'Vehicle serial number',
31
+ description: 'Matches manufacturer or fleet serial numbers recorded on the vehicle.',
32
+ },
33
+ {
34
+ key: 'call_sign',
35
+ label: 'Call sign',
36
+ source: 'Provider call sign',
37
+ target: 'Vehicle call sign',
38
+ description: 'Matches operational call signs when those are shared with the fuel provider.',
39
+ },
40
+ {
41
+ key: 'fuel_card_number',
42
+ label: 'Fuel card number',
43
+ source: 'Provider fuel card number',
44
+ target: 'Vehicle fuel card number',
45
+ description: 'Use when each vehicle has a dedicated fuel card number saved on the vehicle record.',
46
+ },
47
+ {
48
+ key: 'trip_number',
49
+ label: 'Trip number / order reference',
50
+ source: 'Provider trip/order reference',
51
+ target: 'Order public ID, internal ID, or tracking number',
52
+ description: 'Links the transaction to an order when the provider sends a trip or order reference. It does not identify the vehicle by itself.',
53
+ },
54
+ {
55
+ key: 'provider_vehicle_id',
56
+ label: 'Provider vehicle ID',
57
+ source: 'Provider-specific vehicle ID',
58
+ target: 'Vehicle provider metadata',
59
+ description: 'Advanced fallback only. Use it when provider vehicle IDs have been intentionally stored on vehicle metadata.',
60
+ },
61
+ ];
62
+
63
+ const DEFAULT_MATCHING_ORDER = ['plate_number', 'internal_id', 'vin', 'serial_number', 'call_sign', 'fuel_card_number', 'trip_number'];
64
+ const LEGACY_DEFAULT_MATCHING_ORDER = ['provider_vehicle_id', 'internal_number', 'structure_number', 'plate_number', 'vehicle_card_id', 'trip_number'];
65
+ const LEGACY_FIELD_ALIASES = {
66
+ internal_number: 'internal_id',
67
+ vehicle_card_id: 'fuel_card_number',
68
+ };
69
+
70
+ export default class FuelIntegrationMatchingPriorityComponent extends Component {
71
+ fields = MATCHING_FIELDS;
72
+
73
+ get order() {
74
+ if (Array.isArray(this.args.order)) {
75
+ if (this.args.order.join('|') === LEGACY_DEFAULT_MATCHING_ORDER.join('|')) {
76
+ return DEFAULT_MATCHING_ORDER;
77
+ }
78
+
79
+ return Array.from(this.args.order)
80
+ .map((key) => LEGACY_FIELD_ALIASES[key] ?? key)
81
+ .filter((key, index, order) => key && order.indexOf(key) === index);
82
+ }
83
+
84
+ return DEFAULT_MATCHING_ORDER;
85
+ }
86
+
87
+ get selectedFields() {
88
+ const lastIndex = this.order.length - 1;
89
+
90
+ return this.order
91
+ .map((key, index) => {
92
+ const field = this.fields.find((option) => option.key === key);
93
+ if (!field) {
94
+ return null;
95
+ }
96
+
97
+ return {
98
+ ...field,
99
+ index,
100
+ priority: index + 1,
101
+ canMoveUp: index > 0,
102
+ canMoveDown: index < lastIndex,
103
+ };
104
+ })
105
+ .filter(Boolean);
106
+ }
107
+
108
+ get availableFields() {
109
+ const selected = new Set(this.order);
110
+ return this.fields.filter((field) => !selected.has(field.key));
111
+ }
112
+
113
+ get hasSelectedFields() {
114
+ return this.selectedFields.length > 0;
115
+ }
116
+
117
+ updateOrder(order) {
118
+ this.args.onChange?.(order);
119
+ }
120
+
121
+ @action addField(field) {
122
+ if (this.order.includes(field.key)) {
123
+ return;
124
+ }
125
+
126
+ this.updateOrder([...this.order, field.key]);
127
+ }
128
+
129
+ @action removeField(field) {
130
+ this.updateOrder(this.order.filter((key) => key !== field.key));
131
+ }
132
+
133
+ @action moveField(field, direction) {
134
+ const currentIndex = this.order.indexOf(field.key);
135
+ const nextIndex = currentIndex + direction;
136
+
137
+ if (currentIndex < 0 || nextIndex < 0 || nextIndex >= this.order.length) {
138
+ return;
139
+ }
140
+
141
+ const nextOrder = [...this.order];
142
+ [nextOrder[currentIndex], nextOrder[nextIndex]] = [nextOrder[nextIndex], nextOrder[currentIndex]];
143
+ this.updateOrder(nextOrder);
144
+ }
145
+ }
@@ -9,6 +9,18 @@
9
9
  <div class="field-name">{{t "common.status"}}</div>
10
10
  <div class="field-value"><Badge @status={{@resource.status}} /></div>
11
11
  </div>
12
+ {{#if @resource.source}}
13
+ <div class="field-info-container">
14
+ <div class="field-name">Source</div>
15
+ <div class="field-value"><Badge @status={{@resource.source}} /></div>
16
+ </div>
17
+ {{/if}}
18
+ {{#if @resource.provider}}
19
+ <div class="field-info-container">
20
+ <div class="field-name">Provider</div>
21
+ <div class="field-value uppercase">{{@resource.provider}}</div>
22
+ </div>
23
+ {{/if}}
12
24
  <div class="field-info-container">
13
25
  <div class="field-name">{{t "fuel-report.fields.reporter"}}</div>
14
26
  <div class="field-value">{{n-a @resource.reporter_name}}</div>
@@ -45,4 +57,4 @@
45
57
  </ContentPanel>
46
58
 
47
59
  <CustomField::Yield @subject={{@resource}} @viewMode={{true}} @wrapperClass="bordered-top" />
48
- </div>
60
+ </div>
@@ -139,67 +139,13 @@
139
139
  </section>
140
140
 
141
141
  <section class="issue-detail-side-card">
142
- <div class="issue-detail-section-title">Linked Order</div>
142
+ <div class="issue-detail-section-title">{{t "order.card.linked-order"}}</div>
143
143
  {{#if this.order}}
144
- <button type="button" class="issue-detail-order-card" {{on "click" this.viewOrder}}>
145
- <div class="issue-detail-order-topline">
146
- <div class="issue-detail-order-title-block">
147
- <div class="issue-detail-order-title">{{this.orderLabel}}</div>
148
- <div class="issue-detail-order-subtitle">{{n-a (smart-humanize this.order.type)}}</div>
149
- </div>
150
- <Badge @status={{this.order.status}} />
151
- </div>
152
- <div class="issue-detail-order-progress {{this.orderProgressClass}}">
153
- <span></span>
154
- </div>
155
- {{#if this.hasOrderStops}}
156
- <div class="issue-detail-order-route">
157
- <div class="issue-detail-order-stop">
158
- <div class="issue-detail-order-stop-marker pickup">1</div>
159
- <div class="min-w-0">
160
- <div class="issue-detail-order-stop-label">Pickup</div>
161
- <div class="issue-detail-order-stop-address">{{n-a this.orderOriginAddress "No pickup address"}}</div>
162
- </div>
163
- </div>
164
- {{#if this.isMultiStopOrder}}
165
- <div class="issue-detail-order-stop compact">
166
- <div class="issue-detail-order-stop-marker middle">+</div>
167
- <div class="min-w-0">
168
- <div class="issue-detail-order-stop-label">Waypoints</div>
169
- <div class="issue-detail-order-stop-address">{{this.middleStopCount}} additional {{if (eq this.middleStopCount 1) "stop" "stops"}}</div>
170
- </div>
171
- </div>
172
- {{/if}}
173
- <div class="issue-detail-order-stop">
174
- <div class="issue-detail-order-stop-marker dropoff">{{this.orderStopCount}}</div>
175
- <div class="min-w-0">
176
- <div class="issue-detail-order-stop-label">{{if (eq this.orderDestination.type "return") "Return" "Dropoff"}}</div>
177
- <div class="issue-detail-order-stop-address">{{n-a this.orderDestinationAddress "No dropoff address"}}</div>
178
- </div>
179
- </div>
180
- </div>
181
- {{else}}
182
- <div class="issue-detail-empty issue-detail-empty-compact">
183
- <FaIcon @icon="route" />
184
- <span>No route details available.</span>
185
- </div>
186
- {{/if}}
187
- <div class="issue-detail-order-meta">
188
- {{#if this.orderScheduledAt}}
189
- <span><FaIcon @icon="calendar" /> {{format-date-fns this.orderScheduledAt "MMM d, HH:mm"}}</span>
190
- {{/if}}
191
- {{#if this.orderDriverLabel}}
192
- <span><FaIcon @icon="id-card" /> {{this.orderDriverLabel}}</span>
193
- {{/if}}
194
- {{#if this.orderVehicleLabel}}
195
- <span><FaIcon @icon="truck" /> {{this.orderVehicleLabel}}</span>
196
- {{/if}}
197
- </div>
198
- </button>
144
+ <Order::Card @order={{this.order}} @variant="default" @interactive={{true}} @onClick={{this.viewOrder}} />
199
145
  {{else}}
200
146
  <div class="issue-detail-empty">
201
147
  <FaIcon @icon="route" />
202
- <span>No order is linked to this issue.</span>
148
+ <span>{{t "order.card.no-order-linked"}}</span>
203
149
  </div>
204
150
  {{/if}}
205
151
  </section>
@@ -3,9 +3,6 @@ import { inject as service } from '@ember/service';
3
3
  import { action } from '@ember/object';
4
4
  import { formatDistanceStrict, isValid } from 'date-fns';
5
5
 
6
- const COMPLETE_ORDER_STATUSES = ['completed', 'delivered'];
7
- const ACTIVE_ORDER_STATUSES = ['dispatched', 'started', 'in_progress', 'driver_enroute', 'driver_nearby'];
8
-
9
6
  export default class IssueDetailsComponent extends Component {
10
7
  @service hostRouter;
11
8
  @service issueActions;
@@ -121,104 +118,11 @@ export default class IssueDetailsComponent extends Component {
121
118
  return formatDistanceStrict(createdAt, resolvedAt);
122
119
  }
123
120
 
124
- get orderLabel() {
125
- return this.order?.tracking_number?.tracking_number || this.order?.tracking_number || this.order?.tracking || this.order?.public_id || this.order?.id;
126
- }
127
-
128
- get orderStops() {
129
- const payload = this.order?.payload ?? {};
130
- const stops = [];
131
-
132
- if (payload.pickup) {
133
- stops.push({ type: 'pickup', place: payload.pickup });
134
- }
135
-
136
- (payload.waypoints ?? []).forEach((waypoint, index) => {
137
- stops.push({
138
- type: waypoint.type ?? 'waypoint',
139
- place: waypoint.place ?? waypoint,
140
- index: index + 1,
141
- });
142
- });
143
-
144
- if (payload.dropoff) {
145
- stops.push({ type: 'dropoff', place: payload.dropoff });
146
- }
147
-
148
- if (payload.return) {
149
- stops.push({ type: 'return', place: payload.return });
150
- }
151
-
152
- return stops.filter((stop) => this.addressForPlace(stop.place));
153
- }
154
-
155
- get orderOrigin() {
156
- return this.orderStops[0];
157
- }
158
-
159
- get orderDestination() {
160
- return this.orderStops[this.orderStops.length - 1];
161
- }
162
-
163
- get orderOriginAddress() {
164
- return this.addressForPlace(this.orderOrigin?.place);
165
- }
166
-
167
- get orderDestinationAddress() {
168
- return this.addressForPlace(this.orderDestination?.place);
169
- }
170
-
171
- get orderStopCount() {
172
- return this.orderStops.length;
173
- }
174
-
175
- get middleStopCount() {
176
- return Math.max(this.orderStopCount - 2, 0);
177
- }
178
-
179
- get isMultiStopOrder() {
180
- return this.orderStopCount > 2;
181
- }
182
-
183
- get hasOrderStops() {
184
- return this.orderStopCount > 0;
185
- }
186
-
187
- get orderProgressClass() {
188
- const status = this.order?.status;
189
-
190
- if (COMPLETE_ORDER_STATUSES.includes(status)) {
191
- return 'is-complete';
192
- }
193
-
194
- if (ACTIVE_ORDER_STATUSES.includes(status)) {
195
- return 'is-active';
196
- }
197
-
198
- return 'is-pending';
199
- }
200
-
201
- get orderScheduledAt() {
202
- return this.order?.scheduled_at || this.order?.created_at || this.order?.createdAt;
203
- }
204
-
205
- get orderDriverLabel() {
206
- return this.order?.driver_assigned?.name || this.order?.driver_name || this.order?.driver?.name;
207
- }
208
-
209
- get orderVehicleLabel() {
210
- return this.order?.vehicle_assigned?.displayName || this.order?.vehicle_assigned?.display_name || this.order?.vehicle_name || this.order?.vehicle?.displayName;
211
- }
212
-
213
121
  get hasLocation() {
214
122
  const location = this.resource?.location;
215
123
  return Boolean(location?.latitude || location?.longitude || location?.coordinates);
216
124
  }
217
125
 
218
- addressForPlace(place) {
219
- return place?.address ?? place?.address_html ?? place?.street1 ?? place?.name;
220
- }
221
-
222
126
  dateFromValue(value) {
223
127
  if (!value) {
224
128
  return null;
@@ -162,6 +162,15 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
162
162
  },
163
163
  {
164
164
  priority: 7,
165
+ intl: 'menu.fuel-transactions',
166
+ title: this.intl.t('menu.fuel-transactions'),
167
+ icon: 'credit-card',
168
+ route: 'management.fuel-transactions',
169
+ permission: 'fleet-ops list fuel-report',
170
+ visible: this.abilities.can('fleet-ops see fuel-report'),
171
+ },
172
+ {
173
+ priority: 8,
165
174
  intl: 'menu.issues',
166
175
  title: this.intl.t('menu.issues'),
167
176
  icon: 'triangle-exclamation',
@@ -184,6 +193,15 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
184
193
  },
185
194
  {
186
195
  priority: 1,
196
+ intl: 'menu.fuel-providers',
197
+ title: this.intl.t('menu.fuel-providers'),
198
+ icon: 'gas-pump',
199
+ route: 'connectivity.fuel-providers',
200
+ permission: 'fleet-ops list fuel-report',
201
+ visible: this.abilities.can('fleet-ops see fuel-report'),
202
+ },
203
+ {
204
+ priority: 2,
187
205
  intl: 'menu.devices',
188
206
  title: this.intl.t('menu.devices'),
189
207
  icon: 'hard-drive',
@@ -192,7 +210,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
192
210
  visible: this.abilities.can('fleet-ops see device'),
193
211
  },
194
212
  {
195
- priority: 2,
213
+ priority: 3,
196
214
  intl: 'menu.sensors',
197
215
  title: this.intl.t('menu.sensors'),
198
216
  icon: 'temperature-full',
@@ -201,7 +219,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
201
219
  visible: this.abilities.can('fleet-ops see sensor'),
202
220
  },
203
221
  {
204
- priority: 3,
222
+ priority: 4,
205
223
  intl: 'menu.events',
206
224
  title: this.intl.t('menu.events'),
207
225
  icon: 'stream',
@@ -60,5 +60,15 @@
60
60
  {{/if}}
61
61
  </div>
62
62
  </div>
63
- <Table @rows={{this.events}} @columns={{this.columns}} />
64
- <Spacer @height="200px" />
63
+ <Table
64
+ @rows={{this.events}}
65
+ @columns={{this.columns}}
66
+ @emptyStateComponent={{component
67
+ "table/empty-state"
68
+ variant="compact"
69
+ icon="bolt"
70
+ title="No device events"
71
+ description="Events appear here after connected devices report activity for the selected filters."
72
+ }}
73
+ />
74
+ <Spacer @height="200px" />
@@ -3,4 +3,17 @@
3
3
  <Input @value={{this.query}} @type="text" class="form-input form-input-sm w-60" placeholder={{t "live-map-drawer.driver-listing.message"}} />
4
4
  </div>
5
5
  </div>
6
- <Table @rows={{this.filteredDrivers}} @columns={{this.columns}} />
6
+ <Table
7
+ @rows={{this.filteredDrivers}}
8
+ @columns={{this.columns}}
9
+ @searchQuery={{this.query}}
10
+ @emptyStateComponent={{component
11
+ "table/empty-state"
12
+ variant="compact"
13
+ icon="id-card"
14
+ title="No drivers visible"
15
+ description="Drivers appear here when they are available in the live map context."
16
+ filteredTitle="No drivers match this search"
17
+ filteredDescription="Adjust the search to find another driver."
18
+ }}
19
+ />
@@ -3,4 +3,17 @@
3
3
  <Input @value={{this.query}} @type="text" class="form-input form-input-sm w-60" placeholder={{t "live-map-drawer.place-listing.message"}} />
4
4
  </div>
5
5
  </div>
6
- <Table @rows={{this.filteredPlaces}} @columns={{this.columns}} />
6
+ <Table
7
+ @rows={{this.filteredPlaces}}
8
+ @columns={{this.columns}}
9
+ @searchQuery={{this.query}}
10
+ @emptyStateComponent={{component
11
+ "table/empty-state"
12
+ variant="compact"
13
+ icon="location-dot"
14
+ title="No places visible"
15
+ description="Places appear here when they are available in the current map context."
16
+ filteredTitle="No places match this search"
17
+ filteredDescription="Adjust the search to find another place."
18
+ }}
19
+ />
@@ -96,5 +96,15 @@
96
96
  </div>
97
97
  </div>
98
98
  </div>
99
- <Table @rows={{this.positions}} @columns={{this.columns}} />
100
- <Spacer @height="400px" />
99
+ <Table
100
+ @rows={{this.positions}}
101
+ @columns={{this.columns}}
102
+ @emptyStateComponent={{component
103
+ "table/empty-state"
104
+ variant="compact"
105
+ icon="route"
106
+ title="No positions loaded"
107
+ description="Select a trackable and date range to load position history for replay."
108
+ }}
109
+ />
110
+ <Spacer @height="400px" />
@@ -3,4 +3,17 @@
3
3
  <Input @value={{this.query}} @type="text" class="form-input form-input-sm w-60" placeholder={{t "live-map-drawer.vehicle-listing.message"}} />
4
4
  </div>
5
5
  </div>
6
- <Table @rows={{this.filteredVehicles}} @columns={{this.columns}} />
6
+ <Table
7
+ @rows={{this.filteredVehicles}}
8
+ @columns={{this.columns}}
9
+ @searchQuery={{this.query}}
10
+ @emptyStateComponent={{component
11
+ "table/empty-state"
12
+ variant="compact"
13
+ icon="truck"
14
+ title="No vehicles visible"
15
+ description="Vehicles appear here when they are available in the live map context."
16
+ filteredTitle="No vehicles match this search"
17
+ filteredDescription="Adjust the search to find another vehicle."
18
+ }}
19
+ />
@@ -0,0 +1,40 @@
1
+ <Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
2
+ <div class="modal-body-container">
3
+ <div class="mb-4 rounded-md border border-gray-200 bg-gray-50 p-3 dark:border-gray-700 dark:bg-gray-800">
4
+ <div class="text-xs font-semibold uppercase text-gray-500 dark:text-gray-400">{{@options.subjectLabel}}</div>
5
+ <div class="mt-1 text-sm font-semibold text-gray-900 dark:text-gray-100">{{@options.subjectName}}</div>
6
+ <div class="mt-1 text-xs text-gray-500 dark:text-gray-400">{{t "modals.assigned-orders.help-text" count=@options.orders.length}}</div>
7
+ </div>
8
+
9
+ <div class="space-y-2">
10
+ {{#each @options.orders as |order|}}
11
+ <div class="rounded-md border border-gray-200 p-3 dark:border-gray-700">
12
+ <div class="flex items-start gap-3">
13
+ <Checkbox
14
+ @value={{includes order.id @options.selectedOrderIds}}
15
+ @onToggle={{fn @options.toggleOrder order}}
16
+ @alignItems="center"
17
+ @labelClass="mb-0i"
18
+ />
19
+ <div class="min-w-0 flex-1">
20
+ <div class="flex items-center justify-between gap-2">
21
+ <div class="truncate text-sm font-semibold text-gray-900 dark:text-gray-100">
22
+ {{or order.tracking order.public_id order.id}}
23
+ </div>
24
+ <div class="flex shrink-0 items-center gap-1">
25
+ {{#if order.is_current_job}}
26
+ <Badge @hideStatusDot={{true}} @status="info">{{t "common.current-job"}}</Badge>
27
+ {{/if}}
28
+ <Badge @hideStatusDot={{true}} @status={{order.status}} />
29
+ </div>
30
+ </div>
31
+ <div class="mt-1 truncate text-xs text-gray-500 dark:text-gray-400">
32
+ {{or order.internal_id order.public_id}}
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ {{/each}}
38
+ </div>
39
+ </div>
40
+ </Modal::Default>
@@ -1,12 +1,13 @@
1
1
  <Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
2
2
  <div class="modal-body-container">
3
- <InputGroup @name={{t "common.select-field" field=(t "resource.device")}} @value={{@options.driver.vehicle_uuid}}>
3
+ <InputGroup @name={{t "common.select-field" field=(t "resource.device")}} @value={{@options.selectedDevice}}>
4
4
  <ModelSelect
5
5
  @modelName="device"
6
6
  @selectedModel={{@options.selectedDevice}}
7
+ @query={{hash attachment_state="unattached"}}
7
8
  @placeholder={{t "common.select-field" field=(t "resource.device")}}
8
9
  @triggerClass="form-select form-input"
9
- @infiniteScroll={{false}}
10
+ @infiniteScroll={{true}}
10
11
  @renderInPlace={{true}}
11
12
  @onChange={{fn (mut @options.selectedDevice)}}
12
13
  as |model|
@@ -15,4 +16,4 @@
15
16
  </ModelSelect>
16
17
  </InputGroup>
17
18
  </div>
18
- </Modal::Default>
19
+ </Modal::Default>
@@ -0,0 +1,25 @@
1
+ <Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
2
+ <div class="modal-body-container">
3
+ <div class="mb-4 rounded-md border border-gray-200 bg-gray-50 p-3 dark:border-gray-700 dark:bg-gray-800">
4
+ <div class="text-xs font-semibold uppercase text-gray-500 dark:text-gray-400">Synced device</div>
5
+ <div class="mt-2">
6
+ <Device::Pill @device={{@options.device}} />
7
+ </div>
8
+ </div>
9
+
10
+ <InputGroup @name={{t "common.select-field" field=(t "resource.vehicle")}} @value={{@options.selectedVehicle}}>
11
+ <ModelSelect
12
+ @modelName="vehicle"
13
+ @selectedModel={{@options.selectedVehicle}}
14
+ @placeholder={{t "common.select-field" field=(t "resource.vehicle")}}
15
+ @triggerClass="form-select form-input"
16
+ @infiniteScroll={{true}}
17
+ @renderInPlace={{true}}
18
+ @onChange={{fn (mut @options.selectedVehicle)}}
19
+ as |vehicle|
20
+ >
21
+ <Vehicle::Pill @resource={{vehicle}} />
22
+ </ModelSelect>
23
+ </InputGroup>
24
+ </div>
25
+ </Modal::Default>
@@ -0,0 +1,3 @@
1
+ import Component from '@glimmer/component';
2
+
3
+ export default class ModalsAttachTelematicDeviceComponent extends Component {}