@fleetbase/fleetops-engine 0.6.37 → 0.6.39

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 (434) hide show
  1. package/addon/components/activity/form.hbs +2 -12
  2. package/addon/components/activity/logic-builder.hbs +1 -1
  3. package/addon/components/custom-entity/form.hbs +4 -20
  4. package/addon/components/device/form.hbs +3 -15
  5. package/addon/components/device/panel-header.hbs +13 -2
  6. package/addon/components/driver/details.hbs +33 -2
  7. package/addon/components/driver/form.hbs +42 -0
  8. package/addon/components/driver/panel-header.hbs +8 -1
  9. package/addon/components/driver/schedule.hbs +115 -76
  10. package/addon/components/driver/schedule.js +349 -157
  11. package/addon/components/driver-onboard-settings.hbs +2 -8
  12. package/addon/components/entity-field-editing-settings.hbs +2 -5
  13. package/addon/components/equipment/card.hbs +49 -0
  14. package/addon/components/equipment/card.js +6 -0
  15. package/addon/components/equipment/details.hbs +83 -44
  16. package/addon/components/equipment/form.hbs +111 -41
  17. package/addon/components/equipment/form.js +78 -10
  18. package/addon/components/equipment/panel-header.hbs +36 -0
  19. package/addon/components/equipment/panel-header.js +2 -0
  20. package/addon/components/fleet/driver-listing.hbs +3 -1
  21. package/addon/components/fleet/vehicle-listing.hbs +4 -7
  22. package/addon/components/fleet-panel/vehicle-listing.hbs +1 -6
  23. package/addon/components/fuel-report/form.hbs +1 -5
  24. package/addon/components/layout/fleet-ops-sidebar.hbs +40 -36
  25. package/addon/components/layout/fleet-ops-sidebar.js +61 -10
  26. package/addon/components/maintenance/cost-panel.hbs +176 -0
  27. package/addon/components/maintenance/cost-panel.js +241 -0
  28. package/addon/components/maintenance/details.hbs +123 -60
  29. package/addon/components/maintenance/form.hbs +138 -78
  30. package/addon/components/maintenance/form.js +131 -6
  31. package/addon/components/maintenance/panel-header.hbs +31 -0
  32. package/addon/components/maintenance/panel-header.js +2 -0
  33. package/addon/components/maintenance-schedule/details.hbs +260 -0
  34. package/addon/components/maintenance-schedule/details.js +158 -0
  35. package/addon/components/maintenance-schedule/form.hbs +287 -0
  36. package/addon/components/maintenance-schedule/form.js +199 -0
  37. package/addon/components/map/container.hbs +1 -1
  38. package/addon/components/map/drawer/device-event-listing.hbs +1 -1
  39. package/addon/components/map/drawer/driver-listing.hbs +1 -6
  40. package/addon/components/map/drawer/place-listing.hbs +1 -6
  41. package/addon/components/map/drawer/vehicle-listing.hbs +1 -6
  42. package/addon/components/map/drawer.hbs +8 -1
  43. package/addon/components/map/leaflet-live-map.hbs +2 -1
  44. package/addon/components/map/toolbar/visibility-control-panel.hbs +1 -1
  45. package/addon/components/map/toolbar.hbs +4 -29
  46. package/addon/components/modals/add-driver-shift.hbs +155 -0
  47. package/addon/components/modals/add-driver-shift.js +210 -0
  48. package/addon/components/modals/bulk-assign-orders.hbs +67 -0
  49. package/addon/components/modals/driver-shift.hbs +43 -0
  50. package/addon/components/modals/driver-shift.js +56 -0
  51. package/addon/components/modals/entity-form.hbs +5 -28
  52. package/addon/components/modals/orchestrator-import.hbs +351 -0
  53. package/addon/components/modals/orchestrator-import.js +807 -0
  54. package/addon/components/modals/order-config-new-status.hbs +1 -5
  55. package/addon/components/modals/scheduling-conflict.hbs +47 -0
  56. package/addon/components/modals/scheduling-conflict.js +53 -0
  57. package/addon/components/modals/send-work-order.hbs +91 -0
  58. package/addon/components/modals/send-work-order.js +3 -0
  59. package/addon/components/modals/service-area-form.hbs +1 -6
  60. package/addon/components/modals/set-driver-availability.hbs +50 -0
  61. package/addon/components/modals/set-driver-availability.js +57 -0
  62. package/addon/components/modals/update-order-activity.hbs +13 -9
  63. package/addon/components/modals/user-form.hbs +1 -5
  64. package/addon/components/modals/vehicle-form.hbs +17 -102
  65. package/addon/components/modals/vendor-form.hbs +15 -82
  66. package/addon/components/orchestrator/card-fields-settings.hbs +76 -0
  67. package/addon/components/orchestrator/card-fields-settings.js +134 -0
  68. package/addon/components/orchestrator/order-pool.hbs +264 -0
  69. package/addon/components/orchestrator/order-pool.js +394 -0
  70. package/addon/components/orchestrator/phase-builder.hbs +162 -0
  71. package/addon/components/orchestrator/phase-builder.js +162 -0
  72. package/addon/components/orchestrator/plan-viewer.hbs +278 -0
  73. package/addon/components/orchestrator/plan-viewer.js +342 -0
  74. package/addon/components/orchestrator/resource-panel.hbs +301 -0
  75. package/addon/components/orchestrator/resource-panel.js +106 -0
  76. package/addon/components/orchestrator-workbench.hbs +318 -0
  77. package/addon/components/orchestrator-workbench.js +1087 -0
  78. package/addon/components/order/details/custom-fields.hbs +10 -1
  79. package/addon/components/order/details/detail.hbs +37 -2
  80. package/addon/components/order/details/detail.js +0 -1
  81. package/addon/components/order/details/integrated-vendor-details.hbs +4 -4
  82. package/addon/components/order/details/notes.hbs +1 -7
  83. package/addon/components/order/details/route.hbs +1 -5
  84. package/addon/components/order/form/details.hbs +44 -10
  85. package/addon/components/order/form/details.js +57 -0
  86. package/addon/components/order/form/notes.hbs +1 -7
  87. package/addon/components/order/form/payload.hbs +1 -7
  88. package/addon/components/order/form/route.hbs +3 -15
  89. package/addon/components/order/header.hbs +1 -7
  90. package/addon/components/order/route-editor.hbs +4 -25
  91. package/addon/components/order/schedule-card.hbs +102 -95
  92. package/addon/components/order/schedule-card.js +8 -3
  93. package/addon/components/order-config-manager/details.hbs +2 -10
  94. package/addon/components/order-config-manager/entities.hbs +1 -7
  95. package/addon/components/order-config-manager.hbs +1 -6
  96. package/addon/components/part/card.hbs +49 -0
  97. package/addon/components/part/card.js +6 -0
  98. package/addon/components/part/details.hbs +102 -56
  99. package/addon/components/part/form.hbs +131 -56
  100. package/addon/components/part/form.js +78 -11
  101. package/addon/components/part/panel-header.hbs +36 -0
  102. package/addon/components/part/panel-header.js +2 -0
  103. package/addon/components/place/form.hbs +1 -7
  104. package/addon/components/sensor/details.hbs +1 -1
  105. package/addon/components/sensor/form.hbs +5 -3
  106. package/addon/components/sensor/panel-header.hbs +8 -1
  107. package/addon/components/service-area/form.hbs +1 -6
  108. package/addon/components/service-rate/form.hbs +12 -60
  109. package/addon/components/telematic/form.hbs +6 -2
  110. package/addon/components/vehicle/details/maintenance-history.hbs +42 -0
  111. package/addon/components/vehicle/details/maintenance-history.js +32 -0
  112. package/addon/components/vehicle/details/schedules.hbs +40 -0
  113. package/addon/components/vehicle/details/schedules.js +32 -0
  114. package/addon/components/vehicle/details/work-orders.hbs +42 -0
  115. package/addon/components/vehicle/details/work-orders.js +32 -0
  116. package/addon/components/vehicle/details.hbs +30 -0
  117. package/addon/components/vehicle/form.hbs +39 -0
  118. package/addon/components/vehicle/panel-header.hbs +19 -49
  119. package/addon/components/warranty/details.hbs +3 -2
  120. package/addon/components/warranty/form.hbs +3 -17
  121. package/addon/components/work-order/details.hbs +135 -40
  122. package/addon/components/work-order/form.hbs +178 -45
  123. package/addon/components/work-order/form.js +197 -4
  124. package/addon/components/work-order/panel-header.hbs +31 -0
  125. package/addon/components/work-order/panel-header.js +2 -0
  126. package/addon/controllers/connectivity/devices/index/details.js +1 -1
  127. package/addon/controllers/maintenance/equipment/index/details/index.js +0 -1
  128. package/addon/controllers/maintenance/equipment/index/details.js +36 -1
  129. package/addon/controllers/maintenance/equipment/index/edit.js +56 -1
  130. package/addon/controllers/maintenance/equipment/index/new.js +32 -1
  131. package/addon/controllers/maintenance/equipment/index.js +127 -113
  132. package/addon/controllers/maintenance/maintenances/index/details/index.js +3 -0
  133. package/addon/controllers/maintenance/maintenances/index/details.js +54 -0
  134. package/addon/controllers/maintenance/maintenances/index/edit.js +68 -0
  135. package/addon/controllers/maintenance/maintenances/index/new.js +34 -0
  136. package/addon/controllers/maintenance/maintenances/index.js +191 -0
  137. package/addon/controllers/maintenance/parts/index/details/index.js +0 -1
  138. package/addon/controllers/maintenance/parts/index/details.js +36 -1
  139. package/addon/controllers/maintenance/parts/index/edit.js +56 -1
  140. package/addon/controllers/maintenance/parts/index/new.js +32 -1
  141. package/addon/controllers/maintenance/parts/index.js +135 -113
  142. package/addon/controllers/maintenance/schedules/index/details.js +115 -0
  143. package/addon/controllers/maintenance/schedules/index/edit.js +41 -0
  144. package/addon/controllers/maintenance/schedules/index/new.js +33 -0
  145. package/addon/controllers/maintenance/schedules/index.js +280 -0
  146. package/addon/controllers/maintenance/work-orders/index/details.js +41 -1
  147. package/addon/controllers/maintenance/work-orders/index/edit.js +67 -1
  148. package/addon/controllers/maintenance/work-orders/index/new.js +43 -1
  149. package/addon/controllers/maintenance/work-orders/index.js +105 -113
  150. package/addon/controllers/management/drivers/index/details.js +6 -1
  151. package/addon/controllers/management/vehicles/index/details.js +65 -0
  152. package/addon/controllers/management/vehicles/index.js +18 -0
  153. package/addon/controllers/operations/orchestrator.js +10 -0
  154. package/addon/controllers/operations/orders/index/details.js +5 -0
  155. package/addon/controllers/operations/orders/index.js +6 -0
  156. package/addon/controllers/operations/scheduler/fleet-schedule.js +341 -0
  157. package/addon/controllers/operations/scheduler/index.js +799 -275
  158. package/addon/controllers/operations/scheduler.js +21 -0
  159. package/addon/controllers/settings/orchestrator.js +70 -0
  160. package/addon/controllers/settings/scheduling.js +155 -0
  161. package/addon/extension.js +74 -1
  162. package/addon/instance-initializers/register-vroom-allocation.js +27 -0
  163. package/addon/models/maintenance-schedule.js +61 -0
  164. package/addon/routes/maintenance/equipment/index/details.js +27 -1
  165. package/addon/routes/maintenance/equipment/index/edit.js +27 -1
  166. package/addon/routes/maintenance/maintenances/index/details/index.js +3 -0
  167. package/addon/routes/maintenance/maintenances/index/details.js +29 -0
  168. package/addon/routes/maintenance/maintenances/index/edit.js +29 -0
  169. package/addon/routes/maintenance/maintenances/index/new.js +3 -0
  170. package/addon/routes/maintenance/maintenances/index.js +23 -0
  171. package/addon/routes/maintenance/maintenances.js +3 -0
  172. package/addon/routes/maintenance/parts/index/details.js +27 -1
  173. package/addon/routes/maintenance/parts/index/edit.js +27 -1
  174. package/addon/routes/maintenance/schedules/index/details/index.js +2 -0
  175. package/addon/routes/maintenance/schedules/index/details/work-orders.js +11 -0
  176. package/addon/routes/maintenance/schedules/index/details.js +25 -0
  177. package/addon/routes/maintenance/schedules/index/edit.js +25 -0
  178. package/addon/routes/maintenance/schedules/index/new.js +2 -0
  179. package/addon/routes/maintenance/schedules/index.js +21 -0
  180. package/addon/routes/maintenance/schedules.js +2 -0
  181. package/addon/routes/maintenance/work-orders/index/details.js +27 -1
  182. package/addon/routes/maintenance/work-orders/index/edit.js +27 -1
  183. package/addon/routes/management/vehicles/index/details/maintenance-history.js +3 -0
  184. package/addon/routes/management/vehicles/index/details/schedules.js +3 -0
  185. package/addon/routes/management/vehicles/index/details/work-orders.js +3 -0
  186. package/addon/routes/operations/orchestrator.js +23 -0
  187. package/addon/routes/operations/orders/index/details/virtual.js +23 -0
  188. package/addon/routes/operations/scheduler/fleet-schedule.js +28 -0
  189. package/addon/routes/operations/scheduler/index.js +48 -26
  190. package/addon/routes/operations/scheduler.js +14 -1
  191. package/addon/routes/settings/orchestrator.js +27 -0
  192. package/addon/routes/settings/scheduling.js +3 -0
  193. package/addon/routes.js +33 -1
  194. package/addon/services/driver-actions.js +40 -7
  195. package/addon/services/driver-scheduling.js +4 -1
  196. package/addon/services/equipment-actions.js +15 -5
  197. package/addon/services/leaflet-map-manager.js +14 -6
  198. package/addon/services/maintenance-actions.js +17 -14
  199. package/addon/services/maintenance-schedule-actions.js +118 -0
  200. package/addon/services/orchestration-engine-interface.js +49 -0
  201. package/addon/services/orchestration-engine.js +74 -0
  202. package/addon/services/order-actions.js +15 -0
  203. package/addon/services/order-allocation.js +116 -0
  204. package/addon/services/part-actions.js +12 -2
  205. package/addon/services/scheduling.js +316 -0
  206. package/addon/services/vehicle-actions.js +70 -7
  207. package/addon/services/vroom-allocation-engine.js +45 -0
  208. package/addon/services/work-order-actions.js +80 -0
  209. package/addon/styles/fleetops-engine.css +1658 -0
  210. package/addon/templates/analytics/reports/index/edit.hbs +1 -1
  211. package/addon/templates/analytics/reports/index/new.hbs +1 -1
  212. package/addon/templates/application.hbs +6 -1
  213. package/addon/templates/connectivity/devices/index/details/events.hbs +0 -1
  214. package/addon/templates/connectivity/devices.hbs +0 -1
  215. package/addon/templates/connectivity/events/index/details.hbs +0 -1
  216. package/addon/templates/connectivity/events.hbs +0 -1
  217. package/addon/templates/connectivity/sensors.hbs +0 -1
  218. package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
  219. package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
  220. package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
  221. package/addon/templates/connectivity/telematics.hbs +0 -1
  222. package/addon/templates/connectivity/tracking.hbs +0 -1
  223. package/addon/templates/connectivity.hbs +0 -1
  224. package/addon/templates/maintenance/equipment/index/details/index.hbs +1 -2
  225. package/addon/templates/maintenance/equipment/index/details.hbs +15 -2
  226. package/addon/templates/maintenance/equipment/index/edit.hbs +12 -2
  227. package/addon/templates/maintenance/equipment/index/new.hbs +1 -2
  228. package/addon/templates/maintenance/equipment/index.hbs +48 -13
  229. package/addon/templates/maintenance/equipment.hbs +0 -1
  230. package/addon/templates/maintenance/maintenances/index/details/index.hbs +1 -0
  231. package/addon/templates/maintenance/maintenances/index/details.hbs +15 -0
  232. package/addon/templates/maintenance/maintenances/index/edit.hbs +12 -0
  233. package/addon/templates/maintenance/maintenances/index/new.hbs +11 -0
  234. package/addon/templates/maintenance/maintenances/index.hbs +14 -0
  235. package/addon/templates/maintenance/maintenances.hbs +1 -0
  236. package/addon/templates/maintenance/parts/index/details/index.hbs +1 -2
  237. package/addon/templates/maintenance/parts/index/details.hbs +15 -2
  238. package/addon/templates/maintenance/parts/index/edit.hbs +12 -2
  239. package/addon/templates/maintenance/parts/index/new.hbs +1 -2
  240. package/addon/templates/maintenance/parts/index.hbs +48 -13
  241. package/addon/templates/maintenance/parts.hbs +0 -1
  242. package/addon/templates/maintenance/schedules/index/details/index.hbs +1 -0
  243. package/addon/templates/maintenance/schedules/index/details/work-orders.hbs +39 -0
  244. package/addon/templates/maintenance/schedules/index/details.hbs +14 -0
  245. package/addon/templates/maintenance/schedules/index/edit.hbs +12 -0
  246. package/addon/templates/maintenance/schedules/index/new.hbs +11 -0
  247. package/addon/templates/maintenance/schedules/index.hbs +40 -0
  248. package/addon/templates/maintenance/schedules.hbs +1 -0
  249. package/addon/templates/maintenance/work-orders/index/details.hbs +2 -1
  250. package/addon/templates/maintenance/work-orders/index/edit.hbs +2 -4
  251. package/addon/templates/maintenance/work-orders/index/new.hbs +1 -2
  252. package/addon/templates/maintenance/work-orders.hbs +0 -1
  253. package/addon/templates/management/contacts/customers/edit.hbs +1 -2
  254. package/addon/templates/management/contacts/customers/new.hbs +1 -2
  255. package/addon/templates/management/contacts/customers.hbs +1 -1
  256. package/addon/templates/management/contacts/index/edit.hbs +1 -2
  257. package/addon/templates/management/contacts/index/new.hbs +1 -2
  258. package/addon/templates/management/drivers/index/details/orders.hbs +0 -1
  259. package/addon/templates/management/drivers/index/edit.hbs +1 -2
  260. package/addon/templates/management/drivers/index/new.hbs +1 -2
  261. package/addon/templates/management/fleets/index/edit.hbs +1 -2
  262. package/addon/templates/management/fleets/index/new.hbs +1 -2
  263. package/addon/templates/management/fleets/index.hbs +1 -2
  264. package/addon/templates/management/fuel-reports/index/edit.hbs +1 -2
  265. package/addon/templates/management/fuel-reports/index/new.hbs +1 -2
  266. package/addon/templates/management/fuel-reports/index.hbs +1 -2
  267. package/addon/templates/management/issues/index/edit.hbs +1 -2
  268. package/addon/templates/management/issues/index/new.hbs +1 -2
  269. package/addon/templates/management/issues/index.hbs +1 -2
  270. package/addon/templates/management/places/index/details/activity.hbs +0 -1
  271. package/addon/templates/management/places/index/details/comments.hbs +0 -1
  272. package/addon/templates/management/places/index/details/documents.hbs +0 -1
  273. package/addon/templates/management/places/index/details/map.hbs +0 -1
  274. package/addon/templates/management/places/index/details/operations.hbs +0 -1
  275. package/addon/templates/management/places/index/details/performance.hbs +0 -1
  276. package/addon/templates/management/places/index/details/rules.hbs +0 -1
  277. package/addon/templates/management/vehicles/index/details/equipment.hbs +0 -1
  278. package/addon/templates/management/vehicles/index/details/maintenance-history.hbs +2 -0
  279. package/addon/templates/management/vehicles/index/details/schedules.hbs +2 -0
  280. package/addon/templates/management/vehicles/index/details/work-orders.hbs +2 -0
  281. package/addon/templates/management/vehicles/index/details.hbs +1 -1
  282. package/addon/templates/management/vehicles/index/edit.hbs +1 -2
  283. package/addon/templates/management/vehicles/index/new.hbs +1 -2
  284. package/addon/templates/management/vendors/index/edit.hbs +1 -2
  285. package/addon/templates/management/vendors/index/new.hbs +1 -2
  286. package/addon/templates/management/vendors/index.hbs +1 -2
  287. package/addon/templates/management/vendors/integrated.hbs +1 -2
  288. package/addon/templates/operations/orchestrator.hbs +1 -0
  289. package/addon/templates/operations/orders/index/details/virtual.hbs +1 -0
  290. package/addon/templates/operations/orders/index.hbs +6 -1
  291. package/addon/templates/operations/scheduler/fleet-schedule.hbs +41 -0
  292. package/addon/templates/operations/scheduler/index.hbs +147 -88
  293. package/addon/templates/operations/scheduler.hbs +7 -1
  294. package/addon/templates/settings/avatars.hbs +1 -1
  295. package/addon/templates/settings/orchestrator.hbs +65 -0
  296. package/addon/templates/settings/payments/index.hbs +1 -5
  297. package/addon/templates/settings/scheduling.hbs +82 -0
  298. package/addon/utils/create-full-calendar-event-from-order.js +52 -14
  299. package/addon/utils/create-full-calendar-event-from-schedule-item.js +50 -0
  300. package/addon/utils/fleet-ops-options.js +254 -0
  301. package/addon/utils/route-colors.js +99 -0
  302. package/addon/utils/to-calendar-date.js +70 -0
  303. package/app/components/driver/schedule.js +1 -0
  304. package/app/components/maintenance/cost-panel.js +1 -0
  305. package/app/components/maintenance/panel-header.js +1 -0
  306. package/app/components/maintenance-schedule/details.js +1 -0
  307. package/app/components/maintenance-schedule/form.js +1 -0
  308. package/app/components/modals/add-driver-shift.js +1 -0
  309. package/app/components/modals/bulk-assign-orders.js +1 -0
  310. package/app/components/modals/driver-shift.js +1 -0
  311. package/app/components/modals/orchestrator-import.js +1 -0
  312. package/app/components/modals/scheduling-conflict.js +1 -0
  313. package/app/components/modals/send-work-order.js +1 -0
  314. package/app/components/modals/set-driver-availability.js +1 -0
  315. package/app/components/orchestrator/card-fields-settings.js +1 -0
  316. package/app/components/orchestrator/order-pool.js +1 -0
  317. package/app/components/orchestrator/phase-builder.js +1 -0
  318. package/app/components/orchestrator/plan-viewer.js +1 -0
  319. package/app/components/orchestrator/resource-panel.js +1 -0
  320. package/app/components/orchestrator-workbench.js +1 -0
  321. package/app/components/vehicle/details/maintenance-history.js +1 -0
  322. package/app/components/vehicle/details/schedules.js +1 -0
  323. package/app/components/vehicle/details/work-orders.js +1 -0
  324. package/app/controllers/operations/orchestrator.js +1 -0
  325. package/app/controllers/settings/orchestrator.js +1 -0
  326. package/app/controllers/settings/scheduling.js +1 -0
  327. package/app/routes/operations/orchestrator.js +1 -0
  328. package/app/routes/operations/orders/index/details/virtual.js +1 -0
  329. package/app/routes/settings/orchestrator.js +1 -0
  330. package/app/routes/settings/scheduling.js +1 -0
  331. package/app/services/maintenance-schedule-actions.js +1 -0
  332. package/app/services/orchestration-engine-interface.js +1 -0
  333. package/app/services/orchestration-engine.js +1 -0
  334. package/app/services/order-allocation.js +1 -0
  335. package/app/services/scheduling.js +1 -0
  336. package/app/services/vroom-allocation-engine.js +1 -0
  337. package/app/templates/operations/orders/index/details/virtual.js +1 -0
  338. package/app/templates/settings/scheduling.js +1 -0
  339. package/app/utils/create-full-calendar-event-from-schedule-item.js +1 -0
  340. package/app/utils/route-colors.js +1 -0
  341. package/composer.json +5 -3
  342. package/extension.json +1 -1
  343. package/package.json +6 -5
  344. package/server/config/fleetops.php +20 -1
  345. package/server/migrations/2025_08_28_054927_create_parts_table.php +2 -2
  346. package/server/migrations/2025_08_28_054932_add_public_id_to_maintenance_tables.php +45 -0
  347. package/server/migrations/2025_09_01_000001_create_maintenance_schedules_table.php +88 -0
  348. package/server/migrations/2026_04_01_000001_fix_monetary_columns_in_parts_table.php +48 -0
  349. package/server/migrations/2026_04_01_000003_add_photo_uuid_to_equipment_and_parts_tables.php +61 -0
  350. package/server/migrations/2026_04_01_000004_add_public_id_to_equipments_table.php +38 -0
  351. package/server/migrations/2026_04_01_000005_add_missing_columns_to_parts_table.php +67 -0
  352. package/server/migrations/2026_04_04_000001_add_reminder_offsets_to_maintenance_schedules.php +44 -0
  353. package/server/migrations/2026_04_08_000001_add_orchestrator_columns_to_vehicles_table.php +58 -0
  354. package/server/migrations/2026_04_08_000002_add_orchestrator_columns_to_drivers_table.php +41 -0
  355. package/server/migrations/2026_04_08_000003_add_orchestrator_columns_to_orders_table.php +38 -0
  356. package/server/migrations/2026_04_08_000004_add_orchestrator_columns_to_payloads_table.php +41 -0
  357. package/server/migrations/2026_04_08_000005_add_orchestrator_columns_to_waypoints_table.php +38 -0
  358. package/server/migrations/2026_04_09_000001_create_manifests_table.php +48 -0
  359. package/server/migrations/2026_04_09_000002_create_manifest_stops_table.php +48 -0
  360. package/server/migrations/2026_04_09_000003_add_manifest_uuid_to_orders_table.php +28 -0
  361. package/server/migrations/2026_04_13_000001_add_pod_notes_columns_to_waypoints_table.php +39 -0
  362. package/server/resources/views/mail/maintenance-schedule-reminder.blade.php +59 -0
  363. package/server/resources/views/mail/work-order-dispatched.blade.php +67 -0
  364. package/server/src/Auth/Schemas/FleetOps.php +44 -0
  365. package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +150 -0
  366. package/server/src/Console/Commands/SendMaintenanceReminders.php +128 -0
  367. package/server/src/Http/Controllers/Internal/v1/DriverController.php +1 -0
  368. package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +27 -0
  369. package/server/src/Http/Controllers/Internal/v1/LiveController.php +9 -2
  370. package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +165 -0
  371. package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +304 -0
  372. package/server/src/Http/Controllers/Internal/v1/ManifestController.php +138 -0
  373. package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +975 -0
  374. package/server/src/Http/Controllers/Internal/v1/OrderController.php +42 -0
  375. package/server/src/Http/Controllers/Internal/v1/PartController.php +27 -0
  376. package/server/src/Http/Controllers/Internal/v1/SettingController.php +118 -0
  377. package/server/src/Http/Controllers/Internal/v1/Traits/DriverSchedulingTrait.php +214 -0
  378. package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +68 -0
  379. package/server/src/Http/Resources/v1/Driver.php +1 -0
  380. package/server/src/Http/Resources/v1/Maintenance.php +138 -0
  381. package/server/src/Http/Resources/v1/MaintenanceSchedule.php +137 -0
  382. package/server/src/Http/Resources/v1/Orchestrator/Order.php +116 -0
  383. package/server/src/Http/Resources/v1/Order.php +7 -4
  384. package/server/src/Http/Resources/v1/Waypoint.php +7 -0
  385. package/server/src/Http/Resources/v1/WorkOrder.php +136 -0
  386. package/server/src/Imports/EquipmentImport.php +32 -0
  387. package/server/src/Imports/MaintenanceImport.php +32 -0
  388. package/server/src/Imports/MaintenanceScheduleImport.php +32 -0
  389. package/server/src/Imports/PartImport.php +32 -0
  390. package/server/src/Imports/WorkOrderImport.php +32 -0
  391. package/server/src/Jobs/ProcessAllocationJob.php +119 -0
  392. package/server/src/Listeners/HandleDeliveryCompletion.php +47 -0
  393. package/server/src/Listeners/NotifyDriverOnShiftChange.php +63 -0
  394. package/server/src/Mail/MaintenanceScheduleReminder.php +68 -0
  395. package/server/src/Mail/WorkOrderDispatched.php +58 -0
  396. package/server/src/Models/Asset.php +2 -2
  397. package/server/src/Models/Device.php +1 -1
  398. package/server/src/Models/Driver.php +82 -4
  399. package/server/src/Models/Equipment.php +62 -2
  400. package/server/src/Models/Maintenance.php +127 -9
  401. package/server/src/Models/MaintenanceSchedule.php +353 -0
  402. package/server/src/Models/Manifest.php +214 -0
  403. package/server/src/Models/ManifestStop.php +162 -0
  404. package/server/src/Models/Order.php +70 -0
  405. package/server/src/Models/OrderConfig.php +5 -2
  406. package/server/src/Models/Part.php +69 -3
  407. package/server/src/Models/Payload.php +7 -2
  408. package/server/src/Models/Place.php +1 -1
  409. package/server/src/Models/Sensor.php +1 -1
  410. package/server/src/Models/ServiceQuote.php +1 -1
  411. package/server/src/Models/Vehicle.php +20 -1
  412. package/server/src/Models/Warranty.php +1 -1
  413. package/server/src/Models/Waypoint.php +7 -1
  414. package/server/src/Models/WorkOrder.php +122 -12
  415. package/server/src/Notifications/DriverShiftChanged.php +110 -0
  416. package/server/src/Observers/WorkOrderObserver.php +107 -0
  417. package/server/src/Orchestration/Contracts/OrchestrationEngineInterface.php +63 -0
  418. package/server/src/Orchestration/Engines/DriverAssignmentEngine.php +265 -0
  419. package/server/src/Orchestration/Engines/GreedyOrchestrationEngine.php +155 -0
  420. package/server/src/Orchestration/Engines/RouteSequencingEngine.php +272 -0
  421. package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +192 -0
  422. package/server/src/Orchestration/OrchestrationEngineRegistry.php +83 -0
  423. package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +290 -0
  424. package/server/src/Providers/EventServiceProvider.php +7 -1
  425. package/server/src/Providers/FleetOpsServiceProvider.php +42 -15
  426. package/server/src/routes.php +65 -4
  427. package/translations/ar-ae.yml +44 -12
  428. package/translations/bg-bg.yaml +51 -10
  429. package/translations/en-us.yaml +444 -1
  430. package/translations/fr-fr.yaml +51 -10
  431. package/translations/mn-mn.yaml +51 -10
  432. package/translations/pt-br.yaml +51 -10
  433. package/translations/ru-ru.yaml +51 -10
  434. package/translations/vi-vn.yaml +48 -12
@@ -1 +1,10 @@
1
- <CustomField::Yield @subject={{@resource}} @owner={{@resource.order_config}} @loadOptions={{false}} @viewMode={{true}} @editable={{not-eq @resource.status "canceled"}} @onChange={{this.saveCustomFields}} @permission="fleet-ops update order" @wrapperClass="bordered-top" />
1
+ <CustomField::Yield
2
+ @subject={{@resource}}
3
+ @owner={{@resource.order_config}}
4
+ @loadOptions={{false}}
5
+ @viewMode={{true}}
6
+ @editable={{not-eq @resource.status "canceled"}}
7
+ @onChange={{this.saveCustomFields}}
8
+ @permission="fleet-ops update order"
9
+ @wrapperClass="bordered-top"
10
+ />
@@ -16,7 +16,12 @@
16
16
  <span>{{t "order.fields.driver-assigned"}}</span>
17
17
  </div>
18
18
  <div class="field-value">
19
- <Driver::Pill @driver={{@resource.driver_assigned}} @onClick={{this.focusOrderAssignedDriver}} @titleFallback="No driver assigned" @titleClass={{unless @resource.driver_assigned "text-gray-300"}} />
19
+ <Driver::Pill
20
+ @driver={{@resource.driver_assigned}}
21
+ @onClick={{this.focusOrderAssignedDriver}}
22
+ @titleFallback="No driver assigned"
23
+ @titleClass={{unless @resource.driver_assigned "text-gray-300"}}
24
+ />
20
25
  </div>
21
26
  </div>
22
27
  <div class="field-info-container">
@@ -114,4 +119,34 @@
114
119
  {{/if}}
115
120
  </div>
116
121
  </:default>
117
- </ContentPanel>
122
+ </ContentPanel>
123
+
124
+ {{! ORCHESTRATOR CONSTRAINTS (read-only view) }}
125
+ {{#if (or @resource.time_window_start @resource.time_window_end @resource.required_skills.length @resource.orchestrator_priority)}}
126
+ <ContentPanel @title="Orchestrator Constraints" @open={{true}} @isLoading={{@isLoading}} @wrapperClass="bordered-top">
127
+ <div class="grid grid-cols-2 gap-2 text-xs dark:text-gray-100">
128
+ {{#if (or @resource.time_window_start @resource.time_window_end)}}
129
+ <div class="field-info-container">
130
+ <div class="field-name">Earliest Arrival</div>
131
+ <div class="field-value">{{n-a @resource.time_window_start}}</div>
132
+ </div>
133
+ <div class="field-info-container">
134
+ <div class="field-name">Latest Arrival</div>
135
+ <div class="field-value">{{n-a @resource.time_window_end}}</div>
136
+ </div>
137
+ {{/if}}
138
+ {{#if @resource.required_skills.length}}
139
+ <div class="field-info-container col-span-2">
140
+ <div class="field-name">Required Skills</div>
141
+ <div class="field-value">{{join @resource.required_skills ", "}}</div>
142
+ </div>
143
+ {{/if}}
144
+ {{#if @resource.orchestrator_priority}}
145
+ <div class="field-info-container">
146
+ <div class="field-name">Priority</div>
147
+ <div class="field-value">{{@resource.orchestrator_priority}}</div>
148
+ </div>
149
+ {{/if}}
150
+ </div>
151
+ </ContentPanel>
152
+ {{/if}}
@@ -36,7 +36,6 @@ export default class OrderDetailsDetailComponent extends Component {
36
36
  }
37
37
 
38
38
  @action focusOrderAssignedDriver(driver) {
39
- console.log('[focusOrderAssignedDriver]', ...arguments);
40
39
  this.driverActions.panel.view(driver);
41
40
  this.leafletMapManager.map?.flyTo(driver.coordinates, 18);
42
41
  }
@@ -1,5 +1,5 @@
1
1
  {{#if @resource.isIntegratedVendorOrder}}
2
- <ContentPanel @title={{concat @resource.facilitator.name (t "order.fields.order-details-title")}} @open={{true}} @wrapperClass="bordered-top">
3
- <IntegratedOrderDetails @integratedVendor={{@resource.facilitator}} @details={{@resource.meta.integrated_vendor_order}} />
4
- </ContentPanel>
5
- {{/if}}
2
+ <ContentPanel @title={{concat @resource.facilitator.name (t "order.fields.order-details-title")}} @open={{true}} @wrapperClass="bordered-top">
3
+ <IntegratedOrderDetails @integratedVendor={{@resource.facilitator}} @details={{@resource.meta.integrated_vendor_order}} />
4
+ </ContentPanel>
5
+ {{/if}}
@@ -1,12 +1,6 @@
1
1
  <ContentPanel @title={{t "order.fields.notes-title"}} @isLoading={{@isLoading}} @open={{true}} @actionButtons={{this.actionButtons}} @wrapperClass="bordered-top">
2
2
  {{#if this.isEditing}}
3
- <Textarea
4
- @value={{@resource.notes}}
5
- class="form-input w-full"
6
- placeholder={{t "order.fields.notes-placeholder"}}
7
- rows={{4}}
8
- disabled={{cannot-write @resource}}
9
- />
3
+ <Textarea @value={{@resource.notes}} class="form-input w-full" placeholder={{t "order.fields.notes-placeholder"}} rows={{4}} disabled={{cannot-write @resource}} />
10
4
  <div class="flex items-center space-x-2">
11
5
  <Button
12
6
  @type="primary"
@@ -1,11 +1,7 @@
1
1
  <ContentPanel @title={{t "order.fields.route-panel-title"}} @open={{true}} @actionButtons={{this.actionButtons}} @wrapperClass="bordered-top">
2
2
  {{#if @resource.payload.isMultiDrop}}
3
3
  <div>
4
- <RouteList
5
- @order={{@resource}}
6
- @eta={{@resource.eta}}
7
- @waypointActions={{hash viewWaypointLabel=(hash label=(t "order.fields.get-label") fn=this.viewWaypointLabel)}}
8
- />
4
+ <RouteList @order={{@resource}} @eta={{@resource.eta}} @waypointActions={{hash viewWaypointLabel=(hash label=(t "order.fields.get-label") fn=this.viewWaypointLabel)}} />
9
5
  </div>
10
6
  {{else}}
11
7
  <div class="grid grid-cols-1 lg:grid-cols-2 gap-4 lg:gap-2">
@@ -19,12 +19,7 @@
19
19
  </div>
20
20
  </InputGroup>
21
21
 
22
- <InputGroup
23
- @name={{t "order.fields.internal-id"}}
24
- @value={{@resource.internal_id}}
25
- @helpText={{t "order.fields.internal-id-help-text"}}
26
- @disabled={{cannot-write @resource}}
27
- />
22
+ <InputGroup @name={{t "order.fields.internal-id"}} @value={{@resource.internal_id}} @helpText={{t "order.fields.internal-id-help-text"}} @disabled={{cannot-write @resource}} />
28
23
 
29
24
  <InputGroup>
30
25
  <InputLabel @labelText={{t "order.fields.schedule"}} @helpText={{t "order.fields.schedule-help-text"}} />
@@ -92,10 +87,7 @@
92
87
  </InputGroup>
93
88
 
94
89
  {{#if (and @resource.facilitator.isIntegratedVendor @resource.facilitator.service_types.length)}}
95
- <InputGroup
96
- @name={{t "order.fields.service-type"}}
97
- @helpText={{concat (t "order.fields.service-type-help-text") @resource.facilitator.name "."}}
98
- >
90
+ <InputGroup @name={{t "order.fields.service-type"}} @helpText={{concat (t "order.fields.service-type-help-text") @resource.facilitator.name "."}}>
99
91
  <Select
100
92
  class="w-full"
101
93
  @options={{@resource.facilitator.service_types}}
@@ -246,4 +238,46 @@
246
238
  </div>
247
239
  </ContentPanel>
248
240
 
241
+ {{! ORCHESTRATOR CONSTRAINTS }}
242
+ <ContentPanel @title="Orchestrator Constraints" @open={{true}} @wrapperClass="bordered-top">
243
+ <div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-2 no-input-group-padding text-xs">
244
+ <div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-1">
245
+ Delivery Window
246
+ </div>
247
+ <InputGroup
248
+ @name="Time Window Start"
249
+ @helpText="Earliest acceptable arrival time at the delivery location. The date defaults to the order's scheduled date (or creation date if not yet scheduled)."
250
+ >
251
+ <DateTimeInput class="form-input" @value={{@resource.time_window_start}} @onUpdate={{fn this.setTimeWindow "time_window_start"}} @disabled={{cannot-write @resource}} />
252
+ </InputGroup>
253
+ <InputGroup
254
+ @name="Time Window End"
255
+ @helpText="Latest acceptable arrival time at the delivery location. The date defaults to the order's scheduled date (or creation date if not yet scheduled)."
256
+ >
257
+ <DateTimeInput class="form-input" @value={{@resource.time_window_end}} @onUpdate={{fn this.setTimeWindow "time_window_end"}} @disabled={{cannot-write @resource}} />
258
+ </InputGroup>
259
+ <div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-3">
260
+ Requirements & Priority
261
+ </div>
262
+ <div class="col-span-1 lg:col-span-2">
263
+ <InputGroup @name="Required Skills" @helpText="Skills the assigned driver and vehicle must have to fulfil this order.">
264
+ <MultiSelect
265
+ @options={{get-fleet-ops-options "driverSkills"}}
266
+ @selected={{@resource.required_skills}}
267
+ @onChange={{fn (mut @resource.required_skills)}}
268
+ @placeholder="Select required skills…"
269
+ @triggerClass="form-select form-input"
270
+ @disabled={{cannot-write @resource}}
271
+ as |option|
272
+ >
273
+ {{option.label}}
274
+ </MultiSelect>
275
+ </InputGroup>
276
+ </div>
277
+ <InputGroup @name="Orchestrator Priority" @helpText="Priority score 0–100. Higher values are scheduled first when capacity is constrained. Default is 0.">
278
+ <Input @value={{@resource.orchestrator_priority}} @type="number" class="form-input w-full" placeholder="0–100" disabled={{cannot-write @resource}} />
279
+ </InputGroup>
280
+ </div>
281
+ </ContentPanel>
282
+
249
283
  <Order::Form::CustomFields @resource={{@resource}} @customFields={{this.customFields}} />
@@ -64,6 +64,63 @@ export default class OrderFormDetailsComponent extends Component {
64
64
  this.leafletLayerVisibilityManager.showModelLayer(this.args.resource.driver_assigned);
65
65
  }
66
66
 
67
+ /**
68
+ * Resolves the reference date to use when pre-populating the date portion
69
+ * of a time window field. Prefers scheduled_at, falls back to created_at,
70
+ * and finally falls back to now so there is always a valid date.
71
+ *
72
+ * @returns {Date}
73
+ */
74
+ get _timeWindowReferenceDate() {
75
+ const raw = this.args.resource.scheduled_at ?? this.args.resource.created_at ?? new Date();
76
+ return raw instanceof Date ? raw : new Date(raw);
77
+ }
78
+
79
+ /**
80
+ * Called by DateTimeInput @onUpdate for time_window_start and time_window_end.
81
+ *
82
+ * When the user picks a time, we preserve their chosen time but replace the
83
+ * date portion with the order's scheduled_at date (or created_at if
84
+ * scheduled_at is not set). This means the user only ever needs to set the
85
+ * time — the date is always contextually correct.
86
+ *
87
+ * If the incoming value already carries a different date (e.g. the user
88
+ * explicitly changed it via the date part of the picker) we respect that
89
+ * and do not override it.
90
+ *
91
+ * @param {'time_window_start'|'time_window_end'} field
92
+ * @param {Date|string|null} value Value emitted by DateTimeInput
93
+ */
94
+ @action setTimeWindow(field, value) {
95
+ if (!value) {
96
+ this.args.resource[field] = null;
97
+ return;
98
+ }
99
+
100
+ const picked = value instanceof Date ? value : new Date(value);
101
+ if (isNaN(picked.getTime())) {
102
+ this.args.resource[field] = value;
103
+ return;
104
+ }
105
+
106
+ const ref = this._timeWindowReferenceDate;
107
+
108
+ // Only inject the reference date when the picked value has no meaningful
109
+ // date of its own — i.e. when the date portion is the Unix epoch
110
+ // (1970-01-01), which is what DateTimeInput emits when the user has only
111
+ // touched the time picker and not the date picker.
112
+ const isEpochDate = picked.getUTCFullYear() === 1970 && picked.getUTCMonth() === 0 && picked.getUTCDate() === 1;
113
+
114
+ if (isEpochDate) {
115
+ const merged = new Date(ref);
116
+ merged.setHours(picked.getHours(), picked.getMinutes(), picked.getSeconds(), 0);
117
+ this.args.resource[field] = merged;
118
+ } else {
119
+ // User explicitly set a date — honour it as-is.
120
+ this.args.resource[field] = picked;
121
+ }
122
+ }
123
+
67
124
  @action toggleAdhoc(toggled) {
68
125
  this.args.resource.adhoc = toggled;
69
126
  this.args.resource.adhoc_distance = this.currentUser.getCompanyOption('fleetops.adhoc_distance', 5000);
@@ -1,11 +1,5 @@
1
1
  <ContentPanel @title={{t "order.fields.notes-title"}} @open={{true}} @wrapperClass="bordered-top">
2
2
  <div>
3
- <Textarea
4
- @value={{@resource.notes}}
5
- class="form-input w-full"
6
- placeholder={{t "order.fields.notes-placeholder"}}
7
- disabled={{cannot-write @resource}}
8
- rows={{or @rows 4}}
9
- />
3
+ <Textarea @value={{@resource.notes}} class="form-input w-full" placeholder={{t "order.fields.notes-placeholder"}} disabled={{cannot-write @resource}} rows={{or @rows 4}} />
10
4
  </div>
11
5
  </ContentPanel>
@@ -54,13 +54,7 @@
54
54
  <h4 class="font-bold dark:text-gray-100">{{group.waypoint.place.address}}</h4>
55
55
  </div>
56
56
  <div>
57
- <Button
58
- @icon="plus"
59
- @iconPrefix="fas"
60
- @text={{t "order.fields.add-item-button"}}
61
- @size="sm"
62
- @onClick={{fn this.addEntity group.importId}}
63
- />
57
+ <Button @icon="plus" @iconPrefix="fas" @text={{t "order.fields.add-item-button"}} @size="sm" @onClick={{fn this.addEntity group.importId}} />
64
58
  </div>
65
59
  </div>
66
60
  <div class="grid grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-2">
@@ -175,11 +175,7 @@
175
175
  </ModelSelect>
176
176
 
177
177
  {{#if (and @resource.facilitator.isIntegratedVendor (is-not-facilitator-supported-place @resource.facilitator @resource.payload.pickup))}}
178
- <InfoBlock
179
- class="my-2 px-4 py-1.5 danger"
180
- @blockClass="flex flex-row items-center"
181
- @text={{concat @resource.facilitator.name (t "order.fields.infoblock-text")}}
182
- />
178
+ <InfoBlock class="my-2 px-4 py-1.5 danger" @blockClass="flex flex-row items-center" @text={{concat @resource.facilitator.name (t "order.fields.infoblock-text")}} />
183
179
  {{/if}}
184
180
 
185
181
  {{#if @resource.payload.pickup.hasInvalidCoordinates}}
@@ -223,11 +219,7 @@
223
219
  </ModelSelect>
224
220
 
225
221
  {{#if (and @resource.facilitator.isIntegratedVendor (is-not-facilitator-supported-place @resource.facilitator @resource.payload.dropoff))}}
226
- <InfoBlock
227
- class="my-2 px-4 py-1.5 danger"
228
- @blockClass="flex flex-row items-center"
229
- @text={{concat @resource.facilitator.name (t "order.fields.infoblock-text")}}
230
- />
222
+ <InfoBlock class="my-2 px-4 py-1.5 danger" @blockClass="flex flex-row items-center" @text={{concat @resource.facilitator.name (t "order.fields.infoblock-text")}} />
231
223
  {{/if}}
232
224
 
233
225
  {{#if @resource.payload.dropoff.hasInvalidCoordinates}}
@@ -264,11 +256,7 @@
264
256
  </ModelSelect>
265
257
 
266
258
  {{#if (and @resource.facilitator.isIntegratedVendor (is-not-facilitator-supported-place @resource.facilitator @resource.payload.return))}}
267
- <InfoBlock
268
- class="my-2 px-4 py-1.5 danger"
269
- @blockClass="flex flex-row items-center"
270
- @text={{concat @resource.facilitator.name (t "order.fields.infoblock-text")}}
271
- />
259
+ <InfoBlock class="my-2 px-4 py-1.5 danger" @blockClass="flex flex-row items-center" @text={{concat @resource.facilitator.name (t "order.fields.infoblock-text")}} />
272
260
  {{/if}}
273
261
 
274
262
  {{#if @resource.payload.return.hasInvalidCoordinates}}
@@ -7,13 +7,7 @@
7
7
  {{@order.public_id}}
8
8
  </h1>
9
9
  <div class="flex flex-row">
10
- <Badge
11
- @status={{@order.status}}
12
- @helpText={{if
13
- (eq @order.status (t "order.header.dispatched"))
14
- (concat (t "order.header.dispatched-at") @order.dispatchedAt)
15
- }}
16
- />
10
+ <Badge @status={{@order.status}} @helpText={{if (eq @order.status (t "order.header.dispatched")) (concat (t "order.header.dispatched-at") @order.dispatchedAt)}} />
17
11
  {{#if @order.shouldDisplayDispatchLabel}}
18
12
  <Badge @status="info" class="ml-2" @helpText={{t "order.header.dispatched" htmlSafe=true order=@order.dispatchedAt}}>{{t
19
13
  "fleet-ops.component.order.header.dispatched"
@@ -20,13 +20,7 @@
20
20
  @isLoading={{this.optimizeRoute.isRunning}}
21
21
  />
22
22
  {{/if}}
23
- <Button
24
- @icon="map-marked-alt"
25
- @text={{t "modals.order-route-form.add"}}
26
- @size="sm"
27
- @onClick={{this.addWaypoint}}
28
- @helpText={{t "modals.order-route-form.add-text"}}
29
- />
23
+ <Button @icon="map-marked-alt" @text={{t "modals.order-route-form.add"}} @size="sm" @onClick={{this.addWaypoint}} @helpText={{t "modals.order-route-form.add-text"}} />
30
24
  {{/if}}
31
25
  </div>
32
26
  </div>
@@ -82,12 +76,7 @@
82
76
  <label class="mb-0i">{{t "modals.order-route-form.pickup"}}</label>
83
77
 
84
78
  {{#if @resource.payload.pickup}}
85
- <Button
86
- @text={{t "modals.order-route-form.edit-address"}}
87
- @icon="edit"
88
- @size="xs"
89
- @onClick={{fn this.placeActions.modal.edit @resource.payload.pickup}}
90
- />
79
+ <Button @text={{t "modals.order-route-form.edit-address"}} @icon="edit" @size="xs" @onClick={{fn this.placeActions.modal.edit @resource.payload.pickup}} />
91
80
  {{/if}}
92
81
  </div>
93
82
 
@@ -119,12 +108,7 @@
119
108
  <label class="mb-0i">{{t "modals.order-route-form.dropoff"}}</label>
120
109
 
121
110
  {{#if @resource.payload.dropoff}}
122
- <Button
123
- @text={{t "modals.order-route-form.edit-address"}}
124
- @icon="edit"
125
- @size="xs"
126
- @onClick={{fn this.placeActions.modal.edit @resource.payload.dropoff}}
127
- />
111
+ <Button @text={{t "modals.order-route-form.edit-address"}} @icon="edit" @size="xs" @onClick={{fn this.placeActions.modal.edit @resource.payload.dropoff}} />
128
112
  {{/if}}
129
113
  </div>
130
114
 
@@ -156,12 +140,7 @@
156
140
  <label class="mb-0i">{{t "modals.order-route-form.return"}}</label>
157
141
 
158
142
  {{#if @resource.payload.return}}
159
- <Button
160
- @text={{t "modals.order-route-form.edit-address"}}
161
- @icon="edit"
162
- @size="xs"
163
- @onClick={{fn this.placeActions.modal.edit @resource.payload.return}}
164
- />
143
+ <Button @text={{t "modals.order-route-form.edit-address"}} @icon="edit" @size="xs" @onClick={{fn this.placeActions.modal.edit @resource.payload.return}} />
165
144
  {{/if}}
166
145
  </div>
167
146
 
@@ -1,60 +1,79 @@
1
- <div class="order-schedule-card border border-gray-200 dark:border-gray-700" ...attributes>
2
- <a href="javascript:;" class="{{@titleClass}} card-title border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900" {{on "click" (fn this.onTitleClick @order)}}>
3
- <span>{{@order.tracking}}</span>
4
- <div>
1
+ {{!
2
+ Order::ScheduleCard
3
+ Compact sidebar card used in the Scheduler's unscheduled-orders panel.
4
+ Layout: header row (checkbox + tracking + badge), then a 2-column grid
5
+ of label/value pairs so everything fits without line-breaking.
6
+ }}
7
+ <div
8
+ class="order-schedule-card rounded border border-gray-200 dark:border-gray-700 overflow-hidden {{if @selected 'ring-2 ring-indigo-500 border-indigo-400 dark:border-indigo-500'}}"
9
+ ...attributes
10
+ >
11
+ {{! ── Header ─────────────────────────────────────────────────────── }}
12
+ <div class="flex items-center gap-1.5 px-2 py-1.5 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
13
+ {{#if @selectable}}
14
+ <input
15
+ type="checkbox"
16
+ class="form-checkbox h-3.5 w-3.5 rounded text-indigo-600 border-gray-300 dark:border-gray-600 cursor-pointer flex-shrink-0"
17
+ checked={{@selected}}
18
+ {{on "click" @onSelect}}
19
+ />
20
+ {{/if}}
21
+ <a
22
+ href="javascript:;"
23
+ class="flex-1 min-w-0 truncate text-xs font-semibold text-gray-800 dark:text-gray-100 hover:text-indigo-500 dark:hover:text-indigo-400 {{@titleClass}}"
24
+ {{on "click" (fn this.onTitleClick @order)}}
25
+ >
26
+ {{@order.tracking}}
27
+ </a>
28
+ <div class="flex-shrink-0">
5
29
  <Badge @status={{@order.status}} />
6
30
  </div>
7
- </a>
8
- <div class="{{@contentClass}} card-content bg-white dark:bg-gray-900 text-sm space-y-2">
9
- <div class="flex items-center justify-between">
10
- <div class="flex flex-row items-center leading-5">
11
- <div class="w-4">
12
- <FaIcon @icon="clock" @size="xs" />
13
- </div>
14
- <span class="font-semibold">{{t "order.schedule-card.date"}}</span>
15
- </div>
16
- <span class={{unless @order.scheduled_at "dark:text-gray-600 text-gray-400"}}>{{n-a @order.scheduledAt "Not Scheduled"}}</span>
17
- </div>
18
- <div class="flex items-center justify-between">
19
- <div class="flex flex-row items-center leading-5">
20
- <div class="w-4">
21
- <FaIcon @icon="calendar" @size="xs" />
22
- </div>
23
- <span class="font-semibold">Date created</span>
24
- </div>
25
- <span>{{n-a @order.createdAtWithTime}}</span>
26
- </div>
27
- <div class="flex items-center justify-between">
28
- <div class="flex flex-row items-center">
29
- <div class="w-4">
30
- <FaIcon @icon="id-card-alt" @size="xs" />
31
- </div>
32
- <span class="font-semibold">{{t "order.schedule-card.driver-assigned"}}</span>
33
- <div class="ml-1">
34
- {{#let (cannot "fleet-ops assign-driver-for order") as |unauthorized|}}
35
- <a
36
- href="javascript:;"
37
- class="text-blue-400 text-xs hover:opacity-75 {{if unauthorized 'opacity-50 disabled'}}"
38
- {{on "click" this.startAssignDriver}}
39
- disabled={{unauthorized}}
40
- >
41
- <FaIcon @icon="edit" @size="xs" />
42
- </a>
43
- {{#if unauthorized}}
44
- <Attach::Tooltip @class="clean" @animation="scale" @placement="right">
45
- <InputInfo @text={{t "common.unauthorized"}} />
46
- </Attach::Tooltip>
47
- {{/if}}
48
- {{/let}}
49
- </div>
50
- </div>
51
- <div>
31
+ </div>
32
+
33
+ {{! ── Body — 2-column grid ───────────────────────────────────────── }}
34
+ <div class="{{@contentClass}} card-content bg-white dark:bg-gray-900 px-2 py-1.5">
35
+ <dl class="grid grid-cols-[auto_1fr] gap-x-2 gap-y-1 text-xs">
36
+
37
+ {{! Scheduled date }}
38
+ <dt class="flex items-center gap-1 text-gray-500 dark:text-gray-400 whitespace-nowrap">
39
+ <FaIcon @icon="clock" @size="xs" class="w-3 text-center" />
40
+ {{t "order.schedule-card.date"}}
41
+ </dt>
42
+ <dd class="truncate text-right {{unless @order.scheduled_at 'text-gray-400 dark:text-gray-600'}}">
43
+ {{n-a @order.scheduledAt (t "scheduler.not-scheduled")}}
44
+ </dd>
45
+
46
+ {{! Created date }}
47
+ <dt class="flex items-center gap-1 text-gray-500 dark:text-gray-400 whitespace-nowrap">
48
+ <FaIcon @icon="calendar" @size="xs" class="w-3 text-center" />
49
+ {{t "order.schedule-card.date-created"}}
50
+ </dt>
51
+ <dd class="truncate text-right">
52
+ {{n-a @order.createdAtWithTime}}
53
+ </dd>
54
+
55
+ {{! Driver }}
56
+ <dt class="flex items-center gap-1 text-gray-500 dark:text-gray-400 whitespace-nowrap">
57
+ <FaIcon @icon="id-card-alt" @size="xs" class="w-3 text-center" />
58
+ {{t "order.schedule-card.driver-assigned"}}
59
+ {{#let (cannot "fleet-ops assign-driver-for order") as |unauthorized|}}
60
+ <a href="javascript:;" class="text-indigo-400 hover:text-indigo-300 {{if unauthorized 'opacity-40 pointer-events-none'}}" {{on "click" this.startAssignDriver}}>
61
+ <FaIcon @icon="pen" @size="xs" />
62
+ </a>
63
+ {{#if unauthorized}}
64
+ <Attach::Tooltip @class="clean" @animation="scale" @placement="right">
65
+ <InputInfo @text={{t "common.unauthorized"}} />
66
+ </Attach::Tooltip>
67
+ {{/if}}
68
+ {{/let}}
69
+ </dt>
70
+ <dd class="truncate text-right">
52
71
  {{#if this.isAssigningDriver}}
53
72
  <ModelSelect
54
73
  @modelName="driver"
55
74
  @selectedModel={{@order.driver_assigned}}
56
75
  @placeholder={{t "order.schedule-card.select-driver"}}
57
- @triggerClass="form-select form-input form-input-sm w-48"
76
+ @triggerClass="form-select form-input form-input-sm w-full"
58
77
  @infiniteScroll={{false}}
59
78
  @renderInPlace={{true}}
60
79
  @allowClear={{true}}
@@ -63,58 +82,46 @@
63
82
  @permission="fleet-ops assign-driver-for order"
64
83
  as |model|
65
84
  >
66
- <div class="flex flex-row items-center truncate uppercase">
67
- <span class="uppercase mr-1.5">{{model.name}}</span>
68
- <span class="uppercase">{{model.phone}}</span>
69
- </div>
85
+ <span class="truncate uppercase text-xs">{{model.name}}</span>
70
86
  </ModelSelect>
71
87
  {{else}}
72
88
  <a
73
89
  href="javascript:;"
74
90
  disabled={{not @order.driver_assigned}}
75
- class={{unless @order.driver_assigned "dark:text-gray-600 text-gray-400"}}
91
+ class="truncate {{unless @order.driver_assigned 'text-gray-400 dark:text-gray-600'}}"
76
92
  {{on "click" (fn this.onClickDriver @order.driver_assigned)}}
77
- >{{n-a @order.driver_assigned.name (t "order.schedule-card.no-driver")}}</a>
93
+ >
94
+ {{n-a @order.driver_assigned.name (t "order.schedule-card.no-driver")}}
95
+ </a>
78
96
  {{/if}}
79
- </div>
80
- </div>
81
- <div class="flex items-center justify-between">
82
- <div class="flex flex-row items-center leading-5">
83
- <div class="w-4">
84
- <FaIcon @icon="car" @size="xs" />
85
- </div>
86
- <span class="font-semibold">{{t "order.schedule-card.vehicle-assigned"}}</span>
87
- </div>
88
- {{#if @order.vehicle_assigned}}
89
- <a
90
- href="javascript:;"
91
- disabled={{not @order.vehicle_assigned}}
92
- class={{unless @order.vehicle_assigned "dark:text-gray-600 text-gray-400"}}
93
- {{on "click" (fn this.onClickVehicle @order.vehicle_assigned)}}
94
- >{{n-a @order.vehicle_assigned.display_name (t "order.schedule-card.no-vehicle")}}</a>
95
- {{else if @order.driver_assigned.vehicle}}
96
- <a
97
- href="javascript:;"
98
- disabled={{not @order.driver_assigned.vehicle}}
99
- class={{unless @order.driver_assigned.vehicle "dark:text-gray-600 text-gray-400"}}
100
- {{on "click" (fn this.onClickVehicle @order.driver_assigned.vehicle)}}
101
- >{{n-a @order.driver_assigned.vehicle_name (t "order.schedule-card.no-vehicle")}}</a>
102
- {{else}}
103
- <div class="dark:text-gray-600 text-gray-400">{{t "order.schedule-card.no-vehicle"}}</div>
104
- {{/if}}
105
- </div>
106
- <div class="flex items-center justify-between">
107
- <div class="flex flex-row items-center leading-5">
108
- <div class="w-4">
109
- <FaIcon @icon="location-dot" @size="xs" />
110
- </div>
111
- <span class="font-semibold">{{t "order.schedule-card.destination"}}</span>
112
- </div>
113
- <span>{{n-a @order.pickupName}}</span>
114
- </div>
115
- {{!-- <div class="z-20 relative">
116
- <RouteList @order={{@order}} />
117
- </div> --}}
97
+ </dd>
98
+
99
+ {{! Vehicle }}
100
+ <dt class="flex items-center gap-1 text-gray-500 dark:text-gray-400 whitespace-nowrap">
101
+ <FaIcon @icon="truck" @size="xs" class="w-3 text-center" />
102
+ {{t "order.schedule-card.vehicle-assigned"}}
103
+ </dt>
104
+ <dd class="truncate text-right">
105
+ {{#if @order.vehicle_assigned}}
106
+ <a href="javascript:;" class="truncate" {{on "click" (fn this.onClickVehicle @order.vehicle_assigned)}}>{{@order.vehicle_assigned.display_name}}</a>
107
+ {{else if @order.driver_assigned.vehicle}}
108
+ <a href="javascript:;" class="truncate" {{on "click" (fn this.onClickVehicle @order.driver_assigned.vehicle)}}>{{@order.driver_assigned.vehicle_name}}</a>
109
+ {{else}}
110
+ <span class="text-gray-400 dark:text-gray-600">{{t "order.schedule-card.no-vehicle"}}</span>
111
+ {{/if}}
112
+ </dd>
113
+
114
+ {{! Destination }}
115
+ <dt class="flex items-center gap-1 text-gray-500 dark:text-gray-400 whitespace-nowrap">
116
+ <FaIcon @icon="location-dot" @size="xs" class="w-3 text-center" />
117
+ {{t "order.schedule-card.destination"}}
118
+ </dt>
119
+ <dd class="truncate text-right">
120
+ {{n-a @order.pickupName}}
121
+ </dd>
122
+
123
+ </dl>
118
124
  </div>
125
+
119
126
  {{yield}}
120
127
  </div>