@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
|
@@ -3,12 +3,7 @@
|
|
|
3
3
|
<div class="mb-3 flex items-center justify-between">
|
|
4
4
|
<div class="flex items-center">
|
|
5
5
|
<div class="fleet-vehicle-listing-search">
|
|
6
|
-
<Input
|
|
7
|
-
@type="text"
|
|
8
|
-
{{on "input" this.onInput}}
|
|
9
|
-
placeholder={{t "fleet-panel.vehicle-listing.search-vehicle"}}
|
|
10
|
-
class="w-64 form-input form-input-sm"
|
|
11
|
-
/>
|
|
6
|
+
<Input @type="text" {{on "input" this.onInput}} placeholder={{t "fleet-panel.vehicle-listing.search-vehicle"}} class="w-64 form-input form-input-sm" />
|
|
12
7
|
</div>
|
|
13
8
|
{{#if this.search.isRunning}}
|
|
14
9
|
<div class="mx-2">
|
|
@@ -77,11 +77,7 @@
|
|
|
77
77
|
@disabled={{cannot-write @resource}}
|
|
78
78
|
/>
|
|
79
79
|
</InputGroup>
|
|
80
|
-
<InputGroup
|
|
81
|
-
@name={{t "fuel-report.fields.fuel-volume"}}
|
|
82
|
-
@helpText={{t "fuel-report.fields.select-volume-help-text"}}
|
|
83
|
-
@wrapperClass="w-full"
|
|
84
|
-
>
|
|
80
|
+
<InputGroup @name={{t "fuel-report.fields.fuel-volume"}} @helpText={{t "fuel-report.fields.select-volume-help-text"}} @wrapperClass="w-full">
|
|
85
81
|
<UnitInput
|
|
86
82
|
class="w-full"
|
|
87
83
|
@measurement="volume"
|
|
@@ -104,8 +104,9 @@
|
|
|
104
104
|
}}
|
|
105
105
|
{{else}}
|
|
106
106
|
<Layout::Sidebar::Item
|
|
107
|
-
@onClick={{menuItem.onClick}}
|
|
108
|
-
@
|
|
107
|
+
@onClick={{if menuItem._virtual (fn this.universe.transitionMenuItem (concat this.routePrefix "virtual") menuItem) menuItem.onClick}}
|
|
108
|
+
@menuItem={{menuItem}}
|
|
109
|
+
@route={{if menuItem._virtual null (concat this.routePrefix menuItem.route)}}
|
|
109
110
|
@icon={{menuItem.icon}}
|
|
110
111
|
@iconComponent={{menuItem.iconComponent}}
|
|
111
112
|
@iconComponentOptions={{menuItem.iconComponentOptions}}
|
|
@@ -135,44 +136,48 @@
|
|
|
135
136
|
>{{if menuItem.intl (t menuItem.intl) menuItem.title}}</Layout::Sidebar::Item>
|
|
136
137
|
{{/if}}
|
|
137
138
|
{{/each}}
|
|
138
|
-
{{#
|
|
139
|
-
{{#each
|
|
140
|
-
{{#if
|
|
141
|
-
{{
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
139
|
+
{{!-- {{#let (array "operations" "management" "connectivity" "maintenance" "analytics" "settings") as |sectionsToRender|}}
|
|
140
|
+
{{#each sectionsToRender as |section|}}
|
|
141
|
+
{{#if (eq menuPanel.routePrefix section)}}
|
|
142
|
+
{{#each (get this (concat "universe" (capitalize section) "MenuItems")) as |menuItem|}}
|
|
143
|
+
{{#if menuItem.renderComponentInPlace}}
|
|
144
|
+
{{component menuItem.component}}
|
|
145
|
+
{{else}}
|
|
146
|
+
<Layout::Sidebar::Item
|
|
147
|
+
@onClick={{fn this.universe.transitionMenuItem (concat this.routePrefix "virtual") menuItem}}
|
|
148
|
+
@menuItem={{menuItem}}
|
|
149
|
+
@icon={{menuItem.icon}}
|
|
150
|
+
@iconComponent={{menuItem.iconComponent}}
|
|
151
|
+
@iconComponentOptions={{menuItem.iconComponentOptions}}
|
|
152
|
+
@iconSize={{menuItem.iconSize}}
|
|
153
|
+
@iconPrefix={{menuItem.iconPrefix}}
|
|
154
|
+
@iconClass={{menuItem.iconClass}}
|
|
155
|
+
@rightSideComponent={{menuItem.rightSideComponent}}
|
|
156
|
+
@rightSideComponentContext={{menuItem.rightSideComponentContext}}
|
|
157
|
+
@rightSideStatus={{menuItem.rightSideStatus}}
|
|
158
|
+
@rightSideStatusText={{menuItem.rightSideStatusText}}
|
|
159
|
+
@hideRightSideStatusDot={{menuItem.hideRightSideStatusDot}}
|
|
160
|
+
@rightSideStatusClass={{menuItem.rightSideStatusClass}}
|
|
161
|
+
@disableRightSideStatusHumanize={{menuItem.disableRightSideStatusHumanize}}
|
|
162
|
+
@dropdownButton={{menuItem.dropdownButton}}
|
|
163
|
+
@dropdownButtonActions={{menuItem.dropdownButtonActions}}
|
|
164
|
+
@dropdownButtonIcon={{menuItem.dropdownButtonIcon}}
|
|
165
|
+
@dropdownButtonIconPrefix={{menuItem.dropdownButtonIconPrefix}}
|
|
166
|
+
@dropdownButtonText={{menuItem.dropdownButtonText}}
|
|
167
|
+
@dropdownButtonCalculatePosition={{menuItem.dropdownButtonCalculatePosition}}
|
|
168
|
+
@dropdownButtonRenderInPlace={{menuItem.dropdownButtonRenderInPlace}}
|
|
169
|
+
@dropdownButtonMenuLabel={{menuItem.dropdownButtonMenuLabel}}
|
|
170
|
+
@dropdownButtonWrapperClass={{menuItem.dropdownButtonWrapperClass}}
|
|
171
|
+
@dropdownButtonTriggerClass={{menuItem.dropdownButtonTriggerClass}}
|
|
172
|
+
@registerDropdownButtonAPI={{menuItem.registerDropdownButtonAPI}}
|
|
173
|
+
@permission={{menuItem.permission}}
|
|
174
|
+
@visible={{menuItem.visible}}
|
|
175
|
+
>{{if menuItem.intl (t menuItem.intl) menuItem.title}}</Layout::Sidebar::Item>
|
|
176
|
+
{{/if}}
|
|
177
|
+
{{/each}}
|
|
173
178
|
{{/if}}
|
|
174
179
|
{{/each}}
|
|
175
|
-
{{/
|
|
180
|
+
{{/let}} --}}
|
|
176
181
|
</Layout::Sidebar::Panel>
|
|
177
182
|
{{/each}}
|
|
178
183
|
{{#each this.universeMenuPanels as |menuPanel|}}
|
|
@@ -15,6 +15,11 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
15
15
|
@tracked routePrefix = 'console.fleet-ops.';
|
|
16
16
|
@tracked menuPanels = [];
|
|
17
17
|
@tracked universeMenuItems = [];
|
|
18
|
+
@tracked universeOperationsMenuItems = [];
|
|
19
|
+
@tracked universeManagementMenuItems = [];
|
|
20
|
+
@tracked universeConnectivityMenuItems = [];
|
|
21
|
+
@tracked universeMaintenanceMenuItems = [];
|
|
22
|
+
@tracked universeAnalyticsMenuItems = [];
|
|
18
23
|
@tracked universeSettingsMenuItems = [];
|
|
19
24
|
@tracked universeMenuPanels = [];
|
|
20
25
|
|
|
@@ -28,6 +33,11 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
28
33
|
const registeredMenuItems = this.menuService.getMenuItems('engine:fleet-ops');
|
|
29
34
|
this.universeMenuPanels = this.menuService.getMenuPanels('engine:fleet-ops');
|
|
30
35
|
this.universeMenuItems = registeredMenuItems.filter((menuItem) => menuItem.section === undefined);
|
|
36
|
+
this.universeOperationsMenuItems = registeredMenuItems.filter((menuItem) => menuItem.section === 'operations');
|
|
37
|
+
this.universeManagementMenuItems = registeredMenuItems.filter((menuItem) => menuItem.section === 'management');
|
|
38
|
+
this.universeMaintenanceMenuItems = registeredMenuItems.filter((menuItem) => menuItem.section === 'maintenance');
|
|
39
|
+
this.universeConnectivityMenuItems = registeredMenuItems.filter((menuItem) => menuItem.section === 'connectivity');
|
|
40
|
+
this.universeAnalyticsMenuItems = registeredMenuItems.filter((menuItem) => menuItem.section === 'analytics');
|
|
31
41
|
this.universeSettingsMenuItems = registeredMenuItems.filter((menuItem) => menuItem.section === 'settings');
|
|
32
42
|
}
|
|
33
43
|
|
|
@@ -35,6 +45,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
35
45
|
createMenuPanels() {
|
|
36
46
|
const operationsItems = [
|
|
37
47
|
{
|
|
48
|
+
priority: 0,
|
|
38
49
|
intl: 'menu.dashboard',
|
|
39
50
|
title: this.intl.t('menu.dashboard'),
|
|
40
51
|
icon: 'home',
|
|
@@ -43,14 +54,16 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
43
54
|
visible: this.abilities.can('fleet-ops see order'),
|
|
44
55
|
},
|
|
45
56
|
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
priority: 1,
|
|
58
|
+
intl: 'menu.orchestrator',
|
|
59
|
+
title: this.intl.t('menu.orchestrator'),
|
|
60
|
+
icon: 'circle-nodes',
|
|
61
|
+
route: 'operations.orchestrator',
|
|
62
|
+
permission: 'fleet-ops list order',
|
|
63
|
+
visible: this.abilities.can('fleet-ops see order'),
|
|
52
64
|
},
|
|
53
65
|
{
|
|
66
|
+
priority: 2,
|
|
54
67
|
intl: 'menu.scheduler',
|
|
55
68
|
title: this.intl.t('menu.scheduler'),
|
|
56
69
|
icon: 'calendar-day',
|
|
@@ -59,6 +72,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
59
72
|
visible: this.abilities.can('fleet-ops see order'),
|
|
60
73
|
},
|
|
61
74
|
{
|
|
75
|
+
priority: 3,
|
|
62
76
|
intl: 'menu.order-config',
|
|
63
77
|
title: this.intl.t('menu.order-config'),
|
|
64
78
|
icon: 'diagram-project',
|
|
@@ -66,10 +80,21 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
66
80
|
permission: 'fleet-ops list order-config',
|
|
67
81
|
visible: this.abilities.can('fleet-ops see order-config'),
|
|
68
82
|
},
|
|
69
|
-
|
|
83
|
+
{
|
|
84
|
+
priority: 4,
|
|
85
|
+
intl: 'menu.service-rates',
|
|
86
|
+
title: this.intl.t('menu.service-rates'),
|
|
87
|
+
icon: 'file-invoice-dollar',
|
|
88
|
+
route: 'operations.service-rates',
|
|
89
|
+
permission: 'fleet-ops list service-rate',
|
|
90
|
+
visible: this.abilities.can('fleet-ops see service-rate'),
|
|
91
|
+
},
|
|
92
|
+
...(this.universeOperationsMenuItems ?? []).map((item) => ({ ...item, _virtual: true })),
|
|
93
|
+
].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
70
94
|
|
|
71
95
|
const resourcesItems = [
|
|
72
96
|
{
|
|
97
|
+
priority: 0,
|
|
73
98
|
intl: 'menu.drivers',
|
|
74
99
|
title: this.intl.t('menu.drivers'),
|
|
75
100
|
icon: 'id-card',
|
|
@@ -80,6 +105,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
80
105
|
visible: this.abilities.can('fleet-ops see driver'),
|
|
81
106
|
},
|
|
82
107
|
{
|
|
108
|
+
priority: 1,
|
|
83
109
|
intl: 'menu.vehicles',
|
|
84
110
|
title: this.intl.t('menu.vehicles'),
|
|
85
111
|
icon: 'truck',
|
|
@@ -88,6 +114,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
88
114
|
visible: this.abilities.can('fleet-ops see vehicle'),
|
|
89
115
|
},
|
|
90
116
|
{
|
|
117
|
+
priority: 2,
|
|
91
118
|
intl: 'menu.fleets',
|
|
92
119
|
title: this.intl.t('menu.fleets'),
|
|
93
120
|
icon: 'user-group',
|
|
@@ -98,6 +125,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
98
125
|
visible: this.abilities.can('fleet-ops see fleet'),
|
|
99
126
|
},
|
|
100
127
|
{
|
|
128
|
+
priority: 3,
|
|
101
129
|
intl: 'menu.vendors',
|
|
102
130
|
title: this.intl.t('menu.vendors'),
|
|
103
131
|
icon: 'warehouse',
|
|
@@ -106,6 +134,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
106
134
|
visible: this.abilities.can('fleet-ops see vendor'),
|
|
107
135
|
},
|
|
108
136
|
{
|
|
137
|
+
priority: 4,
|
|
109
138
|
intl: 'menu.contacts',
|
|
110
139
|
title: this.intl.t('menu.contacts'),
|
|
111
140
|
icon: 'address-book',
|
|
@@ -114,6 +143,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
114
143
|
visible: this.abilities.can('fleet-ops see contact'),
|
|
115
144
|
},
|
|
116
145
|
{
|
|
146
|
+
priority: 5,
|
|
117
147
|
intl: 'menu.places',
|
|
118
148
|
title: this.intl.t('menu.places'),
|
|
119
149
|
icon: 'location-dot',
|
|
@@ -122,6 +152,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
122
152
|
visible: this.abilities.can('fleet-ops see place'),
|
|
123
153
|
},
|
|
124
154
|
{
|
|
155
|
+
priority: 6,
|
|
125
156
|
intl: 'menu.fuel-reports',
|
|
126
157
|
title: this.intl.t('menu.fuel-reports'),
|
|
127
158
|
icon: 'gas-pump',
|
|
@@ -130,6 +161,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
130
161
|
visible: this.abilities.can('fleet-ops see fuel-report'),
|
|
131
162
|
},
|
|
132
163
|
{
|
|
164
|
+
priority: 7,
|
|
133
165
|
intl: 'menu.issues',
|
|
134
166
|
title: this.intl.t('menu.issues'),
|
|
135
167
|
icon: 'triangle-exclamation',
|
|
@@ -137,10 +169,12 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
137
169
|
permission: 'fleet-ops list issue',
|
|
138
170
|
visible: this.abilities.can('fleet-ops see issue'),
|
|
139
171
|
},
|
|
140
|
-
|
|
172
|
+
...(this.universeManagementMenuItems ?? []).map((item) => ({ ...item, _virtual: true })),
|
|
173
|
+
].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
141
174
|
|
|
142
175
|
const connectivityItems = [
|
|
143
176
|
{
|
|
177
|
+
priority: 0,
|
|
144
178
|
intl: 'menu.telematics',
|
|
145
179
|
title: this.intl.t('menu.telematics'),
|
|
146
180
|
icon: 'satellite-dish',
|
|
@@ -149,6 +183,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
149
183
|
visible: this.abilities.can('fleet-ops see telematic'),
|
|
150
184
|
},
|
|
151
185
|
{
|
|
186
|
+
priority: 1,
|
|
152
187
|
intl: 'menu.devices',
|
|
153
188
|
title: this.intl.t('menu.devices'),
|
|
154
189
|
icon: 'hard-drive',
|
|
@@ -157,6 +192,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
157
192
|
visible: this.abilities.can('fleet-ops see device'),
|
|
158
193
|
},
|
|
159
194
|
{
|
|
195
|
+
priority: 2,
|
|
160
196
|
intl: 'menu.sensors',
|
|
161
197
|
title: this.intl.t('menu.sensors'),
|
|
162
198
|
icon: 'temperature-full',
|
|
@@ -165,6 +201,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
165
201
|
visible: this.abilities.can('fleet-ops see sensor'),
|
|
166
202
|
},
|
|
167
203
|
{
|
|
204
|
+
priority: 3,
|
|
168
205
|
intl: 'menu.events',
|
|
169
206
|
title: this.intl.t('menu.events'),
|
|
170
207
|
icon: 'stream',
|
|
@@ -172,18 +209,21 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
172
209
|
permission: 'fleet-ops list device-event',
|
|
173
210
|
visible: this.abilities.can('fleet-ops see device-event'),
|
|
174
211
|
},
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
// title: this.intl.t('menu.tracking'),
|
|
178
|
-
// icon: 'map-marked-alt',
|
|
179
|
-
// route: 'connectivity.tracking',
|
|
180
|
-
// permission: 'fleet-ops list device',
|
|
181
|
-
// visible: this.abilities.can('fleet-ops see device'),
|
|
182
|
-
// },
|
|
183
|
-
];
|
|
212
|
+
...(this.universeConnectivityMenuItems ?? []).map((item) => ({ ...item, _virtual: true })),
|
|
213
|
+
].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
184
214
|
|
|
185
215
|
const maintenanceItems = [
|
|
186
216
|
{
|
|
217
|
+
priority: 0,
|
|
218
|
+
intl: 'menu.schedules',
|
|
219
|
+
title: this.intl.t('menu.schedules'),
|
|
220
|
+
icon: 'calendar-alt',
|
|
221
|
+
route: 'maintenance.schedules',
|
|
222
|
+
permission: 'fleet-ops list maintenance-schedule',
|
|
223
|
+
visible: this.abilities.can('fleet-ops see maintenance-schedule'),
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
priority: 1,
|
|
187
227
|
intl: 'menu.work-orders',
|
|
188
228
|
title: this.intl.t('menu.work-orders'),
|
|
189
229
|
icon: 'clipboard-list',
|
|
@@ -192,6 +232,16 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
192
232
|
visible: this.abilities.can('fleet-ops see work-order'),
|
|
193
233
|
},
|
|
194
234
|
{
|
|
235
|
+
priority: 2,
|
|
236
|
+
intl: 'menu.maintenances',
|
|
237
|
+
title: this.intl.t('menu.maintenances'),
|
|
238
|
+
icon: 'history',
|
|
239
|
+
route: 'maintenance.maintenances',
|
|
240
|
+
permission: 'fleet-ops list maintenance',
|
|
241
|
+
visible: this.abilities.can('fleet-ops see maintenance'),
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
priority: 3,
|
|
195
245
|
intl: 'menu.equipment',
|
|
196
246
|
title: this.intl.t('menu.equipment'),
|
|
197
247
|
icon: 'trailer',
|
|
@@ -200,6 +250,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
200
250
|
visible: this.abilities.can('fleet-ops see equipment'),
|
|
201
251
|
},
|
|
202
252
|
{
|
|
253
|
+
priority: 4,
|
|
203
254
|
intl: 'menu.parts',
|
|
204
255
|
title: this.intl.t('menu.parts'),
|
|
205
256
|
icon: 'cog',
|
|
@@ -207,10 +258,12 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
207
258
|
permission: 'fleet-ops list part',
|
|
208
259
|
visible: this.abilities.can('fleet-ops see part'),
|
|
209
260
|
},
|
|
210
|
-
|
|
261
|
+
...(this.universeMaintenanceMenuItems ?? []).map((item) => ({ ...item, _virtual: true })),
|
|
262
|
+
].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
211
263
|
|
|
212
264
|
const analyticsItems = [
|
|
213
265
|
{
|
|
266
|
+
priority: 0,
|
|
214
267
|
intl: 'menu.reports',
|
|
215
268
|
title: this.intl.t('menu.reports'),
|
|
216
269
|
icon: 'file-import',
|
|
@@ -218,10 +271,12 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
218
271
|
permission: 'iam list report',
|
|
219
272
|
visible: this.abilities.can('fleet-ops see report'),
|
|
220
273
|
},
|
|
221
|
-
|
|
274
|
+
...(this.universeAnalyticsMenuItems ?? []).map((item) => ({ ...item, _virtual: true })),
|
|
275
|
+
].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
222
276
|
|
|
223
277
|
const settingsItems = [
|
|
224
278
|
{
|
|
279
|
+
priority: 0,
|
|
225
280
|
intl: 'menu.navigator-app',
|
|
226
281
|
title: this.intl.t('menu.navigator-app'),
|
|
227
282
|
icon: 'location-arrow',
|
|
@@ -230,6 +285,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
230
285
|
visible: this.abilities.can('fleet-ops see navigator-settings'),
|
|
231
286
|
},
|
|
232
287
|
{
|
|
288
|
+
priority: 1,
|
|
233
289
|
intl: 'menu.payments',
|
|
234
290
|
title: this.intl.t('menu.payments'),
|
|
235
291
|
icon: 'cash-register',
|
|
@@ -238,6 +294,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
238
294
|
visible: this.abilities.can('fleet-ops see payments'),
|
|
239
295
|
},
|
|
240
296
|
{
|
|
297
|
+
priority: 2,
|
|
241
298
|
intl: 'menu.notifications',
|
|
242
299
|
title: this.intl.t('menu.notifications'),
|
|
243
300
|
icon: 'bell',
|
|
@@ -246,6 +303,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
246
303
|
visible: this.abilities.can('fleet-ops see notification-settings'),
|
|
247
304
|
},
|
|
248
305
|
{
|
|
306
|
+
priority: 3,
|
|
249
307
|
intl: 'menu.routing',
|
|
250
308
|
title: this.intl.t('menu.routing'),
|
|
251
309
|
icon: 'route',
|
|
@@ -254,6 +312,25 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
254
312
|
visible: this.abilities.can('fleet-ops see routing-settings'),
|
|
255
313
|
},
|
|
256
314
|
{
|
|
315
|
+
priority: 4,
|
|
316
|
+
intl: 'menu.orchestrator',
|
|
317
|
+
title: this.intl.t('menu.orchestrator'),
|
|
318
|
+
icon: 'circle-nodes',
|
|
319
|
+
route: 'settings.orchestrator',
|
|
320
|
+
permission: 'fleet-ops view routing-settings',
|
|
321
|
+
visible: this.abilities.can('fleet-ops see routing-settings'),
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
priority: 5,
|
|
325
|
+
intl: 'menu.scheduling',
|
|
326
|
+
title: this.intl.t('menu.scheduling'),
|
|
327
|
+
icon: 'calendar-days',
|
|
328
|
+
route: 'settings.scheduling',
|
|
329
|
+
permission: 'fleet-ops view scheduling-settings',
|
|
330
|
+
visible: this.abilities.can('fleet-ops see scheduling-settings'),
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
priority: 6,
|
|
257
334
|
intl: 'menu.custom-fields',
|
|
258
335
|
title: this.intl.t('menu.custom-fields'),
|
|
259
336
|
icon: 'rectangle-list',
|
|
@@ -262,6 +339,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
262
339
|
visible: this.abilities.can('fleet-ops see custom-field'),
|
|
263
340
|
},
|
|
264
341
|
{
|
|
342
|
+
priority: 7,
|
|
265
343
|
intl: 'menu.avatars',
|
|
266
344
|
title: this.intl.t('menu.avatars'),
|
|
267
345
|
icon: 'icons',
|
|
@@ -269,7 +347,8 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
269
347
|
permission: 'fleet-ops view avatar',
|
|
270
348
|
visible: this.abilities.can('fleet-ops see avatar'),
|
|
271
349
|
},
|
|
272
|
-
|
|
350
|
+
...(this.universeSettingsMenuItems ?? []).map((item) => ({ ...item, _virtual: true })),
|
|
351
|
+
].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
273
352
|
|
|
274
353
|
const createPanel = (intl, routePrefix, items = [], options = {}) => ({
|
|
275
354
|
intl,
|
|
@@ -289,10 +368,10 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
289
368
|
open: this.appCache.get('fleet-ops:sidebar:management:open', true),
|
|
290
369
|
onToggle: (open) => this.appCache.set('fleet-ops:sidebar:management:open', open),
|
|
291
370
|
}),
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
371
|
+
createPanel('menu.maintenance', 'maintenance', maintenanceItems, {
|
|
372
|
+
open: this.appCache.get('fleet-ops:sidebar:maintenance:open', false),
|
|
373
|
+
onToggle: (open) => this.appCache.set('fleet-ops:sidebar:maintenance:open', open),
|
|
374
|
+
}),
|
|
296
375
|
createPanel('menu.connectivity', 'connectivity', connectivityItems, {
|
|
297
376
|
open: this.appCache.get('fleet-ops:sidebar:connectivity:open', false),
|
|
298
377
|
onToggle: (open) => this.appCache.set('fleet-ops:sidebar:connectivity:open', open),
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
{{! ===== COST PANEL — invoice-style line items ===== }}
|
|
2
|
+
<ContentPanel @title="Costs" @open={{true}} @wrapperClass="bordered-top">
|
|
3
|
+
|
|
4
|
+
{{! ── Currency selector (single, shared by all money fields) ── }}
|
|
5
|
+
<div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-2 no-input-group-padding text-xs mb-2">
|
|
6
|
+
<InputGroup @name="Currency">
|
|
7
|
+
<CurrencySelect @currency={{@resource.currency}} @onCurrencyChange={{fn (mut @resource.currency)}} @triggerClass="w-full form-select" @disabled={{this.isDisabled}} />
|
|
8
|
+
</InputGroup>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
{{! ── Labour & Tax inputs (always editable on the form) ── }}
|
|
12
|
+
<div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-2 no-input-group-padding text-xs mb-4">
|
|
13
|
+
<InputGroup @name="Labour Cost">
|
|
14
|
+
<MoneyInput class="w-full" @value={{@resource.labor_cost}} @currency={{this.currency}} @onChange={{fn (mut @resource.labor_cost)}} @disabled={{this.isDisabled}} />
|
|
15
|
+
</InputGroup>
|
|
16
|
+
<InputGroup @name="Tax">
|
|
17
|
+
<MoneyInput class="w-full" @value={{@resource.tax}} @currency={{this.currency}} @onChange={{fn (mut @resource.tax)}} @disabled={{this.isDisabled}} />
|
|
18
|
+
</InputGroup>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
{{! ── Line items table ── }}
|
|
22
|
+
<div class="text-[11px] uppercase tracking-wide text-gray-500 dark:text-gray-400 font-semibold mb-2">
|
|
23
|
+
Parts & Services
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<table class="w-full text-xs border-collapse mb-2 table-fixed">
|
|
27
|
+
<colgroup>
|
|
28
|
+
<col class="w-[45%]" />
|
|
29
|
+
<col class="w-[10%]" />
|
|
30
|
+
<col class="w-[20%]" />
|
|
31
|
+
<col class="w-[15%]" />
|
|
32
|
+
{{#unless this.isDisabled}}
|
|
33
|
+
<col class="w-[10%]" />
|
|
34
|
+
{{/unless}}
|
|
35
|
+
</colgroup>
|
|
36
|
+
<thead>
|
|
37
|
+
<tr class="border-b border-gray-200 dark:border-gray-700 text-gray-500 dark:text-gray-400 text-left">
|
|
38
|
+
<th class="pb-1 pr-2 font-medium">Description</th>
|
|
39
|
+
<th class="pb-1 pr-2 font-medium text-right">Qty</th>
|
|
40
|
+
<th class="pb-1 pr-2 font-medium text-right">Unit Cost</th>
|
|
41
|
+
<th class="pb-1 pr-2 font-medium text-right">Total</th>
|
|
42
|
+
{{#unless this.isDisabled}}
|
|
43
|
+
<th class="pb-1"></th>
|
|
44
|
+
{{/unless}}
|
|
45
|
+
</tr>
|
|
46
|
+
</thead>
|
|
47
|
+
<tbody>
|
|
48
|
+
{{#each this.lineItems as |item index|}}
|
|
49
|
+
{{#if (eq this.editingIndex index)}}
|
|
50
|
+
{{! ── Inline edit row ── }}
|
|
51
|
+
<tr class="border-b border-gray-100 dark:border-gray-800">
|
|
52
|
+
<td class="py-1 pr-2">
|
|
53
|
+
<Input @value={{this.draftDescription}} class="form-input w-full text-xs" placeholder="Description" />
|
|
54
|
+
</td>
|
|
55
|
+
<td class="py-1 pr-2">
|
|
56
|
+
<Input @value={{this.draftQuantity}} @type="number" class="form-input w-full text-xs text-right" min="0" />
|
|
57
|
+
</td>
|
|
58
|
+
<td class="py-1 pr-2">
|
|
59
|
+
<MoneyInput class="w-full" @value={{this.draftUnitCost}} @currency={{this.currency}} @onChange={{this.setDraftUnitCost}} />
|
|
60
|
+
</td>
|
|
61
|
+
<td class="py-1 pr-2 text-right text-gray-500 dark:text-gray-400">
|
|
62
|
+
{{format-currency this.draftLineTotal this.currency}}
|
|
63
|
+
</td>
|
|
64
|
+
<td class="py-1">
|
|
65
|
+
<div class="flex items-center space-x-1">
|
|
66
|
+
<Button @size="xs" @type="primary" @onClick={{this.saveEdit}} class="px-2 py-0.5">
|
|
67
|
+
Save
|
|
68
|
+
</Button>
|
|
69
|
+
<Button @size="xs" @type="default" @onClick={{this.cancelEdit}} class="px-2 py-0.5">
|
|
70
|
+
Cancel
|
|
71
|
+
</Button>
|
|
72
|
+
</div>
|
|
73
|
+
</td>
|
|
74
|
+
</tr>
|
|
75
|
+
{{else}}
|
|
76
|
+
{{! ── Read row ── }}
|
|
77
|
+
<tr class="border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/40 group">
|
|
78
|
+
<td class="py-1.5 pr-2 text-gray-800 dark:text-gray-200 truncate">{{item.description}}</td>
|
|
79
|
+
<td class="py-1.5 pr-2 text-right text-gray-600 dark:text-gray-400">{{item.quantity}}</td>
|
|
80
|
+
<td class="py-1.5 pr-2 text-right text-gray-600 dark:text-gray-400">
|
|
81
|
+
{{format-currency (this._toCents item.unit_cost) this.currency}}
|
|
82
|
+
</td>
|
|
83
|
+
<td class="py-1.5 pr-2 text-right font-medium text-gray-800 dark:text-gray-200">
|
|
84
|
+
{{format-currency (this.lineTotal item) this.currency}}
|
|
85
|
+
</td>
|
|
86
|
+
{{#unless this.isDisabled}}
|
|
87
|
+
<td class="py-1.5">
|
|
88
|
+
<div class="flex items-center space-x-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
89
|
+
<button
|
|
90
|
+
type="button"
|
|
91
|
+
class="text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 transition-colors"
|
|
92
|
+
title="Edit"
|
|
93
|
+
{{on "click" (fn this.startEdit index)}}
|
|
94
|
+
>
|
|
95
|
+
<FaIcon @icon="pencil" @size="xs" />
|
|
96
|
+
</button>
|
|
97
|
+
<button
|
|
98
|
+
type="button"
|
|
99
|
+
class="text-gray-400 hover:text-red-500 dark:hover:text-red-400 transition-colors"
|
|
100
|
+
title="Remove"
|
|
101
|
+
{{on "click" (fn this.removeLineItem index)}}
|
|
102
|
+
>
|
|
103
|
+
<FaIcon @icon="trash" @size="xs" />
|
|
104
|
+
</button>
|
|
105
|
+
</div>
|
|
106
|
+
</td>
|
|
107
|
+
{{/unless}}
|
|
108
|
+
</tr>
|
|
109
|
+
{{/if}}
|
|
110
|
+
{{/each}}
|
|
111
|
+
|
|
112
|
+
{{! ── Add new item row ── }}
|
|
113
|
+
{{#if this.isAddingItem}}
|
|
114
|
+
<tr class="border-b border-gray-100 dark:border-gray-800">
|
|
115
|
+
<td class="py-1 pr-2">
|
|
116
|
+
<Input @value={{this.draftDescription}} class="form-input w-full text-xs" placeholder="Description" />
|
|
117
|
+
</td>
|
|
118
|
+
<td class="py-1 pr-2">
|
|
119
|
+
<Input @value={{this.draftQuantity}} @type="number" class="form-input w-full text-xs text-right" min="0" />
|
|
120
|
+
</td>
|
|
121
|
+
<td class="py-1 pr-2">
|
|
122
|
+
<MoneyInput class="w-full" @value={{this.draftUnitCost}} @currency={{this.currency}} @onChange={{this.setDraftUnitCost}} />
|
|
123
|
+
</td>
|
|
124
|
+
<td class="py-1 pr-2 text-right text-gray-500 dark:text-gray-400">
|
|
125
|
+
{{format-currency this.draftLineTotal this.currency}}
|
|
126
|
+
</td>
|
|
127
|
+
<td class="py-1">
|
|
128
|
+
<div class="flex items-center space-x-1">
|
|
129
|
+
<Button @size="xs" @type="primary" @onClick={{this.addLineItem}} class="px-2 py-0.5">
|
|
130
|
+
Add
|
|
131
|
+
</Button>
|
|
132
|
+
<Button @size="xs" @type="default" @onClick={{this.cancelAdd}} class="px-2 py-0.5">
|
|
133
|
+
Cancel
|
|
134
|
+
</Button>
|
|
135
|
+
</div>
|
|
136
|
+
</td>
|
|
137
|
+
</tr>
|
|
138
|
+
{{/if}}
|
|
139
|
+
</tbody>
|
|
140
|
+
</table>
|
|
141
|
+
|
|
142
|
+
{{! ── Add item button ── }}
|
|
143
|
+
{{#unless this.isDisabled}}
|
|
144
|
+
{{#unless this.isAddingItem}}
|
|
145
|
+
<button
|
|
146
|
+
type="button"
|
|
147
|
+
class="flex items-center space-x-1 text-xs text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 font-medium mb-3 transition-colors"
|
|
148
|
+
{{on "click" this.showAddRow}}
|
|
149
|
+
>
|
|
150
|
+
<FaIcon @icon="plus" @size="xs" />
|
|
151
|
+
<span>Add line item</span>
|
|
152
|
+
</button>
|
|
153
|
+
{{/unless}}
|
|
154
|
+
{{/unless}}
|
|
155
|
+
|
|
156
|
+
{{! ── Totals summary ── }}
|
|
157
|
+
<div class="border-t border-gray-200 dark:border-gray-700 pt-2 mt-1 space-y-1 text-xs">
|
|
158
|
+
<div class="flex justify-between text-gray-500 dark:text-gray-400">
|
|
159
|
+
<span>Labour</span>
|
|
160
|
+
<span>{{format-currency this.laborCost this.currency}}</span>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="flex justify-between text-gray-500 dark:text-gray-400">
|
|
163
|
+
<span>Parts</span>
|
|
164
|
+
<span>{{format-currency this.partsCost this.currency}}</span>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="flex justify-between text-gray-500 dark:text-gray-400">
|
|
167
|
+
<span>Tax</span>
|
|
168
|
+
<span>{{format-currency this.tax this.currency}}</span>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="flex justify-between font-semibold text-gray-800 dark:text-gray-100 border-t border-gray-200 dark:border-gray-700 pt-1 mt-1">
|
|
171
|
+
<span>Total</span>
|
|
172
|
+
<span>{{format-currency this.totalCost this.currency}}</span>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
</ContentPanel>
|