@fleetbase/fleetops-engine 0.6.38 → 0.6.40

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 (432) 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 +43 -38
  25. package/addon/components/layout/fleet-ops-sidebar.js +103 -24
  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 +1088 -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 +52 -0
  117. package/addon/components/vehicle/form.hbs +51 -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.js +6 -0
  155. package/addon/controllers/operations/scheduler/fleet-schedule.js +341 -0
  156. package/addon/controllers/operations/scheduler/index.js +799 -275
  157. package/addon/controllers/operations/scheduler.js +21 -0
  158. package/addon/controllers/settings/orchestrator.js +70 -0
  159. package/addon/controllers/settings/scheduling.js +155 -0
  160. package/addon/extension.js +19 -0
  161. package/addon/instance-initializers/register-vroom-allocation.js +27 -0
  162. package/addon/models/maintenance-schedule.js +61 -0
  163. package/addon/routes/maintenance/equipment/index/details.js +27 -1
  164. package/addon/routes/maintenance/equipment/index/edit.js +27 -1
  165. package/addon/routes/maintenance/maintenances/index/details/index.js +3 -0
  166. package/addon/routes/maintenance/maintenances/index/details.js +29 -0
  167. package/addon/routes/maintenance/maintenances/index/edit.js +29 -0
  168. package/addon/routes/maintenance/maintenances/index/new.js +3 -0
  169. package/addon/routes/maintenance/maintenances/index.js +23 -0
  170. package/addon/routes/maintenance/maintenances.js +3 -0
  171. package/addon/routes/maintenance/parts/index/details.js +27 -1
  172. package/addon/routes/maintenance/parts/index/edit.js +27 -1
  173. package/addon/routes/maintenance/schedules/index/details/index.js +2 -0
  174. package/addon/routes/maintenance/schedules/index/details/work-orders.js +11 -0
  175. package/addon/routes/maintenance/schedules/index/details.js +25 -0
  176. package/addon/routes/maintenance/schedules/index/edit.js +25 -0
  177. package/addon/routes/maintenance/schedules/index/new.js +2 -0
  178. package/addon/routes/maintenance/schedules/index.js +21 -0
  179. package/addon/routes/maintenance/schedules.js +2 -0
  180. package/addon/routes/maintenance/work-orders/index/details.js +27 -1
  181. package/addon/routes/maintenance/work-orders/index/edit.js +27 -1
  182. package/addon/routes/management/vehicles/index/details/maintenance-history.js +3 -0
  183. package/addon/routes/management/vehicles/index/details/schedules.js +3 -0
  184. package/addon/routes/management/vehicles/index/details/work-orders.js +3 -0
  185. package/addon/routes/operations/orchestrator.js +23 -0
  186. package/addon/routes/operations/scheduler/fleet-schedule.js +28 -0
  187. package/addon/routes/operations/scheduler/index.js +48 -26
  188. package/addon/routes/operations/scheduler.js +14 -1
  189. package/addon/routes/settings/orchestrator.js +27 -0
  190. package/addon/routes/settings/scheduling.js +3 -0
  191. package/addon/routes.js +31 -1
  192. package/addon/services/driver-actions.js +40 -7
  193. package/addon/services/driver-scheduling.js +4 -1
  194. package/addon/services/equipment-actions.js +15 -5
  195. package/addon/services/leaflet-map-manager.js +14 -6
  196. package/addon/services/maintenance-actions.js +17 -14
  197. package/addon/services/maintenance-schedule-actions.js +118 -0
  198. package/addon/services/orchestration-engine-interface.js +49 -0
  199. package/addon/services/orchestration-engine.js +74 -0
  200. package/addon/services/order-actions.js +15 -0
  201. package/addon/services/order-allocation.js +116 -0
  202. package/addon/services/part-actions.js +12 -2
  203. package/addon/services/scheduling.js +316 -0
  204. package/addon/services/vehicle-actions.js +70 -7
  205. package/addon/services/vroom-allocation-engine.js +45 -0
  206. package/addon/services/work-order-actions.js +79 -0
  207. package/addon/styles/fleetops-engine.css +1658 -0
  208. package/addon/templates/analytics/reports/index/edit.hbs +1 -1
  209. package/addon/templates/analytics/reports/index/new.hbs +1 -1
  210. package/addon/templates/application.hbs +6 -1
  211. package/addon/templates/connectivity/devices/index/details/events.hbs +0 -1
  212. package/addon/templates/connectivity/devices.hbs +0 -1
  213. package/addon/templates/connectivity/events/index/details.hbs +0 -1
  214. package/addon/templates/connectivity/events.hbs +0 -1
  215. package/addon/templates/connectivity/sensors.hbs +0 -1
  216. package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
  217. package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
  218. package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
  219. package/addon/templates/connectivity/telematics.hbs +0 -1
  220. package/addon/templates/connectivity/tracking.hbs +0 -1
  221. package/addon/templates/connectivity.hbs +0 -1
  222. package/addon/templates/maintenance/equipment/index/details/index.hbs +1 -2
  223. package/addon/templates/maintenance/equipment/index/details.hbs +15 -2
  224. package/addon/templates/maintenance/equipment/index/edit.hbs +12 -2
  225. package/addon/templates/maintenance/equipment/index/new.hbs +1 -2
  226. package/addon/templates/maintenance/equipment/index.hbs +48 -13
  227. package/addon/templates/maintenance/equipment.hbs +0 -1
  228. package/addon/templates/maintenance/maintenances/index/details/index.hbs +1 -0
  229. package/addon/templates/maintenance/maintenances/index/details.hbs +15 -0
  230. package/addon/templates/maintenance/maintenances/index/edit.hbs +12 -0
  231. package/addon/templates/maintenance/maintenances/index/new.hbs +11 -0
  232. package/addon/templates/maintenance/maintenances/index.hbs +14 -0
  233. package/addon/templates/maintenance/maintenances.hbs +1 -0
  234. package/addon/templates/maintenance/parts/index/details/index.hbs +1 -2
  235. package/addon/templates/maintenance/parts/index/details.hbs +15 -2
  236. package/addon/templates/maintenance/parts/index/edit.hbs +12 -2
  237. package/addon/templates/maintenance/parts/index/new.hbs +1 -2
  238. package/addon/templates/maintenance/parts/index.hbs +48 -13
  239. package/addon/templates/maintenance/parts.hbs +0 -1
  240. package/addon/templates/maintenance/schedules/index/details/index.hbs +1 -0
  241. package/addon/templates/maintenance/schedules/index/details/work-orders.hbs +39 -0
  242. package/addon/templates/maintenance/schedules/index/details.hbs +14 -0
  243. package/addon/templates/maintenance/schedules/index/edit.hbs +12 -0
  244. package/addon/templates/maintenance/schedules/index/new.hbs +11 -0
  245. package/addon/templates/maintenance/schedules/index.hbs +40 -0
  246. package/addon/templates/maintenance/schedules.hbs +1 -0
  247. package/addon/templates/maintenance/work-orders/index/details.hbs +2 -1
  248. package/addon/templates/maintenance/work-orders/index/edit.hbs +2 -4
  249. package/addon/templates/maintenance/work-orders/index/new.hbs +1 -2
  250. package/addon/templates/maintenance/work-orders.hbs +0 -1
  251. package/addon/templates/management/contacts/customers/edit.hbs +1 -2
  252. package/addon/templates/management/contacts/customers/new.hbs +1 -2
  253. package/addon/templates/management/contacts/customers.hbs +1 -1
  254. package/addon/templates/management/contacts/index/edit.hbs +1 -2
  255. package/addon/templates/management/contacts/index/new.hbs +1 -2
  256. package/addon/templates/management/drivers/index/details/orders.hbs +0 -1
  257. package/addon/templates/management/drivers/index/edit.hbs +1 -2
  258. package/addon/templates/management/drivers/index/new.hbs +1 -2
  259. package/addon/templates/management/fleets/index/edit.hbs +1 -2
  260. package/addon/templates/management/fleets/index/new.hbs +1 -2
  261. package/addon/templates/management/fleets/index.hbs +1 -2
  262. package/addon/templates/management/fuel-reports/index/edit.hbs +1 -2
  263. package/addon/templates/management/fuel-reports/index/new.hbs +1 -2
  264. package/addon/templates/management/fuel-reports/index.hbs +1 -2
  265. package/addon/templates/management/issues/index/edit.hbs +1 -2
  266. package/addon/templates/management/issues/index/new.hbs +1 -2
  267. package/addon/templates/management/issues/index.hbs +1 -2
  268. package/addon/templates/management/places/index/details/activity.hbs +0 -1
  269. package/addon/templates/management/places/index/details/comments.hbs +0 -1
  270. package/addon/templates/management/places/index/details/documents.hbs +0 -1
  271. package/addon/templates/management/places/index/details/map.hbs +0 -1
  272. package/addon/templates/management/places/index/details/operations.hbs +0 -1
  273. package/addon/templates/management/places/index/details/performance.hbs +0 -1
  274. package/addon/templates/management/places/index/details/rules.hbs +0 -1
  275. package/addon/templates/management/vehicles/index/details/equipment.hbs +0 -1
  276. package/addon/templates/management/vehicles/index/details/maintenance-history.hbs +2 -0
  277. package/addon/templates/management/vehicles/index/details/schedules.hbs +2 -0
  278. package/addon/templates/management/vehicles/index/details/work-orders.hbs +2 -0
  279. package/addon/templates/management/vehicles/index/details.hbs +1 -1
  280. package/addon/templates/management/vehicles/index/edit.hbs +1 -2
  281. package/addon/templates/management/vehicles/index/new.hbs +1 -2
  282. package/addon/templates/management/vendors/index/edit.hbs +1 -2
  283. package/addon/templates/management/vendors/index/new.hbs +1 -2
  284. package/addon/templates/management/vendors/index.hbs +1 -2
  285. package/addon/templates/management/vendors/integrated.hbs +1 -2
  286. package/addon/templates/operations/orchestrator.hbs +1 -0
  287. package/addon/templates/operations/orders/index.hbs +6 -1
  288. package/addon/templates/operations/scheduler/fleet-schedule.hbs +41 -0
  289. package/addon/templates/operations/scheduler/index.hbs +147 -88
  290. package/addon/templates/operations/scheduler.hbs +7 -1
  291. package/addon/templates/settings/avatars.hbs +1 -1
  292. package/addon/templates/settings/orchestrator.hbs +65 -0
  293. package/addon/templates/settings/payments/index.hbs +1 -5
  294. package/addon/templates/settings/scheduling.hbs +82 -0
  295. package/addon/utils/create-full-calendar-event-from-order.js +52 -14
  296. package/addon/utils/create-full-calendar-event-from-schedule-item.js +50 -0
  297. package/addon/utils/fleet-ops-options.js +254 -0
  298. package/addon/utils/route-colors.js +99 -0
  299. package/addon/utils/to-calendar-date.js +70 -0
  300. package/app/components/driver/schedule.js +1 -0
  301. package/app/components/maintenance/cost-panel.js +1 -0
  302. package/app/components/maintenance/panel-header.js +1 -0
  303. package/app/components/maintenance-schedule/details.js +1 -0
  304. package/app/components/maintenance-schedule/form.js +1 -0
  305. package/app/components/modals/add-driver-shift.js +1 -0
  306. package/app/components/modals/bulk-assign-orders.js +1 -0
  307. package/app/components/modals/driver-shift.js +1 -0
  308. package/app/components/modals/orchestrator-import.js +1 -0
  309. package/app/components/modals/scheduling-conflict.js +1 -0
  310. package/app/components/modals/send-work-order.js +1 -0
  311. package/app/components/modals/set-driver-availability.js +1 -0
  312. package/app/components/orchestrator/card-fields-settings.js +1 -0
  313. package/app/components/orchestrator/order-pool.js +1 -0
  314. package/app/components/orchestrator/phase-builder.js +1 -0
  315. package/app/components/orchestrator/plan-viewer.js +1 -0
  316. package/app/components/orchestrator/resource-panel.js +1 -0
  317. package/app/components/orchestrator-workbench.js +1 -0
  318. package/app/components/vehicle/details/maintenance-history.js +1 -0
  319. package/app/components/vehicle/details/schedules.js +1 -0
  320. package/app/components/vehicle/details/work-orders.js +1 -0
  321. package/app/controllers/operations/orchestrator.js +1 -0
  322. package/app/controllers/settings/orchestrator.js +1 -0
  323. package/app/controllers/settings/scheduling.js +1 -0
  324. package/app/routes/operations/orchestrator.js +1 -0
  325. package/app/routes/settings/orchestrator.js +1 -0
  326. package/app/routes/settings/scheduling.js +1 -0
  327. package/app/services/maintenance-schedule-actions.js +1 -0
  328. package/app/services/orchestration-engine-interface.js +1 -0
  329. package/app/services/orchestration-engine.js +1 -0
  330. package/app/services/order-allocation.js +1 -0
  331. package/app/services/scheduling.js +1 -0
  332. package/app/services/vroom-allocation-engine.js +1 -0
  333. package/app/templates/settings/scheduling.js +1 -0
  334. package/app/utils/create-full-calendar-event-from-schedule-item.js +1 -0
  335. package/app/utils/route-colors.js +1 -0
  336. package/composer.json +4 -2
  337. package/extension.json +1 -1
  338. package/package.json +6 -5
  339. package/server/config/fleetops.php +20 -1
  340. package/server/migrations/2025_08_28_054927_create_parts_table.php +2 -2
  341. package/server/migrations/2025_08_28_054932_add_public_id_to_maintenance_tables.php +45 -0
  342. package/server/migrations/2025_09_01_000001_create_maintenance_schedules_table.php +88 -0
  343. package/server/migrations/2026_04_01_000001_fix_monetary_columns_in_parts_table.php +48 -0
  344. package/server/migrations/2026_04_01_000003_add_photo_uuid_to_equipment_and_parts_tables.php +61 -0
  345. package/server/migrations/2026_04_01_000004_add_public_id_to_equipments_table.php +38 -0
  346. package/server/migrations/2026_04_01_000005_add_missing_columns_to_parts_table.php +67 -0
  347. package/server/migrations/2026_04_04_000001_add_reminder_offsets_to_maintenance_schedules.php +44 -0
  348. package/server/migrations/2026_04_08_000001_add_orchestrator_columns_to_vehicles_table.php +53 -0
  349. package/server/migrations/2026_04_08_000002_add_orchestrator_columns_to_drivers_table.php +41 -0
  350. package/server/migrations/2026_04_08_000003_add_orchestrator_columns_to_orders_table.php +38 -0
  351. package/server/migrations/2026_04_08_000004_add_orchestrator_columns_to_payloads_table.php +38 -0
  352. package/server/migrations/2026_04_08_000005_add_orchestrator_columns_to_waypoints_table.php +38 -0
  353. package/server/migrations/2026_04_09_000001_create_manifests_table.php +48 -0
  354. package/server/migrations/2026_04_09_000002_create_manifest_stops_table.php +48 -0
  355. package/server/migrations/2026_04_09_000003_add_manifest_uuid_to_orders_table.php +28 -0
  356. package/server/migrations/2026_04_13_000001_add_pod_notes_columns_to_waypoints_table.php +39 -0
  357. package/server/migrations/2026_04_14_000001_drop_redundant_capacity_columns_from_payloads_table.php +42 -0
  358. package/server/migrations/2026_04_14_000002_rename_capacity_columns_on_vehicles_table.php +48 -0
  359. package/server/resources/views/mail/maintenance-schedule-reminder.blade.php +59 -0
  360. package/server/resources/views/mail/work-order-dispatched.blade.php +67 -0
  361. package/server/src/Auth/Schemas/FleetOps.php +44 -0
  362. package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +150 -0
  363. package/server/src/Console/Commands/SendMaintenanceReminders.php +128 -0
  364. package/server/src/Http/Controllers/Api/v1/OrderController.php +15 -2
  365. package/server/src/Http/Controllers/Api/v1/VehicleController.php +18 -2
  366. package/server/src/Http/Controllers/Internal/v1/DriverController.php +1 -0
  367. package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +27 -0
  368. package/server/src/Http/Controllers/Internal/v1/LiveController.php +9 -2
  369. package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +165 -0
  370. package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +304 -0
  371. package/server/src/Http/Controllers/Internal/v1/ManifestController.php +138 -0
  372. package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +975 -0
  373. package/server/src/Http/Controllers/Internal/v1/OrderController.php +42 -0
  374. package/server/src/Http/Controllers/Internal/v1/PartController.php +27 -0
  375. package/server/src/Http/Controllers/Internal/v1/SettingController.php +118 -0
  376. package/server/src/Http/Controllers/Internal/v1/Traits/DriverSchedulingTrait.php +214 -0
  377. package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +68 -0
  378. package/server/src/Http/Resources/v1/Driver.php +1 -0
  379. package/server/src/Http/Resources/v1/Maintenance.php +138 -0
  380. package/server/src/Http/Resources/v1/MaintenanceSchedule.php +137 -0
  381. package/server/src/Http/Resources/v1/Orchestrator/Order.php +116 -0
  382. package/server/src/Http/Resources/v1/Order.php +7 -4
  383. package/server/src/Http/Resources/v1/Waypoint.php +7 -0
  384. package/server/src/Http/Resources/v1/WorkOrder.php +136 -0
  385. package/server/src/Imports/EquipmentImport.php +32 -0
  386. package/server/src/Imports/MaintenanceImport.php +32 -0
  387. package/server/src/Imports/MaintenanceScheduleImport.php +32 -0
  388. package/server/src/Imports/PartImport.php +32 -0
  389. package/server/src/Imports/WorkOrderImport.php +32 -0
  390. package/server/src/Jobs/ProcessAllocationJob.php +119 -0
  391. package/server/src/Listeners/HandleDeliveryCompletion.php +47 -0
  392. package/server/src/Listeners/NotifyDriverOnShiftChange.php +63 -0
  393. package/server/src/Mail/MaintenanceScheduleReminder.php +68 -0
  394. package/server/src/Mail/WorkOrderDispatched.php +58 -0
  395. package/server/src/Models/Asset.php +2 -2
  396. package/server/src/Models/Device.php +1 -1
  397. package/server/src/Models/Driver.php +82 -4
  398. package/server/src/Models/Equipment.php +62 -2
  399. package/server/src/Models/Maintenance.php +127 -9
  400. package/server/src/Models/MaintenanceSchedule.php +353 -0
  401. package/server/src/Models/Manifest.php +214 -0
  402. package/server/src/Models/ManifestStop.php +162 -0
  403. package/server/src/Models/Order.php +70 -0
  404. package/server/src/Models/OrderConfig.php +5 -2
  405. package/server/src/Models/Part.php +69 -3
  406. package/server/src/Models/Place.php +1 -1
  407. package/server/src/Models/Sensor.php +1 -1
  408. package/server/src/Models/ServiceQuote.php +1 -1
  409. package/server/src/Models/Vehicle.php +18 -1
  410. package/server/src/Models/Warranty.php +1 -1
  411. package/server/src/Models/Waypoint.php +7 -1
  412. package/server/src/Models/WorkOrder.php +122 -12
  413. package/server/src/Notifications/DriverShiftChanged.php +110 -0
  414. package/server/src/Observers/WorkOrderObserver.php +107 -0
  415. package/server/src/Orchestration/Contracts/OrchestrationEngineInterface.php +63 -0
  416. package/server/src/Orchestration/Engines/DriverAssignmentEngine.php +265 -0
  417. package/server/src/Orchestration/Engines/GreedyOrchestrationEngine.php +155 -0
  418. package/server/src/Orchestration/Engines/RouteSequencingEngine.php +272 -0
  419. package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +192 -0
  420. package/server/src/Orchestration/OrchestrationEngineRegistry.php +83 -0
  421. package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +380 -0
  422. package/server/src/Providers/EventServiceProvider.php +7 -1
  423. package/server/src/Providers/FleetOpsServiceProvider.php +42 -15
  424. package/server/src/routes.php +65 -4
  425. package/translations/ar-ae.yml +44 -12
  426. package/translations/bg-bg.yaml +51 -10
  427. package/translations/en-us.yaml +444 -1
  428. package/translations/fr-fr.yaml +51 -10
  429. package/translations/mn-mn.yaml +51 -10
  430. package/translations/pt-br.yaml +51 -10
  431. package/translations/ru-ru.yaml +51 -10
  432. package/translations/vi-vn.yaml +48 -12
@@ -1851,3 +1851,1661 @@ body[data-theme='dark'] .positions-replay-component .metric-card:hover {
1851
1851
  height: 40px;
1852
1852
  flex-shrink: 0;
1853
1853
  }
1854
+
1855
+ /* Scheduling: Availability Type Toggle Buttons */
1856
+ .availability-type-btn {
1857
+ flex: 1;
1858
+ display: flex;
1859
+ align-items: center;
1860
+ justify-content: center;
1861
+ gap: 0.5rem;
1862
+ padding: 0.625rem 0;
1863
+ border-radius: 0.5rem;
1864
+ border: 1px solid;
1865
+ font-size: 0.75rem;
1866
+ font-weight: 500;
1867
+ transition:
1868
+ color 0.15s,
1869
+ background-color 0.15s,
1870
+ border-color 0.15s;
1871
+ cursor: pointer;
1872
+ }
1873
+
1874
+ .availability-type-btn.is-unselected {
1875
+ background-color: #fff;
1876
+ border-color: #d1d5db;
1877
+ color: #4b5563;
1878
+ }
1879
+
1880
+ body[data-theme='dark'] .availability-type-btn.is-unselected {
1881
+ background-color: #1f2937;
1882
+ border-color: #4b5563;
1883
+ color: #9ca3af;
1884
+ }
1885
+
1886
+ .availability-type-btn.is-selected-available {
1887
+ background-color: #f0fdf4;
1888
+ border-color: #22c55e;
1889
+ color: #15803d;
1890
+ }
1891
+
1892
+ body[data-theme='dark'] .availability-type-btn.is-selected-available {
1893
+ background-color: #14532d;
1894
+ border-color: #4ade80;
1895
+ color: #bbf7d0;
1896
+ }
1897
+
1898
+ .availability-type-btn.is-selected-unavailable {
1899
+ background-color: #fef2f2;
1900
+ border-color: #ef4444;
1901
+ color: #b91c1c;
1902
+ }
1903
+
1904
+ body[data-theme='dark'] .availability-type-btn.is-selected-unavailable {
1905
+ background-color: #7f1d1d;
1906
+ border-color: #f87171;
1907
+ color: #fecaca;
1908
+ }
1909
+
1910
+ /* Scheduling: Shift Chip in Driver Calendar (ember-ui Badge info style) */
1911
+
1912
+ .driver-schedule-shift-chip {
1913
+ display: flex;
1914
+ flex-direction: column;
1915
+ width: 100%;
1916
+ border-radius: 0.25rem;
1917
+ margin-bottom: 0.25rem;
1918
+ padding: 0.25rem 0.375rem;
1919
+ font-size: 0.7rem;
1920
+ line-height: 1.3;
1921
+ border: 1px solid #bfdbfe;
1922
+ background-color: #eff6ff;
1923
+ color: #1e40af;
1924
+ }
1925
+
1926
+ body[data-theme='dark'] .driver-schedule-shift-chip {
1927
+ background-color: #1e3a5f;
1928
+ border-color: #3b82f6;
1929
+ color: #93c5fd;
1930
+ }
1931
+
1932
+ .driver-schedule-shift-chip .shift-chip-time {
1933
+ font-weight: 600;
1934
+ white-space: nowrap;
1935
+ overflow: hidden;
1936
+ text-overflow: ellipsis;
1937
+ }
1938
+
1939
+ .driver-schedule-shift-chip .shift-chip-actions {
1940
+ display: flex;
1941
+ gap: 0.125rem;
1942
+ margin-top: 0.125rem;
1943
+ }
1944
+
1945
+ .driver-schedule-shift-chip .shift-chip-action-btn {
1946
+ padding: 0.125rem;
1947
+ border-radius: 0.25rem;
1948
+ background: transparent;
1949
+ border: none;
1950
+ cursor: pointer;
1951
+ line-height: 1;
1952
+ opacity: 0.7;
1953
+ transition: opacity 0.15s;
1954
+ }
1955
+
1956
+ .driver-schedule-shift-chip .shift-chip-action-btn:hover {
1957
+ opacity: 1;
1958
+ }
1959
+
1960
+ .driver-schedule-shift-chip .shift-chip-action-btn.edit {
1961
+ color: #2563eb;
1962
+ }
1963
+
1964
+ body[data-theme='dark'] .driver-schedule-shift-chip .shift-chip-action-btn.edit {
1965
+ color: #93c5fd;
1966
+ }
1967
+
1968
+ .driver-schedule-shift-chip .shift-chip-action-btn.delete {
1969
+ color: #dc2626;
1970
+ }
1971
+
1972
+ body[data-theme='dark'] .driver-schedule-shift-chip .shift-chip-action-btn.delete {
1973
+ color: #fca5a5;
1974
+ }
1975
+
1976
+ /* Fleet Calendar FullCalendar Overrides */
1977
+
1978
+ #fleet-ops-fleet-schedule-container .fc {
1979
+ font-size: 0.75rem;
1980
+ font-family: inherit;
1981
+ }
1982
+
1983
+ #fleet-ops-fleet-schedule-container .fc-theme-standard td,
1984
+ #fleet-ops-fleet-schedule-container .fc-theme-standard th,
1985
+ #fleet-ops-fleet-schedule-container .fc-theme-standard .fc-scrollgrid {
1986
+ border-color: #e5e7eb;
1987
+ }
1988
+
1989
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-theme-standard td,
1990
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-theme-standard th,
1991
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-theme-standard .fc-scrollgrid {
1992
+ border-color: #374151;
1993
+ }
1994
+
1995
+ #fleet-ops-fleet-schedule-container .fc-col-header-cell {
1996
+ background-color: #f9fafb;
1997
+ font-weight: 600;
1998
+ font-size: 0.7rem;
1999
+ text-transform: uppercase;
2000
+ letter-spacing: 0.05em;
2001
+ color: #6b7280;
2002
+ }
2003
+
2004
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-col-header-cell {
2005
+ background-color: #111827;
2006
+ color: #9ca3af;
2007
+ }
2008
+
2009
+ #fleet-ops-fleet-schedule-container .fc-resource-area .fc-cell-text {
2010
+ font-weight: 500;
2011
+ font-size: 0.75rem;
2012
+ color: #111827;
2013
+ }
2014
+
2015
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-resource-area .fc-cell-text {
2016
+ color: #f3f4f6;
2017
+ }
2018
+
2019
+ #fleet-ops-fleet-schedule-container .fc-resource-area th {
2020
+ background-color: #f9fafb;
2021
+ }
2022
+
2023
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-resource-area th {
2024
+ background-color: #111827;
2025
+ }
2026
+
2027
+ #fleet-ops-fleet-schedule-container .fc-timeline-lane {
2028
+ background-color: #fff;
2029
+ }
2030
+
2031
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-timeline-lane {
2032
+ background-color: #1f2937;
2033
+ }
2034
+
2035
+ #fleet-ops-fleet-schedule-container .fc-timeline-slot.fc-day-today {
2036
+ background-color: #eff6ff;
2037
+ }
2038
+
2039
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-timeline-slot.fc-day-today {
2040
+ background-color: #1e3a5f;
2041
+ }
2042
+
2043
+ #fleet-ops-fleet-schedule-container .fc-event {
2044
+ border-radius: 0.25rem;
2045
+ border: none;
2046
+ font-size: 0.7rem;
2047
+ font-weight: 500;
2048
+ padding: 0.1rem 0.35rem;
2049
+ cursor: pointer;
2050
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 8%);
2051
+ }
2052
+
2053
+ #fleet-ops-fleet-schedule-container .fc-event:hover {
2054
+ filter: brightness(0.95);
2055
+ }
2056
+
2057
+ #fleet-ops-fleet-schedule-container .fc-timeline-slot-label {
2058
+ font-size: 0.65rem;
2059
+ color: #9ca3af;
2060
+ padding: 0 0.25rem;
2061
+ }
2062
+
2063
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-timeline-slot-label {
2064
+ color: #6b7280;
2065
+ }
2066
+
2067
+ #fleet-ops-fleet-schedule-container .fc-scrollgrid {
2068
+ border-radius: 0.5rem;
2069
+ overflow: hidden;
2070
+ border: 1px solid #e5e7eb;
2071
+ }
2072
+
2073
+ body[data-theme='dark'] #fleet-ops-fleet-schedule-container .fc-scrollgrid {
2074
+ border-color: #374151;
2075
+ }
2076
+
2077
+ /* ============================================================
2078
+ @event-calendar/core - Fleetbase Scheduler Overrides
2079
+ ============================================================ */
2080
+
2081
+ /* Light-mode variable overrides */
2082
+ #fleet-ops-scheduler-timeline .ec {
2083
+ --ec-color-400: #9ca3af;
2084
+ --ec-color-300: #d1d5db;
2085
+ --ec-color-200: #e5e7eb;
2086
+ --ec-color-100: #f3f4f6;
2087
+ --ec-color-50: #f9fafb;
2088
+ --ec-bg-color: #fff;
2089
+ --ec-text-color: #111827;
2090
+ --ec-border-color: #e5e7eb;
2091
+ --ec-button-bg-color: #fff;
2092
+ --ec-button-border-color: #d1d5db;
2093
+ --ec-button-text-color: #374151;
2094
+ --ec-button-active-bg-color: #4f46e5;
2095
+ --ec-button-active-border-color: #4338ca;
2096
+ --ec-button-active-text-color: #fff;
2097
+ --ec-today-bg-color: #eff6ff;
2098
+ --ec-highlight-color: #e0e7ff;
2099
+ --ec-event-bg-color: #4f46e5;
2100
+ --ec-event-text-color: #fff;
2101
+ --ec-bg-event-color: #e5e7eb;
2102
+ --ec-bg-event-opacity: 0.4;
2103
+ --ec-now-indicator-color: #ef4444;
2104
+
2105
+ font-size: 0.75rem;
2106
+ font-family: inherit;
2107
+ }
2108
+
2109
+ /* Dark-mode variable overrides */
2110
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline .ec {
2111
+ --ec-color-400: #4b5563;
2112
+ --ec-color-300: #374151;
2113
+ --ec-color-200: #1f2937;
2114
+ --ec-color-100: #111827;
2115
+ --ec-color-50: #0f172a;
2116
+ --ec-bg-color: #111827;
2117
+ --ec-text-color: #f3f4f6;
2118
+ --ec-border-color: #374151;
2119
+ --ec-button-bg-color: #1f2937;
2120
+ --ec-button-border-color: #374151;
2121
+ --ec-button-text-color: #d1d5db;
2122
+ --ec-button-active-bg-color: #4f46e5;
2123
+ --ec-button-active-border-color: #6366f1;
2124
+ --ec-button-active-text-color: #fff;
2125
+ --ec-today-bg-color: #1e3a5f;
2126
+ --ec-highlight-color: #312e81;
2127
+ --ec-event-bg-color: #6366f1;
2128
+ --ec-event-text-color: #fff;
2129
+ --ec-bg-event-color: #374151;
2130
+ --ec-bg-event-opacity: 0.5;
2131
+ --ec-now-indicator-color: #f87171;
2132
+ }
2133
+
2134
+ /* Toolbar refinements */
2135
+ #fleet-ops-scheduler-timeline .ec-toolbar {
2136
+ padding: 0.5rem 0.75rem;
2137
+ margin-block-end: 0;
2138
+ border-bottom: none;
2139
+ background-color: var(--ec-bg-color);
2140
+ }
2141
+
2142
+ #fleet-ops-scheduler-timeline .ec-title {
2143
+ font-size: 0.875rem;
2144
+ font-weight: 600;
2145
+ color: var(--ec-text-color);
2146
+ }
2147
+
2148
+ #fleet-ops-scheduler-timeline .ec-button {
2149
+ font-size: 0.75rem;
2150
+ padding: 0.25rem 0.625rem;
2151
+ border-radius: 0.375rem;
2152
+ transition:
2153
+ background-color 0.15s,
2154
+ border-color 0.15s,
2155
+ color 0.15s;
2156
+ }
2157
+
2158
+ #fleet-ops-scheduler-timeline .ec-button:not(:disabled):hover {
2159
+ background-color: var(--ec-color-100);
2160
+ border-color: var(--ec-color-300);
2161
+ }
2162
+
2163
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline .ec-button:not(:disabled):hover {
2164
+ background-color: var(--ec-color-200);
2165
+ }
2166
+
2167
+ /* Resource label column */
2168
+ #fleet-ops-scheduler-timeline .ec-sidebar {
2169
+ background-color: var(--ec-color-50);
2170
+ border-inline-end-color: var(--ec-border-color);
2171
+ min-width: 180px;
2172
+ }
2173
+
2174
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline .ec-sidebar {
2175
+ background-color: var(--ec-color-100);
2176
+ }
2177
+
2178
+ #fleet-ops-scheduler-timeline .ec-resource {
2179
+ font-size: 0.75rem;
2180
+ font-weight: 500;
2181
+ color: var(--ec-text-color);
2182
+ padding: 0;
2183
+ }
2184
+
2185
+ /* Column headers (time slots) */
2186
+ #fleet-ops-scheduler-timeline .ec-col-head,
2187
+ #fleet-ops-scheduler-timeline .ec-col-group {
2188
+ background-color: var(--ec-color-50);
2189
+ font-size: 0.65rem;
2190
+ font-weight: 600;
2191
+ text-transform: uppercase;
2192
+ letter-spacing: 0.05em;
2193
+ color: #6b7280;
2194
+ border-color: var(--ec-border-color);
2195
+ }
2196
+
2197
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline .ec-col-head,
2198
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline .ec-col-group {
2199
+ background-color: var(--ec-color-100);
2200
+ color: #9ca3af;
2201
+ }
2202
+
2203
+ /* Row / lane backgrounds */
2204
+ #fleet-ops-scheduler-timeline .ec-day {
2205
+ background-color: var(--ec-bg-color);
2206
+ }
2207
+
2208
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline .ec-day {
2209
+ background-color: #1f2937;
2210
+ }
2211
+
2212
+ /* Events */
2213
+ #fleet-ops-scheduler-timeline .ec-event {
2214
+ border-radius: 0.25rem;
2215
+ font-size: 0.7rem;
2216
+ font-weight: 500;
2217
+ padding: 0.25rem 0.5rem;
2218
+ cursor: pointer;
2219
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 8%);
2220
+ border: none;
2221
+ min-height: 3.25rem;
2222
+ overflow: hidden;
2223
+ }
2224
+
2225
+ #fleet-ops-scheduler-timeline .ec-event:hover {
2226
+ filter: brightness(0.92);
2227
+ }
2228
+
2229
+ /* Now indicator */
2230
+ #fleet-ops-scheduler-timeline .ec-now-indicator {
2231
+ border-color: var(--ec-now-indicator-color);
2232
+ }
2233
+
2234
+ #fleet-ops-scheduler-timeline .ec-now-indicator-arrow {
2235
+ border-top-color: var(--ec-now-indicator-color);
2236
+ border-bottom-color: var(--ec-now-indicator-color);
2237
+ }
2238
+
2239
+ /* Drag-over hover state */
2240
+ #fleet-ops-scheduler-timeline[data-dragging-over='true'] .ec-main {
2241
+ background-color: rgba(99, 102, 241, 4%);
2242
+ }
2243
+
2244
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline[data-dragging-over='true'] .ec-main {
2245
+ background-color: rgba(129, 140, 248, 6%);
2246
+ }
2247
+
2248
+ /* Per-column drop cursor indicator */
2249
+ #fleet-ops-scheduler-timeline .ec-drop-cursor {
2250
+ position: absolute;
2251
+ top: 0;
2252
+ bottom: 0;
2253
+ width: 2px;
2254
+ background-color: #6366f1;
2255
+ pointer-events: none;
2256
+ z-index: 10;
2257
+ border-radius: 1px;
2258
+ box-shadow: 0 0 6px rgba(99, 102, 241, 70%);
2259
+ transition: left 0.04s linear;
2260
+ }
2261
+
2262
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline .ec-drop-cursor {
2263
+ background-color: #818cf8;
2264
+ box-shadow: 0 0 6px rgba(129, 140, 248, 70%);
2265
+ }
2266
+
2267
+ /* Full-height timeline */
2268
+ #fleet-ops-scheduler-timeline {
2269
+ display: flex;
2270
+ flex-direction: column;
2271
+ height: 100%;
2272
+ overflow: hidden;
2273
+ }
2274
+
2275
+ #fleet-ops-scheduler-timeline .fleetbase-event-calendar,
2276
+ #fleet-ops-scheduler-timeline .ec {
2277
+ flex: 1 1 0;
2278
+ min-height: 0;
2279
+ height: 100%;
2280
+ display: flex;
2281
+ flex-direction: column;
2282
+ }
2283
+
2284
+ #fleet-ops-scheduler-timeline .ec-main {
2285
+ flex: 1 1 0;
2286
+ min-height: 0;
2287
+ overflow: auto;
2288
+ }
2289
+
2290
+ /* Scrollbar styling (Webkit) */
2291
+ #fleet-ops-scheduler-timeline .ec-main::-webkit-scrollbar {
2292
+ width: 6px;
2293
+ height: 6px;
2294
+ background-color: transparent;
2295
+ }
2296
+
2297
+ #fleet-ops-scheduler-timeline .ec-main::-webkit-scrollbar-thumb {
2298
+ background-color: #d1d5db;
2299
+ border-radius: 3px;
2300
+ }
2301
+
2302
+ body[data-theme='dark'] #fleet-ops-scheduler-timeline .ec-main::-webkit-scrollbar-thumb {
2303
+ background-color: #4b5563;
2304
+ }
2305
+
2306
+ /* ============================================================
2307
+ Scheduler - Full-height layout & header overflow fixes
2308
+ ============================================================ */
2309
+
2310
+ /* 1. Make the tab-navigation a flex column so the tab-content
2311
+ fills the remaining height below the tab-list. */
2312
+ .tab-navigation.fleet-ops-scheduler-tab-nav {
2313
+ display: flex;
2314
+ flex-direction: column;
2315
+ overflow: hidden;
2316
+ }
2317
+
2318
+ /* 2. The tab-content should grow to fill all remaining space
2319
+ below the tab-list. */
2320
+ .tab-navigation.fleet-ops-scheduler-tab-nav > .tab-content {
2321
+ flex: 1 1 0;
2322
+ min-height: 0;
2323
+ overflow: hidden;
2324
+ display: flex;
2325
+ flex-direction: column;
2326
+ }
2327
+
2328
+ /* 3. The next-view-section-body inside the scheduler should
2329
+ fill the remaining space below the subheader. */
2330
+ .tab-navigation.fleet-ops-scheduler-tab-nav .next-view-section-body {
2331
+ flex: 1 1 0;
2332
+ min-height: 0;
2333
+ overflow: hidden;
2334
+ display: flex;
2335
+ flex-direction: column;
2336
+ }
2337
+
2338
+ /* 4. Fix the subheader overflow: prevent the actions from
2339
+ stretching beyond the viewport width. */
2340
+ .tab-navigation.fleet-ops-scheduler-tab-nav .next-view-section-subheader {
2341
+ flex-shrink: 0;
2342
+ min-width: 0;
2343
+ max-width: 100%;
2344
+ overflow: hidden;
2345
+ }
2346
+
2347
+ /* 5. Allow the actions area to shrink and wrap so buttons
2348
+ remain visible when the timeline stretches the layout. */
2349
+ .tab-navigation.fleet-ops-scheduler-tab-nav .next-view-section-subheader-actions {
2350
+ flex-shrink: 1;
2351
+ min-width: 0;
2352
+ overflow: hidden;
2353
+ flex-wrap: wrap;
2354
+ gap: 0.25rem;
2355
+ }
2356
+
2357
+ /* 6. The scheduler container and timeline fill the body. */
2358
+ #fleet-ops-scheduler-container {
2359
+ flex: 1 1 0;
2360
+ min-height: 0;
2361
+ }
2362
+
2363
+ /* ============================================================
2364
+ Scheduler – follow-up fixes (round 3)
2365
+ ============================================================ */
2366
+
2367
+ /* 1. Resource label: make the inner span (direct child of .ec-row-head)
2368
+ fill the full cell width so the workload bar stretches correctly. */
2369
+ #fleet-ops-orchestrator-plan-timeline .ec-row-head > span,
2370
+ #fleet-ops-scheduler-timeline .ec-row-head > span {
2371
+ display: block;
2372
+ width: 100%;
2373
+ text-align: left;
2374
+ }
2375
+
2376
+ /* 2. Event blocks: ensure a minimum width so the 3-line content is readable.
2377
+ The timeline slot width determines how wide each column is; we set a
2378
+ sensible min-width so the block never collapses to an unreadable sliver. */
2379
+ #fleet-ops-orchestrator-plan-timeline .ec-event,
2380
+ #fleet-ops-scheduler-timeline .ec-event {
2381
+ min-width: 200px;
2382
+ }
2383
+
2384
+ /* 3. Search icon: FontAwesome SVGs carry vertical-align:-0.125em which shifts
2385
+ the icon slightly below the visual centre of the flex container.
2386
+ The span uses Tailwind utility classes (absolute, inset-y-0, flex,
2387
+ items-center) not a semantic class, so we target the first span child
2388
+ of the .relative wrapper. */
2389
+ #fleet-ops-scheduler-sidebar .relative > span:first-child .svg-inline--fa,
2390
+ #fleet-ops-scheduler-sidebar .relative > span:first-child svg {
2391
+ vertical-align: middle;
2392
+ display: block;
2393
+ line-height: 1;
2394
+ }
2395
+
2396
+ /* 4. Schedule card: remove horizontal padding from .card-content so the
2397
+ content sits flush with the card border. */
2398
+ .order-schedule-card .card-content {
2399
+ padding-left: 0 !important;
2400
+ padding-right: 0 !important;
2401
+ }
2402
+
2403
+ /* ============================================================
2404
+ Orchestrator Workbench
2405
+ ============================================================ */
2406
+
2407
+ /* ── Workbench layout ── */
2408
+ .orchestrator-workbench {
2409
+ background: #f9fafb; /* gray-50 — light mode default */
2410
+ }
2411
+
2412
+ body[data-theme='dark'] .orchestrator-workbench,
2413
+ .dark .orchestrator-workbench {
2414
+ background: #111827; /* gray-900 — dark mode */
2415
+ }
2416
+
2417
+ /* ── Toolbar ── */
2418
+ .workbench-toolbar {
2419
+ min-height: 44px;
2420
+ }
2421
+
2422
+ /* ── Options panel ── */
2423
+ .workbench-options-panel label {
2424
+ white-space: nowrap;
2425
+ }
2426
+
2427
+ /* ── Order pool card ── */
2428
+
2429
+ /* Light-mode base: white card with gray-200 border */
2430
+ .order-pool-card {
2431
+ background: #fff;
2432
+ border-color: #e5e7eb; /* gray-200 */
2433
+ transition:
2434
+ background 0.1s,
2435
+ border-color 0.1s;
2436
+ }
2437
+
2438
+ .order-pool-card:hover {
2439
+ background: #f9fafb;
2440
+ border-color: #93c5fd; /* blue-300 */
2441
+ }
2442
+
2443
+ .order-pool-card.selected {
2444
+ background: #eff6ff; /* blue-50 */
2445
+ border-color: #3b82f6;
2446
+ }
2447
+
2448
+ /* Dark-mode overrides */
2449
+ body[data-theme='dark'] .order-pool-card,
2450
+ .dark .order-pool-card {
2451
+ background: #1f2937;
2452
+ border-color: #374151;
2453
+ }
2454
+
2455
+ body[data-theme='dark'] .order-pool-card:hover,
2456
+ .dark .order-pool-card:hover {
2457
+ background: #263040;
2458
+ border-color: #4b5563;
2459
+ }
2460
+
2461
+ body[data-theme='dark'] .order-pool-card.selected,
2462
+ .dark .order-pool-card.selected {
2463
+ background: #1e3a5f;
2464
+ border-color: #3b82f6;
2465
+ }
2466
+
2467
+ /* ── Order filter chips ── */
2468
+ .order-filter-chip {
2469
+ padding: 2px 8px;
2470
+ border-radius: 9999px;
2471
+ font-size: 0.65rem;
2472
+ font-weight: 500;
2473
+ color: #9ca3af;
2474
+ background: transparent;
2475
+ border: 1px solid #374151;
2476
+ cursor: pointer;
2477
+ white-space: nowrap;
2478
+ transition:
2479
+ background 0.1s,
2480
+ color 0.1s,
2481
+ border-color 0.1s;
2482
+ }
2483
+
2484
+ .order-filter-chip:hover {
2485
+ background: #374151;
2486
+ color: #e5e7eb;
2487
+ }
2488
+
2489
+ .order-filter-chip.active {
2490
+ background: #1d4ed8;
2491
+ border-color: #3b82f6;
2492
+ color: #fff;
2493
+ }
2494
+
2495
+ /* ── Skill tags ── */
2496
+ .skill-tag {
2497
+ display: inline-block;
2498
+ padding: 1px 6px;
2499
+ border-radius: 4px;
2500
+ font-size: 0.6rem;
2501
+ font-weight: 500;
2502
+ background: #1e3a5f;
2503
+ color: #93c5fd;
2504
+ border: 1px solid #1d4ed8;
2505
+ }
2506
+
2507
+ /* ── Vehicle route cards ── */
2508
+ .vehicle-route-card {
2509
+ transition: box-shadow 0.1s;
2510
+ }
2511
+
2512
+ .vehicle-route-card:hover {
2513
+ box-shadow: 0 0 0 1px #3b82f6;
2514
+ }
2515
+
2516
+ /* ── Assigned stop row ── */
2517
+ .assigned-stop {
2518
+ transition: background 0.1s;
2519
+ }
2520
+
2521
+ .assigned-stop:hover {
2522
+ background: #263040 !important;
2523
+ }
2524
+
2525
+ /* ── Driver card ── */
2526
+ .driver-card {
2527
+ cursor: pointer;
2528
+ transition:
2529
+ background 0.1s,
2530
+ border-color 0.1s;
2531
+ }
2532
+
2533
+ .driver-card:hover {
2534
+ background: #263040;
2535
+ border-color: #4b5563;
2536
+ }
2537
+
2538
+ /* ── Vehicle drop zone (drag target) ── */
2539
+ .vehicle-drop-zone {
2540
+ min-height: 32px;
2541
+ transition: background 0.1s;
2542
+ }
2543
+
2544
+ .vehicle-drop-zone.drag-over {
2545
+ background: rgba(59, 130, 246, 10%);
2546
+ outline: 1px dashed #3b82f6;
2547
+ border-radius: 4px;
2548
+ }
2549
+
2550
+ /* ── Import modal ── */
2551
+ .import-dropzone {
2552
+ display: flex;
2553
+ flex-direction: column;
2554
+ align-items: center;
2555
+ justify-content: center;
2556
+ padding: 2rem;
2557
+ border: 2px dashed #d1d5db; /* gray-300 — works in both modes */
2558
+ border-radius: 0.5rem;
2559
+ background: #f9fafb; /* gray-50 — light mode default */
2560
+ text-align: center;
2561
+ cursor: pointer;
2562
+ transition:
2563
+ border-color 0.15s,
2564
+ background 0.15s;
2565
+ }
2566
+
2567
+ /* Dark mode override */
2568
+ body[data-theme='dark'] .import-dropzone,
2569
+ .dark .import-dropzone {
2570
+ border-color: #374151;
2571
+ background: #1f2937;
2572
+ }
2573
+
2574
+ .import-dropzone:hover,
2575
+ .import-dropzone.dragging {
2576
+ border-color: #3b82f6;
2577
+ background: #eff6ff; /* blue-50 for light mode */
2578
+ }
2579
+
2580
+ body[data-theme='dark'] .import-dropzone:hover,
2581
+ body[data-theme='dark'] .import-dropzone.dragging,
2582
+ .dark .import-dropzone:hover,
2583
+ .dark .import-dropzone.dragging {
2584
+ background: #1e3a5f;
2585
+ }
2586
+
2587
+ .import-dropzone p {
2588
+ margin: 0;
2589
+ }
2590
+
2591
+ /* ── Import step indicator ── */
2592
+ .import-step {
2593
+ display: flex;
2594
+ align-items: center;
2595
+ gap: 6px;
2596
+ font-size: 0.7rem;
2597
+ color: #6b7280;
2598
+ font-weight: 500;
2599
+ }
2600
+
2601
+ .import-step.active {
2602
+ color: #3b82f6;
2603
+ }
2604
+
2605
+ .import-step-num {
2606
+ display: inline-flex;
2607
+ align-items: center;
2608
+ justify-content: center;
2609
+ width: 18px;
2610
+ height: 18px;
2611
+ border-radius: 50%;
2612
+ background: #374151;
2613
+ font-size: 0.6rem;
2614
+ font-weight: 700;
2615
+ color: #9ca3af;
2616
+ }
2617
+
2618
+ .import-step.active .import-step-num {
2619
+ background: #1d4ed8;
2620
+ color: #fff;
2621
+ }
2622
+
2623
+ .import-step-divider {
2624
+ flex: 1;
2625
+ height: 1px;
2626
+ background: #374151;
2627
+ min-width: 16px;
2628
+ }
2629
+
2630
+ /* ── Orchestrator Workbench: panel toggle buttons ── */
2631
+ .workbench-panel-toggle {
2632
+ cursor: pointer;
2633
+ z-index: 1;
2634
+ }
2635
+
2636
+ /* ── Orchestrator Workbench: Leaflet div-icon markers ── */
2637
+
2638
+ /* The wrapper div produced by div-icon must have no default background/border */
2639
+ .orch-marker-wrapper {
2640
+ background: transparent !important;
2641
+ border: none !important;
2642
+ }
2643
+
2644
+ /* Order drop-off dot — blue */
2645
+ .orch-marker-order {
2646
+ width: 14px;
2647
+ height: 14px;
2648
+ border-radius: 50%;
2649
+ background: #3b82f6;
2650
+ border: 2px solid #fff;
2651
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 50%);
2652
+ transition: transform 0.1s;
2653
+ }
2654
+
2655
+ .orch-marker-order.selected {
2656
+ background: #f59e0b;
2657
+ border-color: #fff;
2658
+ transform: scale(1.3);
2659
+ }
2660
+
2661
+ /* Driver/vehicle dot — green online, red offline */
2662
+ .orch-marker-driver {
2663
+ width: 16px;
2664
+ height: 16px;
2665
+ border-radius: 50%;
2666
+ border: 2px solid #fff;
2667
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 50%);
2668
+ background: #ef4444; /* default: offline */
2669
+ }
2670
+
2671
+ .orch-marker-driver.online {
2672
+ background: #10b981;
2673
+ }
2674
+
2675
+ .pl-7i {
2676
+ padding-left: 1.75rem !important;
2677
+ }
2678
+
2679
+ /**
2680
+ * Base reset for the Leaflet divIcon container.
2681
+ * Leaflet adds its own background/border by default; we clear those
2682
+ * so our custom HTML circle renders cleanly.
2683
+ */
2684
+ .fleetops-waypoint-marker {
2685
+ background: transparent !important;
2686
+ border: none !important;
2687
+ }
2688
+
2689
+ /**
2690
+ * Tooltip shown on hover over a waypoint marker.
2691
+ * Minimal padding, small font, semi-transparent dark background.
2692
+ */
2693
+ .fleetops-waypoint-tooltip {
2694
+ background: rgba(15, 23, 42, 88%) !important;
2695
+ border: none !important;
2696
+ border-radius: 4px !important;
2697
+ color: #f8fafc !important;
2698
+ font-size: 11px !important;
2699
+ font-weight: 600 !important;
2700
+ padding: 3px 7px !important;
2701
+ white-space: nowrap;
2702
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 35%) !important;
2703
+ }
2704
+
2705
+ .fleetops-waypoint-tooltip::before {
2706
+ border-top-color: rgba(15, 23, 42, 88%) !important;
2707
+ }
2708
+
2709
+ /* ============================================================
2710
+ Route Visualization – Waypoint Popup
2711
+ ============================================================ */
2712
+
2713
+ /**
2714
+ * Override Leaflet's default popup wrapper to use our design system.
2715
+ */
2716
+ .fleetops-waypoint-popup-wrapper .leaflet-popup-content-wrapper {
2717
+ border-radius: 6px !important;
2718
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 20%) !important;
2719
+ padding: 0 !important;
2720
+ overflow: hidden;
2721
+ }
2722
+
2723
+ .fleetops-waypoint-popup-wrapper .leaflet-popup-content {
2724
+ margin: 0 !important;
2725
+ width: auto !important;
2726
+ min-width: 180px;
2727
+ }
2728
+
2729
+ .fleetops-waypoint-popup-wrapper .leaflet-popup-tip-container {
2730
+ margin-top: -1px;
2731
+ }
2732
+
2733
+ /**
2734
+ * Inner popup layout.
2735
+ */
2736
+ .fleetops-waypoint-popup {
2737
+ font-family:
2738
+ ui-sans-serif,
2739
+ system-ui,
2740
+ -apple-system,
2741
+ sans-serif;
2742
+ font-size: 12px;
2743
+ line-height: 1.5;
2744
+ color: #1e293b;
2745
+ padding: 10px 12px;
2746
+ }
2747
+
2748
+ .fleetops-waypoint-popup__header {
2749
+ display: flex;
2750
+ align-items: center;
2751
+ gap: 7px;
2752
+ margin-bottom: 6px;
2753
+ font-size: 13px;
2754
+ font-weight: 700;
2755
+ color: #0f172a;
2756
+ }
2757
+
2758
+ .fleetops-waypoint-popup__badge {
2759
+ display: inline-flex;
2760
+ align-items: center;
2761
+ justify-content: center;
2762
+ width: 22px;
2763
+ height: 22px;
2764
+ border-radius: 50%;
2765
+ color: #fff;
2766
+ font-size: 11px;
2767
+ font-weight: 700;
2768
+ flex-shrink: 0;
2769
+ }
2770
+
2771
+ .fleetops-waypoint-popup__name {
2772
+ font-weight: 600;
2773
+ color: #0f172a;
2774
+ margin-bottom: 2px;
2775
+ }
2776
+
2777
+ .fleetops-waypoint-popup__address {
2778
+ color: #475569;
2779
+ font-size: 11px;
2780
+ margin-bottom: 4px;
2781
+ }
2782
+
2783
+ .fleetops-waypoint-popup__meta {
2784
+ color: #64748b;
2785
+ font-size: 11px;
2786
+ margin-top: 2px;
2787
+ }
2788
+
2789
+ .fleetops-waypoint-popup__meta strong {
2790
+ color: #334155;
2791
+ }
2792
+
2793
+ /* ============================================================
2794
+ Route Visualization – Live Map Route Tooltips
2795
+ ============================================================ */
2796
+
2797
+ /**
2798
+ * Tooltip shown when hovering over a live-map route polyline.
2799
+ */
2800
+ .fleetops-route-tooltip-wrapper {
2801
+ pointer-events: none;
2802
+ }
2803
+
2804
+ .fleetops-route-tooltip-wrapper .leaflet-tooltip {
2805
+ background: rgba(15, 23, 42, 92%) !important;
2806
+ border: none !important;
2807
+ border-radius: 5px !important;
2808
+ box-shadow: 0 3px 10px rgba(0, 0, 0, 30%) !important;
2809
+ padding: 6px 10px !important;
2810
+ color: #f1f5f9 !important;
2811
+ font-size: 11px !important;
2812
+ white-space: nowrap;
2813
+ }
2814
+
2815
+ .fleetops-route-tooltip-wrapper .leaflet-tooltip::before {
2816
+ border-top-color: rgba(15, 23, 42, 92%) !important;
2817
+ }
2818
+
2819
+ .fleetops-route-tooltip {
2820
+ font-family:
2821
+ ui-sans-serif,
2822
+ system-ui,
2823
+ -apple-system,
2824
+ sans-serif;
2825
+ line-height: 1.6;
2826
+ }
2827
+
2828
+ .fleetops-route-tooltip__id {
2829
+ font-weight: 700;
2830
+ font-size: 12px;
2831
+ color: #f8fafc;
2832
+ margin-bottom: 1px;
2833
+ }
2834
+
2835
+ .fleetops-route-tooltip__driver,
2836
+ .fleetops-route-tooltip__status {
2837
+ font-size: 11px;
2838
+ color: #94a3b8;
2839
+ }
2840
+
2841
+ /* ============================================================
2842
+ Route Visualization – In-Progress Pulse Animation
2843
+ Applies a subtle animated glow to active (in_progress) routes.
2844
+ ============================================================ */
2845
+
2846
+ @keyframes fleetops-route-pulse {
2847
+ 0% {
2848
+ opacity: 1;
2849
+ }
2850
+
2851
+ 50% {
2852
+ opacity: 0.55;
2853
+ }
2854
+
2855
+ 100% {
2856
+ opacity: 1;
2857
+ }
2858
+ }
2859
+
2860
+ .fleetops-route-active path {
2861
+ animation: fleetops-route-pulse 2s ease-in-out infinite;
2862
+ }
2863
+
2864
+ .card-fields-settings .card-fields-settings-container {
2865
+ height: 300px;
2866
+ min-height: 300px;
2867
+ max-height: 300px;
2868
+ overflow-y: scroll;
2869
+ }
2870
+
2871
+ /* ============================================================
2872
+ @event-calendar/core - Orchestrator Plan Timeline Overrides
2873
+ Mirrors the scheduler timeline styles, scoped to the
2874
+ #fleet-ops-orchestrator-plan-timeline wrapper div.
2875
+ ============================================================ */
2876
+ #fleet-ops-orchestrator-plan-timeline .ec {
2877
+ --ec-color-400: #9ca3af;
2878
+ --ec-color-300: #d1d5db;
2879
+ --ec-color-200: #e5e7eb;
2880
+ --ec-color-100: #f3f4f6;
2881
+ --ec-color-50: #f9fafb;
2882
+ --ec-bg-color: #fff;
2883
+ --ec-text-color: #111827;
2884
+ --ec-border-color: #e5e7eb;
2885
+ --ec-button-bg-color: #fff;
2886
+ --ec-button-border-color: #d1d5db;
2887
+ --ec-button-text-color: #374151;
2888
+ --ec-button-active-bg-color: #4f46e5;
2889
+ --ec-button-active-border-color: #4338ca;
2890
+ --ec-button-active-text-color: #fff;
2891
+ --ec-today-bg-color: #eff6ff;
2892
+ --ec-highlight-color: #e0e7ff;
2893
+ --ec-event-bg-color: #4f46e5;
2894
+ --ec-event-text-color: #fff;
2895
+ --ec-bg-event-color: #e5e7eb;
2896
+ --ec-bg-event-opacity: 0.4;
2897
+ --ec-now-indicator-color: #ef4444;
2898
+
2899
+ font-size: 0.75rem;
2900
+ font-family: inherit;
2901
+ }
2902
+
2903
+ body[data-theme='dark'] #fleet-ops-orchestrator-plan-timeline .ec {
2904
+ --ec-color-400: #4b5563;
2905
+ --ec-color-300: #374151;
2906
+ --ec-color-200: #1f2937;
2907
+ --ec-color-100: #111827;
2908
+ --ec-color-50: #0f172a;
2909
+ --ec-bg-color: #111827;
2910
+ --ec-text-color: #f3f4f6;
2911
+ --ec-border-color: #374151;
2912
+ --ec-button-bg-color: #1f2937;
2913
+ --ec-button-border-color: #374151;
2914
+ --ec-button-text-color: #d1d5db;
2915
+ --ec-button-active-bg-color: #4f46e5;
2916
+ --ec-button-active-border-color: #6366f1;
2917
+ --ec-button-active-text-color: #fff;
2918
+ --ec-today-bg-color: #1e3a5f;
2919
+ --ec-highlight-color: #312e81;
2920
+ --ec-event-bg-color: #6366f1;
2921
+ --ec-event-text-color: #fff;
2922
+ --ec-bg-event-color: #374151;
2923
+ --ec-bg-event-opacity: 0.5;
2924
+ --ec-now-indicator-color: #f87171;
2925
+ }
2926
+
2927
+ #fleet-ops-orchestrator-plan-timeline .ec-toolbar {
2928
+ padding: 0.5rem 0.75rem;
2929
+ margin-block-end: 0;
2930
+ border-bottom: none;
2931
+ background-color: var(--ec-bg-color);
2932
+ }
2933
+
2934
+ #fleet-ops-orchestrator-plan-timeline .ec-title {
2935
+ font-size: 0.875rem;
2936
+ font-weight: 600;
2937
+ color: var(--ec-text-color);
2938
+ }
2939
+
2940
+ #fleet-ops-orchestrator-plan-timeline .ec-button {
2941
+ font-size: 0.75rem;
2942
+ padding: 0.25rem 0.625rem;
2943
+ border-radius: 0.375rem;
2944
+ transition:
2945
+ background-color 0.15s,
2946
+ border-color 0.15s,
2947
+ color 0.15s;
2948
+ }
2949
+
2950
+ #fleet-ops-orchestrator-plan-timeline .ec-button:not(:disabled):hover {
2951
+ background-color: var(--ec-color-100);
2952
+ border-color: var(--ec-color-300);
2953
+ }
2954
+
2955
+ body[data-theme='dark'] #fleet-ops-orchestrator-plan-timeline .ec-button:not(:disabled):hover {
2956
+ background-color: var(--ec-color-200);
2957
+ }
2958
+
2959
+ #fleet-ops-orchestrator-plan-timeline .ec-sidebar {
2960
+ background-color: var(--ec-color-50);
2961
+ border-inline-end-color: var(--ec-border-color);
2962
+ min-width: 160px;
2963
+ }
2964
+
2965
+ body[data-theme='dark'] #fleet-ops-orchestrator-plan-timeline .ec-sidebar {
2966
+ background-color: var(--ec-color-100);
2967
+ }
2968
+
2969
+ #fleet-ops-orchestrator-plan-timeline .ec-resource {
2970
+ font-size: 0.75rem;
2971
+ font-weight: 500;
2972
+ color: var(--ec-text-color);
2973
+ padding: 0;
2974
+ }
2975
+
2976
+ #fleet-ops-orchestrator-plan-timeline .ec-col-head,
2977
+ #fleet-ops-orchestrator-plan-timeline .ec-col-group {
2978
+ background-color: var(--ec-color-50);
2979
+ font-size: 0.65rem;
2980
+ font-weight: 600;
2981
+ text-transform: uppercase;
2982
+ letter-spacing: 0.05em;
2983
+ color: #6b7280;
2984
+ border-color: var(--ec-border-color);
2985
+ }
2986
+
2987
+ body[data-theme='dark'] #fleet-ops-orchestrator-plan-timeline .ec-col-head,
2988
+ body[data-theme='dark'] #fleet-ops-orchestrator-plan-timeline .ec-col-group {
2989
+ background-color: var(--ec-color-100);
2990
+ color: #9ca3af;
2991
+ }
2992
+
2993
+ #fleet-ops-orchestrator-plan-timeline .ec-day {
2994
+ background-color: var(--ec-bg-color);
2995
+ }
2996
+
2997
+ body[data-theme='dark'] #fleet-ops-orchestrator-plan-timeline .ec-day {
2998
+ background-color: #1f2937;
2999
+ }
3000
+
3001
+ #fleet-ops-orchestrator-plan-timeline .ec-event {
3002
+ border-radius: 0.25rem;
3003
+ font-size: 0.7rem;
3004
+ font-weight: 500;
3005
+ padding: 0.25rem 0.5rem;
3006
+ cursor: default;
3007
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 8%);
3008
+ border: none;
3009
+ min-height: 3.25rem;
3010
+ overflow: hidden;
3011
+ }
3012
+
3013
+ #fleet-ops-orchestrator-plan-timeline .ec-event:hover {
3014
+ filter: brightness(0.92);
3015
+ }
3016
+
3017
+ #fleet-ops-orchestrator-plan-timeline .ec-now-indicator {
3018
+ border-color: var(--ec-now-indicator-color);
3019
+ }
3020
+
3021
+ #fleet-ops-orchestrator-plan-timeline .ec-now-indicator-arrow {
3022
+ border-top-color: var(--ec-now-indicator-color);
3023
+ border-bottom-color: var(--ec-now-indicator-color);
3024
+ }
3025
+
3026
+ #fleet-ops-orchestrator-plan-timeline {
3027
+ display: flex;
3028
+ flex-direction: column;
3029
+ height: 100%;
3030
+ overflow: hidden;
3031
+ }
3032
+
3033
+ #fleet-ops-orchestrator-plan-timeline .fleetbase-event-calendar,
3034
+ #fleet-ops-orchestrator-plan-timeline .ec {
3035
+ flex: 1 1 0;
3036
+ min-height: 0;
3037
+ height: 100%;
3038
+ display: flex;
3039
+ flex-direction: column;
3040
+ }
3041
+
3042
+ #fleet-ops-orchestrator-plan-timeline .ec-main {
3043
+ flex: 1 1 0;
3044
+ min-height: 0;
3045
+ overflow: auto;
3046
+ }
3047
+
3048
+ #fleet-ops-orchestrator-plan-timeline .ec-main::-webkit-scrollbar {
3049
+ width: 6px;
3050
+ height: 6px;
3051
+ background-color: transparent;
3052
+ }
3053
+
3054
+ #fleet-ops-orchestrator-plan-timeline .ec-main::-webkit-scrollbar-thumb {
3055
+ background-color: #d1d5db;
3056
+ border-radius: 3px;
3057
+ }
3058
+
3059
+ body[data-theme='dark'] #fleet-ops-orchestrator-plan-timeline .ec-main::-webkit-scrollbar-thumb {
3060
+ background-color: #4b5563;
3061
+ }
3062
+
3063
+ .orchestrator-map-container.next-map-container .leaflet-top {
3064
+ top: 0;
3065
+ }
3066
+
3067
+ /* ── Orchestrator Import Modal: tab-style step indicator ── */
3068
+ .import-step-tab {
3069
+ display: flex;
3070
+ align-items: center;
3071
+ gap: 8px;
3072
+ padding: 12px 22px 12px 16px;
3073
+ font-size: 0.8rem;
3074
+ font-weight: 600;
3075
+ color: #6b7280;
3076
+ border-bottom: 3px solid transparent;
3077
+ cursor: default;
3078
+ user-select: none;
3079
+ letter-spacing: 0.01em;
3080
+ transition:
3081
+ color 0.15s,
3082
+ border-color 0.15s;
3083
+ }
3084
+
3085
+ /* Light mode: gray-500 on gray-50 background */
3086
+ body[data-theme='light'] .import-step-tab {
3087
+ color: #6b7280; /* gray-500 — readable on gray-50 */
3088
+ }
3089
+
3090
+ /* Dark mode: gray-400 on gray-800 background */
3091
+ body[data-theme='dark'] .import-step-tab {
3092
+ color: #9ca3af; /* gray-400 — readable on gray-800 */
3093
+ }
3094
+
3095
+ .import-step-tab--active {
3096
+ color: #3b82f6;
3097
+ border-bottom-color: #3b82f6;
3098
+ }
3099
+
3100
+ .import-step-tab-num {
3101
+ display: inline-flex;
3102
+ align-items: center;
3103
+ justify-content: center;
3104
+ width: 22px;
3105
+ height: 22px;
3106
+ border-radius: 50%;
3107
+ background: #e5e7eb; /* gray-200 — light mode default */
3108
+ font-size: 0.7rem;
3109
+ font-weight: 700;
3110
+ color: #6b7280;
3111
+ flex-shrink: 0;
3112
+ transition:
3113
+ background 0.15s,
3114
+ color 0.15s;
3115
+ }
3116
+
3117
+ /* Dark mode step number badge */
3118
+ body[data-theme='dark'] .import-step-tab-num,
3119
+ .dark .import-step-tab-num {
3120
+ background: #374151;
3121
+ color: #9ca3af;
3122
+ }
3123
+
3124
+ .import-step-tab-num--active {
3125
+ background: #1d4ed8;
3126
+ color: #fff;
3127
+ }
3128
+
3129
+ /* ── Orchestrator Import Modal: column-mapping table layout ── */
3130
+
3131
+ /* Sticky column header bar (Target field / Your spreadsheet) */
3132
+ .import-mapping-header {
3133
+ display: grid;
3134
+ grid-template-columns: 1fr 28px 1fr;
3135
+ align-items: center;
3136
+ padding: 6px 16px;
3137
+ background: #f3f4f6; /* gray-100 — light mode */
3138
+ border-bottom: 1px solid #e5e7eb;
3139
+ position: sticky;
3140
+ top: 0;
3141
+ z-index: 10;
3142
+ font-size: 0.68rem;
3143
+ font-weight: 700;
3144
+ text-transform: uppercase;
3145
+ letter-spacing: 0.07em;
3146
+ color: #6b7280;
3147
+ }
3148
+
3149
+ body[data-theme='dark'] .import-mapping-header,
3150
+ .dark .import-mapping-header {
3151
+ background: #111827;
3152
+ border-bottom-color: #1f2937;
3153
+ color: #4b5563;
3154
+ }
3155
+
3156
+ /* Scrollable body that holds all groups + rows */
3157
+ .import-mapping-body {
3158
+ overflow-y: auto;
3159
+ max-height: 420px;
3160
+ }
3161
+
3162
+ /* Section group header (ORDER, PICKUP, DROPOFF, etc.) */
3163
+ .import-mapping-group-header {
3164
+ display: flex;
3165
+ align-items: center;
3166
+ padding: 5px 16px;
3167
+ background: #e5e7eb; /* gray-200 — light mode */
3168
+ border-top: 1px solid #d1d5db;
3169
+ border-bottom: 1px solid #d1d5db;
3170
+ font-size: 0.65rem;
3171
+ font-weight: 700;
3172
+ text-transform: uppercase;
3173
+ letter-spacing: 0.09em;
3174
+ color: #6b7280;
3175
+ position: sticky;
3176
+ top: 0;
3177
+ z-index: 5;
3178
+ }
3179
+
3180
+ body[data-theme='dark'] .import-mapping-group-header,
3181
+ .dark .import-mapping-group-header {
3182
+ background: #0f172a;
3183
+ border-top-color: #1f2937;
3184
+ border-bottom-color: #1f2937;
3185
+ color: #4b5563;
3186
+ }
3187
+
3188
+ .import-mapping-group-header:first-child {
3189
+ border-top: none;
3190
+ }
3191
+
3192
+ /* Individual mapping row */
3193
+ .import-mapping-row {
3194
+ display: grid;
3195
+ grid-template-columns: 1fr 28px 1fr;
3196
+ align-items: center;
3197
+ padding: 5px 16px;
3198
+ border-bottom: 1px solid #f3f4f6; /* gray-100 — light mode */
3199
+ transition: background 0.1s;
3200
+ }
3201
+
3202
+ body[data-theme='dark'] .import-mapping-row,
3203
+ .dark .import-mapping-row {
3204
+ border-bottom-color: #1f2937;
3205
+ }
3206
+
3207
+ .import-mapping-row:last-child {
3208
+ border-bottom: none;
3209
+ }
3210
+
3211
+ .import-mapping-row:hover {
3212
+ background: rgba(0, 0, 0, 2%); /* light mode hover */
3213
+ }
3214
+
3215
+ body[data-theme='dark'] .import-mapping-row:hover,
3216
+ .dark .import-mapping-row:hover {
3217
+ background: rgba(255, 255, 255, 2%);
3218
+ }
3219
+
3220
+ /* Highlight rows that have a mapping applied */
3221
+ .import-mapping-row--mapped {
3222
+ background: rgba(16, 185, 129, 5%);
3223
+ }
3224
+
3225
+ .import-mapping-row--mapped:hover {
3226
+ background: rgba(16, 185, 129, 9%);
3227
+ }
3228
+
3229
+ /* Column sizing helpers */
3230
+ .import-mapping-col-target {
3231
+ display: flex;
3232
+ flex-direction: column;
3233
+ gap: 1px;
3234
+ padding-right: 8px;
3235
+ }
3236
+
3237
+ .import-mapping-col-arrow {
3238
+ display: flex;
3239
+ align-items: center;
3240
+ justify-content: center;
3241
+ font-size: 0.65rem;
3242
+ color: #374151;
3243
+ }
3244
+
3245
+ .import-mapping-col-source {
3246
+ padding-left: 8px;
3247
+ }
3248
+
3249
+ /* Field name label */
3250
+ .import-mapping-field-name {
3251
+ font-size: 0.75rem;
3252
+ font-weight: 500;
3253
+ color: #374151; /* gray-700 — light mode */
3254
+ line-height: 1.3;
3255
+ }
3256
+
3257
+ body[data-theme='dark'] .import-mapping-field-name,
3258
+ .dark .import-mapping-field-name {
3259
+ color: #d1d5db; /* gray-300 — dark mode */
3260
+ }
3261
+
3262
+ /* Optional hint text below field name */
3263
+ .import-mapping-field-hint {
3264
+ font-size: 0.65rem;
3265
+ color: #6b7280; /* gray-500 — light mode */
3266
+ line-height: 1.2;
3267
+ }
3268
+
3269
+ body[data-theme='dark'] .import-mapping-field-hint,
3270
+ .dark .import-mapping-field-hint {
3271
+ color: #4b5563; /* gray-600 — dark mode */
3272
+ }
3273
+
3274
+ /* The select inside a mapping row — full width, compact */
3275
+ select.import-mapping-select {
3276
+ width: 100%;
3277
+ font-size: 0.72rem !important;
3278
+ padding-top: 3px !important;
3279
+ padding-bottom: 3px !important;
3280
+ }
3281
+
3282
+ /* Red border on required fields that are not yet mapped */
3283
+ select.import-mapping-select--error {
3284
+ border-color: #ef4444 !important;
3285
+ }
3286
+
3287
+ /* ── Orchestrator Import Modal: unified header + step-tab region ──
3288
+ The header background is applied via modalHeaderClass='import-modal-header'
3289
+ which lands directly on .flb--modal-header via ...attributes, bypassing
3290
+ any CSS cascade conflict with ember-ui's own modal.css rules.
3291
+ Dark mode : gray-800 (#1f2937)
3292
+ Light mode : gray-50 (#f9fafb) */
3293
+
3294
+ /* Modal header — class applied via modalHeaderClass option */
3295
+ .flb--modal-header.import-modal-header {
3296
+ background: #f9fafb !important; /* gray-50 — light mode */
3297
+ border-bottom: none !important;
3298
+ }
3299
+
3300
+ body[data-theme='dark'] .flb--modal-header.import-modal-header {
3301
+ background: #1f2937 !important; /* gray-800 — dark mode */
3302
+ border-bottom: none !important;
3303
+ }
3304
+
3305
+ /* Step tabs nav — must match the header background */
3306
+ .fleetops-order-import nav.import-step-tabs {
3307
+ background: #f9fafb; /* gray-50 — light mode */
3308
+ border-bottom: 1px solid #e5e7eb; /* gray-200 */
3309
+ }
3310
+
3311
+ body[data-theme='dark'] .fleetops-order-import nav.import-step-tabs {
3312
+ background: #1f2937; /* gray-800 — dark mode */
3313
+ border-bottom: 1px solid #374151; /* gray-700 subtle separator */
3314
+ }
3315
+
3316
+ /* ── Orchestrator Import Modal: modal body + step content layout ── */
3317
+
3318
+ /* The modal body is made flex so the step content div fills it, which in turn
3319
+ allows the download block to be pushed to the very bottom with margin-top:auto. */
3320
+ .fleetops-order-import .flb--modal-body {
3321
+ display: flex;
3322
+ flex-direction: column;
3323
+ min-height: 480px; /* consistent height across all steps */
3324
+ }
3325
+
3326
+ .fleetops-order-import .import-step-content {
3327
+ display: flex;
3328
+ flex-direction: column;
3329
+ flex: 1; /* fill all available body space */
3330
+ }
3331
+
3332
+ /* Upload step inner content — grows to fill available space above the download block */
3333
+ .fleetops-order-import .import-upload-content {
3334
+ flex: 1;
3335
+ }
3336
+
3337
+ /* ── Orchestrator Import Modal: download template InfoBlock ── */
3338
+
3339
+ /* The InfoBlock is placed inside the flex column; margin-top:auto pushes it
3340
+ to the bottom of the upload step regardless of the dropzone height. */
3341
+ .import-template-download {
3342
+ margin-top: auto;
3343
+ }
3344
+
3345
+ /* ── Button: trailing icon support (wrapperClass = btn-icon-right) ── */
3346
+
3347
+ /* When a Button is given @wrapperClass="btn-icon-right" the icon wrapper
3348
+ appears after the text label (trailing position). */
3349
+ .btn-wrapper.btn-icon-right .btn {
3350
+ flex-direction: row-reverse;
3351
+ }
3352
+
3353
+ .btn-wrapper.btn-icon-right .btn .btn-icon-wrapper {
3354
+ margin-right: 0;
3355
+ margin-left: 0.375rem;
3356
+ }
3357
+
3358
+ .btn-wrapper.btn-icon-right .btn .btn-icon-wrapper .svg-inline--fa {
3359
+ margin-right: 0 !important;
3360
+ }
3361
+
3362
+ /* ── Orchestrator Import Modal: preview table ── */
3363
+
3364
+ .import-preview-wrap {
3365
+ display: flex;
3366
+ flex-direction: column;
3367
+ gap: 0;
3368
+ }
3369
+
3370
+ .import-preview-summary {
3371
+ display: flex;
3372
+ align-items: center;
3373
+ justify-content: space-between;
3374
+ padding: 10px 16px;
3375
+ border-bottom: 1px solid #1f2937;
3376
+ font-size: 0.75rem;
3377
+ }
3378
+
3379
+ .import-preview-table-wrap {
3380
+ overflow: auto auto;
3381
+ max-height: 360px;
3382
+ }
3383
+
3384
+ .import-preview-table {
3385
+ width: 100%;
3386
+ border-collapse: collapse;
3387
+ font-size: 0.72rem;
3388
+ white-space: nowrap;
3389
+ }
3390
+
3391
+ .import-preview-table thead {
3392
+ position: sticky;
3393
+ top: 0;
3394
+ z-index: 5;
3395
+ background: #111827;
3396
+ }
3397
+
3398
+ body[data-theme='light'] .import-preview-table thead {
3399
+ background: #f3f4f6;
3400
+ }
3401
+
3402
+ .import-preview-table th {
3403
+ padding: 6px 10px;
3404
+ text-align: left;
3405
+ font-weight: 600;
3406
+ font-size: 0.65rem;
3407
+ text-transform: uppercase;
3408
+ letter-spacing: 0.06em;
3409
+ color: #4b5563;
3410
+ border-bottom: 1px solid #1f2937;
3411
+ }
3412
+
3413
+ body[data-theme='light'] .import-preview-table th {
3414
+ color: #6b7280;
3415
+ border-bottom-color: #e5e7eb;
3416
+ }
3417
+
3418
+ .import-preview-table td {
3419
+ padding: 5px 10px;
3420
+ color: #9ca3af;
3421
+ border-bottom: 1px solid #1f2937;
3422
+ max-width: 160px;
3423
+ overflow: hidden;
3424
+ text-overflow: ellipsis;
3425
+ }
3426
+
3427
+ body[data-theme='light'] .import-preview-table td {
3428
+ color: #374151;
3429
+ border-bottom-color: #e5e7eb;
3430
+ }
3431
+
3432
+ .import-preview-table tbody tr:last-child td {
3433
+ border-bottom: none;
3434
+ }
3435
+
3436
+ .import-preview-table tbody tr:hover td {
3437
+ background: rgba(255, 255, 255, 2%);
3438
+ }
3439
+
3440
+ body[data-theme='light'] .import-preview-table tbody tr:hover td {
3441
+ background: rgba(0, 0, 0, 2%);
3442
+ }
3443
+
3444
+ .import-preview-row--error td {
3445
+ background: rgba(239, 68, 68, 6%) !important;
3446
+ }
3447
+
3448
+ /* Address cell — allow wrapping for long addresses */
3449
+ .import-preview-addr {
3450
+ white-space: normal !important;
3451
+ min-width: 120px;
3452
+ max-width: 180px;
3453
+ line-height: 1.3;
3454
+ }
3455
+
3456
+ /* Status badges */
3457
+ .import-preview-badge {
3458
+ display: inline-flex;
3459
+ align-items: center;
3460
+ gap: 3px;
3461
+ padding: 1px 6px;
3462
+ border-radius: 4px;
3463
+ font-size: 0.65rem;
3464
+ font-weight: 600;
3465
+ white-space: nowrap;
3466
+ }
3467
+
3468
+ .import-preview-badge--blue {
3469
+ background: rgba(59, 130, 246, 15%);
3470
+ color: #60a5fa;
3471
+ }
3472
+
3473
+ .import-preview-badge--gray {
3474
+ background: rgba(107, 114, 128, 15%);
3475
+ color: #9ca3af;
3476
+ }
3477
+
3478
+ .import-preview-badge--green {
3479
+ background: rgba(16, 185, 129, 15%);
3480
+ color: #34d399;
3481
+ }
3482
+
3483
+ /* Row status indicator */
3484
+ .import-preview-status {
3485
+ display: inline-flex;
3486
+ align-items: center;
3487
+ gap: 3px;
3488
+ font-size: 0.7rem;
3489
+ font-weight: 500;
3490
+ }
3491
+
3492
+ .import-preview-status--ok {
3493
+ color: #34d399;
3494
+ }
3495
+
3496
+ .import-preview-status--error {
3497
+ color: #f87171;
3498
+ cursor: help;
3499
+ }
3500
+
3501
+ /* Warning strip at the bottom of the preview step */
3502
+ .import-preview-warning {
3503
+ display: flex;
3504
+ align-items: center;
3505
+ gap: 6px;
3506
+ padding: 8px 16px;
3507
+ border-top: 1px solid #1f2937;
3508
+ font-size: 0.72rem;
3509
+ color: #fbbf24;
3510
+ background: rgba(251, 191, 36, 6%);
3511
+ }