@fleetbase/fleetops-engine 0.6.50 → 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 (494) hide show
  1. package/README.md +183 -67
  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/contact/panel-header.hbs +11 -48
  7. package/addon/components/customer/details.hbs +1 -2
  8. package/addon/components/customer/form.hbs +63 -51
  9. package/addon/components/customer/form.js +27 -1
  10. package/addon/components/customer/orders.hbs +48 -0
  11. package/addon/components/customer/orders.js +67 -5
  12. package/addon/components/device/manager.hbs +5 -6
  13. package/addon/components/device/manager.js +12 -15
  14. package/addon/components/driver/details.hbs +1 -1
  15. package/addon/components/driver/form.hbs +1 -1
  16. package/addon/components/fleet/vehicle-listing.js +1 -0
  17. package/addon/components/fuel-integration/form.hbs +200 -0
  18. package/addon/components/fuel-integration/form.js +242 -0
  19. package/addon/components/fuel-integration/hub.hbs +154 -0
  20. package/addon/components/fuel-integration/hub.js +165 -0
  21. package/addon/components/fuel-integration/matching-priority.hbs +76 -0
  22. package/addon/components/fuel-integration/matching-priority.js +145 -0
  23. package/addon/components/fuel-report/details.hbs +13 -1
  24. package/addon/components/home/getting-started-guidance.hbs +113 -0
  25. package/addon/components/home/getting-started-guidance.js +107 -0
  26. package/addon/components/issue/details/comments.hbs +3 -0
  27. package/addon/components/issue/details/comments.js +3 -0
  28. package/addon/components/issue/details/correspondence.hbs +9 -0
  29. package/addon/components/issue/details/correspondence.js +83 -0
  30. package/addon/components/issue/details/documents.hbs +69 -0
  31. package/addon/components/issue/details/documents.js +85 -0
  32. package/addon/components/issue/details.hbs +166 -59
  33. package/addon/components/issue/details.js +149 -0
  34. package/addon/components/issue/form.hbs +19 -1
  35. package/addon/components/issue/panel-header.hbs +43 -0
  36. package/addon/components/issue/panel-header.js +22 -0
  37. package/addon/components/issue/timeline.hbs +40 -0
  38. package/addon/components/issue/timeline.js +45 -0
  39. package/addon/components/layout/fleet-ops-sidebar.js +20 -2
  40. package/addon/components/leaflet-tracking-marker.js +3 -0
  41. package/addon/components/map/drawer/device-event-listing.hbs +12 -2
  42. package/addon/components/map/drawer/driver-listing.hbs +14 -1
  43. package/addon/components/map/drawer/place-listing.hbs +14 -1
  44. package/addon/components/map/drawer/position-listing.hbs +12 -2
  45. package/addon/components/map/drawer/position-listing.js +3 -0
  46. package/addon/components/map/drawer/vehicle-listing.hbs +14 -1
  47. package/addon/components/map/leaflet-live-map.hbs +2 -2
  48. package/addon/components/map/leaflet-live-map.js +17 -0
  49. package/addon/components/map/order-list-overlay.hbs +4 -4
  50. package/addon/components/modals/assigned-orders.hbs +40 -0
  51. package/addon/components/modals/attach-device.hbs +4 -3
  52. package/addon/components/modals/attach-telematic-device.hbs +25 -0
  53. package/addon/components/modals/attach-telematic-device.js +3 -0
  54. package/addon/components/modals/convert-customer-to-vendor.hbs +30 -0
  55. package/addon/components/modals/convert-customer-to-vendor.js +55 -0
  56. package/addon/components/modals/driver-assign-order.hbs +7 -58
  57. package/addon/components/modals/driver-assign-vehicle.hbs +10 -2
  58. package/addon/components/modals/fleet-assign-driver.hbs +18 -0
  59. package/addon/components/modals/fleet-assign-driver.js +3 -0
  60. package/addon/components/modals/fleet-assign-vehicle.hbs +18 -0
  61. package/addon/components/modals/fleet-assign-vehicle.js +3 -0
  62. package/addon/components/modals/issue-assign.hbs +20 -0
  63. package/addon/components/modals/issue-assign.js +49 -0
  64. package/addon/components/modals/issue-close.hbs +30 -0
  65. package/addon/components/modals/issue-close.js +73 -0
  66. package/addon/components/modals/issue-status.hbs +20 -0
  67. package/addon/components/modals/issue-status.js +43 -0
  68. package/addon/components/modals/reset-customer-credentials.js +12 -6
  69. package/addon/components/modals/telematic-connection-diagnostics.hbs +75 -0
  70. package/addon/components/modals/telematic-connection-diagnostics.js +287 -0
  71. package/addon/components/modals/update-order-activity.hbs +51 -17
  72. package/addon/components/modals/update-order-activity.js +59 -5
  73. package/addon/components/modals/vehicle-details.hbs +6 -1
  74. package/addon/components/modals/vehicle-form.hbs +8 -1
  75. package/addon/components/order/card.hbs +106 -0
  76. package/addon/components/order/card.js +257 -0
  77. package/addon/components/order/details/activity.js +2 -2
  78. package/addon/components/order/details/proof.hbs +40 -38
  79. package/addon/components/order/details/proof.js +31 -4
  80. package/addon/components/order/details.hbs +5 -5
  81. package/addon/components/order/details.js +19 -1
  82. package/addon/components/order/form/service-rate.hbs +2 -0
  83. package/addon/components/order/header.hbs +1 -1
  84. package/addon/components/route-list.hbs +0 -12
  85. package/addon/components/service-rate/details.hbs +1 -1
  86. package/addon/components/service-rate/form.hbs +4 -3
  87. package/addon/components/service-rate/form.js +4 -0
  88. package/addon/components/telematic/details.hbs +98 -87
  89. package/addon/components/telematic/details.js +230 -1
  90. package/addon/components/telematic/form.hbs +303 -72
  91. package/addon/components/telematic/form.js +519 -3
  92. package/addon/components/telematic/hub.hbs +149 -0
  93. package/addon/components/telematic/hub.js +142 -0
  94. package/addon/components/telematic/settings.hbs +152 -0
  95. package/addon/components/telematic/settings.js +45 -0
  96. package/addon/components/telematic/tab-empty-state.hbs +29 -0
  97. package/addon/components/telematic/tab-empty-state.js +33 -0
  98. package/addon/components/vehicle/details.hbs +6 -1
  99. package/addon/components/vehicle/form.hbs +2 -1
  100. package/addon/components/vendor/personnel-manager.hbs +166 -0
  101. package/addon/components/vendor/personnel-manager.js +143 -0
  102. package/addon/components/widget/fuel-providers.hbs +43 -0
  103. package/addon/components/widget/fuel-providers.js +27 -0
  104. package/addon/components/widget/live-fleet.hbs +1 -0
  105. package/addon/components/widget/live-fleet.js +2 -7
  106. package/addon/components/widget/revenue-trend.hbs +1 -1
  107. package/addon/components/widget/revenue-trend.js +75 -2
  108. package/addon/controllers/connectivity/devices/index/details.js +27 -1
  109. package/addon/controllers/connectivity/devices/index.js +14 -0
  110. package/addon/controllers/connectivity/fuel-providers/details/sync.js +18 -0
  111. package/addon/controllers/connectivity/fuel-providers/details/transactions.js +24 -0
  112. package/addon/controllers/connectivity/fuel-providers/details.js +69 -0
  113. package/addon/controllers/connectivity/fuel-providers/edit.js +24 -0
  114. package/addon/controllers/connectivity/fuel-providers/index.js +177 -0
  115. package/addon/controllers/connectivity/fuel-providers/new.js +37 -0
  116. package/addon/controllers/connectivity/telematics/details/attachments.js +247 -0
  117. package/addon/controllers/connectivity/telematics/details/devices.js +368 -0
  118. package/addon/controllers/connectivity/telematics/details/events.js +244 -0
  119. package/addon/controllers/connectivity/telematics/details/index.js +3 -0
  120. package/addon/controllers/connectivity/telematics/details/logs.js +43 -0
  121. package/addon/controllers/connectivity/telematics/details/sensors.js +270 -0
  122. package/addon/controllers/connectivity/telematics/details.js +149 -0
  123. package/addon/controllers/connectivity/telematics/{index/edit.js → edit.js} +15 -4
  124. package/addon/controllers/connectivity/telematics/index.js +25 -5
  125. package/addon/controllers/connectivity/telematics/{index/new.js → new.js} +8 -2
  126. package/addon/controllers/management/contacts/customers/details.js +31 -13
  127. package/addon/controllers/management/contacts/customers.js +16 -5
  128. package/addon/controllers/management/contacts/index/details.js +31 -13
  129. package/addon/controllers/management/contacts/index.js +7 -0
  130. package/addon/controllers/management/drivers/index/details.js +78 -1
  131. package/addon/controllers/management/drivers/index.js +39 -0
  132. package/addon/controllers/management/fleets/index/details.js +23 -1
  133. package/addon/controllers/management/fleets/index.js +6 -1
  134. package/addon/controllers/management/fuel-reports/index.js +37 -1
  135. package/addon/controllers/management/fuel-transactions/index/details.js +70 -0
  136. package/addon/controllers/management/fuel-transactions/index.js +240 -0
  137. package/addon/controllers/management/issues/index/details.js +52 -6
  138. package/addon/controllers/management/vehicles/index/details.js +32 -0
  139. package/addon/controllers/management/vehicles/index.js +26 -0
  140. package/addon/controllers/management/vendors/index/details.js +4 -0
  141. package/addon/controllers/operations/orders/index/details.js +11 -3
  142. package/addon/controllers/operations/orders/index.js +5 -1
  143. package/addon/controllers/settings/payments/index.js +5 -0
  144. package/addon/extension.js +29 -12
  145. package/addon/helpers/format-duration.js +1 -38
  146. package/addon/initializers/load-leaflet-assets.js +5 -6
  147. package/addon/initializers/patch-ember-leaflet-tooltip-layer.js +51 -0
  148. package/addon/routes/connectivity/fuel-providers/details/index.js +7 -0
  149. package/addon/routes/connectivity/fuel-providers/details/matching.js +7 -0
  150. package/addon/routes/connectivity/fuel-providers/details/settings.js +7 -0
  151. package/addon/routes/connectivity/fuel-providers/details/sync.js +18 -0
  152. package/addon/routes/connectivity/fuel-providers/details/transactions.js +14 -0
  153. package/addon/routes/connectivity/fuel-providers/details.js +18 -0
  154. package/addon/routes/connectivity/fuel-providers/edit.js +18 -0
  155. package/addon/routes/connectivity/fuel-providers/index.js +20 -0
  156. package/addon/routes/connectivity/fuel-providers/new.js +3 -0
  157. package/addon/routes/connectivity/fuel-providers.js +3 -0
  158. package/addon/routes/connectivity/telematics/details/attachments.js +28 -0
  159. package/addon/routes/connectivity/telematics/details/devices.js +30 -0
  160. package/addon/routes/connectivity/telematics/details/events.js +33 -0
  161. package/addon/routes/connectivity/telematics/details/index.js +3 -0
  162. package/addon/routes/connectivity/telematics/details/logs.js +17 -0
  163. package/addon/routes/connectivity/telematics/details/sensors.js +29 -0
  164. package/addon/routes/connectivity/telematics/{index/details.js → details.js} +1 -1
  165. package/addon/routes/connectivity/telematics/{index/edit.js → edit.js} +1 -1
  166. package/addon/routes/connectivity/telematics/new.js +3 -0
  167. package/addon/routes/management/drivers/index/details/activity.js +3 -0
  168. package/addon/routes/management/fuel-reports/index.js +2 -0
  169. package/addon/routes/management/fuel-transactions/index/details.js +18 -0
  170. package/addon/routes/management/fuel-transactions/index.js +21 -0
  171. package/addon/routes/management/fuel-transactions.js +3 -0
  172. package/addon/routes/management/issues/index/details.js +1 -1
  173. package/addon/routes.js +29 -9
  174. package/addon/services/contact-actions.js +231 -1
  175. package/addon/services/device-actions.js +64 -1
  176. package/addon/services/device-event-actions.js +12 -1
  177. package/addon/services/driver-actions.js +147 -11
  178. package/addon/services/fleet-actions.js +66 -1
  179. package/addon/services/fuel-integration-actions.js +31 -0
  180. package/addon/services/getting-started.js +44 -0
  181. package/addon/services/issue-actions.js +72 -1
  182. package/addon/services/leaflet-map-manager.js +2 -0
  183. package/addon/services/map-adapter/leaflet.js +19 -0
  184. package/addon/services/service-areas.js +3 -0
  185. package/addon/services/telematic-actions.js +9 -3
  186. package/addon/services/vehicle-actions.js +125 -0
  187. package/addon/styles/fleetops-engine.css +1313 -1
  188. package/addon/templates/analytics/reports/index.hbs +19 -1
  189. package/addon/templates/connectivity/devices/index.hbs +19 -1
  190. package/addon/templates/connectivity/events/index.hbs +16 -1
  191. package/addon/templates/connectivity/fuel-providers/details/index.hbs +38 -0
  192. package/addon/templates/connectivity/fuel-providers/details/matching.hbs +13 -0
  193. package/addon/templates/connectivity/fuel-providers/details/settings.hbs +11 -0
  194. package/addon/templates/connectivity/fuel-providers/details/sync.hbs +48 -0
  195. package/addon/templates/connectivity/fuel-providers/details/transactions.hbs +21 -0
  196. package/addon/templates/connectivity/fuel-providers/details.hbs +51 -0
  197. package/addon/templates/connectivity/fuel-providers/edit.hbs +24 -0
  198. package/addon/templates/connectivity/fuel-providers/index.hbs +12 -0
  199. package/addon/templates/connectivity/fuel-providers/new.hbs +22 -0
  200. package/addon/templates/connectivity/fuel-providers.hbs +1 -0
  201. package/addon/templates/connectivity/sensors/index.hbs +19 -1
  202. package/addon/templates/connectivity/telematics/details/attachments.hbs +163 -0
  203. package/addon/templates/connectivity/telematics/details/devices.hbs +88 -0
  204. package/addon/templates/connectivity/telematics/details/events.hbs +101 -0
  205. package/addon/templates/connectivity/telematics/{index/details → details}/index.hbs +0 -1
  206. package/addon/templates/connectivity/telematics/details/logs.hbs +69 -0
  207. package/addon/templates/connectivity/telematics/details/sensors.hbs +88 -0
  208. package/addon/templates/connectivity/telematics/details.hbs +53 -0
  209. package/addon/templates/connectivity/telematics/edit.hbs +27 -0
  210. package/addon/templates/connectivity/telematics/index.hbs +6 -8
  211. package/addon/templates/connectivity/telematics/new.hbs +24 -0
  212. package/addon/templates/maintenance/equipment/index.hbs +19 -1
  213. package/addon/templates/maintenance/maintenances/index.hbs +15 -1
  214. package/addon/templates/maintenance/parts/index.hbs +19 -1
  215. package/addon/templates/maintenance/schedules/index.hbs +19 -1
  216. package/addon/templates/maintenance/work-orders/index.hbs +19 -1
  217. package/addon/templates/management/contacts/customers/details.hbs +1 -1
  218. package/addon/templates/management/contacts/customers.hbs +15 -1
  219. package/addon/templates/management/contacts/index/details.hbs +1 -1
  220. package/addon/templates/management/contacts/index.hbs +19 -1
  221. package/addon/templates/management/contacts.hbs +2 -2
  222. package/addon/templates/management/drivers/index/details/activity.hbs +1 -0
  223. package/addon/templates/management/drivers/index.hbs +19 -1
  224. package/addon/templates/management/fleets/index.hbs +19 -1
  225. package/addon/templates/management/fuel-reports/index.hbs +19 -1
  226. package/addon/templates/management/fuel-transactions/index/details.hbs +73 -0
  227. package/addon/templates/management/fuel-transactions/index.hbs +58 -0
  228. package/addon/templates/management/fuel-transactions.hbs +1 -0
  229. package/addon/templates/management/issues/index/details/index.hbs +3 -1
  230. package/addon/templates/management/issues/index/details.hbs +3 -2
  231. package/addon/templates/management/issues/index.hbs +19 -1
  232. package/addon/templates/management/places/index.hbs +19 -1
  233. package/addon/templates/management/vehicles/index.hbs +19 -1
  234. package/addon/templates/management/vendors/index/details/personnel.hbs +1 -2
  235. package/addon/templates/management/vendors/index.hbs +19 -1
  236. package/addon/templates/management/vendors/integrated.hbs +13 -1
  237. package/addon/templates/operations/orders/index/details/index.hbs +2 -2
  238. package/addon/templates/operations/orders/index.hbs +20 -2
  239. package/addon/templates/operations/service-rates/index/edit.hbs +1 -0
  240. package/addon/templates/operations/service-rates/index/new.hbs +1 -0
  241. package/addon/templates/operations/service-rates/index.hbs +19 -1
  242. package/addon/templates/settings/payments/index.hbs +15 -1
  243. package/addon/templates/settings/payments/onboard.hbs +8 -8
  244. package/addon/utils/fleet-ops-options.js +3 -0
  245. package/addon/utils/leaflet-draw-namespace-guard.js +22 -0
  246. package/addon/utils/leaflet-plugin-loader.js +219 -0
  247. package/addon/utils/setup-customer-portal.js +4 -64
  248. package/app/components/cell/telematic-provider.js +1 -0
  249. package/app/components/cell/telematic-status.js +1 -0
  250. package/app/components/fuel-integration/form.js +1 -0
  251. package/app/components/fuel-integration/hub.js +1 -0
  252. package/app/components/fuel-integration/matching-priority.js +1 -0
  253. package/app/components/home/getting-started-guidance.js +1 -0
  254. package/app/components/issue/details/comments.js +1 -0
  255. package/app/components/issue/details/correspondence.js +1 -0
  256. package/app/components/issue/details/documents.js +1 -0
  257. package/app/components/issue/panel-header.js +1 -0
  258. package/app/components/modals/assigned-orders.js +1 -0
  259. package/app/components/modals/attach-telematic-device.js +1 -0
  260. package/app/components/modals/convert-customer-to-vendor.js +1 -0
  261. package/app/components/modals/fleet-assign-driver.js +1 -0
  262. package/app/components/modals/fleet-assign-vehicle.js +1 -0
  263. package/app/components/modals/issue-assign.js +1 -0
  264. package/app/components/modals/issue-close.js +1 -0
  265. package/app/components/modals/issue-status.js +1 -0
  266. package/app/components/modals/telematic-connection-diagnostics.js +1 -0
  267. package/app/components/order/card.js +1 -0
  268. package/app/components/telematic/hub.js +1 -0
  269. package/app/components/telematic/settings.js +1 -0
  270. package/app/components/telematic/tab-empty-state.js +1 -0
  271. package/app/components/vendor/personnel-manager.js +1 -0
  272. package/app/components/widget/fuel-providers.js +1 -0
  273. package/app/controllers/connectivity/fuel-providers/details/sync.js +1 -0
  274. package/app/controllers/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  275. package/app/controllers/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  276. package/app/controllers/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  277. package/app/controllers/connectivity/{telematics/index/details → fuel-providers}/index.js +1 -1
  278. package/app/controllers/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  279. package/app/controllers/connectivity/telematics/details/attachments.js +1 -0
  280. package/app/controllers/connectivity/telematics/details/devices.js +1 -0
  281. package/app/controllers/connectivity/telematics/details/events.js +1 -0
  282. package/app/controllers/connectivity/telematics/details/index.js +1 -0
  283. package/app/controllers/connectivity/telematics/details/logs.js +1 -0
  284. package/app/controllers/connectivity/telematics/details/sensors.js +1 -0
  285. package/app/controllers/connectivity/telematics/details.js +1 -0
  286. package/app/controllers/connectivity/telematics/edit.js +1 -0
  287. package/app/controllers/connectivity/telematics/new.js +1 -0
  288. package/app/controllers/management/fuel-transactions/index/details.js +1 -0
  289. package/app/controllers/management/fuel-transactions/index.js +1 -0
  290. package/app/helpers/format-duration.js +1 -1
  291. package/app/routes/connectivity/{telematics/index → fuel-providers}/details/index.js +1 -1
  292. package/app/routes/connectivity/{telematics/index/details/events.js → fuel-providers/details/matching.js} +1 -1
  293. package/app/routes/connectivity/fuel-providers/details/settings.js +1 -0
  294. package/app/routes/connectivity/fuel-providers/details/sync.js +1 -0
  295. package/app/routes/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  296. package/app/routes/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  297. package/app/routes/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  298. package/app/routes/connectivity/fuel-providers/index.js +1 -0
  299. package/app/routes/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  300. package/app/routes/connectivity/fuel-providers.js +1 -0
  301. package/app/routes/connectivity/telematics/details/attachments.js +1 -0
  302. package/app/routes/connectivity/telematics/details/devices.js +1 -0
  303. package/app/routes/connectivity/telematics/details/events.js +1 -0
  304. package/app/routes/connectivity/telematics/details/index.js +1 -0
  305. package/app/routes/connectivity/telematics/details/logs.js +1 -0
  306. package/app/routes/connectivity/telematics/details/sensors.js +1 -0
  307. package/app/routes/connectivity/telematics/details.js +1 -0
  308. package/app/routes/connectivity/telematics/edit.js +1 -0
  309. package/app/routes/connectivity/telematics/new.js +1 -0
  310. package/app/routes/management/drivers/index/details/activity.js +1 -0
  311. package/app/routes/management/fuel-transactions/index/details.js +1 -0
  312. package/app/routes/management/fuel-transactions/index.js +1 -0
  313. package/app/routes/management/fuel-transactions.js +1 -0
  314. package/app/services/fuel-integration-actions.js +1 -0
  315. package/app/services/getting-started.js +1 -0
  316. package/app/templates/connectivity/{telematics/index → fuel-providers}/details/index.js +1 -1
  317. package/app/templates/connectivity/{telematics/index/details/events.js → fuel-providers/details/matching.js} +1 -1
  318. package/app/templates/connectivity/fuel-providers/details/settings.js +1 -0
  319. package/app/templates/connectivity/fuel-providers/details/sync.js +1 -0
  320. package/app/templates/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
  321. package/app/templates/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
  322. package/app/templates/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
  323. package/app/templates/connectivity/fuel-providers/index.js +1 -0
  324. package/app/templates/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
  325. package/app/templates/connectivity/fuel-providers.js +1 -0
  326. package/app/templates/connectivity/telematics/details/attachments.js +1 -0
  327. package/app/templates/connectivity/telematics/details/devices.js +1 -0
  328. package/app/templates/connectivity/telematics/details/events.js +1 -0
  329. package/app/templates/connectivity/telematics/details/index.js +1 -0
  330. package/app/templates/connectivity/telematics/details/logs.js +1 -0
  331. package/app/templates/connectivity/telematics/details/sensors.js +1 -0
  332. package/app/templates/connectivity/telematics/details.js +1 -0
  333. package/app/templates/connectivity/telematics/edit.js +1 -0
  334. package/app/templates/connectivity/telematics/new.js +1 -0
  335. package/app/templates/management/drivers/index/details/activity.js +1 -0
  336. package/app/templates/management/fuel-transactions/index/details.js +1 -0
  337. package/app/templates/management/fuel-transactions/index.js +1 -0
  338. package/app/templates/management/fuel-transactions.js +1 -0
  339. package/app/utils/leaflet-draw-namespace-guard.js +1 -0
  340. package/app/utils/leaflet-plugin-loader.js +1 -0
  341. package/assets/images/telematics/providers/afaqy.webp +0 -0
  342. package/assets/images/telematics/providers/default.webp +0 -0
  343. package/assets/images/telematics/providers/flespi.webp +0 -0
  344. package/assets/images/telematics/providers/geotab.webp +0 -0
  345. package/assets/images/telematics/providers/safee.webp +0 -0
  346. package/assets/images/telematics/providers/samsara.webp +0 -0
  347. package/composer.json +1 -1
  348. package/extension.json +1 -1
  349. package/package.json +5 -5
  350. package/server/config/fuel-providers.php +42 -0
  351. package/server/config/telematics.php +139 -130
  352. package/server/migrations/2026_05_31_000001_add_portal_fields_to_vendor_personnels_table.php +30 -0
  353. package/server/migrations/2026_06_03_000000_ensure_tags_column_on_issues_table.php +31 -0
  354. package/server/migrations/2026_06_03_000001_add_order_uuid_to_issues_table.php +25 -0
  355. package/server/migrations/2026_06_04_000001_backfill_order_transaction_subjects.php +39 -0
  356. package/server/migrations/2026_06_04_000002_backfill_order_transaction_directions.php +24 -0
  357. package/server/migrations/2026_06_06_000001_harden_device_events_telematics_contract.php +59 -0
  358. package/server/migrations/2026_06_08_000001_create_fuel_provider_connections_table.php +37 -0
  359. package/server/migrations/2026_06_08_000002_create_fuel_provider_transactions_table.php +53 -0
  360. package/server/migrations/2026_06_08_000003_create_fuel_provider_sync_runs_table.php +40 -0
  361. package/server/migrations/2026_06_10_000001_add_fuel_card_number_to_vehicles_table.php +25 -0
  362. package/server/migrations/2026_06_10_000002_add_vehicle_identity_columns_to_fuel_provider_transactions_table.php +39 -0
  363. package/server/resources/views/mail/customer-credentials.blade.php +16 -13
  364. package/server/src/Contracts/FuelProvider.php +30 -0
  365. package/server/src/Contracts/TelematicProviderDescriptor.php +3 -1
  366. package/server/src/Events/FuelProviderTransactionImported.php +17 -0
  367. package/server/src/Events/FuelProviderTransactionMatched.php +17 -0
  368. package/server/src/Events/FuelProviderTransactionUnmatched.php +17 -0
  369. package/server/src/Events/FuelReportCreatedFromProvider.php +18 -0
  370. package/server/src/Expansions/UserFilterExpansion.php +28 -0
  371. package/server/src/Http/Controllers/Api/v1/IssueController.php +2 -0
  372. package/server/src/Http/Controllers/Api/v1/OrderController.php +26 -25
  373. package/server/src/Http/Controllers/Api/v1/PlaceController.php +10 -58
  374. package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +6 -0
  375. package/server/src/Http/Controllers/Internal/v1/ContactController.php +135 -0
  376. package/server/src/Http/Controllers/Internal/v1/CustomerController.php +116 -6
  377. package/server/src/Http/Controllers/Internal/v1/DeviceController.php +76 -2
  378. package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +44 -0
  379. package/server/src/Http/Controllers/Internal/v1/DriverController.php +158 -7
  380. package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +124 -0
  381. package/server/src/Http/Controllers/Internal/v1/FuelProviderSyncRunController.php +10 -0
  382. package/server/src/Http/Controllers/Internal/v1/FuelProviderTransactionController.php +76 -0
  383. package/server/src/Http/Controllers/Internal/v1/GettingStartedController.php +17 -0
  384. package/server/src/Http/Controllers/Internal/v1/IssueController.php +251 -0
  385. package/server/src/Http/Controllers/Internal/v1/OrderController.php +172 -97
  386. package/server/src/Http/Controllers/Internal/v1/PlaceController.php +10 -68
  387. package/server/src/Http/Controllers/Internal/v1/SensorController.php +1 -1
  388. package/server/src/Http/Controllers/Internal/v1/TelematicController.php +178 -15
  389. package/server/src/Http/Controllers/Internal/v1/VehicleController.php +165 -0
  390. package/server/src/Http/Controllers/Internal/v1/VendorController.php +89 -0
  391. package/server/src/Http/Controllers/TelematicWebhookController.php +103 -19
  392. package/server/src/Http/Filter/FuelProviderConnectionFilter.php +33 -0
  393. package/server/src/Http/Filter/FuelProviderSyncRunFilter.php +28 -0
  394. package/server/src/Http/Filter/FuelProviderTransactionFilter.php +59 -0
  395. package/server/src/Http/Filter/FuelReportFilter.php +10 -0
  396. package/server/src/Http/Requests/CreateIssueRequest.php +4 -0
  397. package/server/src/Http/Requests/UpdateIssueRequest.php +4 -0
  398. package/server/src/Http/Resources/v1/Driver.php +15 -0
  399. package/server/src/Http/Resources/v1/FuelProviderConnection.php +30 -0
  400. package/server/src/Http/Resources/v1/FuelProviderSyncRun.php +36 -0
  401. package/server/src/Http/Resources/v1/FuelProviderTransaction.php +54 -0
  402. package/server/src/Http/Resources/v1/FuelReport.php +28 -22
  403. package/server/src/Http/Resources/v1/Index/Driver.php +26 -20
  404. package/server/src/Http/Resources/v1/Index/Order.php +12 -9
  405. package/server/src/Http/Resources/v1/Index/Vehicle.php +29 -22
  406. package/server/src/Http/Resources/v1/Issue.php +25 -0
  407. package/server/src/Http/Resources/v1/Order.php +20 -18
  408. package/server/src/Http/Resources/v1/Vehicle.php +17 -0
  409. package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +2 -0
  410. package/server/src/Jobs/SyncFuelProviderTransactionsJob.php +57 -0
  411. package/server/src/Jobs/SyncTelematicDevicesJob.php +36 -6
  412. package/server/src/Jobs/TestTelematicConnectionJob.php +9 -22
  413. package/server/src/Mail/CustomerCredentialsMail.php +5 -6
  414. package/server/src/Models/Asset.php +2 -1
  415. package/server/src/Models/Contact.php +32 -52
  416. package/server/src/Models/Device.php +27 -4
  417. package/server/src/Models/DeviceEvent.php +40 -3
  418. package/server/src/Models/Driver.php +2 -1
  419. package/server/src/Models/Equipment.php +2 -1
  420. package/server/src/Models/Fleet.php +2 -1
  421. package/server/src/Models/FuelProviderConnection.php +60 -0
  422. package/server/src/Models/FuelProviderSyncRun.php +58 -0
  423. package/server/src/Models/FuelProviderTransaction.php +119 -0
  424. package/server/src/Models/FuelReport.php +16 -1
  425. package/server/src/Models/Issue.php +47 -6
  426. package/server/src/Models/Order.php +33 -6
  427. package/server/src/Models/Part.php +2 -1
  428. package/server/src/Models/Sensor.php +21 -4
  429. package/server/src/Models/ServiceArea.php +1 -1
  430. package/server/src/Models/ServiceRate.php +39 -2
  431. package/server/src/Models/Vehicle.php +14 -2
  432. package/server/src/Models/Vendor.php +2 -1
  433. package/server/src/Models/VendorPersonnel.php +10 -1
  434. package/server/src/Models/Zone.php +1 -1
  435. package/server/src/Observers/PurchaseRateObserver.php +20 -0
  436. package/server/src/Observers/ZoneObserver.php +56 -0
  437. package/server/src/Providers/FleetOpsServiceProvider.php +11 -0
  438. package/server/src/Support/Analytics/FuelProviderSummary.php +42 -0
  439. package/server/src/Support/Analytics/TopDrivers.php +9 -1
  440. package/server/src/Support/FuelProviders/FuelProviderDescriptor.php +55 -0
  441. package/server/src/Support/FuelProviders/FuelProviderRegistry.php +75 -0
  442. package/server/src/Support/FuelProviders/FuelProviderService.php +447 -0
  443. package/server/src/Support/FuelProviders/Providers/AbstractFuelProvider.php +98 -0
  444. package/server/src/Support/FuelProviders/Providers/PetroAppFuelProvider.php +167 -0
  445. package/server/src/Support/GettingStarted.php +144 -0
  446. package/server/src/Support/PlaceSearch.php +282 -0
  447. package/server/src/Support/ResolvesOrderServiceStops.php +22 -12
  448. package/server/src/Support/Telematics/Providers/AbstractProvider.php +27 -6
  449. package/server/src/Support/Telematics/Providers/AfaqyProvider.php +55 -26
  450. package/server/src/Support/Telematics/Providers/FlespiProvider.php +1 -0
  451. package/server/src/Support/Telematics/Providers/GeotabProvider.php +1 -0
  452. package/server/src/Support/Telematics/Providers/SafeeProvider.php +32 -22
  453. package/server/src/Support/Telematics/Providers/SamsaraProvider.php +3 -1
  454. package/server/src/Support/Telematics/TelematicService.php +340 -21
  455. package/server/src/routes.php +74 -5
  456. package/server/tests/AnalyticsRoutesTest.php +8 -0
  457. package/server/tests/CustomerContactIdentitySafetyTest.php +41 -0
  458. package/server/tests/DriverVehicleStatusDefaultTest.php +2 -2
  459. package/server/tests/FuelProviderRegistryTest.php +416 -0
  460. package/server/tests/GettingStartedStatusTest.php +21 -0
  461. package/server/tests/OrderActivityFlowRegressionTest.php +116 -0
  462. package/server/tests/ServiceAreaZoneApiShapeTest.php +44 -0
  463. package/server/tests/ServiceRateAlgorithmWeightVariablesTest.php +44 -0
  464. package/server/tests/TelematicsHardeningTest.php +268 -0
  465. package/server/tests/VehicleDriverAssignmentTest.php +51 -0
  466. package/translations/ar-ae.yml +31 -0
  467. package/translations/bg-bg.yaml +81 -0
  468. package/translations/en-us.yaml +94 -0
  469. package/translations/es-pa.yaml +81 -0
  470. package/translations/fr-fr.yaml +81 -0
  471. package/translations/mn-mn.yaml +81 -0
  472. package/translations/pt-br.yaml +81 -0
  473. package/translations/ru-ru.yaml +81 -0
  474. package/translations/vi-vn.yaml +106 -0
  475. package/addon/controllers/connectivity/telematics/index/details/devices.js +0 -3
  476. package/addon/controllers/connectivity/telematics/index/details/events.js +0 -3
  477. package/addon/controllers/connectivity/telematics/index/details/index.js +0 -3
  478. package/addon/controllers/connectivity/telematics/index/details/sensors.js +0 -3
  479. package/addon/controllers/connectivity/telematics/index/details.js +0 -24
  480. package/addon/routes/connectivity/telematics/index/details/devices.js +0 -3
  481. package/addon/routes/connectivity/telematics/index/details/events.js +0 -3
  482. package/addon/routes/connectivity/telematics/index/details/index.js +0 -3
  483. package/addon/routes/connectivity/telematics/index/details/sensors.js +0 -3
  484. package/addon/routes/connectivity/telematics/index/new.js +0 -3
  485. package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
  486. package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
  487. package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
  488. package/addon/templates/connectivity/telematics/index/details.hbs +0 -14
  489. package/addon/templates/connectivity/telematics/index/edit.hbs +0 -12
  490. package/addon/templates/connectivity/telematics/index/new.hbs +0 -12
  491. package/app/controllers/connectivity/telematics/index/details/events.js +0 -1
  492. package/app/controllers/connectivity/telematics/index/details/sensors.js +0 -1
  493. package/app/routes/connectivity/telematics/index/details/sensors.js +0 -1
  494. package/app/templates/connectivity/telematics/index/details/sensors.js +0 -1
@@ -0,0 +1,149 @@
1
+ <div class="h-full overflow-y-auto bg-gray-50 dark:bg-gray-900" ...attributes>
2
+ <div class="flex w-full flex-col">
3
+ <section class="sticky top-0 z-50 border-b border-gray-200 bg-white px-4 py-4 shadow-sm dark:border-gray-700 dark:bg-gray-900 md:px-6">
4
+ <div class="mx-auto flex w-full max-w-7xl flex-col gap-3 md:flex-row md:items-start md:justify-between">
5
+ <div class="min-w-0">
6
+ <div class="flex flex-wrap items-center gap-2">
7
+ <h1 class="text-lg font-bold text-gray-900 dark:text-gray-100">Connectivity Hub</h1>
8
+ <Badge @status={{if this.healthWarningCount "warning" "success"}} @hideStatusDot={{true}}>
9
+ {{this.healthWarningCount}} warnings
10
+ </Badge>
11
+ </div>
12
+ <p class="mt-1 max-w-3xl text-sm leading-5 text-gray-500 dark:text-gray-300">
13
+ Connect telematics providers, sync devices, attach them to vehicles, and monitor telemetry health from one workflow.
14
+ </p>
15
+ </div>
16
+ <div class="flex flex-shrink-0 items-center gap-2 whitespace-nowrap">
17
+ <Button @icon="refresh" @size="sm" @helpText={{t "common.reload"}} @onClick={{this.refresh}} />
18
+ <Button @icon="plus" @text="Connect Provider" @type="primary" @size="sm" @onClick={{this.telematicActions.transition.create}} />
19
+ </div>
20
+ </div>
21
+ </section>
22
+
23
+ <div class="mx-auto flex w-full max-w-7xl flex-col gap-4 px-4 py-4 md:px-6">
24
+ <section class="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
25
+ {{#each this.kpiWidgets as |widget|}}
26
+ <div
27
+ class="fleet-ops-widget fleet-ops-kpi-tile fleetops-connectivity-kpi-tile {{widget.accentClass}} relative flex min-h-[118px] flex-col overflow-hidden rounded-md border bg-white shadow-sm transition hover:-translate-y-px hover:shadow-lg dark:bg-gray-800"
28
+ >
29
+ <div class="flex h-full flex-col justify-between p-3">
30
+ <div class="flex items-start justify-between gap-2">
31
+ <div class="min-w-0">
32
+ <div class="truncate text-[10px] font-bold uppercase text-gray-500 dark:text-gray-400">{{widget.label}}</div>
33
+ <div class="mt-2 truncate text-[1.55rem] font-extrabold leading-none text-gray-900 dark:text-gray-50">{{widget.value}}</div>
34
+ </div>
35
+ <div class="fleetops-connectivity-kpi-icon flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md text-[13px]">
36
+ <FaIcon @icon={{widget.icon}} />
37
+ </div>
38
+ </div>
39
+
40
+ <div class="mt-3 flex items-center justify-between gap-2 text-[11px]">
41
+ <span class="min-w-0 truncate text-gray-500 dark:text-gray-400">{{widget.help}}</span>
42
+ <button
43
+ type="button"
44
+ class="inline-flex flex-shrink-0 items-center gap-1 font-semibold text-blue-600 hover:text-blue-700 dark:text-blue-300 dark:hover:text-blue-200"
45
+ {{on "click" (fn this.runKpiAction widget)}}
46
+ >
47
+ <span>{{widget.action}}</span>
48
+ <FaIcon @icon="arrow-right" class="text-[9px]" />
49
+ </button>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ {{/each}}
54
+ </section>
55
+
56
+ {{#if this.hasProviderConnections}}
57
+ <section class="fleetops-provider-connections-panel min-w-0 overflow-hidden rounded-md border border-gray-200 bg-white shadow-sm dark:border-gray-700 dark:bg-gray-800">
58
+ <div class="fleetops-provider-connections-header border-b border-gray-200 px-4 py-3 dark:border-gray-700">
59
+ <div class="min-w-0 max-w-md">
60
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Provider Connections</h2>
61
+ <p class="mt-1 text-xs leading-5 text-gray-500 dark:text-gray-300">Manage connected provider accounts, review sync status, and open a connection to sync devices or update settings.</p>
62
+ </div>
63
+ <div class="fleetops-provider-connections-actions flex min-w-0 flex-wrap items-center gap-2 lg:ml-auto lg:flex-nowrap lg:justify-end">
64
+ <Layout::Resource::TabularActions
65
+ @title="Provider Connections"
66
+ @searchQuery={{@searchQuery}}
67
+ @onSearch={{@onSearch}}
68
+ @columns={{this.columns}}
69
+ @bulkActions={{@bulkActions}}
70
+ @controller={{@controller}}
71
+ @table={{this.table}}
72
+ @searchInputClass="fleetops-provider-connections-search"
73
+ @filterPickerButtonClass="fleetops-provider-connections-action-button"
74
+ @columnPickerButtonClass="fleetops-provider-connections-action-button"
75
+ />
76
+ </div>
77
+ </div>
78
+ <Layout::Resource::Tabular
79
+ @resource="telematic"
80
+ @title=""
81
+ @withoutHeader={{true}}
82
+ @searchQuery={{@searchQuery}}
83
+ @onSearch={{@onSearch}}
84
+ @data={{@integrations}}
85
+ @columns={{this.columns}}
86
+ @page={{@page}}
87
+ @onPageChange={{@onPageChange}}
88
+ @bulkActions={{@bulkActions}}
89
+ @controller={{@controller}}
90
+ @setupTable={{this.setupTable}}
91
+ @emptyStateComponent={{component
92
+ "table/empty-state"
93
+ variant="compact"
94
+ icon="satellite-dish"
95
+ title="No provider connections"
96
+ description="Connect a telematics provider to sync devices, events, and vehicle attachments."
97
+ primaryText="Connect provider"
98
+ primaryIcon="plus"
99
+ primaryAction=this.telematicActions.transition.create
100
+ docsSlug="fleet-ops/connectivity/telematics/overview"
101
+ docsTitle="Telematics guide"
102
+ docsText="Telematics guide"
103
+ }}
104
+ />
105
+ </section>
106
+ {{/if}}
107
+
108
+ <section class="rounded-md border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
109
+ <div class="mb-3 flex flex-col gap-1 md:flex-row md:items-end md:justify-between">
110
+ <div>
111
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Native Providers</h2>
112
+ <p class="text-xs leading-5 text-gray-500 dark:text-gray-300">Start with a provider connection, then sync devices and attach them to vehicles.</p>
113
+ </div>
114
+ {{#if @providersLoading}}
115
+ <div class="flex items-center gap-2 text-xs text-gray-500 dark:text-gray-300"><Spinner /> Loading providers</div>
116
+ {{/if}}
117
+ </div>
118
+
119
+ <div class="grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-4">
120
+ {{#each this.providerCards as |provider|}}
121
+ <button
122
+ type="button"
123
+ class="group flex min-h-[132px] flex-col rounded-md border border-gray-200 bg-white p-3 text-left transition hover:border-blue-300 hover:shadow-sm dark:border-gray-700 dark:bg-gray-800 dark:hover:border-blue-400"
124
+ {{on "click" (fn this.openProvider provider)}}
125
+ >
126
+ <div class="flex items-start justify-between gap-3">
127
+ <div class="flex min-w-0 items-start gap-3">
128
+ <Image src={{provider.icon}} class="h-7 w-7 flex-shrink-0 rounded" />
129
+ <div class="min-w-0">
130
+ <div class="truncate text-sm font-bold text-gray-900 dark:text-gray-100">{{provider.label}}</div>
131
+ <div class="truncate text-[10px] uppercase text-gray-400 dark:text-gray-500">{{provider.type}}</div>
132
+ </div>
133
+ </div>
134
+ <Badge @status={{if provider.connected "success" "info"}} @hideStatusDot={{true}}>
135
+ {{if provider.connected "Connected" "Available"}}
136
+ </Badge>
137
+ </div>
138
+ <p class="mt-3 line-clamp-2 text-xs leading-5 text-gray-500 dark:text-gray-300">{{provider.description}}</p>
139
+ <div class="mt-auto flex items-center justify-between pt-3 text-xs font-semibold text-blue-600 dark:text-blue-300">
140
+ <span>{{if provider.connected "Manage connection" "Connect provider"}}</span>
141
+ <FaIcon @icon="arrow-right" class="transition group-hover:translate-x-0.5" />
142
+ </div>
143
+ </button>
144
+ {{/each}}
145
+ </div>
146
+ </section>
147
+ </div>
148
+ </div>
149
+ </div>
@@ -0,0 +1,142 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { action } from '@ember/object';
5
+
6
+ const WARNING_STATUSES = ['error', 'degraded', 'disconnected'];
7
+
8
+ export default class TelematicHubComponent extends Component {
9
+ @service telematicActions;
10
+ @service hostRouter;
11
+ @tracked table;
12
+ @tracked columns = this.args.columns ?? [];
13
+
14
+ get integrations() {
15
+ return Array.from(this.args.integrations ?? []);
16
+ }
17
+
18
+ get providers() {
19
+ return Array.from(this.args.providers ?? []);
20
+ }
21
+
22
+ get connectedProviderKeys() {
23
+ return new Set(this.integrations.map((integration) => integration.provider).filter(Boolean));
24
+ }
25
+
26
+ get hasProviderConnections() {
27
+ return this.integrations.length > 0;
28
+ }
29
+
30
+ get providerCards() {
31
+ const connected = this.connectedProviderKeys;
32
+
33
+ return this.providers.map((provider) => {
34
+ const integration = this.integrations.find((record) => record.provider === provider.key);
35
+
36
+ return {
37
+ ...provider,
38
+ connected: connected.has(provider.key),
39
+ integration,
40
+ };
41
+ });
42
+ }
43
+
44
+ get activeProviderCount() {
45
+ return this.integrations.filter((integration) => !['disabled', 'archived'].includes(integration.status)).length;
46
+ }
47
+
48
+ get syncedDeviceCount() {
49
+ return this.integrations.reduce((total, integration) => total + Number(integration.meta?.last_sync_total ?? 0), 0);
50
+ }
51
+
52
+ get unattachedDeviceCount() {
53
+ return this.integrations.reduce((total, integration) => total + Number(integration.meta?.unattached_devices_count ?? 0), 0);
54
+ }
55
+
56
+ get healthWarningCount() {
57
+ return this.integrations.filter((integration) => WARNING_STATUSES.includes(integration.status) || integration.meta?.last_error || integration.meta?.last_sync_error).length;
58
+ }
59
+
60
+ get kpiWidgets() {
61
+ return [
62
+ {
63
+ icon: 'plug',
64
+ label: 'Provider count',
65
+ value: this.activeProviderCount,
66
+ help: 'Connected provider accounts',
67
+ action: 'Connect a provider',
68
+ routeAction: 'create',
69
+ accent: 'blue',
70
+ accentClass: 'fleetops-connectivity-kpi-accent-blue',
71
+ },
72
+ {
73
+ icon: 'satellite-dish',
74
+ label: 'Synced Devices',
75
+ value: this.syncedDeviceCount,
76
+ help: 'Discovered from providers',
77
+ action: 'Review synced devices',
78
+ routeAction: 'devices',
79
+ accent: 'green',
80
+ accentClass: 'fleetops-connectivity-kpi-accent-green',
81
+ },
82
+ {
83
+ icon: 'truck',
84
+ label: 'Unattached devices',
85
+ value: this.unattachedDeviceCount,
86
+ help: this.unattachedDeviceCount > 0 ? 'Devices need vehicles' : 'No open attachment count',
87
+ action: 'Attach to vehicles',
88
+ routeAction: 'attachments',
89
+ accent: 'amber',
90
+ accentClass: 'fleetops-connectivity-kpi-accent-amber',
91
+ },
92
+ {
93
+ icon: 'wave-square',
94
+ label: 'Health warnings',
95
+ value: this.healthWarningCount,
96
+ help: this.healthWarningCount > 0 ? 'Warnings need review' : 'No warnings',
97
+ action: 'Review health',
98
+ routeAction: 'health',
99
+ accent: 'rose',
100
+ accentClass: 'fleetops-connectivity-kpi-accent-rose',
101
+ },
102
+ ];
103
+ }
104
+
105
+ statusForProvider(provider) {
106
+ if (provider.connected) {
107
+ return provider.integration?.status ?? 'connected';
108
+ }
109
+
110
+ return 'not-connected';
111
+ }
112
+
113
+ @action openProvider(provider) {
114
+ if (provider.integration) {
115
+ return this.telematicActions.transition.view(provider.integration);
116
+ }
117
+
118
+ return this.telematicActions.transition.create(provider.key);
119
+ }
120
+
121
+ @action refresh() {
122
+ return this.telematicActions.refresh();
123
+ }
124
+
125
+ @action setupTable(table) {
126
+ this.table = table;
127
+ }
128
+
129
+ @action runKpiAction(widget) {
130
+ if (widget.routeAction === 'create') {
131
+ return this.telematicActions.transition.create();
132
+ }
133
+
134
+ const integration = this.integrations[0];
135
+
136
+ if (!integration) {
137
+ return this.telematicActions.transition.create();
138
+ }
139
+
140
+ return this.telematicActions.transition.view(integration);
141
+ }
142
+ }
@@ -0,0 +1,152 @@
1
+ <div class="flex min-h-0 flex-1 flex-col" ...attributes>
2
+ <div class="min-h-0 flex-1 overflow-y-auto px-4 py-4 md:px-6">
3
+ <div class="mx-auto flex w-full max-w-6xl flex-col gap-4">
4
+ <section class="rounded-md border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
5
+ <div class="mb-3">
6
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Provider</h2>
7
+ <p class="text-xs text-gray-500 dark:text-gray-300">Provider identity is locked after the connection is created.</p>
8
+ </div>
9
+
10
+ <div class="flex flex-col gap-3 rounded-md border border-gray-200 bg-gray-50 p-3 dark:border-gray-700 dark:bg-gray-900/40 md:flex-row md:items-start md:justify-between">
11
+ <div class="flex min-w-0 items-start gap-3">
12
+ <Image src={{this.provider.icon}} class="h-10 w-10 flex-shrink-0 rounded" />
13
+ <div class="min-w-0">
14
+ <div class="truncate text-sm font-bold text-gray-900 dark:text-gray-100">{{or this.provider.label @resource.provider}}</div>
15
+ <p class="mt-1 max-w-3xl text-xs leading-5 text-gray-500 dark:text-gray-300">{{this.provider.description}}</p>
16
+ </div>
17
+ </div>
18
+ <div class="flex flex-shrink-0 flex-wrap items-center gap-2">
19
+ <Badge @status="info" @hideStatusDot={{true}}>{{@resource.provider}}</Badge>
20
+ {{#if @resource.public_id}}
21
+ <Badge @status="default" @hideStatusDot={{true}}>{{@resource.public_id}}</Badge>
22
+ {{/if}}
23
+ </div>
24
+ </div>
25
+ </section>
26
+
27
+ <section class="grid grid-cols-1 gap-4 lg:grid-cols-3">
28
+ <div 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">
29
+ <div class="mb-3">
30
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Connection</h2>
31
+ <p class="text-xs text-gray-500 dark:text-gray-300">Update connection naming and saved provider credentials.</p>
32
+ </div>
33
+
34
+ <div class="grid grid-cols-1 gap-2 no-input-group-padding text-xs">
35
+ <InputGroup @value={{@resource.name}} @name="Connection Name" />
36
+
37
+ {{#if (or this.credentialFields.length this.hasAdvancedCredentialFields)}}
38
+ <div class="mt-2 grid grid-cols-1 gap-2 lg:grid-cols-2">
39
+ {{#each this.credentialFields as |field|}}
40
+ <InputGroup
41
+ @name={{field.label}}
42
+ @value={{get @resource.credentials field.name}}
43
+ @required={{field.required}}
44
+ @type={{field.type}}
45
+ @placeholder={{field.placeholder}}
46
+ @helpText={{field.help_text}}
47
+ {{on "input" (fn this.setCredential field)}}
48
+ />
49
+ {{/each}}
50
+ </div>
51
+ {{#if this.hasAdvancedCredentialFields}}
52
+ <details class="mt-4 rounded-md border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-900/40">
53
+ <summary class="flex cursor-pointer list-none items-center justify-between gap-3 px-3 py-2 text-xs font-semibold text-gray-700 dark:text-gray-200">
54
+ <span class="inline-flex items-center gap-2">
55
+ <FaIcon @icon="sliders" />
56
+ Advanced connection settings
57
+ </span>
58
+ <span class="text-[11px] font-normal text-gray-400 dark:text-gray-500">Endpoint overrides</span>
59
+ </summary>
60
+ <div class="border-t border-gray-200 p-3 dark:border-gray-700">
61
+ <div class="grid grid-cols-1 gap-2 lg:grid-cols-2 no-input-group-padding text-xs">
62
+ {{#each this.advancedCredentialFields as |field|}}
63
+ <InputGroup
64
+ @name={{field.label}}
65
+ @value={{or (get @resource.credentials field.name) field.default_value}}
66
+ @required={{field.required}}
67
+ @type={{field.type}}
68
+ @placeholder={{field.placeholder}}
69
+ @helpText={{field.help_text}}
70
+ {{on "input" (fn this.setCredential field)}}
71
+ />
72
+ {{/each}}
73
+ </div>
74
+ </div>
75
+ </details>
76
+ {{/if}}
77
+ {{else}}
78
+ <div class="rounded-md border border-dashed border-gray-300 p-3 text-xs text-gray-500 dark:border-gray-700 dark:text-gray-300">
79
+ This provider does not define editable credential fields.
80
+ </div>
81
+ {{/if}}
82
+ </div>
83
+ </div>
84
+
85
+ <aside class="rounded-md border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
86
+ <div class="mb-3">
87
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Capabilities</h2>
88
+ <p class="text-xs text-gray-500 dark:text-gray-300">Provider-supported connectivity features.</p>
89
+ </div>
90
+ <div class="flex flex-wrap gap-2">
91
+ <Badge @status={{if this.provider.supports_discovery "success" "default"}} @hideStatusDot={{true}}>Discovery</Badge>
92
+ <Badge @status={{if this.provider.supports_webhooks "success" "default"}} @hideStatusDot={{true}}>Webhooks</Badge>
93
+ </div>
94
+ </aside>
95
+ </section>
96
+
97
+ <section class="rounded-md border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
98
+ <div class="mb-3">
99
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Webhook</h2>
100
+ <p class="text-xs text-gray-500 dark:text-gray-300">Provider-facing URL used for inbound telemetry when supported.</p>
101
+ </div>
102
+
103
+ {{#if this.provider.supports_webhooks}}
104
+ {{#if this.hasWebhookUrl}}
105
+ <ClickToCopy @value={{this.webhookUrl}} class="block w-full">
106
+ <Input @value={{this.webhookUrl}} class="form-input w-full" readonly />
107
+ </ClickToCopy>
108
+ {{else}}
109
+ <div class="rounded-md border border-yellow-200 bg-yellow-50 p-3 text-xs text-yellow-800 dark:border-yellow-700 dark:bg-gray-800 dark:text-yellow-300">
110
+ Webhook URL unavailable until this connection has a public ID.
111
+ </div>
112
+ {{/if}}
113
+ {{else}}
114
+ <div class="rounded-md border border-dashed border-gray-300 p-3 text-xs text-gray-500 dark:border-gray-700 dark:text-gray-300">
115
+ This provider does not require FleetOps webhook configuration.
116
+ </div>
117
+ {{/if}}
118
+ </section>
119
+
120
+ <section class="rounded-md border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
121
+ <div class="mb-3">
122
+ <h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Hardware Identity</h2>
123
+ <p class="text-xs text-gray-500 dark:text-gray-300">Optional blackbox metadata for provider hardware installed in the fleet.</p>
124
+ </div>
125
+ <div class="grid grid-cols-1 gap-2 no-input-group-padding text-xs lg:grid-cols-3">
126
+ <InputGroup @value={{@resource.model}} @name="Model" />
127
+ <InputGroup @value={{@resource.serial_number}} @name="Serial Number" />
128
+ <InputGroup @value={{@resource.firmware_version}} @name="Firmware Version" />
129
+ <InputGroup @value={{@resource.imei}} @name="IMEI" />
130
+ <InputGroup @value={{@resource.imsi}} @name="IMSI" />
131
+ <InputGroup @value={{@resource.iccid}} @name="ICCID" />
132
+ </div>
133
+ </section>
134
+
135
+ <CustomField::Yield @subject={{@resource}} @wrapperClass="bordered-top" />
136
+
137
+ <RegistryYield @registry="fleet-ops:component:telematic:form" as |RegistryComponent|>
138
+ <RegistryComponent @resource={{@resource}} @controller={{@controller}} @permission={{get-write-permission @resource}} />
139
+ </RegistryYield>
140
+ </div>
141
+ </div>
142
+
143
+ <footer class="flex-shrink-0 border-t border-gray-200 bg-white px-4 py-3 shadow-sm dark:border-gray-700 dark:bg-gray-900 dark:shadow-sm dark:shadow-black/30 md:px-6">
144
+ <div class="mx-auto flex w-full max-w-6xl flex-col gap-2 md:flex-row md:items-center md:justify-between">
145
+ <div class="text-xs text-gray-500 dark:text-gray-300">{{@footerHelp}}</div>
146
+ <div class="flex items-center justify-end gap-2">
147
+ <Button @icon="times" @text="Cancel" @size="sm" @onClick={{@onCancel}} />
148
+ <Button @icon="save" @text={{if @isSaving @savingLabel @saveLabel}} @type="primary" @size="sm" @isLoading={{@isSaving}} @onClick={{@onSave}} />
149
+ </div>
150
+ </div>
151
+ </footer>
152
+ </div>
@@ -0,0 +1,45 @@
1
+ import Component from '@glimmer/component';
2
+ import { action } from '@ember/object';
3
+
4
+ export default class TelematicSettingsComponent extends Component {
5
+ get provider() {
6
+ return this.args.resource?.provider_descriptor ?? {};
7
+ }
8
+
9
+ get credentialFields() {
10
+ return (this.provider.required_fields ?? []).filter((field) => !field.advanced && !field.is_endpoint);
11
+ }
12
+
13
+ get advancedCredentialFields() {
14
+ return (this.provider.required_fields ?? []).filter((field) => field.advanced || field.is_endpoint);
15
+ }
16
+
17
+ get hasAdvancedCredentialFields() {
18
+ return this.advancedCredentialFields.length > 0;
19
+ }
20
+
21
+ get webhookUrl() {
22
+ const url = this.provider.webhook_url;
23
+ const id = this.args.resource?.public_id;
24
+
25
+ if (!url || !id) {
26
+ return null;
27
+ }
28
+
29
+ const separator = url.includes('?') ? '&' : '?';
30
+ return `${url}${separator}telematic=${id}`;
31
+ }
32
+
33
+ get hasWebhookUrl() {
34
+ return Boolean(this.webhookUrl);
35
+ }
36
+
37
+ @action setCredential(field, { target: { value } }) {
38
+ const credentials = this.args.resource?.credentials ?? {};
39
+
40
+ this.args.resource?.set('credentials', {
41
+ ...credentials,
42
+ [field.name]: value,
43
+ });
44
+ }
45
+ }
@@ -0,0 +1,29 @@
1
+ <div class="rounded-md border p-4 shadow-sm {{this.toneClass}}" ...attributes>
2
+ <div class="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
3
+ <div class="flex min-w-0 items-start gap-3">
4
+ <div class="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-md {{this.iconClass}}">
5
+ <FaIcon @icon={{or @icon "circle-info"}} />
6
+ </div>
7
+ <div class="min-w-0">
8
+ <h4 class="text-sm font-bold">{{@title}}</h4>
9
+ {{#if @message}}
10
+ <p class="mt-1 text-sm leading-5 opacity-80">{{@message}}</p>
11
+ {{/if}}
12
+ {{#if @note}}
13
+ <p class="mt-2 text-xs leading-5 opacity-70">{{@note}}</p>
14
+ {{/if}}
15
+ </div>
16
+ </div>
17
+
18
+ {{#if (or @primaryAction @secondaryAction)}}
19
+ <div class="flex flex-shrink-0 flex-wrap items-center gap-2 md:justify-end">
20
+ {{#if @secondaryAction}}
21
+ <Button @type="default" @size="xs" @icon={{@secondaryIcon}} @text={{@secondaryText}} @onClick={{@secondaryAction}} />
22
+ {{/if}}
23
+ {{#if @primaryAction}}
24
+ <Button @type="primary" @size="xs" @icon={{@primaryIcon}} @text={{@primaryText}} @onClick={{@primaryAction}} />
25
+ {{/if}}
26
+ </div>
27
+ {{/if}}
28
+ </div>
29
+ </div>
@@ -0,0 +1,33 @@
1
+ import Component from '@glimmer/component';
2
+
3
+ export default class TelematicTabEmptyStateComponent extends Component {
4
+ get toneClass() {
5
+ switch (this.args.tone) {
6
+ case 'success':
7
+ return 'border-green-200 bg-green-50 text-green-900 dark:border-green-700 dark:bg-green-900/20 dark:text-green-100';
8
+ case 'warning':
9
+ return 'border-yellow-200 bg-yellow-50 text-yellow-900 dark:border-yellow-700 dark:bg-yellow-900/20 dark:text-yellow-100';
10
+ case 'danger':
11
+ return 'border-red-200 bg-red-50 text-red-900 dark:border-red-700 dark:bg-red-900/20 dark:text-red-100';
12
+ case 'info':
13
+ return 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-700 dark:bg-blue-900/20 dark:text-blue-100';
14
+ default:
15
+ return 'border-gray-200 bg-white text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100';
16
+ }
17
+ }
18
+
19
+ get iconClass() {
20
+ switch (this.args.tone) {
21
+ case 'success':
22
+ return 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300';
23
+ case 'warning':
24
+ return 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/40 dark:text-yellow-300';
25
+ case 'danger':
26
+ return 'bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300';
27
+ case 'info':
28
+ return 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300';
29
+ default:
30
+ return 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300';
31
+ }
32
+ }
33
+ }
@@ -57,6 +57,11 @@
57
57
  <div class="field-value">{{n-a @resource.serial_number}}</div>
58
58
  </div>
59
59
 
60
+ <div class="field-info-container">
61
+ <div class="field-name">Fuel Card Number</div>
62
+ <div class="field-value">{{n-a @resource.fuel_card_number}}</div>
63
+ </div>
64
+
60
65
  <div class="field-info-container">
61
66
  <div class="field-name">Class</div>
62
67
  <div class="field-value">{{n-a @resource.class}}</div>
@@ -697,4 +702,4 @@
697
702
  </ContentPanel>
698
703
 
699
704
  <Spacer @height="300px" />
700
- </div>
705
+ </div>
@@ -68,6 +68,7 @@
68
68
  <InputGroup @value={{@resource.trim}} @name="Trim" @placeholder="Trim" />
69
69
  <InputGroup @value={{@resource.color}} @name="Color" @placeholder="Vehicle Color" />
70
70
  <InputGroup @value={{@resource.serial_number}} @name="Serial Number" @placeholder="Serial Number" />
71
+ <InputGroup @value={{@resource.fuel_card_number}} @name="Fuel Card Number" @placeholder="Fuel Card Number" />
71
72
  <InputGroup @value={{@resource.class}} @name="Class" @placeholder="Class" />
72
73
 
73
74
  {{! Assignment & Status }}
@@ -607,4 +608,4 @@
607
608
  <ContentPanel @title={{t "common.metadata"}} @open={{true}} @wrapperClass="bordered-top">
608
609
  <MetadataEditor @value={{@resource.meta}} @onChange={{fn (mut @resource.meta)}} />
609
610
  </ContentPanel>
610
- </div>
611
+ </div>