@fleetbase/fleetops-engine 0.6.71 → 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 +15 -18
- 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/form/route.hbs +1 -1
- package/addon/components/order/form/route.js +13 -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/operations/orders/index/details.js +19 -3
- package/addon/controllers/operations/scheduler/index.js +45 -14
- 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 +65 -1
- package/addon/helpers/parcel-box-image.js +16 -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/location.js +69 -21
- package/addon/services/map-settings.js +28 -0
- package/addon/services/order-allocation.js +1 -1
- package/addon/styles/fleetops-engine.css +1391 -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/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/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 +84 -24
- 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 +200 -9
- 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 +101 -2
- 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/OrderControllerContractsTest.php +110 -14
- 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/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/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 +287 -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
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps the public tracking page current.
|
|
3
|
+
*
|
|
4
|
+
* `start(onUpdate, onState)` calls `load()` on a schedule and hands each result to
|
|
5
|
+
* `onUpdate`; `onState` hears `live`, `reconnecting` or `paused`. It polls every 20
|
|
6
|
+
* seconds while the delivery is moving and every 60 otherwise, pauses while the tab is
|
|
7
|
+
* hidden, and backs off up to 2 minutes when requests fail. A socket source can replace
|
|
8
|
+
* it later with the same two callbacks.
|
|
9
|
+
*/
|
|
10
|
+
export const ACTIVE_INTERVAL = 20000;
|
|
11
|
+
export const IDLE_INTERVAL = 60000;
|
|
12
|
+
export const MAX_BACKOFF = 120000;
|
|
13
|
+
|
|
14
|
+
export default class TrackingLiveSource {
|
|
15
|
+
constructor(load, { isActive = () => true, documentRef = typeof document === 'undefined' ? null : document } = {}) {
|
|
16
|
+
this.load = load;
|
|
17
|
+
this.isActive = isActive;
|
|
18
|
+
this.document = documentRef;
|
|
19
|
+
this.timer = null;
|
|
20
|
+
this.failures = 0;
|
|
21
|
+
this.running = false;
|
|
22
|
+
this.onVisibility = () => this.visibilityChanged();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
start(onUpdate, onState = () => {}) {
|
|
26
|
+
this.onUpdate = onUpdate;
|
|
27
|
+
this.onState = onState;
|
|
28
|
+
this.running = true;
|
|
29
|
+
this.document?.addEventListener('visibilitychange', this.onVisibility);
|
|
30
|
+
this.schedule();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
stop() {
|
|
34
|
+
this.running = false;
|
|
35
|
+
clearTimeout(this.timer);
|
|
36
|
+
this.timer = null;
|
|
37
|
+
this.document?.removeEventListener('visibilitychange', this.onVisibility);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get hidden() {
|
|
41
|
+
return this.document?.visibilityState === 'hidden';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get delay() {
|
|
45
|
+
if (this.failures > 0) {
|
|
46
|
+
return Math.min(MAX_BACKOFF, ACTIVE_INTERVAL * Math.pow(2, this.failures - 1));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return this.isActive() ? ACTIVE_INTERVAL : IDLE_INTERVAL;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
schedule() {
|
|
53
|
+
clearTimeout(this.timer);
|
|
54
|
+
if (!this.running || this.hidden) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.timer = setTimeout(() => this.tick(), this.delay);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async tick() {
|
|
62
|
+
if (!this.running) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const result = await this.load();
|
|
68
|
+
this.failures = 0;
|
|
69
|
+
this.onState('live');
|
|
70
|
+
this.onUpdate(result);
|
|
71
|
+
} catch {
|
|
72
|
+
this.failures += 1;
|
|
73
|
+
this.onState('reconnecting');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.schedule();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
visibilityChanged() {
|
|
80
|
+
if (this.hidden) {
|
|
81
|
+
clearTimeout(this.timer);
|
|
82
|
+
this.onState?.('paused');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.tick();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* An encoded polyline (precision 5, as Google Routes and OSRM return it) as [lat, lng] pairs.
|
|
92
|
+
*/
|
|
93
|
+
export function decodePolyline(encoded) {
|
|
94
|
+
if (typeof encoded !== 'string' || encoded === '') {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const points = [];
|
|
99
|
+
let index = 0;
|
|
100
|
+
let lat = 0;
|
|
101
|
+
let lng = 0;
|
|
102
|
+
|
|
103
|
+
while (index < encoded.length) {
|
|
104
|
+
const deltas = [];
|
|
105
|
+
for (let axis = 0; axis < 2; axis++) {
|
|
106
|
+
let result = 0;
|
|
107
|
+
let shift = 0;
|
|
108
|
+
let byte;
|
|
109
|
+
do {
|
|
110
|
+
byte = encoded.charCodeAt(index++) - 63;
|
|
111
|
+
result |= (byte & 0x1f) << shift;
|
|
112
|
+
shift += 5;
|
|
113
|
+
} while (byte >= 0x20 && index < encoded.length);
|
|
114
|
+
deltas.push(result & 1 ? ~(result >> 1) : result >> 1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
lat += deltas[0];
|
|
118
|
+
lng += deltas[1];
|
|
119
|
+
points.push([lat / 1e5, lng / 1e5]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return points;
|
|
123
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colour tokens for the customer tracking page, derived from a company's one accent colour.
|
|
3
|
+
*
|
|
4
|
+
* The server sanitizes and checks the same values (TrackingPageConfig); this mirrors it so
|
|
5
|
+
* the settings preview and the page itself re-theme live without a round trip.
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_ACCENT = '#1F5FA8';
|
|
8
|
+
export const LIGHT_INK = '#FFFFFF';
|
|
9
|
+
export const DARK_INK = '#14191A';
|
|
10
|
+
|
|
11
|
+
const LIGHT_BASE = {
|
|
12
|
+
bg: '#F3F4F1',
|
|
13
|
+
surface: '#FFFFFF',
|
|
14
|
+
surface2: '#ECEEEA',
|
|
15
|
+
text: '#14191A',
|
|
16
|
+
muted: '#545D5F',
|
|
17
|
+
border: '#D9DED9',
|
|
18
|
+
warn: '#A8430B',
|
|
19
|
+
'warn-soft': '#FBEADF',
|
|
20
|
+
neutral: '#5F686A',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const DARK_BASE = {
|
|
24
|
+
bg: '#0D1112',
|
|
25
|
+
surface: '#151A1B',
|
|
26
|
+
surface2: '#1D2324',
|
|
27
|
+
text: '#E9EDEA',
|
|
28
|
+
muted: '#A1ABAB',
|
|
29
|
+
border: '#2B3335',
|
|
30
|
+
warn: '#F2A262',
|
|
31
|
+
'warn-soft': '#3A2416',
|
|
32
|
+
neutral: '#8E9899',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* `#RGB` or `#RRGGBB` as uppercase `#RRGGBB`, or null.
|
|
37
|
+
*/
|
|
38
|
+
export function normalizeHex(value) {
|
|
39
|
+
const match = typeof value === 'string' ? value.trim().match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i) : null;
|
|
40
|
+
if (!match) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let hex = match[1];
|
|
45
|
+
if (hex.length === 3) {
|
|
46
|
+
hex = hex.replace(/./g, (char) => char + char);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return `#${hex.toUpperCase()}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function channels(hex) {
|
|
53
|
+
const value = hex.replace('#', '');
|
|
54
|
+
return [0, 2, 4].map((offset) => parseInt(value.slice(offset, offset + 2), 16));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function luminance(hex) {
|
|
58
|
+
const [r, g, b] = channels(hex).map((channel) => {
|
|
59
|
+
const value = channel / 255;
|
|
60
|
+
return value <= 0.03928 ? value / 12.92 : Math.pow((value + 0.055) / 1.055, 2.4);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The WCAG contrast ratio of two `#RRGGBB` colours, rounded to two decimals.
|
|
68
|
+
*/
|
|
69
|
+
export function contrastRatio(a, b) {
|
|
70
|
+
const lighter = Math.max(luminance(a), luminance(b));
|
|
71
|
+
const darker = Math.min(luminance(a), luminance(b));
|
|
72
|
+
|
|
73
|
+
return Math.round(((lighter + 0.05) / (darker + 0.05)) * 100) / 100;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The text colour readable on an accent: white when it reaches 4.5:1, otherwise dark.
|
|
78
|
+
*/
|
|
79
|
+
export function inkFor(accent) {
|
|
80
|
+
return contrastRatio(accent, LIGHT_INK) >= 4.5 ? LIGHT_INK : DARK_INK;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A lighter accent for dark mode: the accent mixed toward white until it reads on the dark surface.
|
|
85
|
+
*/
|
|
86
|
+
export function darkAccentFor(accent) {
|
|
87
|
+
const [r, g, b] = channels(accent);
|
|
88
|
+
for (let weight = 0.25; weight <= 0.85; weight += 0.05) {
|
|
89
|
+
const mixed = [r, g, b].map((channel) => Math.round(channel + (255 - channel) * weight));
|
|
90
|
+
const hex = `#${mixed.map((channel) => channel.toString(16).padStart(2, '0')).join('')}`.toUpperCase();
|
|
91
|
+
if (contrastRatio(hex, DARK_BASE.surface) >= 4.5) {
|
|
92
|
+
return hex;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return '#FFFFFF';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The CSS custom properties for a page in the given mode, as a style string.
|
|
101
|
+
*
|
|
102
|
+
* @param {Object} branding the config's branding group
|
|
103
|
+
* @param {Boolean} dark whether the page renders dark
|
|
104
|
+
*/
|
|
105
|
+
export default function trackingPageTheme(branding = {}, dark = false) {
|
|
106
|
+
const accent = normalizeHex(branding.accent) ?? DEFAULT_ACCENT;
|
|
107
|
+
const darkAccent = normalizeHex(branding.accent_dark) ?? darkAccentFor(accent);
|
|
108
|
+
const modeAccent = dark ? darkAccent : accent;
|
|
109
|
+
const base = dark ? DARK_BASE : LIGHT_BASE;
|
|
110
|
+
const tokens = {
|
|
111
|
+
...base,
|
|
112
|
+
accent: modeAccent,
|
|
113
|
+
ink: inkFor(modeAccent),
|
|
114
|
+
'accent-soft': `color-mix(in oklab, ${modeAccent} 14%, ${base.surface})`,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const declarations = [`color-scheme: ${dark ? 'dark' : 'light'}`];
|
|
118
|
+
for (const name of Object.keys(tokens)) {
|
|
119
|
+
declarations.push(`--tp-${name}: ${tokens[name]}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return declarations.join('; ');
|
|
123
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/admin/tracking-page-settings';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/tracking-page/full-view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/tracking-page/locale-selector';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/tracking-page/map';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/tracking-page/order-list';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/tracking-page/public-view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/tracking-page/settings-preview';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/tracking-page/verify-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/tracking-page';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/widget/proof-of-delivery';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/controllers/settings/tracking-page';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/helpers/parcel-box-image';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/settings/tracking-page';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/settings/tracking-page';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@fleetbase/fleetops-engine/utils/map-default-view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, decodePolyline, ACTIVE_INTERVAL, IDLE_INTERVAL, MAX_BACKOFF } from '@fleetbase/fleetops-engine/utils/tracking-live-source';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, normalizeHex, contrastRatio, inkFor, darkAccentFor, DEFAULT_ACCENT, LIGHT_INK, DARK_INK } from '@fleetbase/fleetops-engine/utils/tracking-page-theme';
|
package/composer.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fleetbase/fleetops-api",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.72",
|
|
4
4
|
"description": "Fleet & Transport Management Extension for Fleetbase",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fleetbase-extension",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"barryvdh/laravel-dompdf": "^3.1",
|
|
26
26
|
"brick/geo": "0.7.2",
|
|
27
27
|
"cknow/laravel-money": "^7.1",
|
|
28
|
-
"fleetbase/core-api": "
|
|
28
|
+
"fleetbase/core-api": "^1.6.69",
|
|
29
29
|
"geocoder-php/google-maps-places-provider": "^1.4",
|
|
30
30
|
"giggsey/libphonenumber-for-php": "^8.13",
|
|
31
31
|
"league/geotools": "^1.1.0",
|
package/extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetbase/fleetops-engine",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.72",
|
|
4
4
|
"description": "Fleet & Transport Management Extension for Fleetbase",
|
|
5
5
|
"fleetbase": {
|
|
6
6
|
"route": "fleet-ops"
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@babel/core": "^7.23.2",
|
|
47
|
-
"@fleetbase/ember-core": "^0.3.
|
|
48
|
-
"@fleetbase/ember-ui": "^0.4.
|
|
49
|
-
"@fleetbase/fleetops-data": "^0.2.
|
|
47
|
+
"@fleetbase/ember-core": "^0.3.26",
|
|
48
|
+
"@fleetbase/ember-ui": "^0.4.6",
|
|
49
|
+
"@fleetbase/fleetops-data": "^0.2.3",
|
|
50
50
|
"@fleetbase/leaflet-routing-machine": "^3.2.17",
|
|
51
51
|
"@fortawesome/ember-fontawesome": "^2.0.0",
|
|
52
52
|
"@fortawesome/fontawesome-svg-core": "6.4.0",
|
|
@@ -53,6 +53,10 @@ if (class_exists('Illuminate\Container\Container') && class_exists('Illuminate\S
|
|
|
53
53
|
'fleetops' => [],
|
|
54
54
|
'services' => [],
|
|
55
55
|
'telematics' => [],
|
|
56
|
+
// The core SMS guard is off unless a test turns it on: its counters live in the
|
|
57
|
+
// shared cache, so one file's sends would otherwise rate-limit the next's, and
|
|
58
|
+
// a second text to the same number inside a test trips its cooldown.
|
|
59
|
+
'sms' => ['guard' => ['enabled' => false]],
|
|
56
60
|
]));
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -88,6 +88,10 @@ return [
|
|
|
88
88
|
'route_cache_ttl_seconds' => env('TRACKING_ROUTE_CACHE_TTL_SECONDS', 600),
|
|
89
89
|
'stale_location_threshold_seconds' => env('TRACKING_STALE_LOCATION_THRESHOLD_SECONDS', 300),
|
|
90
90
|
'default_vehicle_speed_kph' => env('TRACKING_DEFAULT_VEHICLE_SPEED_KPH', 35),
|
|
91
|
+
// The public tracking page's device-session cookie. `lax` suits a console and API on
|
|
92
|
+
// the same site (console.example.com and api.example.com); use `none` (sent only over
|
|
93
|
+
// HTTPS) when they are on different domains.
|
|
94
|
+
'cookie_same_site' => env('TRACKING_COOKIE_SAME_SITE', 'lax'),
|
|
91
95
|
],
|
|
92
96
|
|
|
93
97
|
/*
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Database\Migrations\Migration;
|
|
4
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
5
|
+
use Illuminate\Support\Facades\Schema;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Device sessions for the public customer tracking page.
|
|
9
|
+
*
|
|
10
|
+
* A visitor who enters a correct one-time code gets a device session, carried in an
|
|
11
|
+
* httpOnly cookie whose value is never stored: `token_hash` is its SHA-256. Each session
|
|
12
|
+
* holds grants, one per customer within an order (the TrackingScope), so verifying for one
|
|
13
|
+
* delivery never unlocks another and one customer never sees another's stops.
|
|
14
|
+
*/
|
|
15
|
+
return new class extends Migration {
|
|
16
|
+
public function up(): void
|
|
17
|
+
{
|
|
18
|
+
Schema::create('tracking_sessions', function (Blueprint $table) {
|
|
19
|
+
$table->increments('id');
|
|
20
|
+
$table->uuid('uuid')->unique();
|
|
21
|
+
$table->string('token_hash', 64)->unique();
|
|
22
|
+
$table->string('ip', 64)->nullable();
|
|
23
|
+
$table->string('user_agent', 255)->nullable();
|
|
24
|
+
$table->timestamp('last_seen_at')->nullable();
|
|
25
|
+
$table->timestamp('expires_at')->nullable()->index();
|
|
26
|
+
$table->timestamp('revoked_at')->nullable();
|
|
27
|
+
$table->timestamps();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
Schema::create('tracking_session_grants', function (Blueprint $table) {
|
|
31
|
+
$table->increments('id');
|
|
32
|
+
$table->uuid('uuid')->unique();
|
|
33
|
+
$table->uuid('tracking_session_uuid')->index();
|
|
34
|
+
$table->uuid('company_uuid')->nullable()->index();
|
|
35
|
+
$table->uuid('order_uuid');
|
|
36
|
+
$table->string('customer_type');
|
|
37
|
+
$table->uuid('customer_uuid');
|
|
38
|
+
$table->string('channel', 16)->nullable();
|
|
39
|
+
$table->timestamp('expires_at')->nullable()->index();
|
|
40
|
+
$table->timestamps();
|
|
41
|
+
|
|
42
|
+
$table->index(['tracking_session_uuid', 'order_uuid', 'customer_uuid'], 'tracking_session_grants_scope_index');
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public function down(): void
|
|
47
|
+
{
|
|
48
|
+
Schema::dropIfExists('tracking_session_grants');
|
|
49
|
+
Schema::dropIfExists('tracking_sessions');
|
|
50
|
+
}
|
|
51
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Fleetbase\FleetOps\Support\Database\TableIndexes;
|
|
4
|
+
use Illuminate\Database\Migrations\Migration;
|
|
5
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
6
|
+
use Illuminate\Support\Facades\Schema;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* fleetops:prune-telematics-data purges soft-deleted rows on every run; without an
|
|
10
|
+
* index on deleted_at that sweep walks the whole table even when nothing is trashed.
|
|
11
|
+
*/
|
|
12
|
+
return new class extends Migration {
|
|
13
|
+
private const TABLE = 'device_events';
|
|
14
|
+
private const INDEX = 'device_events_company_deleted_at_index';
|
|
15
|
+
private const COLUMNS = ['company_uuid', 'deleted_at'];
|
|
16
|
+
|
|
17
|
+
public function up(): void
|
|
18
|
+
{
|
|
19
|
+
if (!Schema::hasTable(self::TABLE) || !Schema::hasColumns(self::TABLE, self::COLUMNS)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (TableIndexes::covers(self::TABLE, self::COLUMNS)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Schema::table(self::TABLE, fn (Blueprint $table) => $table->index(self::COLUMNS, self::INDEX));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public function down(): void
|
|
31
|
+
{
|
|
32
|
+
if (!Schema::hasTable(self::TABLE)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if ((TableIndexes::for(self::TABLE)[self::INDEX] ?? null) === self::COLUMNS) {
|
|
37
|
+
Schema::table(self::TABLE, fn (Blueprint $table) => $table->dropIndex(self::INDEX));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Fleetbase\FleetOps\Support\Database\TableIndexes;
|
|
4
|
+
use Illuminate\Database\Migrations\Migration;
|
|
5
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
6
|
+
use Illuminate\Support\Facades\Schema;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* fleetops:prune-telematics-data purges soft-deleted rows on every run; without an
|
|
10
|
+
* index on deleted_at that sweep walks the whole table even when nothing is trashed.
|
|
11
|
+
*/
|
|
12
|
+
return new class extends Migration {
|
|
13
|
+
private const TABLE = 'positions';
|
|
14
|
+
private const INDEX = 'positions_company_deleted_at_index';
|
|
15
|
+
private const COLUMNS = ['company_uuid', 'deleted_at'];
|
|
16
|
+
|
|
17
|
+
public function up(): void
|
|
18
|
+
{
|
|
19
|
+
if (!Schema::hasTable(self::TABLE) || !Schema::hasColumns(self::TABLE, self::COLUMNS)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (TableIndexes::covers(self::TABLE, self::COLUMNS)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Schema::table(self::TABLE, fn (Blueprint $table) => $table->index(self::COLUMNS, self::INDEX));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public function down(): void
|
|
31
|
+
{
|
|
32
|
+
if (!Schema::hasTable(self::TABLE)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if ((TableIndexes::for(self::TABLE)[self::INDEX] ?? null) === self::COLUMNS) {
|
|
37
|
+
Schema::table(self::TABLE, fn (Blueprint $table) => $table->dropIndex(self::INDEX));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Database\Migrations\Migration;
|
|
4
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
5
|
+
use Illuminate\Support\Facades\Schema;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* TrackingSession and TrackingSessionGrant extend Fleetbase\Models\Model, which soft
|
|
9
|
+
* deletes, so every query on them reads `deleted_at`. The tables were created without
|
|
10
|
+
* it, which made each session and grant lookup fail and no visitor could verify.
|
|
11
|
+
*/
|
|
12
|
+
return new class extends Migration {
|
|
13
|
+
private const TABLES = ['tracking_sessions', 'tracking_session_grants'];
|
|
14
|
+
|
|
15
|
+
public function up(): void
|
|
16
|
+
{
|
|
17
|
+
foreach (self::TABLES as $table) {
|
|
18
|
+
if (Schema::hasTable($table) && !Schema::hasColumn($table, 'deleted_at')) {
|
|
19
|
+
Schema::table($table, fn (Blueprint $blueprint) => $blueprint->softDeletes());
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public function down(): void
|
|
25
|
+
{
|
|
26
|
+
foreach (self::TABLES as $table) {
|
|
27
|
+
if (Schema::hasTable($table) && Schema::hasColumn($table, 'deleted_at')) {
|
|
28
|
+
Schema::table($table, fn (Blueprint $blueprint) => $blueprint->dropSoftDeletes());
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -53,7 +53,7 @@ use Fleetbase\Support\Utils;
|
|
|
53
53
|
<div style="width: 420px; border: 2px #414141 solid; margin: auto;">
|
|
54
54
|
<div class="group" style="border-bottom: 1px #414141 solid; overflow: hidden;">
|
|
55
55
|
<div style="float: left; width: 130px; height: 120px; border-right: 1px #414141 solid; text-align: center; padding: 10px; box-sizing: border-box;">
|
|
56
|
-
<img src="data:image/png;base64,<?php echo Utils::notEmpty($trackingNumber) ? $trackingNumber->qr_code : $order->trackingNumber->qr_code; ?>" style="width:
|
|
56
|
+
<img src="data:image/png;base64,<?php echo Utils::notEmpty($trackingNumber) ? $trackingNumber->qr_code : $order->trackingNumber->qr_code; ?>" style="width: 100px; height: 100px;">
|
|
57
57
|
</div>
|
|
58
58
|
<div style="margin-top: 10px; padding-left: 10px;">
|
|
59
59
|
<div style="font-size: 18px; font-weight: bold;"><?php echo e($company->name); ?></div>
|
|
@@ -185,7 +185,7 @@ use Fleetbase\Support\Utils;
|
|
|
185
185
|
<?php } ?>
|
|
186
186
|
<div class="group">
|
|
187
187
|
<div style="text-align: center; padding: 15px 0px; border-top: 1px #414141 solid;">
|
|
188
|
-
<img src="data:image/png;base64,<?php echo isset($trackingNumber) ? $trackingNumber->barcode : $order->trackingNumber->barcode; ?>" style="height: 90px; margin-top: 10px;">
|
|
188
|
+
<img src="data:image/png;base64,<?php echo isset($trackingNumber) ? $trackingNumber->barcode : $order->trackingNumber->barcode; ?>" style="max-width: 360px; max-height: 90px; margin-top: 10px;">
|
|
189
189
|
<div><?php echo e(strtoupper(isset($trackingNumber) ? $trackingNumber->tracking_number : $order->trackingNumber->tracking_number)); ?></div>
|
|
190
190
|
</div>
|
|
191
191
|
</div>
|
|
@@ -45,7 +45,7 @@ use Fleetbase\Support\Utils;
|
|
|
45
45
|
<div style="width: 420px; border: 2px #414141 solid; margin: auto;">
|
|
46
46
|
<div class="group" style="border-bottom: 1px #414141 solid; overflow: hidden;">
|
|
47
47
|
<div style="float: left; width: 130px; height: 120px; border-right: 1px #414141 solid; text-align: center; padding: 10px; box-sizing: border-box;">
|
|
48
|
-
<img src="data:image/png;base64,<?= Utils::notEmpty($trackingNumber) ? $trackingNumber->qr_code : $entity->qr_code ?>" style="width:
|
|
48
|
+
<img src="data:image/png;base64,<?= Utils::notEmpty($trackingNumber) ? $trackingNumber->qr_code : $entity->qr_code ?>" style="width: 100px; height: 100px;">
|
|
49
49
|
</div>
|
|
50
50
|
<div style="margin-top: 10px;">
|
|
51
51
|
<span style="padding-left: 10px; font-size: 18px; font-weight: bold;"><?= strtoupper($company->name) ?></span>
|
|
@@ -114,7 +114,7 @@ use Fleetbase\Support\Utils;
|
|
|
114
114
|
<?php } ?>
|
|
115
115
|
<div class="group">
|
|
116
116
|
<div style="text-align: center; padding: 15px 0px; border-top: 1px #414141 solid;">
|
|
117
|
-
<img src="data:image/png;base64,<?= isset($trackingNumber) ? $trackingNumber->barcode : $entity->barcode ?>" style="height: 90px; margin-top: 10px;">
|
|
117
|
+
<img src="data:image/png;base64,<?= isset($trackingNumber) ? $trackingNumber->barcode : $entity->barcode ?>" style="max-width: 360px; max-height: 90px; margin-top: 10px;">
|
|
118
118
|
<div><?= strtoupper(isset($trackingNumber) ? $trackingNumber->tracking_number : $entity->public_id) ?></div>
|
|
119
119
|
</div>
|
|
120
120
|
</div>
|
|
@@ -52,7 +52,7 @@ use Fleetbase\Support\Utils;
|
|
|
52
52
|
<div style="width: 420px; border: 2px #414141 solid; margin: auto;">
|
|
53
53
|
<div class="group" style="border-bottom: 1px #414141 solid; overflow: hidden;">
|
|
54
54
|
<div style="float: left; width: 130px; height: 120px; border-right: 1px #414141 solid; text-align: center; padding: 10px; box-sizing: border-box;">
|
|
55
|
-
<img src="data:image/png;base64,<?php echo Utils::notEmpty($trackingNumber) ? $trackingNumber->qr_code : $order->trackingNumber->qr_code; ?>" style="width:
|
|
55
|
+
<img src="data:image/png;base64,<?php echo Utils::notEmpty($trackingNumber) ? $trackingNumber->qr_code : $order->trackingNumber->qr_code; ?>" style="width: 100px; height: 100px;">
|
|
56
56
|
</div>
|
|
57
57
|
<div style="margin-top: 10px;">
|
|
58
58
|
<span style="padding-left: 10px; font-size: 18px; font-weight: bold;"><?php echo e($company->name); ?></span>
|
|
@@ -123,7 +123,7 @@ use Fleetbase\Support\Utils;
|
|
|
123
123
|
<?php } ?>
|
|
124
124
|
<div class="group">
|
|
125
125
|
<div style="text-align: center; padding: 15px 0px; border-top: 1px #414141 solid;">
|
|
126
|
-
<img src="data:image/png;base64,<?php echo isset($trackingNumber) ? $trackingNumber->barcode : $order->trackingNumber->barcode; ?>" style="height: 90px; margin-top: 10px;">
|
|
126
|
+
<img src="data:image/png;base64,<?php echo isset($trackingNumber) ? $trackingNumber->barcode : $order->trackingNumber->barcode; ?>" style="max-width: 360px; max-height: 90px; margin-top: 10px;">
|
|
127
127
|
<div><?php echo e(strtoupper(isset($trackingNumber) ? $trackingNumber->tracking_number : $order->trackingNumber->tracking_number)); ?></div>
|
|
128
128
|
</div>
|
|
129
129
|
</div>
|
|
@@ -229,6 +229,11 @@ class FleetOps
|
|
|
229
229
|
'actions' => [],
|
|
230
230
|
'remove_actions' => ['delete', 'export', 'create'],
|
|
231
231
|
],
|
|
232
|
+
[
|
|
233
|
+
'name' => 'tracking-page-settings', // the customer tracking page: branding, access and what verified visitors see
|
|
234
|
+
'actions' => [],
|
|
235
|
+
'remove_actions' => ['delete', 'export', 'create'],
|
|
236
|
+
],
|
|
232
237
|
[
|
|
233
238
|
'name' => 'telematics-settings', // organization device event and position history preferences
|
|
234
239
|
'action' => [],
|