@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.
- package/addon/components/activity/form.hbs +2 -12
- package/addon/components/activity/logic-builder.hbs +1 -1
- package/addon/components/custom-entity/form.hbs +4 -20
- package/addon/components/device/form.hbs +3 -15
- package/addon/components/device/panel-header.hbs +13 -2
- package/addon/components/driver/details.hbs +33 -2
- package/addon/components/driver/form.hbs +42 -0
- package/addon/components/driver/panel-header.hbs +8 -1
- package/addon/components/driver/schedule.hbs +115 -76
- package/addon/components/driver/schedule.js +349 -157
- package/addon/components/driver-onboard-settings.hbs +2 -8
- package/addon/components/entity-field-editing-settings.hbs +2 -5
- package/addon/components/equipment/card.hbs +49 -0
- package/addon/components/equipment/card.js +6 -0
- package/addon/components/equipment/details.hbs +83 -44
- package/addon/components/equipment/form.hbs +111 -41
- package/addon/components/equipment/form.js +78 -10
- package/addon/components/equipment/panel-header.hbs +36 -0
- package/addon/components/equipment/panel-header.js +2 -0
- package/addon/components/fleet/driver-listing.hbs +3 -1
- package/addon/components/fleet/vehicle-listing.hbs +4 -7
- package/addon/components/fleet-panel/vehicle-listing.hbs +1 -6
- package/addon/components/fuel-report/form.hbs +1 -5
- package/addon/components/layout/fleet-ops-sidebar.hbs +43 -38
- package/addon/components/layout/fleet-ops-sidebar.js +103 -24
- package/addon/components/maintenance/cost-panel.hbs +176 -0
- package/addon/components/maintenance/cost-panel.js +241 -0
- package/addon/components/maintenance/details.hbs +123 -60
- package/addon/components/maintenance/form.hbs +138 -78
- package/addon/components/maintenance/form.js +131 -6
- package/addon/components/maintenance/panel-header.hbs +31 -0
- package/addon/components/maintenance/panel-header.js +2 -0
- package/addon/components/maintenance-schedule/details.hbs +260 -0
- package/addon/components/maintenance-schedule/details.js +158 -0
- package/addon/components/maintenance-schedule/form.hbs +287 -0
- package/addon/components/maintenance-schedule/form.js +199 -0
- package/addon/components/map/container.hbs +1 -1
- package/addon/components/map/drawer/device-event-listing.hbs +1 -1
- package/addon/components/map/drawer/driver-listing.hbs +1 -6
- package/addon/components/map/drawer/place-listing.hbs +1 -6
- package/addon/components/map/drawer/vehicle-listing.hbs +1 -6
- package/addon/components/map/drawer.hbs +8 -1
- package/addon/components/map/leaflet-live-map.hbs +2 -1
- package/addon/components/map/toolbar/visibility-control-panel.hbs +1 -1
- package/addon/components/map/toolbar.hbs +4 -29
- package/addon/components/modals/add-driver-shift.hbs +155 -0
- package/addon/components/modals/add-driver-shift.js +210 -0
- package/addon/components/modals/bulk-assign-orders.hbs +67 -0
- package/addon/components/modals/driver-shift.hbs +43 -0
- package/addon/components/modals/driver-shift.js +56 -0
- package/addon/components/modals/entity-form.hbs +5 -28
- package/addon/components/modals/orchestrator-import.hbs +351 -0
- package/addon/components/modals/orchestrator-import.js +807 -0
- package/addon/components/modals/order-config-new-status.hbs +1 -5
- package/addon/components/modals/scheduling-conflict.hbs +47 -0
- package/addon/components/modals/scheduling-conflict.js +53 -0
- package/addon/components/modals/send-work-order.hbs +91 -0
- package/addon/components/modals/send-work-order.js +3 -0
- package/addon/components/modals/service-area-form.hbs +1 -6
- package/addon/components/modals/set-driver-availability.hbs +50 -0
- package/addon/components/modals/set-driver-availability.js +57 -0
- package/addon/components/modals/update-order-activity.hbs +13 -9
- package/addon/components/modals/user-form.hbs +1 -5
- package/addon/components/modals/vehicle-form.hbs +17 -102
- package/addon/components/modals/vendor-form.hbs +15 -82
- package/addon/components/orchestrator/card-fields-settings.hbs +76 -0
- package/addon/components/orchestrator/card-fields-settings.js +134 -0
- package/addon/components/orchestrator/order-pool.hbs +264 -0
- package/addon/components/orchestrator/order-pool.js +394 -0
- package/addon/components/orchestrator/phase-builder.hbs +162 -0
- package/addon/components/orchestrator/phase-builder.js +162 -0
- package/addon/components/orchestrator/plan-viewer.hbs +278 -0
- package/addon/components/orchestrator/plan-viewer.js +342 -0
- package/addon/components/orchestrator/resource-panel.hbs +301 -0
- package/addon/components/orchestrator/resource-panel.js +106 -0
- package/addon/components/orchestrator-workbench.hbs +318 -0
- package/addon/components/orchestrator-workbench.js +1088 -0
- package/addon/components/order/details/custom-fields.hbs +10 -1
- package/addon/components/order/details/detail.hbs +37 -2
- package/addon/components/order/details/detail.js +0 -1
- package/addon/components/order/details/integrated-vendor-details.hbs +4 -4
- package/addon/components/order/details/notes.hbs +1 -7
- package/addon/components/order/details/route.hbs +1 -5
- package/addon/components/order/form/details.hbs +44 -10
- package/addon/components/order/form/details.js +57 -0
- package/addon/components/order/form/notes.hbs +1 -7
- package/addon/components/order/form/payload.hbs +1 -7
- package/addon/components/order/form/route.hbs +3 -15
- package/addon/components/order/header.hbs +1 -7
- package/addon/components/order/route-editor.hbs +4 -25
- package/addon/components/order/schedule-card.hbs +102 -95
- package/addon/components/order/schedule-card.js +8 -3
- package/addon/components/order-config-manager/details.hbs +2 -10
- package/addon/components/order-config-manager/entities.hbs +1 -7
- package/addon/components/order-config-manager.hbs +1 -6
- package/addon/components/part/card.hbs +49 -0
- package/addon/components/part/card.js +6 -0
- package/addon/components/part/details.hbs +102 -56
- package/addon/components/part/form.hbs +131 -56
- package/addon/components/part/form.js +78 -11
- package/addon/components/part/panel-header.hbs +36 -0
- package/addon/components/part/panel-header.js +2 -0
- package/addon/components/place/form.hbs +1 -7
- package/addon/components/sensor/details.hbs +1 -1
- package/addon/components/sensor/form.hbs +5 -3
- package/addon/components/sensor/panel-header.hbs +8 -1
- package/addon/components/service-area/form.hbs +1 -6
- package/addon/components/service-rate/form.hbs +12 -60
- package/addon/components/telematic/form.hbs +6 -2
- package/addon/components/vehicle/details/maintenance-history.hbs +42 -0
- package/addon/components/vehicle/details/maintenance-history.js +32 -0
- package/addon/components/vehicle/details/schedules.hbs +40 -0
- package/addon/components/vehicle/details/schedules.js +32 -0
- package/addon/components/vehicle/details/work-orders.hbs +42 -0
- package/addon/components/vehicle/details/work-orders.js +32 -0
- package/addon/components/vehicle/details.hbs +52 -0
- package/addon/components/vehicle/form.hbs +51 -0
- package/addon/components/vehicle/panel-header.hbs +19 -49
- package/addon/components/warranty/details.hbs +3 -2
- package/addon/components/warranty/form.hbs +3 -17
- package/addon/components/work-order/details.hbs +135 -40
- package/addon/components/work-order/form.hbs +178 -45
- package/addon/components/work-order/form.js +197 -4
- package/addon/components/work-order/panel-header.hbs +31 -0
- package/addon/components/work-order/panel-header.js +2 -0
- package/addon/controllers/connectivity/devices/index/details.js +1 -1
- package/addon/controllers/maintenance/equipment/index/details/index.js +0 -1
- package/addon/controllers/maintenance/equipment/index/details.js +36 -1
- package/addon/controllers/maintenance/equipment/index/edit.js +56 -1
- package/addon/controllers/maintenance/equipment/index/new.js +32 -1
- package/addon/controllers/maintenance/equipment/index.js +127 -113
- package/addon/controllers/maintenance/maintenances/index/details/index.js +3 -0
- package/addon/controllers/maintenance/maintenances/index/details.js +54 -0
- package/addon/controllers/maintenance/maintenances/index/edit.js +68 -0
- package/addon/controllers/maintenance/maintenances/index/new.js +34 -0
- package/addon/controllers/maintenance/maintenances/index.js +191 -0
- package/addon/controllers/maintenance/parts/index/details/index.js +0 -1
- package/addon/controllers/maintenance/parts/index/details.js +36 -1
- package/addon/controllers/maintenance/parts/index/edit.js +56 -1
- package/addon/controllers/maintenance/parts/index/new.js +32 -1
- package/addon/controllers/maintenance/parts/index.js +135 -113
- package/addon/controllers/maintenance/schedules/index/details.js +115 -0
- package/addon/controllers/maintenance/schedules/index/edit.js +41 -0
- package/addon/controllers/maintenance/schedules/index/new.js +33 -0
- package/addon/controllers/maintenance/schedules/index.js +280 -0
- package/addon/controllers/maintenance/work-orders/index/details.js +41 -1
- package/addon/controllers/maintenance/work-orders/index/edit.js +67 -1
- package/addon/controllers/maintenance/work-orders/index/new.js +43 -1
- package/addon/controllers/maintenance/work-orders/index.js +105 -113
- package/addon/controllers/management/drivers/index/details.js +6 -1
- package/addon/controllers/management/vehicles/index/details.js +65 -0
- package/addon/controllers/management/vehicles/index.js +18 -0
- package/addon/controllers/operations/orchestrator.js +10 -0
- package/addon/controllers/operations/orders/index.js +6 -0
- package/addon/controllers/operations/scheduler/fleet-schedule.js +341 -0
- package/addon/controllers/operations/scheduler/index.js +799 -275
- package/addon/controllers/operations/scheduler.js +21 -0
- package/addon/controllers/settings/orchestrator.js +70 -0
- package/addon/controllers/settings/scheduling.js +155 -0
- package/addon/extension.js +19 -0
- package/addon/instance-initializers/register-vroom-allocation.js +27 -0
- package/addon/models/maintenance-schedule.js +61 -0
- package/addon/routes/maintenance/equipment/index/details.js +27 -1
- package/addon/routes/maintenance/equipment/index/edit.js +27 -1
- package/addon/routes/maintenance/maintenances/index/details/index.js +3 -0
- package/addon/routes/maintenance/maintenances/index/details.js +29 -0
- package/addon/routes/maintenance/maintenances/index/edit.js +29 -0
- package/addon/routes/maintenance/maintenances/index/new.js +3 -0
- package/addon/routes/maintenance/maintenances/index.js +23 -0
- package/addon/routes/maintenance/maintenances.js +3 -0
- package/addon/routes/maintenance/parts/index/details.js +27 -1
- package/addon/routes/maintenance/parts/index/edit.js +27 -1
- package/addon/routes/maintenance/schedules/index/details/index.js +2 -0
- package/addon/routes/maintenance/schedules/index/details/work-orders.js +11 -0
- package/addon/routes/maintenance/schedules/index/details.js +25 -0
- package/addon/routes/maintenance/schedules/index/edit.js +25 -0
- package/addon/routes/maintenance/schedules/index/new.js +2 -0
- package/addon/routes/maintenance/schedules/index.js +21 -0
- package/addon/routes/maintenance/schedules.js +2 -0
- package/addon/routes/maintenance/work-orders/index/details.js +27 -1
- package/addon/routes/maintenance/work-orders/index/edit.js +27 -1
- package/addon/routes/management/vehicles/index/details/maintenance-history.js +3 -0
- package/addon/routes/management/vehicles/index/details/schedules.js +3 -0
- package/addon/routes/management/vehicles/index/details/work-orders.js +3 -0
- package/addon/routes/operations/orchestrator.js +23 -0
- package/addon/routes/operations/scheduler/fleet-schedule.js +28 -0
- package/addon/routes/operations/scheduler/index.js +48 -26
- package/addon/routes/operations/scheduler.js +14 -1
- package/addon/routes/settings/orchestrator.js +27 -0
- package/addon/routes/settings/scheduling.js +3 -0
- package/addon/routes.js +31 -1
- package/addon/services/driver-actions.js +40 -7
- package/addon/services/driver-scheduling.js +4 -1
- package/addon/services/equipment-actions.js +15 -5
- package/addon/services/leaflet-map-manager.js +14 -6
- package/addon/services/maintenance-actions.js +17 -14
- package/addon/services/maintenance-schedule-actions.js +118 -0
- package/addon/services/orchestration-engine-interface.js +49 -0
- package/addon/services/orchestration-engine.js +74 -0
- package/addon/services/order-actions.js +15 -0
- package/addon/services/order-allocation.js +116 -0
- package/addon/services/part-actions.js +12 -2
- package/addon/services/scheduling.js +316 -0
- package/addon/services/vehicle-actions.js +70 -7
- package/addon/services/vroom-allocation-engine.js +45 -0
- package/addon/services/work-order-actions.js +79 -0
- package/addon/styles/fleetops-engine.css +1658 -0
- package/addon/templates/analytics/reports/index/edit.hbs +1 -1
- package/addon/templates/analytics/reports/index/new.hbs +1 -1
- package/addon/templates/application.hbs +6 -1
- package/addon/templates/connectivity/devices/index/details/events.hbs +0 -1
- package/addon/templates/connectivity/devices.hbs +0 -1
- package/addon/templates/connectivity/events/index/details.hbs +0 -1
- package/addon/templates/connectivity/events.hbs +0 -1
- package/addon/templates/connectivity/sensors.hbs +0 -1
- package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
- package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
- package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
- package/addon/templates/connectivity/telematics.hbs +0 -1
- package/addon/templates/connectivity/tracking.hbs +0 -1
- package/addon/templates/connectivity.hbs +0 -1
- package/addon/templates/maintenance/equipment/index/details/index.hbs +1 -2
- package/addon/templates/maintenance/equipment/index/details.hbs +15 -2
- package/addon/templates/maintenance/equipment/index/edit.hbs +12 -2
- package/addon/templates/maintenance/equipment/index/new.hbs +1 -2
- package/addon/templates/maintenance/equipment/index.hbs +48 -13
- package/addon/templates/maintenance/equipment.hbs +0 -1
- package/addon/templates/maintenance/maintenances/index/details/index.hbs +1 -0
- package/addon/templates/maintenance/maintenances/index/details.hbs +15 -0
- package/addon/templates/maintenance/maintenances/index/edit.hbs +12 -0
- package/addon/templates/maintenance/maintenances/index/new.hbs +11 -0
- package/addon/templates/maintenance/maintenances/index.hbs +14 -0
- package/addon/templates/maintenance/maintenances.hbs +1 -0
- package/addon/templates/maintenance/parts/index/details/index.hbs +1 -2
- package/addon/templates/maintenance/parts/index/details.hbs +15 -2
- package/addon/templates/maintenance/parts/index/edit.hbs +12 -2
- package/addon/templates/maintenance/parts/index/new.hbs +1 -2
- package/addon/templates/maintenance/parts/index.hbs +48 -13
- package/addon/templates/maintenance/parts.hbs +0 -1
- package/addon/templates/maintenance/schedules/index/details/index.hbs +1 -0
- package/addon/templates/maintenance/schedules/index/details/work-orders.hbs +39 -0
- package/addon/templates/maintenance/schedules/index/details.hbs +14 -0
- package/addon/templates/maintenance/schedules/index/edit.hbs +12 -0
- package/addon/templates/maintenance/schedules/index/new.hbs +11 -0
- package/addon/templates/maintenance/schedules/index.hbs +40 -0
- package/addon/templates/maintenance/schedules.hbs +1 -0
- package/addon/templates/maintenance/work-orders/index/details.hbs +2 -1
- package/addon/templates/maintenance/work-orders/index/edit.hbs +2 -4
- package/addon/templates/maintenance/work-orders/index/new.hbs +1 -2
- package/addon/templates/maintenance/work-orders.hbs +0 -1
- package/addon/templates/management/contacts/customers/edit.hbs +1 -2
- package/addon/templates/management/contacts/customers/new.hbs +1 -2
- package/addon/templates/management/contacts/customers.hbs +1 -1
- package/addon/templates/management/contacts/index/edit.hbs +1 -2
- package/addon/templates/management/contacts/index/new.hbs +1 -2
- package/addon/templates/management/drivers/index/details/orders.hbs +0 -1
- package/addon/templates/management/drivers/index/edit.hbs +1 -2
- package/addon/templates/management/drivers/index/new.hbs +1 -2
- package/addon/templates/management/fleets/index/edit.hbs +1 -2
- package/addon/templates/management/fleets/index/new.hbs +1 -2
- package/addon/templates/management/fleets/index.hbs +1 -2
- package/addon/templates/management/fuel-reports/index/edit.hbs +1 -2
- package/addon/templates/management/fuel-reports/index/new.hbs +1 -2
- package/addon/templates/management/fuel-reports/index.hbs +1 -2
- package/addon/templates/management/issues/index/edit.hbs +1 -2
- package/addon/templates/management/issues/index/new.hbs +1 -2
- package/addon/templates/management/issues/index.hbs +1 -2
- package/addon/templates/management/places/index/details/activity.hbs +0 -1
- package/addon/templates/management/places/index/details/comments.hbs +0 -1
- package/addon/templates/management/places/index/details/documents.hbs +0 -1
- package/addon/templates/management/places/index/details/map.hbs +0 -1
- package/addon/templates/management/places/index/details/operations.hbs +0 -1
- package/addon/templates/management/places/index/details/performance.hbs +0 -1
- package/addon/templates/management/places/index/details/rules.hbs +0 -1
- package/addon/templates/management/vehicles/index/details/equipment.hbs +0 -1
- package/addon/templates/management/vehicles/index/details/maintenance-history.hbs +2 -0
- package/addon/templates/management/vehicles/index/details/schedules.hbs +2 -0
- package/addon/templates/management/vehicles/index/details/work-orders.hbs +2 -0
- package/addon/templates/management/vehicles/index/details.hbs +1 -1
- package/addon/templates/management/vehicles/index/edit.hbs +1 -2
- package/addon/templates/management/vehicles/index/new.hbs +1 -2
- package/addon/templates/management/vendors/index/edit.hbs +1 -2
- package/addon/templates/management/vendors/index/new.hbs +1 -2
- package/addon/templates/management/vendors/index.hbs +1 -2
- package/addon/templates/management/vendors/integrated.hbs +1 -2
- package/addon/templates/operations/orchestrator.hbs +1 -0
- package/addon/templates/operations/orders/index.hbs +6 -1
- package/addon/templates/operations/scheduler/fleet-schedule.hbs +41 -0
- package/addon/templates/operations/scheduler/index.hbs +147 -88
- package/addon/templates/operations/scheduler.hbs +7 -1
- package/addon/templates/settings/avatars.hbs +1 -1
- package/addon/templates/settings/orchestrator.hbs +65 -0
- package/addon/templates/settings/payments/index.hbs +1 -5
- package/addon/templates/settings/scheduling.hbs +82 -0
- package/addon/utils/create-full-calendar-event-from-order.js +52 -14
- package/addon/utils/create-full-calendar-event-from-schedule-item.js +50 -0
- package/addon/utils/fleet-ops-options.js +254 -0
- package/addon/utils/route-colors.js +99 -0
- package/addon/utils/to-calendar-date.js +70 -0
- package/app/components/driver/schedule.js +1 -0
- package/app/components/maintenance/cost-panel.js +1 -0
- package/app/components/maintenance/panel-header.js +1 -0
- package/app/components/maintenance-schedule/details.js +1 -0
- package/app/components/maintenance-schedule/form.js +1 -0
- package/app/components/modals/add-driver-shift.js +1 -0
- package/app/components/modals/bulk-assign-orders.js +1 -0
- package/app/components/modals/driver-shift.js +1 -0
- package/app/components/modals/orchestrator-import.js +1 -0
- package/app/components/modals/scheduling-conflict.js +1 -0
- package/app/components/modals/send-work-order.js +1 -0
- package/app/components/modals/set-driver-availability.js +1 -0
- package/app/components/orchestrator/card-fields-settings.js +1 -0
- package/app/components/orchestrator/order-pool.js +1 -0
- package/app/components/orchestrator/phase-builder.js +1 -0
- package/app/components/orchestrator/plan-viewer.js +1 -0
- package/app/components/orchestrator/resource-panel.js +1 -0
- package/app/components/orchestrator-workbench.js +1 -0
- package/app/components/vehicle/details/maintenance-history.js +1 -0
- package/app/components/vehicle/details/schedules.js +1 -0
- package/app/components/vehicle/details/work-orders.js +1 -0
- package/app/controllers/operations/orchestrator.js +1 -0
- package/app/controllers/settings/orchestrator.js +1 -0
- package/app/controllers/settings/scheduling.js +1 -0
- package/app/routes/operations/orchestrator.js +1 -0
- package/app/routes/settings/orchestrator.js +1 -0
- package/app/routes/settings/scheduling.js +1 -0
- package/app/services/maintenance-schedule-actions.js +1 -0
- package/app/services/orchestration-engine-interface.js +1 -0
- package/app/services/orchestration-engine.js +1 -0
- package/app/services/order-allocation.js +1 -0
- package/app/services/scheduling.js +1 -0
- package/app/services/vroom-allocation-engine.js +1 -0
- package/app/templates/settings/scheduling.js +1 -0
- package/app/utils/create-full-calendar-event-from-schedule-item.js +1 -0
- package/app/utils/route-colors.js +1 -0
- package/composer.json +4 -2
- package/extension.json +1 -1
- package/package.json +6 -5
- package/server/config/fleetops.php +20 -1
- package/server/migrations/2025_08_28_054927_create_parts_table.php +2 -2
- package/server/migrations/2025_08_28_054932_add_public_id_to_maintenance_tables.php +45 -0
- package/server/migrations/2025_09_01_000001_create_maintenance_schedules_table.php +88 -0
- package/server/migrations/2026_04_01_000001_fix_monetary_columns_in_parts_table.php +48 -0
- package/server/migrations/2026_04_01_000003_add_photo_uuid_to_equipment_and_parts_tables.php +61 -0
- package/server/migrations/2026_04_01_000004_add_public_id_to_equipments_table.php +38 -0
- package/server/migrations/2026_04_01_000005_add_missing_columns_to_parts_table.php +67 -0
- package/server/migrations/2026_04_04_000001_add_reminder_offsets_to_maintenance_schedules.php +44 -0
- package/server/migrations/2026_04_08_000001_add_orchestrator_columns_to_vehicles_table.php +53 -0
- package/server/migrations/2026_04_08_000002_add_orchestrator_columns_to_drivers_table.php +41 -0
- package/server/migrations/2026_04_08_000003_add_orchestrator_columns_to_orders_table.php +38 -0
- package/server/migrations/2026_04_08_000004_add_orchestrator_columns_to_payloads_table.php +38 -0
- package/server/migrations/2026_04_08_000005_add_orchestrator_columns_to_waypoints_table.php +38 -0
- package/server/migrations/2026_04_09_000001_create_manifests_table.php +48 -0
- package/server/migrations/2026_04_09_000002_create_manifest_stops_table.php +48 -0
- package/server/migrations/2026_04_09_000003_add_manifest_uuid_to_orders_table.php +28 -0
- package/server/migrations/2026_04_13_000001_add_pod_notes_columns_to_waypoints_table.php +39 -0
- package/server/migrations/2026_04_14_000001_drop_redundant_capacity_columns_from_payloads_table.php +42 -0
- package/server/migrations/2026_04_14_000002_rename_capacity_columns_on_vehicles_table.php +48 -0
- package/server/resources/views/mail/maintenance-schedule-reminder.blade.php +59 -0
- package/server/resources/views/mail/work-order-dispatched.blade.php +67 -0
- package/server/src/Auth/Schemas/FleetOps.php +44 -0
- package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +150 -0
- package/server/src/Console/Commands/SendMaintenanceReminders.php +128 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +15 -2
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +18 -2
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +1 -0
- package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +27 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +9 -2
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +165 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +304 -0
- package/server/src/Http/Controllers/Internal/v1/ManifestController.php +138 -0
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +975 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +42 -0
- package/server/src/Http/Controllers/Internal/v1/PartController.php +27 -0
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +118 -0
- package/server/src/Http/Controllers/Internal/v1/Traits/DriverSchedulingTrait.php +214 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +68 -0
- package/server/src/Http/Resources/v1/Driver.php +1 -0
- package/server/src/Http/Resources/v1/Maintenance.php +138 -0
- package/server/src/Http/Resources/v1/MaintenanceSchedule.php +137 -0
- package/server/src/Http/Resources/v1/Orchestrator/Order.php +116 -0
- package/server/src/Http/Resources/v1/Order.php +7 -4
- package/server/src/Http/Resources/v1/Waypoint.php +7 -0
- package/server/src/Http/Resources/v1/WorkOrder.php +136 -0
- package/server/src/Imports/EquipmentImport.php +32 -0
- package/server/src/Imports/MaintenanceImport.php +32 -0
- package/server/src/Imports/MaintenanceScheduleImport.php +32 -0
- package/server/src/Imports/PartImport.php +32 -0
- package/server/src/Imports/WorkOrderImport.php +32 -0
- package/server/src/Jobs/ProcessAllocationJob.php +119 -0
- package/server/src/Listeners/HandleDeliveryCompletion.php +47 -0
- package/server/src/Listeners/NotifyDriverOnShiftChange.php +63 -0
- package/server/src/Mail/MaintenanceScheduleReminder.php +68 -0
- package/server/src/Mail/WorkOrderDispatched.php +58 -0
- package/server/src/Models/Asset.php +2 -2
- package/server/src/Models/Device.php +1 -1
- package/server/src/Models/Driver.php +82 -4
- package/server/src/Models/Equipment.php +62 -2
- package/server/src/Models/Maintenance.php +127 -9
- package/server/src/Models/MaintenanceSchedule.php +353 -0
- package/server/src/Models/Manifest.php +214 -0
- package/server/src/Models/ManifestStop.php +162 -0
- package/server/src/Models/Order.php +70 -0
- package/server/src/Models/OrderConfig.php +5 -2
- package/server/src/Models/Part.php +69 -3
- package/server/src/Models/Place.php +1 -1
- package/server/src/Models/Sensor.php +1 -1
- package/server/src/Models/ServiceQuote.php +1 -1
- package/server/src/Models/Vehicle.php +18 -1
- package/server/src/Models/Warranty.php +1 -1
- package/server/src/Models/Waypoint.php +7 -1
- package/server/src/Models/WorkOrder.php +122 -12
- package/server/src/Notifications/DriverShiftChanged.php +110 -0
- package/server/src/Observers/WorkOrderObserver.php +107 -0
- package/server/src/Orchestration/Contracts/OrchestrationEngineInterface.php +63 -0
- package/server/src/Orchestration/Engines/DriverAssignmentEngine.php +265 -0
- package/server/src/Orchestration/Engines/GreedyOrchestrationEngine.php +155 -0
- package/server/src/Orchestration/Engines/RouteSequencingEngine.php +272 -0
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +192 -0
- package/server/src/Orchestration/OrchestrationEngineRegistry.php +83 -0
- package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +380 -0
- package/server/src/Providers/EventServiceProvider.php +7 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +42 -15
- package/server/src/routes.php +65 -4
- package/translations/ar-ae.yml +44 -12
- package/translations/bg-bg.yaml +51 -10
- package/translations/en-us.yaml +444 -1
- package/translations/fr-fr.yaml +51 -10
- package/translations/mn-mn.yaml +51 -10
- package/translations/pt-br.yaml +51 -10
- package/translations/ru-ru.yaml +51 -10
- package/translations/vi-vn.yaml +48 -12
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { action } from '@ember/object';
|
|
4
|
+
import { inject as service } from '@ember/service';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Orchestrator::PhaseBuilder
|
|
8
|
+
*
|
|
9
|
+
* Allows dispatchers to compose a multi-phase orchestration run.
|
|
10
|
+
* Each phase is a discrete step: a mode (Assign Vehicles, Assign Drivers,
|
|
11
|
+
* Optimize Routes) with its own constraint options and resource/order filters.
|
|
12
|
+
*
|
|
13
|
+
* Phases are executed in sequence. The dispatcher can run all phases at once
|
|
14
|
+
* or step through them manually.
|
|
15
|
+
*
|
|
16
|
+
* @arg phases - Array of phase objects (managed externally)
|
|
17
|
+
* @arg availableEngines - Array of { id, name } engine options
|
|
18
|
+
* @arg onPhasesChange - Action(phases) — called when phases array changes
|
|
19
|
+
* @arg onRunPhases - Action(phases) — called when "Run" is clicked
|
|
20
|
+
*/
|
|
21
|
+
export default class OrchestratorPhaseBuilderComponent extends Component {
|
|
22
|
+
@service intl;
|
|
23
|
+
|
|
24
|
+
/** Index of the phase currently being edited in the editor panel. */
|
|
25
|
+
@tracked editingIndex = null;
|
|
26
|
+
|
|
27
|
+
/** Draft copy of the phase being edited. */
|
|
28
|
+
@tracked draftPhase = null;
|
|
29
|
+
|
|
30
|
+
get modeOptions() {
|
|
31
|
+
return [
|
|
32
|
+
{ value: 'assign_vehicles', label: this.intl.t('orchestrator.mode-assign-vehicles') },
|
|
33
|
+
{ value: 'assign_drivers', label: this.intl.t('orchestrator.mode-assign-drivers') },
|
|
34
|
+
{ value: 'optimize_routes', label: this.intl.t('orchestrator.mode-optimize-routes') },
|
|
35
|
+
{ value: 'allocate', label: this.intl.t('orchestrator.mode-allocate') },
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get orderStatusOptions() {
|
|
40
|
+
return [
|
|
41
|
+
{ value: 'created', label: this.intl.t('orchestrator.status-created') },
|
|
42
|
+
{ value: 'dispatched', label: this.intl.t('orchestrator.status-dispatched') },
|
|
43
|
+
{ value: 'started', label: this.intl.t('orchestrator.status-started') },
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_defaultPhase(mode = 'assign_vehicles') {
|
|
48
|
+
return {
|
|
49
|
+
id: crypto.randomUUID(),
|
|
50
|
+
mode,
|
|
51
|
+
label: this.intl.t(`orchestrator.mode-${mode.replace(/_/g, '-')}`),
|
|
52
|
+
engine: 'greedy',
|
|
53
|
+
orderStatuses: ['created'],
|
|
54
|
+
balanceWorkload: false,
|
|
55
|
+
respectSkills: true,
|
|
56
|
+
respectCapacity: true,
|
|
57
|
+
returnToDepot: false,
|
|
58
|
+
autoCommit: false,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@action addPhase() {
|
|
63
|
+
const newPhase = this._defaultPhase('assign_vehicles');
|
|
64
|
+
const phases = [...(this.args.phases ?? []), newPhase];
|
|
65
|
+
this.args.onPhasesChange?.(phases);
|
|
66
|
+
this.editingIndex = phases.length - 1;
|
|
67
|
+
this.draftPhase = { ...newPhase };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@action removePhase(index) {
|
|
71
|
+
const phases = (this.args.phases ?? []).filter((_, i) => i !== index);
|
|
72
|
+
this.args.onPhasesChange?.(phases);
|
|
73
|
+
if (this.editingIndex === index) {
|
|
74
|
+
this.editingIndex = null;
|
|
75
|
+
this.draftPhase = null;
|
|
76
|
+
} else if (this.editingIndex > index) {
|
|
77
|
+
this.editingIndex = this.editingIndex - 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@action movePhaseUp(index) {
|
|
82
|
+
if (index === 0) return;
|
|
83
|
+
const phases = [...(this.args.phases ?? [])];
|
|
84
|
+
[phases[index - 1], phases[index]] = [phases[index], phases[index - 1]];
|
|
85
|
+
this.args.onPhasesChange?.(phases);
|
|
86
|
+
if (this.editingIndex === index) this.editingIndex = index - 1;
|
|
87
|
+
else if (this.editingIndex === index - 1) this.editingIndex = index;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@action movePhaseDown(index) {
|
|
91
|
+
const phases = this.args.phases ?? [];
|
|
92
|
+
if (index >= phases.length - 1) return;
|
|
93
|
+
const updated = [...phases];
|
|
94
|
+
[updated[index], updated[index + 1]] = [updated[index + 1], updated[index]];
|
|
95
|
+
this.args.onPhasesChange?.(updated);
|
|
96
|
+
if (this.editingIndex === index) this.editingIndex = index + 1;
|
|
97
|
+
else if (this.editingIndex === index + 1) this.editingIndex = index;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@action editPhase(index) {
|
|
101
|
+
this.editingIndex = index;
|
|
102
|
+
this.draftPhase = { ...(this.args.phases ?? [])[index] };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@action closePhasEditor() {
|
|
106
|
+
this.editingIndex = null;
|
|
107
|
+
this.draftPhase = null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@action saveDraftPhase() {
|
|
111
|
+
if (this.editingIndex === null || !this.draftPhase) return;
|
|
112
|
+
const phases = [...(this.args.phases ?? [])];
|
|
113
|
+
phases[this.editingIndex] = { ...this.draftPhase };
|
|
114
|
+
this.args.onPhasesChange?.(phases);
|
|
115
|
+
this.editingIndex = null;
|
|
116
|
+
this.draftPhase = null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@action setDraftMode(mode) {
|
|
120
|
+
this.draftPhase = {
|
|
121
|
+
...this.draftPhase,
|
|
122
|
+
mode,
|
|
123
|
+
label: this.intl.t(`orchestrator.mode-${mode.replace(/_/g, '-')}`),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@action setDraftEngine(engine) {
|
|
128
|
+
this.draftPhase = { ...this.draftPhase, engine };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@action toggleDraftOrderStatus(status) {
|
|
132
|
+
const current = this.draftPhase.orderStatuses ?? [];
|
|
133
|
+
const updated = current.includes(status) ? current.filter((s) => s !== status) : [...current, status];
|
|
134
|
+
this.draftPhase = { ...this.draftPhase, orderStatuses: updated };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@action setDraftOption(key, value) {
|
|
138
|
+
this.draftPhase = { ...this.draftPhase, [key]: value };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@action setDraftLabel(event) {
|
|
142
|
+
this.draftPhase = { ...this.draftPhase, label: event.target.value };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
get isEditing() {
|
|
146
|
+
return this.editingIndex !== null && this.draftPhase !== null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
modeLabel(mode) {
|
|
150
|
+
return this.modeOptions.find((m) => m.value === mode)?.label ?? mode;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
modeIcon(mode) {
|
|
154
|
+
const icons = {
|
|
155
|
+
assign_vehicles: 'truck',
|
|
156
|
+
assign_drivers: 'user',
|
|
157
|
+
optimize_routes: 'route',
|
|
158
|
+
allocate: 'bolt',
|
|
159
|
+
};
|
|
160
|
+
return icons[mode] ?? 'cog';
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
{{! Orchestrator::PlanViewer — Post-run route cards with stop sequences and EventCalendar timeline }}
|
|
2
|
+
<div class="plan-viewer flex flex-col h-full overflow-hidden">
|
|
3
|
+
|
|
4
|
+
{{! ── Header: summary + tab switcher ── }}
|
|
5
|
+
<div class="px-3 py-2 border-b dark:border-gray-700 flex-shrink-0">
|
|
6
|
+
<div class="flex items-center justify-between mb-2">
|
|
7
|
+
<span class="text-xs font-medium uppercase tracking-wide dark:text-gray-400">
|
|
8
|
+
{{t "orchestrator.proposed-routes"}}
|
|
9
|
+
({{@planByVehicle.length}})
|
|
10
|
+
</span>
|
|
11
|
+
{{#if (eq this.activeTab "routes")}}
|
|
12
|
+
<button type="button" class="text-xs text-blue-400 hover:text-blue-300 transition-colors" {{on "click" this.toggleExpandAll}}>
|
|
13
|
+
{{if this.allExpanded (t "orchestrator.collapse-all") (t "orchestrator.expand-all")}}
|
|
14
|
+
</button>
|
|
15
|
+
{{else if (eq this.activeTab "timeline")}}
|
|
16
|
+
{{#if this.timelineDateRange}}
|
|
17
|
+
<span class="text-xs text-gray-400 dark:text-gray-500">{{this.timelineDateRange}}</span>
|
|
18
|
+
{{/if}}
|
|
19
|
+
{{/if}}
|
|
20
|
+
</div>
|
|
21
|
+
{{! Tab bar }}
|
|
22
|
+
<div class="flex gap-1">
|
|
23
|
+
<button
|
|
24
|
+
type="button"
|
|
25
|
+
class="px-2.5 py-1 rounded text-xs font-medium transition-colors
|
|
26
|
+
{{if (eq this.activeTab 'routes') 'bg-indigo-600 text-white' 'text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'}}"
|
|
27
|
+
{{on "click" (fn this.setTab "routes")}}
|
|
28
|
+
>
|
|
29
|
+
<FaIcon @icon="route" @size="xs" class="mr-1" />{{t "orchestrator.tab-routes"}}
|
|
30
|
+
</button>
|
|
31
|
+
<button
|
|
32
|
+
type="button"
|
|
33
|
+
class="px-2.5 py-1 rounded text-xs font-medium transition-colors
|
|
34
|
+
{{if (eq this.activeTab 'timeline') 'bg-indigo-600 text-white' 'text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'}}"
|
|
35
|
+
{{on "click" (fn this.setTab "timeline")}}
|
|
36
|
+
>
|
|
37
|
+
<FaIcon @icon="calendar-alt" @size="xs" class="mr-1" />{{t "orchestrator.tab-timeline"}}
|
|
38
|
+
</button>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
{{! Unassigned warning banner }}
|
|
43
|
+
{{#if this.hasUnassigned}}
|
|
44
|
+
<div class="mx-3 mt-2 px-3 py-2 rounded bg-yellow-900/30 border border-yellow-700 text-yellow-400 text-xs flex-shrink-0">
|
|
45
|
+
<FaIcon @icon="exclamation-triangle" class="mr-1" />
|
|
46
|
+
{{t "orchestrator.unassigned-warning" count=@unassignedAfterRun.length}}
|
|
47
|
+
</div>
|
|
48
|
+
{{/if}}
|
|
49
|
+
|
|
50
|
+
{{! Run message banner }}
|
|
51
|
+
{{#if @runMessage}}
|
|
52
|
+
<div class="flex items-start gap-2 mx-3 mt-2 px-3 py-2 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 rounded flex-shrink-0">
|
|
53
|
+
<FaIcon @icon="exclamation-triangle" class="mt-0.5 flex-shrink-0 text-amber-500" @size="sm" />
|
|
54
|
+
<p class="flex-1 text-xs text-amber-800 dark:text-amber-200">{{@runMessage}}</p>
|
|
55
|
+
<button type="button" class="flex-shrink-0 text-amber-400 hover:text-amber-600" {{on "click" @onDismissMessage}}>
|
|
56
|
+
<FaIcon @icon="times" @size="xs" />
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
{{/if}}
|
|
60
|
+
|
|
61
|
+
{{! ── ROUTES TAB ── }}
|
|
62
|
+
{{#if (eq this.activeTab "routes")}}
|
|
63
|
+
<div class="flex-1 overflow-y-auto">
|
|
64
|
+
{{#each @planByVehicle as |group|}}
|
|
65
|
+
{{! vehicle-route-card }}
|
|
66
|
+
<div
|
|
67
|
+
class="vehicle-route-card mx-3 my-2 rounded border dark:border-gray-600 dark:bg-gray-800 overflow-hidden"
|
|
68
|
+
data-vehicle-id={{group.vehicle.public_id}}
|
|
69
|
+
{{on "dragover" @onDragOver}}
|
|
70
|
+
{{on "drop" (fn @onDropOnVehicle group.vehicle.public_id group.driver.public_id)}}
|
|
71
|
+
>
|
|
72
|
+
{{! Vehicle / driver header — click to expand/collapse
|
|
73
|
+
When a driver phase ran (@hasDriverPhase), show driver as the primary
|
|
74
|
+
label with vehicle as the secondary sub-label. Otherwise show vehicle
|
|
75
|
+
as primary with driver as sub-label (legacy behaviour). }}
|
|
76
|
+
<div
|
|
77
|
+
class="flex items-center px-3 py-2 border-b dark:border-gray-700 cursor-pointer"
|
|
78
|
+
style={{html-safe (concat "border-left: 3px solid " group.routeColor)}}
|
|
79
|
+
{{on "click" (fn this.toggleCard group.vehicle.public_id)}}
|
|
80
|
+
>
|
|
81
|
+
{{#if (and @hasDriverPhase group.driver)}}
|
|
82
|
+
<FaIcon @icon="user" class="mr-2 text-green-400 flex-shrink-0" />
|
|
83
|
+
{{else}}
|
|
84
|
+
<FaIcon @icon="truck" class="mr-2 text-blue-400 flex-shrink-0" />
|
|
85
|
+
{{/if}}
|
|
86
|
+
<div class="flex-1 min-w-0">
|
|
87
|
+
{{#if (and @hasDriverPhase group.driver)}}
|
|
88
|
+
{{! Driver-phase run: driver is primary, vehicle is secondary }}
|
|
89
|
+
<div class="text-xs font-semibold dark:text-white truncate">{{group.driver.name}}</div>
|
|
90
|
+
<div class="text-xs text-gray-400 truncate">{{group.vehicle.display_name}}</div>
|
|
91
|
+
{{else}}
|
|
92
|
+
{{! Vehicle-only run: vehicle is primary, driver (if any) is secondary }}
|
|
93
|
+
<div class="text-xs font-semibold dark:text-white truncate">{{group.vehicle.display_name}}</div>
|
|
94
|
+
{{#if group.driver}}
|
|
95
|
+
<div class="text-xs text-gray-400 truncate">{{group.driver.name}}</div>
|
|
96
|
+
{{/if}}
|
|
97
|
+
{{/if}}
|
|
98
|
+
</div>
|
|
99
|
+
<div class="flex items-center space-x-1 flex-shrink-0">
|
|
100
|
+
<span class="text-xs text-gray-400">{{group.orders.length}} {{t "orchestrator.stops"}}</span>
|
|
101
|
+
{{#if group.summary.duration}}
|
|
102
|
+
<span class="text-xs text-gray-500">·</span>
|
|
103
|
+
<span class="text-xs text-gray-400">{{@formatDuration group.summary.duration}}</span>
|
|
104
|
+
{{/if}}
|
|
105
|
+
<FaIcon @icon={{if (this.isExpanded group.vehicle.public_id) "chevron-up" "chevron-down"}} @size="xs" class="text-gray-500 ml-1" />
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
{{! Expanded stop list }}
|
|
110
|
+
{{#if (this.isExpanded group.vehicle.public_id)}}
|
|
111
|
+
<div class="vehicle-drop-zone" data-vehicle-id={{group.vehicle.public_id}} data-driver-id={{group.driver.public_id}}>
|
|
112
|
+
{{#each group.orders as |item idx|}}
|
|
113
|
+
{{! Order block — draggable unit }}
|
|
114
|
+
<div
|
|
115
|
+
class="assigned-stop cursor-grab {{if item._overridden 'border-l-2 border-orange-500' ''}}"
|
|
116
|
+
draggable="true"
|
|
117
|
+
data-order-id={{item.order.public_id}}
|
|
118
|
+
{{on "dragstart" (fn @onAssignedOrderDragStart item.order)}}
|
|
119
|
+
>
|
|
120
|
+
{{! Order reference header — tracking number + type badge }}
|
|
121
|
+
<div class="flex items-center gap-1.5 px-3 pt-2 pb-1 border-b dark:border-gray-700/60">
|
|
122
|
+
<FaIcon @icon="hashtag" @size="xs" class="text-gray-500 flex-shrink-0" />
|
|
123
|
+
<span class="text-xs font-mono font-semibold dark:text-gray-300 truncate">
|
|
124
|
+
{{or item.order.tracking item.order.public_id}}
|
|
125
|
+
</span>
|
|
126
|
+
{{#if item.order.type}}
|
|
127
|
+
<span class="ml-auto text-xs text-gray-500 capitalize truncate">{{item.order.type}}</span>
|
|
128
|
+
{{/if}}
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
{{! Per-stop rows — one row per _labelledStop }}
|
|
132
|
+
{{#if item._labelledStops.length}}
|
|
133
|
+
{{#each item._labelledStops as |stop stopIdx|}}
|
|
134
|
+
<div
|
|
135
|
+
class="flex items-start gap-2 px-3 py-2
|
|
136
|
+
{{if (gt stopIdx 0) 'border-t dark:border-gray-700/60' ''}}
|
|
137
|
+
{{if item._overridden 'bg-orange-900/10' 'dark:bg-gray-800 hover:dark:bg-gray-750'}}"
|
|
138
|
+
>
|
|
139
|
+
|
|
140
|
+
{{! Letter badge }}
|
|
141
|
+
<span
|
|
142
|
+
class="mt-0.5 w-5 h-5 rounded-full flex-shrink-0 flex items-center justify-center text-white font-bold"
|
|
143
|
+
style={{html-safe (concat "font-size:0.6rem; background-color:" group.routeColor)}}
|
|
144
|
+
>{{stop.label}}</span>
|
|
145
|
+
|
|
146
|
+
{{! Stop content }}
|
|
147
|
+
<div class="flex-1 min-w-0">
|
|
148
|
+
{{! Address }}
|
|
149
|
+
<div class="text-xs font-medium dark:text-white truncate">{{stop.address}}</div>
|
|
150
|
+
|
|
151
|
+
{{! Tags row: Pickup/Dropoff, POD }}
|
|
152
|
+
<div class="flex flex-wrap items-center gap-1 mt-0.5">
|
|
153
|
+
{{#if (eq stop.stopType "pickup")}}
|
|
154
|
+
<span class="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-blue-400 bg-blue-900/30 text-xs leading-none">
|
|
155
|
+
<FaIcon @icon="arrow-up" @size="xs" />
|
|
156
|
+
{{t "orchestrator.stop-type-pickup"}}
|
|
157
|
+
</span>
|
|
158
|
+
{{else if (eq stop.stopType "dropoff")}}
|
|
159
|
+
<span class="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-green-400 bg-green-900/30 text-xs leading-none">
|
|
160
|
+
<FaIcon @icon="arrow-down" @size="xs" />
|
|
161
|
+
{{t "orchestrator.stop-type-dropoff"}}
|
|
162
|
+
</span>
|
|
163
|
+
{{/if}}
|
|
164
|
+
{{#if stop.requiresPod}}
|
|
165
|
+
<span class="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-purple-400 bg-purple-900/30 text-xs leading-none">
|
|
166
|
+
<FaIcon @icon="file-signature" @size="xs" />
|
|
167
|
+
{{t "orchestrator.pod-required"}}
|
|
168
|
+
</span>
|
|
169
|
+
{{else}}
|
|
170
|
+
<span class="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-gray-500 bg-gray-700/40 text-xs leading-none">
|
|
171
|
+
<FaIcon @icon="times" @size="xs" />
|
|
172
|
+
{{t "orchestrator.no-pod"}}
|
|
173
|
+
</span>
|
|
174
|
+
{{/if}}
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
{{! Time window }}
|
|
178
|
+
{{#if (or stop.timeWindowStart stop.timeWindowEnd)}}
|
|
179
|
+
<div class="flex items-center gap-1 mt-0.5 text-xs text-gray-400">
|
|
180
|
+
<FaIcon @icon="clock" @size="xs" class="flex-shrink-0" />
|
|
181
|
+
<span class="tabular-nums">{{@formatTimeWindow stop.timeWindowStart stop.timeWindowEnd}}</span>
|
|
182
|
+
</div>
|
|
183
|
+
{{/if}}
|
|
184
|
+
|
|
185
|
+
{{! Notes }}
|
|
186
|
+
{{#if stop.notes}}
|
|
187
|
+
<div class="flex items-start gap-1 mt-0.5 text-xs text-gray-400">
|
|
188
|
+
<FaIcon @icon="sticky-note" @size="xs" class="flex-shrink-0 mt-0.5" />
|
|
189
|
+
<span class="break-words">{{stop.notes}}</span>
|
|
190
|
+
</div>
|
|
191
|
+
{{/if}}
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
{{! Arrival time (OSRM-estimated) }}
|
|
195
|
+
{{#if item.arrival}}
|
|
196
|
+
<span class="flex-shrink-0 text-xs text-gray-500 tabular-nums mt-0.5">{{@formatUnixTime item.arrival}}</span>
|
|
197
|
+
{{/if}}
|
|
198
|
+
|
|
199
|
+
{{! Override indicator }}
|
|
200
|
+
{{#if item._overridden}}
|
|
201
|
+
<FaIcon @icon="pen" @size="xs" class="text-orange-400 flex-shrink-0 mt-0.5" />
|
|
202
|
+
{{/if}}
|
|
203
|
+
</div>
|
|
204
|
+
{{/each}}
|
|
205
|
+
{{else}}
|
|
206
|
+
{{! Fallback: no _labelledStops — show order tracking number only }}
|
|
207
|
+
<div class="flex items-center gap-2 px-3 py-2 dark:bg-gray-800">
|
|
208
|
+
<span
|
|
209
|
+
class="w-5 h-5 rounded-full flex-shrink-0 flex items-center justify-center text-white font-bold"
|
|
210
|
+
style={{html-safe (concat "font-size:0.6rem; background-color:" group.routeColor)}}
|
|
211
|
+
>{{@getStopLabel idx}}</span>
|
|
212
|
+
<span class="text-xs dark:text-white truncate">{{or item.order.tracking item.order.public_id}}</span>
|
|
213
|
+
</div>
|
|
214
|
+
{{/if}}
|
|
215
|
+
</div>
|
|
216
|
+
{{/each}}
|
|
217
|
+
{{#unless group.orders.length}}
|
|
218
|
+
<div class="py-3 text-center text-xs text-gray-500">
|
|
219
|
+
{{t "orchestrator.drop-orders-here"}}
|
|
220
|
+
</div>
|
|
221
|
+
{{/unless}}
|
|
222
|
+
</div>
|
|
223
|
+
{{! Route summary footer }}
|
|
224
|
+
{{#if (or group.summary.distance group.summary.duration)}}
|
|
225
|
+
<div class="px-3 py-1.5 border-t dark:border-gray-700 flex items-center space-x-3 text-xs text-gray-500">
|
|
226
|
+
{{#if group.summary.distance}}
|
|
227
|
+
<span><FaIcon @icon="road" @size="xs" class="mr-0.5" />{{@formatDistance group.summary.distance}}</span>
|
|
228
|
+
{{/if}}
|
|
229
|
+
{{#if group.summary.duration}}
|
|
230
|
+
<span><FaIcon @icon="clock" @size="xs" class="mr-0.5" />{{@formatDuration group.summary.duration}}</span>
|
|
231
|
+
{{/if}}
|
|
232
|
+
</div>
|
|
233
|
+
{{/if}}
|
|
234
|
+
{{/if}}
|
|
235
|
+
</div>
|
|
236
|
+
{{else}}
|
|
237
|
+
<div class="flex flex-col items-center justify-center py-12 text-gray-400 text-xs">
|
|
238
|
+
<FaIcon @icon="route" @size="2x" class="mb-2 opacity-40" />
|
|
239
|
+
{{t "orchestrator.no-plan"}}
|
|
240
|
+
</div>
|
|
241
|
+
{{/each}}
|
|
242
|
+
</div>
|
|
243
|
+
{{/if}}
|
|
244
|
+
|
|
245
|
+
{{! ── TIMELINE TAB ── }}
|
|
246
|
+
{{! Uses the same EventCalendar component as the Scheduler (resourceTimelineWeek view).
|
|
247
|
+
Each vehicle is a resource row; each planned stop is an event block showing
|
|
248
|
+
sequence number, tracking number, scheduled time, pickup -> dropoff address,
|
|
249
|
+
and customer name. Colors match the route colors used on the map. }}
|
|
250
|
+
{{#if (eq this.activeTab "timeline")}}
|
|
251
|
+
<div id="fleet-ops-orchestrator-plan-timeline" class="flex-1 overflow-hidden">
|
|
252
|
+
{{#if this.calendarEvents.length}}
|
|
253
|
+
<EventCalendar
|
|
254
|
+
@view="resourceTimelineWeek"
|
|
255
|
+
@date={{this.timelineDate}}
|
|
256
|
+
@events={{this.calendarEvents}}
|
|
257
|
+
@resources={{this.calendarResources}}
|
|
258
|
+
@editable={{false}}
|
|
259
|
+
@slotMinTime="00:00:00"
|
|
260
|
+
@slotMaxTime="24:00:00"
|
|
261
|
+
@slotWidth={{120}}
|
|
262
|
+
@height="100%"
|
|
263
|
+
@headerToolbar={{this.calendarHeaderToolbar}}
|
|
264
|
+
@resourceLabelContent={{this.renderResourceLabel}}
|
|
265
|
+
@eventContent={{this.renderEventContent}}
|
|
266
|
+
@onCalendarReady={{this.setCalendarApi}}
|
|
267
|
+
@options={{this.calendarOptions}}
|
|
268
|
+
/>
|
|
269
|
+
{{else}}
|
|
270
|
+
<div class="flex flex-col items-center justify-center py-12 text-gray-400 text-xs">
|
|
271
|
+
<FaIcon @icon="calendar-alt" @size="2x" class="mb-2 opacity-40" />
|
|
272
|
+
{{t "orchestrator.no-plan"}}
|
|
273
|
+
</div>
|
|
274
|
+
{{/if}}
|
|
275
|
+
</div>
|
|
276
|
+
{{/if}}
|
|
277
|
+
|
|
278
|
+
</div>
|