@fleetbase/fleetops-engine 0.6.70 → 0.6.72
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/RELEASE.md +18 -47
- package/addon/components/admin/tracking-page-settings.hbs +56 -0
- package/addon/components/admin/tracking-page-settings.js +67 -0
- package/addon/components/device/form.hbs +2 -2
- package/addon/components/driver/details.hbs +1 -1
- package/addon/components/driver/form.hbs +1 -1
- package/addon/components/equipment/form.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +11 -3
- package/addon/components/maintenance/form.hbs +3 -3
- package/addon/components/map/google-live-map.js +2 -2
- package/addon/components/map/leaflet-live-map.js +45 -32
- package/addon/components/orchestrator/phase-builder.js +2 -1
- package/addon/components/orchestrator-workbench.hbs +7 -1
- package/addon/components/orchestrator-workbench.js +16 -2
- package/addon/components/order/details/activity.hbs +8 -6
- package/addon/components/order/details/activity.js +9 -0
- package/addon/components/order/details.hbs +29 -0
- package/addon/components/order/details.js +26 -0
- package/addon/components/order/form/details.hbs +30 -4
- package/addon/components/order/form/details.js +46 -0
- package/addon/components/order/form/route.hbs +5 -3
- package/addon/components/order/form/route.js +24 -1
- package/addon/components/order/form.hbs +12 -0
- package/addon/components/order/form.js +21 -1
- package/addon/components/order/kanban.js +72 -0
- package/addon/components/order-config-manager/activity-flow.js +45 -10
- package/addon/components/order-config-manager/lifecycle.hbs +250 -0
- package/addon/components/order-config-manager/lifecycle.js +358 -0
- package/addon/components/order-config-manager.js +5 -1
- package/addon/components/service-rate/details.hbs +1 -1
- package/addon/components/service-rate/form.hbs +1 -1
- package/addon/components/tracking-page/full-view.hbs +276 -0
- package/addon/components/tracking-page/full-view.js +474 -0
- package/addon/components/tracking-page/locale-selector.js +30 -0
- package/addon/components/tracking-page/map.hbs +44 -0
- package/addon/components/tracking-page/map.js +328 -0
- package/addon/components/tracking-page/order-list.hbs +35 -0
- package/addon/components/tracking-page/public-view.hbs +60 -0
- package/addon/components/tracking-page/settings-preview.hbs +21 -0
- package/addon/components/tracking-page/settings-preview.js +23 -0
- package/addon/components/tracking-page/verify-panel.hbs +109 -0
- package/addon/components/tracking-page.hbs +142 -0
- package/addon/components/tracking-page.js +564 -0
- package/addon/components/trailer/form.hbs +2 -2
- package/addon/components/vehicle/form.hbs +3 -3
- package/addon/components/warranty/form.hbs +2 -2
- package/addon/components/widget/live-fleet.js +54 -6
- package/addon/components/widget/proof-of-delivery.hbs +49 -0
- package/addon/components/widget/proof-of-delivery.js +62 -0
- package/addon/components/work-order/form.hbs +3 -3
- package/addon/controllers/analytics/reports/index.js +10 -1
- package/addon/controllers/connectivity/devices/index/details.js +1 -0
- package/addon/controllers/connectivity/devices/index.js +8 -2
- package/addon/controllers/connectivity/events/index.js +31 -1
- package/addon/controllers/connectivity/sensors/index/details.js +1 -1
- package/addon/controllers/connectivity/sensors/index.js +37 -1
- package/addon/controllers/maintenance/equipment/index/details.js +2 -2
- package/addon/controllers/maintenance/equipment/index.js +28 -9
- package/addon/controllers/maintenance/inspection-forms/index.js +32 -12
- package/addon/controllers/maintenance/inspection-submissions/index/details.js +2 -1
- package/addon/controllers/maintenance/inspection-submissions/index.js +49 -9
- package/addon/controllers/maintenance/maintenances/index/details.js +2 -0
- package/addon/controllers/maintenance/maintenances/index.js +20 -1
- package/addon/controllers/maintenance/parts/index/details.js +2 -2
- package/addon/controllers/maintenance/parts/index.js +28 -8
- package/addon/controllers/maintenance/schedules/index.js +33 -4
- package/addon/controllers/maintenance/work-orders/index/details.js +3 -3
- package/addon/controllers/maintenance/work-orders/index.js +39 -8
- package/addon/controllers/management/contacts/customers.js +13 -0
- package/addon/controllers/management/contacts/index.js +43 -1
- package/addon/controllers/management/drivers/index/details.js +1 -0
- package/addon/controllers/management/drivers/index.js +32 -2
- package/addon/controllers/management/fleets/index/details.js +1 -0
- package/addon/controllers/management/fleets/index.js +39 -1
- package/addon/controllers/management/fuel-reports/index.js +22 -2
- package/addon/controllers/management/fuel-transactions/index.js +43 -7
- package/addon/controllers/management/issues/index/details.js +1 -0
- package/addon/controllers/management/issues/index.js +22 -2
- package/addon/controllers/management/places/index.js +36 -1
- package/addon/controllers/management/trailers/index/details.js +1 -0
- package/addon/controllers/management/trailers/index.js +50 -2
- package/addon/controllers/management/vehicles/index/details.js +1 -0
- package/addon/controllers/management/vehicles/index.js +33 -2
- package/addon/controllers/management/vendors/index.js +26 -2
- package/addon/controllers/operations/orders/index/details.js +50 -7
- package/addon/controllers/operations/orders/index.js +59 -4
- package/addon/controllers/operations/scheduler/index.js +45 -14
- package/addon/controllers/operations/service-rates/index.js +15 -1
- package/addon/controllers/settings/index.js +6 -0
- package/addon/controllers/settings/map.js +75 -0
- package/addon/controllers/settings/orchestrator.js +8 -6
- package/addon/controllers/settings/tracking-page.js +212 -0
- package/addon/extension.js +97 -1
- package/addon/helpers/parcel-box-image.js +16 -0
- package/addon/routes/operations/orders/index/details.js +1 -0
- package/addon/routes/operations/orders/index/new.js +5 -4
- package/addon/routes/operations/scheduler/index.js +1 -1
- package/addon/routes/settings/tracking-page.js +31 -0
- package/addon/routes.js +1 -0
- package/addon/services/contact-actions.js +1 -0
- package/addon/services/customer-actions.js +2 -1
- package/addon/services/device-actions.js +1 -0
- package/addon/services/device-event-actions.js +1 -0
- package/addon/services/driver-actions.js +4 -13
- package/addon/services/equipment-actions.js +1 -0
- package/addon/services/fleet-actions.js +1 -0
- package/addon/services/fuel-report-actions.js +1 -0
- package/addon/services/inspection-form-actions.js +1 -0
- package/addon/services/inspection-submission-actions.js +1 -0
- package/addon/services/integrated-vendor-actions.js +1 -0
- package/addon/services/issue-actions.js +1 -0
- package/addon/services/location.js +69 -21
- package/addon/services/maintenance-actions.js +1 -0
- package/addon/services/maintenance-schedule-actions.js +2 -1
- package/addon/services/map-settings.js +28 -0
- package/addon/services/order-actions.js +7 -0
- package/addon/services/order-allocation.js +1 -1
- package/addon/services/order-presentation.js +129 -0
- package/addon/services/part-actions.js +1 -0
- package/addon/services/place-actions.js +1 -0
- package/addon/services/sensor-actions.js +1 -0
- package/addon/services/service-area-actions.js +1 -0
- package/addon/services/service-rate-actions.js +1 -0
- package/addon/services/telematic-actions.js +1 -0
- package/addon/services/trailer-actions.js +4 -14
- package/addon/services/vehicle-actions.js +4 -13
- package/addon/services/vendor-actions.js +1 -0
- package/addon/services/work-order-actions.js +1 -0
- package/addon/services/zone-actions.js +1 -0
- package/addon/styles/fleetops-engine.css +1391 -0
- package/addon/templates/analytics/reports/index/details.hbs +1 -0
- package/addon/templates/analytics/reports/index.hbs +1 -0
- package/addon/templates/connectivity/devices/index/details.hbs +1 -0
- package/addon/templates/connectivity/devices/index.hbs +1 -0
- package/addon/templates/connectivity/events/index.hbs +1 -0
- package/addon/templates/connectivity/sensors/index/details.hbs +1 -0
- package/addon/templates/connectivity/sensors/index.hbs +1 -0
- package/addon/templates/maintenance/equipment/index/details.hbs +1 -0
- package/addon/templates/maintenance/equipment/index.hbs +2 -0
- package/addon/templates/maintenance/inspection-forms/index/details.hbs +1 -0
- package/addon/templates/maintenance/inspection-forms/index.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index/details.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index.hbs +1 -0
- package/addon/templates/maintenance/maintenances/index/details.hbs +1 -0
- package/addon/templates/maintenance/maintenances/index.hbs +1 -0
- package/addon/templates/maintenance/parts/index/details.hbs +1 -0
- package/addon/templates/maintenance/parts/index.hbs +2 -0
- package/addon/templates/maintenance/schedules/index/details.hbs +1 -0
- package/addon/templates/maintenance/schedules/index.hbs +2 -0
- package/addon/templates/maintenance/work-orders/index/details.hbs +1 -0
- package/addon/templates/maintenance/work-orders/index.hbs +1 -0
- package/addon/templates/management/contacts/customers/details.hbs +1 -0
- package/addon/templates/management/contacts/customers.hbs +1 -0
- package/addon/templates/management/contacts/index/details.hbs +1 -0
- package/addon/templates/management/contacts/index.hbs +1 -0
- package/addon/templates/management/contacts.hbs +1 -0
- package/addon/templates/management/drivers/index/details.hbs +1 -0
- package/addon/templates/management/drivers/index.hbs +2 -0
- package/addon/templates/management/fleets/index/details.hbs +1 -0
- package/addon/templates/management/fleets/index.hbs +1 -0
- package/addon/templates/management/fuel-reports/index/details.hbs +1 -0
- package/addon/templates/management/fuel-reports/index.hbs +1 -0
- package/addon/templates/management/fuel-transactions/index.hbs +1 -0
- package/addon/templates/management/issues/index/details.hbs +1 -0
- package/addon/templates/management/issues/index.hbs +1 -0
- package/addon/templates/management/places/index/details.hbs +1 -0
- package/addon/templates/management/places/index.hbs +1 -0
- package/addon/templates/management/trailers/index/details.hbs +1 -0
- package/addon/templates/management/trailers/index.hbs +2 -0
- package/addon/templates/management/vehicles/index/details.hbs +1 -0
- package/addon/templates/management/vehicles/index.hbs +2 -0
- package/addon/templates/management/vendors/index/details.hbs +1 -0
- package/addon/templates/management/vendors/index.hbs +2 -0
- package/addon/templates/management/vendors/integrated.hbs +1 -0
- package/addon/templates/operations/orders/index/details.hbs +1 -0
- package/addon/templates/operations/orders/index.hbs +1 -0
- package/addon/templates/operations/service-rates/index/details.hbs +1 -0
- package/addon/templates/operations/service-rates/index.hbs +1 -0
- package/addon/templates/settings/map.hbs +46 -0
- package/addon/templates/settings/tracking-page.hbs +318 -0
- package/addon/utils/identity-cell-resource.js +2 -56
- package/addon/utils/map-default-view.js +132 -0
- package/addon/utils/normalize-order-config-flow.js +6 -1
- package/addon/utils/placeholder-images.js +4 -69
- package/addon/utils/resource-descriptors/assets.js +2 -57
- package/addon/utils/resource-descriptors/helpers.js +23 -122
- package/addon/utils/resource-descriptors/operations.js +2 -61
- package/addon/utils/resource-descriptors/people.js +3 -142
- package/addon/utils/resource-descriptors/shared.js +18 -0
- package/addon/utils/tracking-live-source.js +123 -0
- package/addon/utils/tracking-page-theme.js +123 -0
- package/app/components/admin/tracking-page-settings.js +1 -0
- package/app/components/tracking-page/full-view.js +1 -0
- package/app/components/tracking-page/locale-selector.js +1 -0
- package/app/components/tracking-page/map.js +1 -0
- package/app/components/tracking-page/order-list.js +1 -0
- package/app/components/tracking-page/public-view.js +1 -0
- package/app/components/tracking-page/settings-preview.js +1 -0
- package/app/components/tracking-page/verify-panel.js +1 -0
- package/app/components/tracking-page.js +1 -0
- package/app/components/widget/proof-of-delivery.js +1 -0
- package/app/controllers/settings/tracking-page.js +1 -0
- package/app/helpers/parcel-box-image.js +1 -0
- package/app/routes/settings/tracking-page.js +1 -0
- package/app/services/order-presentation.js +1 -0
- package/app/templates/settings/tracking-page.js +1 -0
- package/app/utils/map-default-view.js +1 -0
- package/app/utils/tracking-live-source.js +1 -0
- package/app/utils/tracking-page-theme.js +1 -0
- package/composer.json +2 -2
- package/extension.json +1 -1
- package/package.json +4 -4
- package/scripts/pest-bootstrap.php +4 -0
- package/server/config/fleetops.php +4 -0
- package/server/migrations/2026_10_08_000001_create_tracking_sessions_tables.php +51 -0
- package/server/migrations/2026_10_10_000001_add_trashed_index_to_device_events.php +40 -0
- package/server/migrations/2026_10_10_000002_add_trashed_index_to_positions.php +40 -0
- package/server/migrations/2026_10_12_000001_add_deleted_at_to_tracking_sessions_tables.php +32 -0
- package/server/resources/views/labels/default.php +2 -2
- package/server/resources/views/labels/entity-label.php +2 -2
- package/server/resources/views/labels/waypoint-label.php +2 -2
- package/server/src/Auth/Schemas/FleetOps.php +5 -0
- package/server/src/Console/Commands/ProcessOperationalAlerts.php +1 -0
- package/server/src/Console/Commands/PruneTelematicsData.php +101 -26
- package/server/src/Events/OrderChanged.php +257 -0
- package/server/src/Events/OrderDriverUnassigned.php +68 -0
- package/server/src/Exceptions/OrderEditLockedException.php +32 -0
- package/server/src/Expansions/CompanyExpansion.php +3 -2
- package/server/src/Expansions/UserExpansion.php +12 -10
- package/server/src/Http/Controllers/Api/v1/CustomerController.php +108 -18
- package/server/src/Http/Controllers/Api/v1/DriverController.php +95 -10
- package/server/src/Http/Controllers/Api/v1/EntityController.php +66 -0
- package/server/src/Http/Controllers/Api/v1/FleetController.php +10 -4
- package/server/src/Http/Controllers/Api/v1/OrderController.php +139 -36
- package/server/src/Http/Controllers/Api/v1/PayloadController.php +76 -8
- package/server/src/Http/Controllers/Api/v1/PlaceController.php +3 -3
- package/server/src/Http/Controllers/Api/v1/TrackingNumberController.php +6 -32
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +5 -0
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +3 -0
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +10 -0
- package/server/src/Http/Controllers/Internal/v1/FleetController.php +16 -2
- package/server/src/Http/Controllers/Internal/v1/InspectionSubmissionController.php +13 -8
- package/server/src/Http/Controllers/Internal/v1/IssueController.php +2 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +4 -2
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +93 -11
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +118 -28
- package/server/src/Http/Controllers/Internal/v1/PositionController.php +22 -0
- package/server/src/Http/Controllers/Internal/v1/ProofController.php +55 -4
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +303 -10
- package/server/src/Http/Controllers/Internal/v1/TrailerController.php +1 -0
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +1 -0
- package/server/src/Http/Controllers/Public/TrackingController.php +518 -0
- package/server/src/Http/Filter/ContactFilter.php +1 -1
- package/server/src/Http/Filter/InspectionFormFilter.php +23 -0
- package/server/src/Http/Filter/InspectionSubmissionFilter.php +23 -0
- package/server/src/Http/Filter/MaintenanceFilter.php +23 -0
- package/server/src/Http/Filter/OrderFilter.php +39 -4
- package/server/src/Http/Filter/ProofFilter.php +18 -0
- package/server/src/Http/Filter/RouteFilter.php +18 -0
- package/server/src/Http/Filter/TelematicFilter.php +23 -0
- package/server/src/Http/Filter/WarrantyFilter.php +23 -0
- package/server/src/Http/Requests/CancelOrderRequest.php +2 -1
- package/server/src/Http/Resources/v1/Concerns/ResolvesPublicRelationFields.php +14 -1
- package/server/src/Http/Resources/v1/Index/Customer.php +18 -0
- package/server/src/Http/Resources/v1/Index/Order.php +11 -2
- package/server/src/Http/Resources/v1/PublicOrderTracking.php +153 -0
- package/server/src/Http/Resources/v1/TrackingNumber.php +8 -34
- package/server/src/Http/Resources/v1/Zone.php +31 -23
- package/server/src/Jobs/FinalizeApiOrderCreation.php +3 -1
- package/server/src/Jobs/ProcessAllocationJob.php +16 -6
- package/server/src/Jobs/PublishTrackingUpdate.php +50 -0
- package/server/src/Listeners/HandleGeofenceEntered.php +31 -15
- package/server/src/Listeners/HandleOrderCanceled.php +9 -1
- package/server/src/Listeners/HandleUserRemovedFromCompany.php +2 -1
- package/server/src/Listeners/PublishTrackingUpdates.php +27 -0
- package/server/src/Mail/CustomerCredentialsMail.php +4 -2
- package/server/src/Models/AssetConnection.php +3 -0
- package/server/src/Models/Contact.php +3 -0
- package/server/src/Models/Device.php +28 -0
- package/server/src/Models/DeviceEvent.php +7 -0
- package/server/src/Models/Driver.php +20 -7
- package/server/src/Models/Entity.php +12 -4
- package/server/src/Models/Fleet.php +11 -32
- package/server/src/Models/FleetDriver.php +3 -0
- package/server/src/Models/FleetVehicle.php +3 -0
- package/server/src/Models/FuelReport.php +5 -13
- package/server/src/Models/Issue.php +4 -16
- package/server/src/Models/Order.php +234 -11
- package/server/src/Models/OrderConfig.php +129 -0
- package/server/src/Models/Payload.php +227 -35
- package/server/src/Models/Place.php +7 -1
- package/server/src/Models/ServiceArea.php +7 -0
- package/server/src/Models/ServiceRate.php +7 -17
- package/server/src/Models/TrackingNumber.php +109 -6
- package/server/src/Models/TrackingSession.php +33 -0
- package/server/src/Models/TrackingSessionGrant.php +22 -0
- package/server/src/Models/TrackingStatus.php +6 -0
- package/server/src/Models/Vehicle.php +21 -2
- package/server/src/Models/Vendor.php +7 -0
- package/server/src/Models/Waypoint.php +13 -4
- package/server/src/Notifications/OrderAssigned.php +2 -1
- package/server/src/Notifications/OrderCanceled.php +7 -1
- package/server/src/Notifications/OrderChanged.php +87 -0
- package/server/src/Notifications/OrderCompleted.php +2 -1
- package/server/src/Notifications/OrderDispatchFailed.php +2 -1
- package/server/src/Notifications/OrderDispatched.php +2 -1
- package/server/src/Notifications/OrderFailed.php +2 -1
- package/server/src/Notifications/OrderUnassigned.php +66 -0
- package/server/src/Notifications/WaypointCompleted.php +2 -1
- package/server/src/Observers/CompanyUserObserver.php +8 -7
- package/server/src/Observers/DriverObserver.php +6 -1
- package/server/src/Observers/OrderObserver.php +141 -1
- package/server/src/Observers/TrackingNumberObserver.php +18 -6
- package/server/src/Observers/UserObserver.php +2 -1
- package/server/src/Observers/VehicleObserver.php +8 -3
- package/server/src/Orchestration/Engines/RouteSequencingEngine.php +21 -3
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +38 -8
- package/server/src/Orchestration/OrchestrationEngineRegistry.php +61 -1
- package/server/src/Orchestration/Support/OrchestratorSettings.php +61 -0
- package/server/src/Orchestration/Support/RouteMetrics.php +165 -0
- package/server/src/Providers/EventServiceProvider.php +11 -0
- package/server/src/Providers/FleetOpsServiceProvider.php +13 -0
- package/server/src/Support/ApiCacheThrottle.php +76 -0
- package/server/src/Support/LiveOrderQuery.php +3 -1
- package/server/src/Support/OrderEdit.php +365 -0
- package/server/src/Support/OrderEditPolicy.php +292 -0
- package/server/src/Support/ProfileAccountManager.php +54 -1
- package/server/src/Support/ResolvesOrderServiceStops.php +5 -0
- package/server/src/Support/SocketChannels.php +346 -0
- package/server/src/Support/Telematics/TelematicService.php +7 -2
- package/server/src/Support/Telematics/Telemetry/Inbox.php +8 -1
- package/server/src/Support/TrackingChannel.php +55 -0
- package/server/src/Support/TrackingCode.php +242 -0
- package/server/src/Support/TrackingPage/TrackingAccess.php +356 -0
- package/server/src/Support/TrackingPage/TrackingPageConfig.php +264 -0
- package/server/src/Support/TrackingPage/TrackingRecipient.php +111 -0
- package/server/src/Support/TrackingPage/TrackingResolver.php +201 -0
- package/server/src/Support/TrackingPage/TrackingTarget.php +40 -0
- package/server/src/Support/TrackingPage/TrackingView.php +543 -0
- package/server/src/Support/TrackingPublisher.php +261 -0
- package/server/src/Support/TrackingScope.php +182 -0
- package/server/src/Support/TrackingUpdate.php +402 -0
- package/server/src/Support/Utils.php +15 -3
- package/server/src/Traits/HasTrackingNumber.php +2 -0
- package/server/src/routes.php +39 -7
- package/server/tests/ApiCustomerControllerContractsTest.php +54 -7
- package/server/tests/ApiDriverPasswordContractsTest.php +25 -21
- package/server/tests/ApiEntityControllerContractsTest.php +84 -0
- package/server/tests/ApiOrderControllerContractsTest.php +245 -0
- package/server/tests/ApiPayloadControllerContractsTest.php +121 -0
- package/server/tests/ApiPlaceControllerContractsTest.php +1 -1
- package/server/tests/ApiTrackingNumberControllerContractsTest.php +6 -9
- package/server/tests/CompactResourceSerializationTest.php +23 -59
- package/server/tests/ControllerFilterContractsTest.php +1 -1
- package/server/tests/CustomerContactIdentitySafetyTest.php +1 -1
- package/server/tests/EventContractsTest.php +26 -60
- package/server/tests/ExpansionContractsTest.php +15 -2
- package/server/tests/Feature/Http/Api/CustomerControllerHelperSeamsTest.php +29 -3
- package/server/tests/Feature/Http/Api/DriverControllerAuthFlowsTest.php +23 -0
- package/server/tests/Feature/Http/Api/OrderControllerNearbyFiltersTest.php +16 -16
- package/server/tests/Feature/Http/Api/OrderControllerQueryFiltersTest.php +41 -14
- package/server/tests/Feature/Http/Api/TrackingNumberControllerHelpersTest.php +57 -22
- package/server/tests/Feature/Http/Internal/DriverControllerCreateRecordTest.php +23 -9
- package/server/tests/Feature/Http/Internal/OrchestrationControllerContractsTest.php +171 -1
- package/server/tests/Feature/Http/Internal/OrderControllerActivityFlowsTest.php +72 -0
- package/server/tests/Feature/Http/Internal/OrderControllerContractsTest.php +110 -14
- package/server/tests/Feature/Http/Internal/OrderControllerCreateRecordTest.php +26 -0
- package/server/tests/Feature/Http/Internal/OrderControllerHelpersTest.php +7 -5
- package/server/tests/Feature/Http/Internal/PositionControllerReplayChannelTest.php +135 -0
- package/server/tests/Feature/Http/Internal/ProofControllerContractsTest.php +3 -3
- package/server/tests/Feature/Http/Internal/ProofControllerRecentTest.php +170 -0
- package/server/tests/Feature/Http/Public/TrackingControllerTest.php +495 -0
- package/server/tests/IndexCustomerPhotoTest.php +151 -0
- package/server/tests/ModelAccessorContractsTest.php +4 -3
- package/server/tests/NotificationAndMailContractsTest.php +5 -8
- package/server/tests/ObserverContractsTest.php +72 -10
- package/server/tests/OrderActivityFlowRegressionTest.php +3 -2
- package/server/tests/OrderConfigLifecycleTest.php +120 -0
- package/server/tests/OrderFilterExecutionTest.php +167 -2
- package/server/tests/ProcessAllocationJobContractsTest.php +20 -0
- package/server/tests/PublicOrderTrackingResourceTest.php +221 -0
- package/server/tests/QueueJobContractsTest.php +2 -1
- package/server/tests/RequestContractsTest.php +1 -1
- package/server/tests/RouteRegistrationExecutionTest.php +26 -0
- package/server/tests/RouteSequencingEngineTest.php +17 -0
- package/server/tests/SettingControllerContractsTest.php +110 -0
- package/server/tests/Support/TrackingPageDatabase.php +200 -0
- package/server/tests/TenantScopingTest.php +206 -0
- package/server/tests/TrackingPageSettingsTest.php +343 -0
- package/server/tests/Unit/Console/PruneTelematicsDataCommandTest.php +51 -0
- package/server/tests/Unit/Events/OrderDispatchFailedTest.php +2 -1
- package/server/tests/Unit/Http/Filter/ContactFilterAddressTest.php +61 -0
- package/server/tests/Unit/Http/Resources/IndexOrderResourceTest.php +30 -0
- package/server/tests/Unit/Jobs/FinalizeApiOrderCreationDispatchGuardTest.php +266 -0
- package/server/tests/Unit/Listeners/HandleGeofenceEnteredTest.php +182 -22
- package/server/tests/Unit/Listeners/HandleUserRemovedFromCompanyTest.php +5 -0
- package/server/tests/Unit/Models/DriverAssignVehicleTest.php +81 -0
- package/server/tests/Unit/Models/FleetTest.php +4 -3
- package/server/tests/Unit/Models/OrderCancelReasonTest.php +143 -0
- package/server/tests/Unit/Models/OrderPayloadConfigAndDistanceTest.php +60 -0
- package/server/tests/Unit/Models/OrderPayloadRouteTest.php +4 -2
- package/server/tests/Unit/Models/PayloadTest.php +18 -4
- package/server/tests/Unit/Models/ServiceRatePersistenceAndServicabilityTest.php +2 -2
- package/server/tests/Unit/Models/TrackingNumberTest.php +67 -6
- package/server/tests/Unit/Models/VehicleTest.php +16 -2
- package/server/tests/Unit/Models/WaypointTest.php +4 -3
- package/server/tests/Unit/Notifications/OrderChangeNotificationsTest.php +59 -0
- package/server/tests/Unit/Notifications/TerminalOrderNotificationsTest.php +3 -3
- package/server/tests/Unit/Observers/DriverDeletionCleanupTest.php +158 -0
- package/server/tests/Unit/Observers/FleetOpsCompanyUserAndServiceAreaObserversTest.php +20 -0
- package/server/tests/Unit/Observers/ObserverListenerSeamsTest.php +3 -3
- package/server/tests/Unit/Observers/OrderAssignmentObserverTest.php +100 -0
- package/server/tests/Unit/Observers/OrderDeleteCascadeTest.php +213 -0
- package/server/tests/Unit/Observers/VehicleObserverDeleteTest.php +67 -0
- package/server/tests/Unit/Orchestration/EngineSelectionAndRouteMetricsTest.php +336 -0
- package/server/tests/Unit/Orchestration/Engines/VroomOrchestrationEngineLifecycleTest.php +8 -1
- package/server/tests/Unit/Support/ApiCacheDependenciesTest.php +347 -0
- package/server/tests/Unit/Support/OrderEditPolicyTest.php +156 -0
- package/server/tests/Unit/Support/OrderOperationsTest.php +514 -0
- package/server/tests/Unit/Support/OsrmProofAndIssueFilterTest.php +4 -3
- package/server/tests/Unit/Support/ProfileAccountManagerTest.php +141 -0
- package/server/tests/Unit/Support/QuerySeamsTest.php +5 -1
- package/server/tests/Unit/Support/SocketChannelsTest.php +396 -0
- package/server/tests/Unit/Support/TrackingChannelTest.php +232 -0
- package/server/tests/Unit/Support/TrackingCodeTest.php +186 -0
- package/server/tests/Unit/Support/TrackingPage/TrackingAccessTest.php +200 -0
- package/server/tests/Unit/Support/TrackingPage/TrackingRecipientTest.php +51 -0
- package/server/tests/Unit/Support/TrackingPage/TrackingResolverTest.php +181 -0
- package/server/tests/Unit/Support/TrackingPage/TrackingViewTest.php +479 -0
- package/server/tests/Unit/Support/TrackingPublisherTest.php +425 -0
- package/server/tests/Unit/Support/TrackingUpdateTest.php +363 -0
- package/server/tests/Unit/Support/UtilsAdditionalTest.php +9 -0
- package/server/tests/Unit/Support/UtilsGeoMatrixAndVendorTest.php +25 -0
- package/server/tests/VehicleResourceContractsTest.php +46 -0
- package/server/tests/VroomOrchestrationEngineTest.php +34 -1
- package/server/tests/ZoneGeofenceSettingsResourceTest.php +121 -0
- package/translations/ar-ae.yml +274 -0
- package/translations/bg-bg.yaml +274 -0
- package/translations/en-us.yaml +347 -0
- package/translations/es-pa.yaml +274 -0
- package/translations/fr-fr.yaml +274 -0
- package/translations/mn-mn.yaml +274 -0
- package/translations/pt-br.yaml +274 -0
- package/translations/ru-ru.yaml +276 -2
- package/translations/uk-ua.yaml +275 -1
- package/translations/vi-vn.yaml +274 -0
- package/addon/components/cell/contact-identity.hbs +0 -1
- package/addon/components/cell/customer-identity.hbs +0 -1
- package/addon/components/cell/driver-identity.hbs +0 -1
- package/addon/components/cell/fleet-identity.hbs +0 -1
- package/addon/components/cell/order-identity.hbs +0 -1
- package/addon/components/cell/place-identity.hbs +0 -1
- package/addon/components/cell/vehicle-identity.hbs +0 -1
- package/addon/components/cell/vendor-identity.hbs +0 -1
- package/addon/components/contact/pill.hbs +0 -24
- package/addon/components/contact/summary.hbs +0 -1
- package/addon/components/customer/pill.hbs +0 -24
- package/addon/components/customer/summary.hbs +0 -1
- package/addon/components/driver/pill.hbs +0 -24
- package/addon/components/driver/summary.hbs +0 -1
- package/addon/components/fleet/pill.hbs +0 -24
- package/addon/components/fleet/summary.hbs +0 -1
- package/addon/components/order/pill.hbs +0 -24
- package/addon/components/order/summary.hbs +0 -1
- package/addon/components/place/pill.hbs +0 -24
- package/addon/components/place/summary.hbs +0 -1
- package/addon/components/select-option/contact.hbs +0 -12
- package/addon/components/select-option/customer.hbs +0 -12
- package/addon/components/select-option/driver.hbs +0 -12
- package/addon/components/select-option/fleet.hbs +0 -12
- package/addon/components/select-option/order.hbs +0 -12
- package/addon/components/select-option/place.hbs +0 -12
- package/addon/components/select-option/vehicle.hbs +0 -12
- package/addon/components/select-option/vendor.hbs +0 -12
- package/addon/components/vehicle/pill.hbs +0 -24
- package/addon/components/vehicle/summary.hbs +0 -1
- package/addon/components/vendor/pill.hbs +0 -24
- package/addon/components/vendor/summary.hbs +0 -1
- package/app/components/cell/contact-identity.js +0 -1
- package/app/components/cell/customer-identity.js +0 -1
- package/app/components/cell/driver-identity.js +0 -1
- package/app/components/cell/fleet-identity.js +0 -1
- package/app/components/cell/order-identity.js +0 -1
- package/app/components/cell/place-identity.js +0 -1
- package/app/components/cell/vehicle-identity.js +0 -1
- package/app/components/cell/vendor-identity.js +0 -1
- package/app/components/contact/pill.js +0 -1
- package/app/components/contact/summary.js +0 -1
- package/app/components/customer/pill.js +0 -1
- package/app/components/customer/summary.js +0 -1
- package/app/components/driver/pill.js +0 -1
- package/app/components/driver/summary.js +0 -1
- package/app/components/fleet/pill.js +0 -1
- package/app/components/fleet/summary.js +0 -1
- package/app/components/order/pill.js +0 -1
- package/app/components/order/summary.js +0 -1
- package/app/components/place/pill.js +0 -1
- package/app/components/place/summary.js +0 -1
- package/app/components/select-option/contact.js +0 -1
- package/app/components/select-option/customer.js +0 -1
- package/app/components/select-option/driver.js +0 -1
- package/app/components/select-option/fleet.js +0 -1
- package/app/components/select-option/order.js +0 -1
- package/app/components/select-option/place.js +0 -1
- package/app/components/select-option/vehicle.js +0 -1
- package/app/components/select-option/vendor.js +0 -1
- package/app/components/vehicle/pill.js +0 -1
- package/app/components/vehicle/summary.js +0 -1
- package/app/components/vendor/pill.js +0 -1
- package/app/components/vendor/summary.js +0 -1
package/addon/extension.js
CHANGED
|
@@ -117,12 +117,34 @@ export default {
|
|
|
117
117
|
icon: 'satellite-dish',
|
|
118
118
|
component: new ExtensionComponent('@fleetbase/fleetops-engine', 'admin/telematics-settings'),
|
|
119
119
|
}),
|
|
120
|
+
new MenuItem({
|
|
121
|
+
title: 'Tracking Page',
|
|
122
|
+
icon: 'magnifying-glass-location',
|
|
123
|
+
component: new ExtensionComponent('@fleetbase/fleetops-engine', 'admin/tracking-page-settings'),
|
|
124
|
+
}),
|
|
120
125
|
],
|
|
121
126
|
{
|
|
122
127
|
slug: 'fleet-ops',
|
|
123
128
|
}
|
|
124
129
|
);
|
|
125
130
|
|
|
131
|
+
// Links printed or emailed without the public `~/` prefix (/track-order?order=...) land
|
|
132
|
+
// inside the console. Signed-out visitors are sent on to the public route after login;
|
|
133
|
+
// registering the page in the console too shows it to signed-in staff instead of an
|
|
134
|
+
// empty console page.
|
|
135
|
+
for (const slug of ['track', 'track-order']) {
|
|
136
|
+
menuService.registerMenuItem(
|
|
137
|
+
'console',
|
|
138
|
+
new MenuItem({
|
|
139
|
+
title: 'Track Order',
|
|
140
|
+
slug,
|
|
141
|
+
section: null,
|
|
142
|
+
view: null,
|
|
143
|
+
component: new ExtensionComponent('@fleetbase/fleetops-engine', 'tracking-page'),
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
126
148
|
// Register track order button
|
|
127
149
|
menuService.registerMenuItem(
|
|
128
150
|
'auth:login',
|
|
@@ -135,7 +157,39 @@ export default {
|
|
|
135
157
|
// btn-auth (ember-ui): the sign-in page's neutral button, matching the
|
|
136
158
|
// console's "Continue with ..." provider buttons, hover included.
|
|
137
159
|
wrapperClass: 'btn-block btn-auth',
|
|
138
|
-
component: new ExtensionComponent('@fleetbase/fleetops-engine', '
|
|
160
|
+
component: new ExtensionComponent('@fleetbase/fleetops-engine', 'tracking-page'),
|
|
161
|
+
onClick: (menuItem) => {
|
|
162
|
+
universe.transitionMenuItem('virtual', menuItem);
|
|
163
|
+
},
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// The customer tracking page: /~/track/{number} is the shared page.
|
|
168
|
+
menuService.registerMenuItem(
|
|
169
|
+
'auth:login',
|
|
170
|
+
new MenuItem({
|
|
171
|
+
title: 'Track',
|
|
172
|
+
route: 'virtual',
|
|
173
|
+
slug: 'track',
|
|
174
|
+
type: 'link',
|
|
175
|
+
wrapperClass: 'hidden',
|
|
176
|
+
component: new ExtensionComponent('@fleetbase/fleetops-engine', 'tracking-page'),
|
|
177
|
+
onClick: (menuItem) => {
|
|
178
|
+
universe.transitionMenuItem('virtual', menuItem);
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// A company's own tracking page: /~/t/{slug}/{number}.
|
|
184
|
+
menuService.registerMenuItem(
|
|
185
|
+
'auth:login',
|
|
186
|
+
new MenuItem({
|
|
187
|
+
title: 'Company tracking',
|
|
188
|
+
route: 'virtual',
|
|
189
|
+
slug: 't',
|
|
190
|
+
type: 'link',
|
|
191
|
+
wrapperClass: 'hidden',
|
|
192
|
+
component: new ExtensionComponent('@fleetbase/fleetops-engine', 'tracking-page'),
|
|
139
193
|
onClick: (menuItem) => {
|
|
140
194
|
universe.transitionMenuItem('virtual', menuItem);
|
|
141
195
|
},
|
|
@@ -162,6 +216,38 @@ export default {
|
|
|
162
216
|
|
|
163
217
|
// Create registries
|
|
164
218
|
this.createRegistries(registryService);
|
|
219
|
+
|
|
220
|
+
// Declare the registries extensions can add table columns, actions and
|
|
221
|
+
// buttons to, e.g. `fleet-ops:driver:table:columns` or `fleet-ops:order:details:menu`.
|
|
222
|
+
universe
|
|
223
|
+
.getService('universe/resource-view-service')
|
|
224
|
+
?.declare('fleet-ops', [
|
|
225
|
+
'contact',
|
|
226
|
+
'customer',
|
|
227
|
+
'device',
|
|
228
|
+
'device-event',
|
|
229
|
+
'driver',
|
|
230
|
+
'equipment',
|
|
231
|
+
'fleet',
|
|
232
|
+
'fuel-report',
|
|
233
|
+
'fuel-transaction',
|
|
234
|
+
'inspection-form',
|
|
235
|
+
'inspection-submission',
|
|
236
|
+
'integrated-vendor',
|
|
237
|
+
'issue',
|
|
238
|
+
'maintenance',
|
|
239
|
+
'order',
|
|
240
|
+
'part',
|
|
241
|
+
'place',
|
|
242
|
+
'report',
|
|
243
|
+
'schedule',
|
|
244
|
+
'sensor',
|
|
245
|
+
'service-rate',
|
|
246
|
+
'trailer',
|
|
247
|
+
'vehicle',
|
|
248
|
+
'vendor',
|
|
249
|
+
'work-order',
|
|
250
|
+
]);
|
|
165
251
|
registryService.registerRenderableComponent('ai:action-preview:fleet-ops.create_order', new ExtensionComponent('@fleetbase/fleetops-engine', 'ai/create-order-preview'));
|
|
166
252
|
|
|
167
253
|
// // Register console home guidance
|
|
@@ -381,6 +467,16 @@ export default {
|
|
|
381
467
|
order: 80,
|
|
382
468
|
default: true,
|
|
383
469
|
}),
|
|
470
|
+
new Widget({
|
|
471
|
+
id: 'fleet-ops-proof-of-delivery-widget',
|
|
472
|
+
name: 'Proof of Delivery',
|
|
473
|
+
description: 'The latest proof of delivery photos, each linking to its order.',
|
|
474
|
+
icon: 'camera',
|
|
475
|
+
component: new ExtensionComponent('@fleetbase/fleetops-engine', 'widget/proof-of-delivery'),
|
|
476
|
+
grid_options: { w: 4, h: 9, minW: 3, minH: 6 },
|
|
477
|
+
category: 'Operations',
|
|
478
|
+
default: false,
|
|
479
|
+
}),
|
|
384
480
|
new Widget({
|
|
385
481
|
id: 'fleet-ops-geofence-violations-widget',
|
|
386
482
|
name: 'Geofence Violations',
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { helper } from '@ember/component/helper';
|
|
2
|
+
|
|
3
|
+
// Each URL is written out in full so a production build's fingerprinting
|
|
4
|
+
// (broccoli-asset-rev) rewrites it to the hashed file name. An interpolated
|
|
5
|
+
// path such as `boxes/${size}.png` is never rewritten, so it misses the
|
|
6
|
+
// fingerprinted file and the server answers with the console's index.html.
|
|
7
|
+
const PARCEL_BOX_IMAGES = {
|
|
8
|
+
small: '/engines-dist/images/boxes/small.png',
|
|
9
|
+
medium: '/engines-dist/images/boxes/medium.png',
|
|
10
|
+
large: '/engines-dist/images/boxes/large.png',
|
|
11
|
+
'x-large': '/engines-dist/images/boxes/x-large.png',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default helper(function parcelBoxImage([size]) {
|
|
15
|
+
return PARCEL_BOX_IMAGES[size] ?? PARCEL_BOX_IMAGES.medium;
|
|
16
|
+
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Route from '@ember/routing/route';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
|
-
import { action } from '@ember/object';
|
|
4
3
|
|
|
5
4
|
export default class OperationsOrdersIndexNewRoute extends Route {
|
|
6
5
|
@service notifications;
|
|
@@ -9,9 +8,11 @@ export default class OperationsOrdersIndexNewRoute extends Route {
|
|
|
9
8
|
@service intl;
|
|
10
9
|
@service sidebar;
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
// Reset the draft only when leaving the route. A refresh of this route (e.g. after saving
|
|
12
|
+
// a place or customer from a modal) also transitions, and must keep what was entered.
|
|
13
|
+
resetController(controller, isExiting) {
|
|
14
|
+
if (isExiting) {
|
|
15
|
+
controller.reset();
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -61,7 +61,7 @@ export default class OperationsSchedulerIndexRoute extends Route {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
resetController(controller) {
|
|
64
|
-
// Close
|
|
64
|
+
// Close the board's own socket channels when the dispatcher navigates away
|
|
65
65
|
// to prevent memory leaks and stale event handlers.
|
|
66
66
|
controller.unsubscribeFromRealTimeUpdates();
|
|
67
67
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class SettingsTrackingPageRoute extends Route {
|
|
5
|
+
@service notifications;
|
|
6
|
+
@service hostRouter;
|
|
7
|
+
@service abilities;
|
|
8
|
+
@service intl;
|
|
9
|
+
@service fetch;
|
|
10
|
+
|
|
11
|
+
beforeModel() {
|
|
12
|
+
if (this.abilities.cannot('fleet-ops view tracking-page-settings')) {
|
|
13
|
+
this.notifications.warning(this.intl.t('common.unauthorized-access'));
|
|
14
|
+
return this.hostRouter.transitionTo('console.fleet-ops');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async model() {
|
|
19
|
+
try {
|
|
20
|
+
return await this.fetch.get('fleet-ops/settings/tracking-page-settings');
|
|
21
|
+
} catch (error) {
|
|
22
|
+
this.notifications.serverError(error);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setupController(controller, model) {
|
|
28
|
+
super.setupController(controller, model);
|
|
29
|
+
controller.load(model);
|
|
30
|
+
}
|
|
31
|
+
}
|
package/addon/routes.js
CHANGED
|
@@ -323,6 +323,7 @@ export default buildRoutes(function () {
|
|
|
323
323
|
this.route('map');
|
|
324
324
|
this.route('orchestrator');
|
|
325
325
|
this.route('scheduling');
|
|
326
|
+
this.route('tracking-page');
|
|
326
327
|
this.route('telematics');
|
|
327
328
|
this.route('payments', function () {
|
|
328
329
|
this.route('index', { path: '/' });
|
|
@@ -48,6 +48,7 @@ export default class ContactActionsService extends ResourceActionService {
|
|
|
48
48
|
},
|
|
49
49
|
view: (contact, options = {}) => {
|
|
50
50
|
return this.resourceContextPanel.open({
|
|
51
|
+
registry: this.detailsRegistry,
|
|
51
52
|
contact,
|
|
52
53
|
title: contact?.name,
|
|
53
54
|
header: 'contact/panel-header',
|
|
@@ -4,7 +4,7 @@ import { PANEL_DEFAULTS, registeredPanelTabs } from '../utils/context-panel';
|
|
|
4
4
|
export default class CustomerActionsService extends ContactActionsService {
|
|
5
5
|
constructor() {
|
|
6
6
|
super(...arguments);
|
|
7
|
-
this.initialize('contact', { defaultAttributes: { type: 'customer', status: 'active' } });
|
|
7
|
+
this.initialize('contact', { defaultAttributes: { type: 'customer', status: 'active' }, registryResource: 'customer' });
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
transition = {
|
|
@@ -38,6 +38,7 @@ export default class CustomerActionsService extends ContactActionsService {
|
|
|
38
38
|
},
|
|
39
39
|
view: (customer, options = {}) => {
|
|
40
40
|
return this.resourceContextPanel.open({
|
|
41
|
+
registry: this.detailsRegistry,
|
|
41
42
|
customer,
|
|
42
43
|
title: customer?.name,
|
|
43
44
|
header: 'contact/panel-header',
|
|
@@ -48,6 +48,7 @@ export default class DeviceActionsService extends ResourceActionService {
|
|
|
48
48
|
const service = this;
|
|
49
49
|
|
|
50
50
|
return this.resourceContextPanel.open({
|
|
51
|
+
registry: this.detailsRegistry,
|
|
51
52
|
device,
|
|
52
53
|
header: 'device/panel-header',
|
|
53
54
|
title: device.name ?? device.serial_number,
|
|
@@ -2,9 +2,7 @@ import ResourceActionService, { inject as service } from '@fleetbase/ember-core/
|
|
|
2
2
|
import leafletIcon from '@fleetbase/ember-core/utils/leaflet-icon';
|
|
3
3
|
import config from 'ember-get-config';
|
|
4
4
|
import { action } from '@ember/object';
|
|
5
|
-
import {
|
|
6
|
-
import { dasherize } from '@ember/string';
|
|
7
|
-
import { PANEL_DEFAULTS, closePanelsThen } from '../utils/context-panel';
|
|
5
|
+
import { PANEL_DEFAULTS, closePanelsThen, registeredPanelTabs } from '../utils/context-panel';
|
|
8
6
|
import { confirmLoginAction, hasInactiveLogin, hasManagedLogin } from '../utils/profile-login-actions';
|
|
9
7
|
|
|
10
8
|
export default class DriverActionsService extends ResourceActionService {
|
|
@@ -13,16 +11,8 @@ export default class DriverActionsService extends ResourceActionService {
|
|
|
13
11
|
@service issueActions;
|
|
14
12
|
|
|
15
13
|
get registeredTabs() {
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
.map((tab) => {
|
|
19
|
-
delete tab.route;
|
|
20
|
-
if (!tab.key) {
|
|
21
|
-
tab.key = tab.id ?? dasherize(tab.label ?? tab.title);
|
|
22
|
-
}
|
|
23
|
-
return tab;
|
|
24
|
-
})
|
|
25
|
-
.filter((tab) => !tab.component);
|
|
14
|
+
// Copies, so the shared registry items keep the \`route\` their routed details view needs.
|
|
15
|
+
return registeredPanelTabs(this.menuService, 'fleet-ops:component:driver:details');
|
|
26
16
|
}
|
|
27
17
|
|
|
28
18
|
get panelTabs() {
|
|
@@ -125,6 +115,7 @@ export default class DriverActionsService extends ResourceActionService {
|
|
|
125
115
|
const service = this;
|
|
126
116
|
|
|
127
117
|
return this.resourceContextPanel.open({
|
|
118
|
+
registry: this.detailsRegistry,
|
|
128
119
|
driver,
|
|
129
120
|
header: 'driver/panel-header',
|
|
130
121
|
actionButtons: [
|
|
@@ -47,6 +47,7 @@ export default class EquipmentActionsService extends ResourceActionService {
|
|
|
47
47
|
},
|
|
48
48
|
view: (equipment, options = {}) => {
|
|
49
49
|
return this.resourceContextPanel.open({
|
|
50
|
+
registry: this.detailsRegistry,
|
|
50
51
|
equipment,
|
|
51
52
|
title: equipment?.name,
|
|
52
53
|
header: 'equipment/panel-header',
|
|
@@ -43,6 +43,7 @@ export default class FuelReportActionsService extends ResourceActionService {
|
|
|
43
43
|
},
|
|
44
44
|
view: (fuelReport, options = {}) => {
|
|
45
45
|
return this.resourceContextPanel.open({
|
|
46
|
+
registry: this.detailsRegistry,
|
|
46
47
|
fuelReport,
|
|
47
48
|
title: fuelReport?.name ?? `Fuel reported on ${fuelReport?.createdAt ?? ''}`.trim(),
|
|
48
49
|
actionButtons: [{ icon: 'pencil', permission: 'fleet-ops update fuel-report', fn: () => closePanelsThen(this.resourceContextPanel, () => this.panel.edit(fuelReport)) }],
|
|
@@ -4,7 +4,7 @@ import { isBlank } from '@ember/utils';
|
|
|
4
4
|
import { isArray } from '@ember/array';
|
|
5
5
|
import { later } from '@ember/runloop';
|
|
6
6
|
import { debug } from '@ember/debug';
|
|
7
|
-
import
|
|
7
|
+
import { isLatitude, isLongitude, isZoom } from '../utils/map-default-view';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Service for managing and retrieving user location data.
|
|
@@ -46,17 +46,30 @@ export default class LocationService extends Service {
|
|
|
46
46
|
*/
|
|
47
47
|
@service fetch;
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Company map settings, which carry the default map view.
|
|
51
|
+
* @type {MapSettingsService}
|
|
52
|
+
*/
|
|
53
|
+
@service mapSettings;
|
|
54
|
+
|
|
49
55
|
/**
|
|
50
56
|
* Current latitude of the user.
|
|
51
57
|
* @type {number}
|
|
52
58
|
*/
|
|
53
|
-
@tracked latitude =
|
|
59
|
+
@tracked latitude = LocationService.DEFAULT_LATITUDE;
|
|
54
60
|
|
|
55
61
|
/**
|
|
56
62
|
* Current longitude of the user.
|
|
57
63
|
* @type {number}
|
|
58
64
|
*/
|
|
59
|
-
@tracked longitude =
|
|
65
|
+
@tracked longitude = LocationService.DEFAULT_LONGITUDE;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Zoom suggested by the source of the location (a company default view or
|
|
69
|
+
* a country centre), or null to let the map use its own default.
|
|
70
|
+
* @type {number|null}
|
|
71
|
+
*/
|
|
72
|
+
@tracked zoom = null;
|
|
60
73
|
|
|
61
74
|
/**
|
|
62
75
|
* Flag indicating whether the user's location has been located.
|
|
@@ -73,7 +86,7 @@ export default class LocationService extends Service {
|
|
|
73
86
|
if (typeof this.latitude === 'number' && !isNaN(this.latitude) && this.latitude >= -90 && this.latitude <= 90) {
|
|
74
87
|
return this.latitude;
|
|
75
88
|
}
|
|
76
|
-
return
|
|
89
|
+
return LocationService.DEFAULT_LATITUDE;
|
|
77
90
|
}
|
|
78
91
|
|
|
79
92
|
/**
|
|
@@ -85,14 +98,23 @@ export default class LocationService extends Service {
|
|
|
85
98
|
if (typeof this.longitude === 'number' && !isNaN(this.longitude) && this.longitude >= -180 && this.longitude <= 180) {
|
|
86
99
|
return this.longitude;
|
|
87
100
|
}
|
|
88
|
-
return
|
|
101
|
+
return LocationService.DEFAULT_LONGITUDE;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Retrieves the zoom suggested by the current location source, or null.
|
|
106
|
+
* @returns {number|null}
|
|
107
|
+
*/
|
|
108
|
+
getZoom() {
|
|
109
|
+
return isZoom(this.zoom) ? this.zoom : null;
|
|
89
110
|
}
|
|
90
111
|
|
|
91
112
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
113
|
+
* Resolves where maps should open. A company-configured default centre
|
|
114
|
+
* (Settings > Map) wins outright. Otherwise it tries the active order
|
|
115
|
+
* destinations, then the browser's geolocation API, then the IP lookup,
|
|
116
|
+
* then the centre of the company's country, then the hardcoded default.
|
|
117
|
+
* See utils/map-default-view for the full precedence.
|
|
96
118
|
*
|
|
97
119
|
* @returns {Promise<Object>} A promise that resolves to an object containing latitude and longitude.
|
|
98
120
|
*/
|
|
@@ -102,6 +124,14 @@ export default class LocationService extends Service {
|
|
|
102
124
|
return { latitude: this.latitude, longitude: this.longitude };
|
|
103
125
|
}
|
|
104
126
|
|
|
127
|
+
// The company's chosen starting point beats any guess about the user.
|
|
128
|
+
await this.mapSettings.load();
|
|
129
|
+
const defaultCenter = this.mapSettings.defaultMapCenter;
|
|
130
|
+
if (defaultCenter) {
|
|
131
|
+
this.updateLocation(defaultCenter);
|
|
132
|
+
return { latitude: defaultCenter.latitude, longitude: defaultCenter.longitude };
|
|
133
|
+
}
|
|
134
|
+
|
|
105
135
|
try {
|
|
106
136
|
const coordinates = await this.fetch.cachedGet('fleet-ops/live/coordinates', {}, { expirationInterval: 1, expirationIntervalUnit: 'hour' });
|
|
107
137
|
|
|
@@ -184,33 +214,51 @@ export default class LocationService extends Service {
|
|
|
184
214
|
}
|
|
185
215
|
}
|
|
186
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Discards the resolved location and resolves it again, e.g. after the
|
|
219
|
+
* company's default map view changed. Listeners of `user.located` (the
|
|
220
|
+
* live map) move to the new location.
|
|
221
|
+
*
|
|
222
|
+
* @returns {Promise<Object>} The newly resolved coordinates.
|
|
223
|
+
*/
|
|
224
|
+
async relocate() {
|
|
225
|
+
this.located = false;
|
|
226
|
+
return this.getUserLocation();
|
|
227
|
+
}
|
|
228
|
+
|
|
187
229
|
/**
|
|
188
230
|
* Retrieves the user's location based on WHOIS data associated with their account.
|
|
189
|
-
*
|
|
231
|
+
* When the IP lookup failed it falls back to the centre of the company's
|
|
232
|
+
* country, and only then to the predefined coordinates.
|
|
190
233
|
*
|
|
191
234
|
* @returns {Object} An object containing latitude and longitude from WHOIS data or default values.
|
|
192
235
|
*/
|
|
193
236
|
getUserLocationFromWhois() {
|
|
194
|
-
const whois = this.currentUser.getOption('whois', {});
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
237
|
+
const whois = this.currentUser.getOption('whois', {}) ?? {};
|
|
238
|
+
const latitude = Number(whois.latitude);
|
|
239
|
+
const longitude = Number(whois.longitude);
|
|
240
|
+
// The IP lookup's fallback reports null coordinates, which Number() turns into Null Island.
|
|
241
|
+
const hasWhoisCoordinates = whois.latitude != null && whois.longitude != null && isLatitude(latitude) && isLongitude(longitude);
|
|
242
|
+
|
|
243
|
+
const location = hasWhoisCoordinates
|
|
244
|
+
? { latitude, longitude }
|
|
245
|
+
: (this.mapSettings.companyCountryCenter ?? { latitude: LocationService.DEFAULT_LATITUDE, longitude: LocationService.DEFAULT_LONGITUDE });
|
|
246
|
+
|
|
247
|
+
this.updateLocation(location);
|
|
248
|
+
return { latitude: location.latitude, longitude: location.longitude };
|
|
202
249
|
}
|
|
203
250
|
|
|
204
251
|
/**
|
|
205
252
|
* Updates the service's tracked properties with the new location data.
|
|
206
253
|
* Triggers an event to notify other parts of the application that the user's location has been updated.
|
|
207
254
|
*
|
|
208
|
-
* @param {Object} coordinates - An object containing the latitude and longitude to be set.
|
|
255
|
+
* @param {Object} coordinates - An object containing the latitude and longitude to be set, and optionally a suggested zoom.
|
|
209
256
|
*/
|
|
210
|
-
updateLocation({ latitude, longitude }) {
|
|
257
|
+
updateLocation({ latitude, longitude, zoom = null }) {
|
|
211
258
|
this.latitude = latitude;
|
|
212
259
|
this.longitude = longitude;
|
|
260
|
+
this.zoom = isZoom(zoom) ? zoom : null;
|
|
213
261
|
this.located = true;
|
|
214
|
-
this.universe.trigger('user.located', { latitude, longitude });
|
|
262
|
+
this.universe.trigger('user.located', { latitude, longitude, zoom: this.zoom });
|
|
215
263
|
}
|
|
216
264
|
}
|
|
@@ -44,6 +44,7 @@ export default class MaintenanceActionsService extends ResourceActionService {
|
|
|
44
44
|
},
|
|
45
45
|
view: (maintenance, options = {}) => {
|
|
46
46
|
return this.resourceContextPanel.open({
|
|
47
|
+
registry: this.detailsRegistry,
|
|
47
48
|
maintenance,
|
|
48
49
|
title: maintenance?.summary,
|
|
49
50
|
header: 'maintenance/panel-header',
|
|
@@ -11,7 +11,7 @@ export default class MaintenanceScheduleActionsService extends ResourceActionSer
|
|
|
11
11
|
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
14
|
-
this.initialize('maintenance-schedule');
|
|
14
|
+
this.initialize('maintenance-schedule', { registryResource: 'schedule' });
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
transition = {
|
|
@@ -43,6 +43,7 @@ export default class MaintenanceScheduleActionsService extends ResourceActionSer
|
|
|
43
43
|
},
|
|
44
44
|
view: (schedule, options = {}) => {
|
|
45
45
|
return this.resourceContextPanel.open({
|
|
46
|
+
registry: this.detailsRegistry,
|
|
46
47
|
schedule,
|
|
47
48
|
title: schedule?.name,
|
|
48
49
|
actionButtons: this.panelActionButtons(schedule, { onDeleted: () => this.resourceContextPanel.closeAll() }),
|
|
@@ -2,6 +2,7 @@ import Service from '@ember/service';
|
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
4
|
import { getLeafletTileUrl } from '../utils/leaflet-tile-url';
|
|
5
|
+
import { defaultMapCenter, companyCountryCenter } from '../utils/map-default-view';
|
|
5
6
|
|
|
6
7
|
const DEFAULT_SETTINGS = {
|
|
7
8
|
mapProvider: 'leaflet',
|
|
@@ -12,6 +13,11 @@ const DEFAULT_SETTINGS = {
|
|
|
12
13
|
googleMapsMapType: 'roadmap',
|
|
13
14
|
showGoogleMapsTrafficLayer: false,
|
|
14
15
|
showGoogleMapsTransitLayer: false,
|
|
16
|
+
defaultMapLatitude: null,
|
|
17
|
+
defaultMapLongitude: null,
|
|
18
|
+
defaultMapZoom: null,
|
|
19
|
+
fitMapToVehicles: false,
|
|
20
|
+
companyMapCenter: null,
|
|
15
21
|
};
|
|
16
22
|
|
|
17
23
|
export default class MapSettingsService extends Service {
|
|
@@ -47,6 +53,28 @@ export default class MapSettingsService extends Service {
|
|
|
47
53
|
return Boolean(this.settings.showGoogleMapsTransitLayer);
|
|
48
54
|
}
|
|
49
55
|
|
|
56
|
+
/**
|
|
57
|
+
* The company's configured default centre for the live map, or null.
|
|
58
|
+
*
|
|
59
|
+
* @return {{latitude: Number, longitude: Number, zoom: Number}|null}
|
|
60
|
+
*/
|
|
61
|
+
get defaultMapCenter() {
|
|
62
|
+
return defaultMapCenter(this.settings);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The centre of the company's country, used when nothing better is known.
|
|
67
|
+
*
|
|
68
|
+
* @return {{latitude: Number, longitude: Number, zoom: Number}|null}
|
|
69
|
+
*/
|
|
70
|
+
get companyCountryCenter() {
|
|
71
|
+
return companyCountryCenter(this.settings);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get fitMapToVehicles() {
|
|
75
|
+
return Boolean(this.settings.fitMapToVehicles);
|
|
76
|
+
}
|
|
77
|
+
|
|
50
78
|
get isGoogleMaps() {
|
|
51
79
|
return this.mapProvider === 'google';
|
|
52
80
|
}
|
|
@@ -6,6 +6,7 @@ import { task } from 'ember-concurrency';
|
|
|
6
6
|
|
|
7
7
|
export default class OrderActionsService extends ResourceActionService {
|
|
8
8
|
@service store;
|
|
9
|
+
@service orderPresentation;
|
|
9
10
|
modelNamePath = 'tracking';
|
|
10
11
|
|
|
11
12
|
constructor() {
|
|
@@ -54,6 +55,7 @@ export default class OrderActionsService extends ResourceActionService {
|
|
|
54
55
|
},
|
|
55
56
|
view: (order, options = {}) => {
|
|
56
57
|
return this.resourceContextPanel.open({
|
|
58
|
+
registry: this.detailsRegistry,
|
|
57
59
|
order,
|
|
58
60
|
tabs: [
|
|
59
61
|
{
|
|
@@ -313,6 +315,11 @@ export default class OrderActionsService extends ResourceActionService {
|
|
|
313
315
|
@action editOrderDetails(order, options = {}) {
|
|
314
316
|
options = options === null ? {} : options;
|
|
315
317
|
|
|
318
|
+
// Orders with a presentation profile are edited in the profiled order form, not the fixed modal.
|
|
319
|
+
if (this.orderPresentation.profileFor(order)) {
|
|
320
|
+
return this.panel.edit(order, options);
|
|
321
|
+
}
|
|
322
|
+
|
|
316
323
|
this.modalsManager.show('modals/order-form', {
|
|
317
324
|
title: this.intl.t('order.actions.edit-order-details'),
|
|
318
325
|
acceptButtonText: this.intl.t('common.save-changes'),
|
|
@@ -35,7 +35,7 @@ export default class OrderAllocationService extends Service {
|
|
|
35
35
|
@task *loadSettings() {
|
|
36
36
|
try {
|
|
37
37
|
const settings = yield this.fetch.get('fleet-ops/settings/orchestrator-settings');
|
|
38
|
-
this.activeEngineId = settings.
|
|
38
|
+
this.activeEngineId = settings.allocation_engine ?? 'greedy';
|
|
39
39
|
return settings;
|
|
40
40
|
} catch (error) {
|
|
41
41
|
this.notifications.serverError(error);
|