@fleetbase/fleetops-engine 0.6.49 → 0.6.51
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/README.md +185 -67
- package/addon/components/contact/panel-header.hbs +11 -48
- package/addon/components/customer/create-order-form.hbs +2 -2
- package/addon/components/customer/details.hbs +1 -2
- package/addon/components/customer/form.hbs +62 -50
- package/addon/components/customer/form.js +27 -1
- package/addon/components/customer/order-form.hbs +2 -2
- package/addon/components/customer/orders.hbs +50 -2
- package/addon/components/customer/orders.js +67 -5
- package/addon/components/display-place.hbs +2 -2
- package/addon/components/driver/form.hbs +1 -1
- package/addon/components/home/getting-started-guidance.hbs +113 -0
- package/addon/components/home/getting-started-guidance.js +107 -0
- package/addon/components/issue/details/comments.hbs +3 -0
- package/addon/components/issue/details/comments.js +3 -0
- package/addon/components/issue/details/correspondence.hbs +9 -0
- package/addon/components/issue/details/correspondence.js +83 -0
- package/addon/components/issue/details/documents.hbs +69 -0
- package/addon/components/issue/details/documents.js +85 -0
- package/addon/components/issue/details.hbs +220 -59
- package/addon/components/issue/details.js +245 -0
- package/addon/components/issue/form.hbs +19 -1
- package/addon/components/issue/panel-header.hbs +43 -0
- package/addon/components/issue/panel-header.js +22 -0
- package/addon/components/issue/timeline.hbs +40 -0
- package/addon/components/issue/timeline.js +45 -0
- package/addon/components/leaflet-tracking-marker.js +3 -0
- package/addon/components/map/drawer/position-listing.js +3 -0
- package/addon/components/map/google-live-map.js +6 -2
- package/addon/components/map/leaflet-live-map.hbs +48 -14
- package/addon/components/map/leaflet-live-map.js +201 -20
- package/addon/components/map/order-list-overlay.hbs +4 -4
- package/addon/components/modals/convert-customer-to-vendor.hbs +30 -0
- package/addon/components/modals/convert-customer-to-vendor.js +55 -0
- package/addon/components/modals/issue-assign.hbs +20 -0
- package/addon/components/modals/issue-assign.js +49 -0
- package/addon/components/modals/issue-close.hbs +30 -0
- package/addon/components/modals/issue-close.js +73 -0
- package/addon/components/modals/issue-status.hbs +20 -0
- package/addon/components/modals/issue-status.js +43 -0
- package/addon/components/modals/order-change-destination.hbs +46 -0
- package/addon/components/modals/order-change-destination.js +106 -0
- package/addon/components/modals/reset-customer-credentials.js +12 -6
- package/addon/components/modals/stop-activity.hbs +28 -0
- package/addon/components/modals/stop-activity.js +52 -0
- package/addon/components/modals/update-order-activity.hbs +78 -2
- package/addon/components/modals/update-order-activity.js +197 -5
- package/addon/components/orchestrator/resource-panel.hbs +0 -10
- package/addon/components/orchestrator/resource-panel.js +2 -4
- package/addon/components/order/activity-list.hbs +2 -2
- package/addon/components/order/activity-timeline.hbs +31 -29
- package/addon/components/order/details/activity.hbs +3 -3
- package/addon/components/order/details/activity.js +13 -2
- package/addon/components/order/details/documents.js +2 -0
- package/addon/components/order/details/proof.hbs +40 -38
- package/addon/components/order/details/proof.js +31 -4
- package/addon/components/order/details/purchase-rate.hbs +2 -2
- package/addon/components/order/details/route.hbs +11 -3
- package/addon/components/order/details/route.js +91 -14
- package/addon/components/order/details/tracking.hbs +101 -72
- package/addon/components/order/details/tracking.js +149 -2
- package/addon/components/order/details.hbs +5 -5
- package/addon/components/order/details.js +19 -1
- package/addon/components/order/form/details.hbs +3 -3
- package/addon/components/order/form/documents.js +11 -4
- package/addon/components/order/form/route.hbs +108 -104
- package/addon/components/order/form/route.js +37 -1
- package/addon/components/order/form/service-rate.hbs +2 -2
- package/addon/components/order/header.hbs +1 -1
- package/addon/components/order-config-manager/activity-flow.hbs +4 -1
- package/addon/components/order-config-manager/activity-flow.js +178 -12
- package/addon/components/place/address.js +1 -1
- package/addon/components/route-list.hbs +17 -29
- package/addon/components/route-list.js +42 -10
- package/addon/components/service-rate/details.hbs +42 -1
- package/addon/components/service-rate/form.hbs +119 -1
- package/addon/components/service-rate/form.js +59 -0
- package/addon/components/vehicle/form.js +1 -1
- package/addon/components/vehicle/pill.hbs +1 -1
- package/addon/components/vendor/personnel-manager.hbs +166 -0
- package/addon/components/vendor/personnel-manager.js +143 -0
- package/addon/components/widget/live-fleet.hbs +1 -0
- package/addon/components/widget/live-fleet.js +2 -7
- package/addon/components/widget/revenue-trend.hbs +1 -1
- package/addon/components/widget/revenue-trend.js +75 -2
- package/addon/controllers/management/contacts/customers/details.js +31 -13
- package/addon/controllers/management/contacts/customers.js +16 -5
- package/addon/controllers/management/contacts/index/details.js +31 -13
- package/addon/controllers/management/contacts/index.js +7 -0
- package/addon/controllers/management/issues/index/details.js +52 -6
- package/addon/controllers/management/vehicles/index/new.js +1 -1
- package/addon/controllers/management/vendors/index/details.js +4 -0
- package/addon/controllers/operations/orders/index/details.js +15 -7
- package/addon/controllers/operations/orders/index.js +15 -1
- package/addon/extension.js +19 -12
- package/addon/helpers/format-duration.js +1 -38
- package/addon/helpers/place-address-html.js +2 -2
- package/addon/initializers/load-leaflet-assets.js +5 -6
- package/addon/initializers/patch-ember-leaflet-tooltip-layer.js +51 -0
- package/addon/routes/management/issues/index/details.js +1 -1
- package/addon/routes/operations/service-rates/index.js +1 -1
- package/addon/routes.js +1 -0
- package/addon/services/contact-actions.js +231 -1
- package/addon/services/geofence.js +163 -19
- package/addon/services/getting-started.js +44 -0
- package/addon/services/issue-actions.js +71 -0
- package/addon/services/leaflet-contextmenu-manager.js +27 -0
- package/addon/services/leaflet-map-manager.js +2 -0
- package/addon/services/map-adapter/leaflet.js +19 -0
- package/addon/services/service-areas.js +3 -0
- package/addon/services/vehicle-actions.js +1 -1
- package/addon/styles/fleetops-engine.css +1127 -1
- package/addon/templates/management/contacts/customers/details.hbs +1 -1
- package/addon/templates/management/contacts/index/details.hbs +1 -1
- package/addon/templates/management/contacts.hbs +2 -2
- package/addon/templates/management/issues/index/details/index.hbs +3 -1
- package/addon/templates/management/issues/index/details.hbs +3 -2
- package/addon/templates/management/vendors/index/details/personnel.hbs +1 -2
- package/addon/templates/operations/orders/index/details/index.hbs +2 -2
- package/addon/templates/operations/orders/index.hbs +1 -1
- package/addon/templates/operations/service-rates/index/edit.hbs +1 -0
- package/addon/templates/operations/service-rates/index/new.hbs +1 -0
- package/addon/templates/settings/payments/onboard.hbs +8 -8
- package/addon/utils/fleet-ops-options.js +2 -1
- package/addon/utils/leaflet-draw-namespace-guard.js +22 -0
- package/addon/utils/leaflet-plugin-loader.js +219 -0
- package/addon/utils/normalize-order-config-flow.js +41 -0
- package/addon/utils/place-address-html.js +3 -2
- package/addon/utils/route-visualization.js +54 -7
- package/addon/utils/setup-customer-portal.js +4 -64
- package/app/components/home/getting-started-guidance.js +1 -0
- package/app/components/issue/details/comments.js +1 -0
- package/app/components/issue/details/correspondence.js +1 -0
- package/app/components/issue/details/documents.js +1 -0
- package/app/components/issue/panel-header.js +1 -0
- package/app/components/modals/convert-customer-to-vendor.js +1 -0
- package/app/components/modals/issue-assign.js +1 -0
- package/app/components/modals/issue-close.js +1 -0
- package/app/components/modals/issue-status.js +1 -0
- package/app/components/modals/order-change-destination.js +1 -0
- package/app/components/modals/stop-activity.js +1 -0
- package/app/components/vendor/personnel-manager.js +1 -0
- package/app/helpers/format-duration.js +1 -1
- package/app/services/getting-started.js +1 -0
- package/app/utils/leaflet-draw-namespace-guard.js +1 -0
- package/app/utils/leaflet-plugin-loader.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +5 -5
- package/server/migrations/2026_05_21_000001_add_geographic_rules_to_service_rate_fees_table.php +37 -0
- package/server/migrations/2026_05_25_000001_add_endpoint_tracking_refs_to_payloads_table.php +50 -0
- package/server/migrations/2026_05_27_000001_default_driver_vehicle_statuses_to_available.php +48 -0
- package/server/migrations/2026_05_31_000001_add_portal_fields_to_vendor_personnels_table.php +30 -0
- package/server/migrations/2026_06_03_000000_ensure_tags_column_on_issues_table.php +31 -0
- package/server/migrations/2026_06_03_000001_add_order_uuid_to_issues_table.php +25 -0
- package/server/migrations/2026_06_04_000001_backfill_order_transaction_subjects.php +39 -0
- package/server/migrations/2026_06_04_000002_backfill_order_transaction_directions.php +24 -0
- package/server/resources/views/labels/default.php +57 -49
- package/server/resources/views/labels/waypoint-label.php +27 -20
- package/server/resources/views/mail/customer-credentials.blade.php +16 -13
- package/server/seeders/Testing/ConnectivitySeeder.php +1 -0
- package/server/seeders/Testing/FleetSeeder.php +22 -22
- package/server/seeders/Testing/OrdersSeeder.php +6 -22
- package/server/seeders/Testing/VroomOrchestrationSeeder.php +21 -21
- package/server/src/Console/Commands/AuditCustomerUserConflicts.php +75 -0
- package/server/src/Exceptions/CustomerUserConflictException.php +13 -0
- package/server/src/Expansions/UserFilterExpansion.php +28 -0
- package/server/src/Http/Controllers/Api/v1/ContactController.php +17 -2
- package/server/src/Http/Controllers/Api/v1/CustomerController.php +876 -0
- package/server/src/Http/Controllers/Api/v1/DriverController.php +1 -1
- package/server/src/Http/Controllers/Api/v1/IssueController.php +2 -0
- package/server/src/Http/Controllers/Api/v1/OrderConfigController.php +54 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +109 -80
- package/server/src/Http/Controllers/Api/v1/PlaceController.php +10 -58
- package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +2 -2
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +20 -3
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +154 -0
- package/server/src/Http/Controllers/Internal/v1/CustomerController.php +116 -6
- package/server/src/Http/Controllers/Internal/v1/GettingStartedController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/IssueController.php +251 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +101 -66
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +530 -52
- package/server/src/Http/Controllers/Internal/v1/PlaceController.php +10 -68
- package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +2 -2
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +54 -1
- package/server/src/Http/Controllers/Internal/v1/VendorController.php +89 -0
- package/server/src/Http/Middleware/AuthenticateCustomerToken.php +34 -0
- package/server/src/Http/Requests/CreateCustomerOrderRequest.php +63 -0
- package/server/src/Http/Requests/CreateCustomerRequest.php +48 -0
- package/server/src/Http/Requests/CreateDriverRequest.php +1 -1
- package/server/src/Http/Requests/CreateIssueRequest.php +4 -0
- package/server/src/Http/Requests/CreateVehicleRequest.php +25 -1
- package/server/src/Http/Requests/Internal/CreateDriverRequest.php +1 -1
- package/server/src/Http/Requests/UpdateIssueRequest.php +4 -0
- package/server/src/Http/Requests/VerifyCreateCustomerRequest.php +29 -0
- package/server/src/Http/Resources/Internal/v1/OrderConfig.php +41 -0
- package/server/src/Http/Resources/v1/Customer.php +79 -0
- package/server/src/Http/Resources/v1/Index/Order.php +12 -9
- package/server/src/Http/Resources/v1/Issue.php +25 -0
- package/server/src/Http/Resources/v1/Order.php +20 -18
- package/server/src/Http/Resources/v1/OrderConfig.php +74 -0
- package/server/src/Http/Resources/v1/Payload.php +23 -20
- package/server/src/Http/Resources/v1/ServiceArea.php +33 -19
- package/server/src/Http/Resources/v1/ServiceRateFee.php +7 -0
- package/server/src/Listeners/HandleOrderDispatched.php +2 -2
- package/server/src/Mail/CustomerCredentialsMail.php +5 -6
- package/server/src/Models/Contact.php +122 -66
- package/server/src/Models/Customer.php +64 -0
- package/server/src/Models/Driver.php +12 -3
- package/server/src/Models/Entity.php +2 -2
- package/server/src/Models/Issue.php +47 -6
- package/server/src/Models/Order.php +62 -10
- package/server/src/Models/Payload.php +17 -1
- package/server/src/Models/ServiceArea.php +1 -1
- package/server/src/Models/ServiceRate.php +273 -1
- package/server/src/Models/ServiceRateFee.php +39 -9
- package/server/src/Models/TrackingNumber.php +8 -2
- package/server/src/Models/Vehicle.php +18 -2
- package/server/src/Models/VendorPersonnel.php +10 -1
- package/server/src/Models/Waypoint.php +2 -2
- package/server/src/Models/Zone.php +1 -1
- package/server/src/Notifications/LateDeparture.php +2 -2
- package/server/src/Notifications/ProlongedStoppage.php +2 -2
- package/server/src/Notifications/RouteDeviation.php +2 -2
- package/server/src/Observers/ContactObserver.php +2 -0
- package/server/src/Observers/PurchaseRateObserver.php +20 -0
- package/server/src/Observers/ServiceRateObserver.php +6 -6
- package/server/src/Observers/ZoneObserver.php +56 -0
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +1 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +2 -0
- package/server/src/Support/Analytics/AbstractAnalytics.php +6 -6
- package/server/src/Support/Analytics/FuelEfficiency.php +2 -2
- package/server/src/Support/Analytics/OrdersByStatus.php +1 -1
- package/server/src/Support/Analytics/RevenueTrend.php +0 -1
- package/server/src/Support/Analytics/TopDrivers.php +10 -2
- package/server/src/Support/CustomerAuth.php +98 -0
- package/server/src/Support/GettingStarted.php +144 -0
- package/server/src/Support/LabelPdf.php +52 -0
- package/server/src/Support/Metrics/AbstractMetric.php +4 -4
- package/server/src/Support/PlaceSearch.php +282 -0
- package/server/src/Support/ResolvesOrderServiceStops.php +522 -0
- package/server/src/Tracking/TrackingContextBuilder.php +41 -38
- package/server/src/Tracking/TrackingIntelligenceService.php +109 -9
- package/server/src/Tracking/TrackingStop.php +13 -11
- package/server/src/routes.php +76 -10
- package/server/tests/AnalyticsRoutesTest.php +8 -0
- package/server/tests/CapacityAllocationEngineTest.php +10 -10
- package/server/tests/CustomerContactIdentitySafetyTest.php +95 -0
- package/server/tests/CustomerEndpointTest.php +199 -0
- package/server/tests/DriverVehicleStatusDefaultTest.php +39 -0
- package/server/tests/GettingStartedStatusTest.php +21 -0
- package/server/tests/LabelPdfRenderingTest.php +23 -0
- package/server/tests/LiveControllerViewportTest.php +60 -0
- package/server/tests/MetricsRegistryTest.php +4 -8
- package/server/tests/OrchestrationPayloadBuilderTest.php +2 -2
- package/server/tests/OrderActivityFlowRegressionTest.php +116 -0
- package/server/tests/OrderConfigEndpointTest.php +86 -0
- package/server/tests/OrderFileAttachmentTest.php +20 -0
- package/server/tests/ServiceAreaZoneApiShapeTest.php +78 -0
- package/server/tests/VehicleDriverAssignmentTest.php +18 -0
- package/translations/ar-ae.yml +9 -0
- package/translations/bg-bg.yaml +9 -0
- package/translations/en-us.yaml +12 -0
- package/translations/es-pa.yaml +9 -0
- package/translations/fr-fr.yaml +9 -0
- package/translations/mn-mn.yaml +9 -0
- package/translations/pt-br.yaml +9 -0
- package/translations/ru-ru.yaml +9 -0
- package/translations/vi-vn.yaml +9 -0
- package/server/migrations/2026_05_13_000001_repair_customer_contact_user_types.php +0 -86
package/README.md
CHANGED
|
@@ -1,122 +1,240 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://flb-assets.s3.ap-southeast-1.amazonaws.com/static/fleetbase-logo-svg.svg" width="380" height="100"
|
|
2
|
+
<img src="https://flb-assets.s3.ap-southeast-1.amazonaws.com/static/fleetbase-logo-svg.svg" alt="Fleetbase" width="380" height="100">
|
|
3
3
|
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Fleet-Ops</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Open-source fleet, dispatch, transport management, and real-time logistics operations for Fleetbase.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
4
11
|
<p align="center">
|
|
5
|
-
|
|
12
|
+
<a href="https://github.com/fleetbase/fleetops">
|
|
13
|
+
<img src="https://img.shields.io/badge/repo-fleetbase%2Ffleetops-111827?style=flat-square" alt="Repository">
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://github.com/fleetbase/fleetops/blob/master/LICENSE.md">
|
|
16
|
+
<img src="https://img.shields.io/badge/license-AGPL--3.0--or--later-blue?style=flat-square" alt="License: AGPL-3.0-or-later">
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/@fleetbase/fleetops-engine">
|
|
19
|
+
<img src="https://img.shields.io/badge/npm-%40fleetbase%2Ffleetops--engine-CB3837?style=flat-square" alt="NPM package">
|
|
20
|
+
</a>
|
|
21
|
+
<a href="https://packagist.org/packages/fleetbase/fleetops-api">
|
|
22
|
+
<img src="https://img.shields.io/badge/packagist-fleetbase%2Ffleetops--api-F28D1A?style=flat-square" alt="Packagist package">
|
|
23
|
+
</a>
|
|
24
|
+
<a href="https://www.fleetbase.io/docs/fleet-ops">
|
|
25
|
+
<img src="https://img.shields.io/badge/docs-fleet--ops-0EA5E9?style=flat-square" alt="Fleet-Ops documentation">
|
|
26
|
+
</a>
|
|
27
|
+
<img src="https://img.shields.io/badge/node-%3E%3D18-339933?style=flat-square" alt="Node >= 18">
|
|
28
|
+
<img src="https://img.shields.io/badge/php-%5E8.0-777BB4?style=flat-square" alt="PHP ^8.0">
|
|
6
29
|
</p>
|
|
7
30
|
|
|
8
|
-
|
|
31
|
+
<p align="center">
|
|
32
|
+
<img src="https://www.fleetbase.io/images/screenshots/fleet-ops/fleet-ops-multi-waypoint-order.webp" alt="Fleet-Ops multi-waypoint order with live map, route, driver assignment, and order details" width="900">
|
|
33
|
+
</p>
|
|
9
34
|
|
|
10
|
-
##
|
|
35
|
+
## What is Fleet-Ops?
|
|
11
36
|
|
|
12
|
-
|
|
37
|
+
Fleet-Ops is the core logistics and fleet management extension for the [Fleetbase](https://www.fleetbase.io) platform. It gives operations teams a dispatch console for managing orders, drivers, vehicles, fleets, service areas, live maps, route execution, analytics, maintenance, and connected telematics.
|
|
13
38
|
|
|
14
|
-
|
|
39
|
+
Fleet-Ops ships as two packages:
|
|
15
40
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
41
|
+
| Package | Purpose |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `@fleetbase/fleetops-engine` | Ember Engine/Add-on that powers the Fleet-Ops console UI. |
|
|
44
|
+
| `fleetbase/fleetops-api` | Laravel/PHP package that provides the Fleet-Ops API, models, jobs, events, and integrations. |
|
|
20
45
|
|
|
21
|
-
|
|
46
|
+
Fleet-Ops is included with Fleetbase Cloud and self-hosted Fleetbase installations. For product concepts, workflows, and setup guides, start with the [Fleet-Ops documentation](https://www.fleetbase.io/docs/fleet-ops).
|
|
22
47
|
|
|
48
|
+
## Features
|
|
49
|
+
|
|
50
|
+
### Operations
|
|
51
|
+
|
|
52
|
+
- Create, import, schedule, dispatch, start, cancel, and complete delivery orders.
|
|
53
|
+
- Manage multi-waypoint routes, payloads, entities, labels, order metadata, notes, comments, files, and proofs.
|
|
54
|
+
- Track live order progress with ETAs, route overlays, driver pings, activity timelines, and configurable status flows.
|
|
55
|
+
- Configure custom order types, activity flows, entity fields, proof requirements, and service-rate rules.
|
|
56
|
+
- Run orchestration workflows for order allocation, driver assignment, vehicle capacity, and route sequencing.
|
|
57
|
+
- Plan work with the scheduler, fleet schedule, service quotes, routes, manifests, and manifest stops.
|
|
58
|
+
|
|
59
|
+
### Live Map
|
|
60
|
+
|
|
61
|
+
- View live drivers, vehicles, active orders, routes, places, service areas, zones, and geofences.
|
|
62
|
+
- Filter and inspect operational layers with Fleet-Ops map controls and drawer panels.
|
|
63
|
+
- Support Leaflet-based and Google-based map experiences through Fleetbase map settings.
|
|
64
|
+
- Capture positions, replay movement, track vehicles and drivers, and surface geofence events.
|
|
65
|
+
|
|
66
|
+
### Fleet Management
|
|
67
|
+
|
|
68
|
+
- Manage drivers, vehicles, fleets, places, contacts, customers, vendors, and integrated vendors.
|
|
69
|
+
- Assign drivers and vehicles to fleets, vendors, and orders.
|
|
70
|
+
- Track driver schedules, availability, positions, active shifts, and hours-of-service status.
|
|
71
|
+
- Track vehicle status, devices, positions, equipment, schedules, work orders, and maintenance history.
|
|
72
|
+
- Manage issues, fuel reports, imports, exports, bulk actions, and custom resource fields.
|
|
73
|
+
|
|
74
|
+
### Maintenance
|
|
75
|
+
|
|
76
|
+
- Define preventive maintenance schedules and calendar feeds.
|
|
77
|
+
- Manage work orders, maintenance records, line items, equipment, parts, and warranties.
|
|
78
|
+
- Send work orders, trigger schedule runs, pause and resume schedules, and review maintenance history.
|
|
79
|
+
|
|
80
|
+
### Connectivity
|
|
81
|
+
|
|
82
|
+
- Connect telematics providers, devices, sensors, events, and tracking data.
|
|
83
|
+
- Discover and link telematics devices, test provider credentials, and receive telematics webhooks.
|
|
84
|
+
- Use Fleet-Ops tracking providers for calculated, OSRM, and Google Routes-backed route intelligence.
|
|
85
|
+
|
|
86
|
+
### Analytics and Dashboards
|
|
87
|
+
|
|
88
|
+
- Use Fleet-Ops KPI widgets for earnings, average order value, distance, active orders, online drivers, and open issues.
|
|
89
|
+
- Review analytics for operations pulse, live fleet, revenue trends, order status volume, on-time delivery, top drivers, fuel efficiency, issues, maintenance, and geofence violations.
|
|
90
|
+
- Create and view reports from the Fleet-Ops analytics workspace.
|
|
91
|
+
|
|
92
|
+
### Settings and Extensions
|
|
93
|
+
|
|
94
|
+
- Configure Navigator app onboarding, routing, tracking, map providers, notifications, scheduling, payments, orchestrator settings, custom fields, and avatars.
|
|
95
|
+
- Expose Fleet-Ops order tracking on the Fleetbase login surface.
|
|
96
|
+
- Integrate Fleet-Ops entities into other Fleetbase extensions through registered components and virtual detail tabs.
|
|
97
|
+
|
|
98
|
+
## Architecture
|
|
99
|
+
|
|
100
|
+
Fleet-Ops follows the Fleetbase extension architecture: an Ember Engine for the console interface and a Laravel package for API and backend capabilities.
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
fleetops/
|
|
104
|
+
+-- addon/ # Ember Engine source: routes, controllers, components, services, templates
|
|
105
|
+
+-- app/ # Ember app re-exports and integration points
|
|
106
|
+
+-- assets/ # Frontend assets bundled with the engine
|
|
107
|
+
+-- translations/ # Fleet-Ops locale files
|
|
108
|
+
+-- server/
|
|
109
|
+
| +-- config/ # Fleet-Ops API configuration
|
|
110
|
+
| +-- migrations/ # Database migrations
|
|
111
|
+
| +-- resources/ # Backend views and resources
|
|
112
|
+
| +-- seeders/ # Seed data
|
|
113
|
+
| +-- src/ # Controllers, models, jobs, events, support services, providers
|
|
114
|
+
| +-- tests/ # Backend test suite
|
|
115
|
+
+-- tests/ # Ember test suite
|
|
116
|
+
+-- package.json # Frontend package metadata and scripts
|
|
117
|
+
+-- composer.json # Backend package metadata and scripts
|
|
23
118
|
```
|
|
24
|
-
├── addon
|
|
25
|
-
├── app
|
|
26
|
-
├── assets
|
|
27
|
-
├── translations
|
|
28
|
-
├── config
|
|
29
|
-
├── node_modules
|
|
30
|
-
├── server
|
|
31
|
-
│ ├── config
|
|
32
|
-
│ ├── data
|
|
33
|
-
│ ├── migrations
|
|
34
|
-
│ ├── resources
|
|
35
|
-
│ ├── src
|
|
36
|
-
│ ├── tests
|
|
37
|
-
│ └── vendor
|
|
38
|
-
├── tests
|
|
39
|
-
├── testem.js
|
|
40
|
-
├── index.js
|
|
41
|
-
├── package.json
|
|
42
|
-
├── phpstan.neon.dist
|
|
43
|
-
├── phpunit.xml.dist
|
|
44
|
-
├── pnpm-lock.yaml
|
|
45
|
-
├── ember-cli-build.js
|
|
46
|
-
├── composer.json
|
|
47
|
-
├── CONTRIBUTING.md
|
|
48
|
-
├── LICENSE.md
|
|
49
|
-
├── README.md
|
|
50
|
-
```
|
|
51
119
|
|
|
52
|
-
|
|
120
|
+
Core frontend dependencies include Ember Octane, Ember Engines, Fleetbase Ember Core, Fleetbase UI, Fleet-Ops Data, Leaflet, Leaflet Draw, Turf, JointJS, and Stripe Connect. Core backend capabilities are provided by Laravel, Fleetbase Core API, Fleet-Ops models/controllers, orchestration engines, tracking providers, analytics, notifications, jobs, and telematics integrations.
|
|
121
|
+
|
|
122
|
+
## Getting Started
|
|
53
123
|
|
|
54
|
-
|
|
124
|
+
Fleet-Ops comes pre-installed with Fleetbase Cloud and standard self-hosted Fleetbase installations. If you are setting up the Fleetbase platform itself, use the Fleetbase documentation:
|
|
55
125
|
|
|
56
|
-
|
|
126
|
+
- [Fleet-Ops documentation](https://www.fleetbase.io/docs/fleet-ops)
|
|
127
|
+
- [Fleetbase documentation](https://www.fleetbase.io/docs)
|
|
128
|
+
- [Fleetbase console](https://console.fleetbase.io)
|
|
129
|
+
|
|
130
|
+
When developing Fleet-Ops from source, install both frontend and backend dependencies:
|
|
57
131
|
|
|
58
132
|
```bash
|
|
59
|
-
|
|
60
|
-
composer
|
|
133
|
+
pnpm install
|
|
134
|
+
composer install
|
|
61
135
|
```
|
|
62
|
-
### Frontend
|
|
63
136
|
|
|
64
|
-
|
|
137
|
+
### Link Fleet-Ops into Fleetbase
|
|
138
|
+
|
|
139
|
+
When working from the Fleetbase monorepo, use the Fleetbase package linker to connect this local package to the running Console and API applications. From the Fleetbase repository root:
|
|
65
140
|
|
|
66
141
|
```bash
|
|
67
|
-
|
|
142
|
+
flb-package-linker enable fleetops
|
|
143
|
+
flb-package-linker install fleetops
|
|
68
144
|
```
|
|
69
145
|
|
|
70
|
-
|
|
146
|
+
This links the local Fleet-Ops Ember engine and Laravel package so Console and API use your source checkout instead of the published packages. See the [Fleetbase development setup guide](https://www.fleetbase.io/docs/platform/quickstart/development-setup) for the full package-linking workflow, Docker setup, Octane reload notes, and frontend hot-reload options.
|
|
71
147
|
|
|
72
|
-
###
|
|
148
|
+
### Link Fleet-Ops Data
|
|
149
|
+
|
|
150
|
+
Fleet-Ops also depends on the shared `@fleetbase/fleetops-data` package. That package contains Fleet-Ops Ember Data models, adapters, and serializers, and can be reused by other Fleetbase modules that need to read or write Fleet-Ops resources without duplicating data-layer definitions.
|
|
151
|
+
|
|
152
|
+
If you are changing shared Fleet-Ops data models or consuming them from another extension, link `fleetops-data` through the root Console workspace:
|
|
73
153
|
|
|
74
|
-
🧹 Keep a modern codebase with **PHP CS Fixer**:
|
|
75
154
|
```bash
|
|
76
|
-
|
|
155
|
+
flb-package-linker enable-shared fleetops-data
|
|
156
|
+
flb-package-linker install
|
|
77
157
|
```
|
|
78
158
|
|
|
79
|
-
|
|
159
|
+
For broader Fleet-Ops frontend work, you may also link the common shared Ember packages used by Fleetbase:
|
|
160
|
+
|
|
80
161
|
```bash
|
|
81
|
-
|
|
162
|
+
flb-package-linker enable fleetops --shared ember-core ember-ui fleetops-data
|
|
163
|
+
flb-package-linker install fleetops
|
|
82
164
|
```
|
|
83
165
|
|
|
84
|
-
|
|
166
|
+
## Development
|
|
167
|
+
|
|
168
|
+
Start the Ember Engine in development mode:
|
|
169
|
+
|
|
85
170
|
```bash
|
|
86
|
-
|
|
171
|
+
pnpm start
|
|
87
172
|
```
|
|
88
173
|
|
|
89
|
-
|
|
174
|
+
Build the production frontend bundle:
|
|
175
|
+
|
|
90
176
|
```bash
|
|
91
|
-
|
|
177
|
+
pnpm build
|
|
92
178
|
```
|
|
93
179
|
|
|
94
|
-
|
|
180
|
+
Run frontend linting:
|
|
95
181
|
|
|
96
|
-
🧹 Keep a modern codebase with **ESLint**:
|
|
97
182
|
```bash
|
|
98
183
|
pnpm lint
|
|
99
184
|
```
|
|
100
185
|
|
|
101
|
-
|
|
186
|
+
Run backend linting:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
composer test:lint
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Testing
|
|
193
|
+
|
|
194
|
+
Run the Ember/QUnit test suite:
|
|
195
|
+
|
|
102
196
|
```bash
|
|
103
|
-
pnpm test
|
|
104
197
|
pnpm test:ember
|
|
105
|
-
pnpm test:ember-compatibility
|
|
106
198
|
```
|
|
107
199
|
|
|
108
|
-
|
|
200
|
+
Run the full frontend check suite:
|
|
201
|
+
|
|
109
202
|
```bash
|
|
110
|
-
pnpm
|
|
203
|
+
pnpm test
|
|
111
204
|
```
|
|
112
205
|
|
|
113
|
-
|
|
206
|
+
Run the backend test suite:
|
|
207
|
+
|
|
114
208
|
```bash
|
|
115
|
-
|
|
209
|
+
composer test
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Run backend checks individually:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
composer test:lint
|
|
216
|
+
composer test:types
|
|
217
|
+
composer test:unit
|
|
116
218
|
```
|
|
117
219
|
|
|
220
|
+
## Documentation
|
|
221
|
+
|
|
222
|
+
- [Fleet-Ops docs](https://www.fleetbase.io/docs/fleet-ops)
|
|
223
|
+
- [Fleet-Ops quickstart](https://www.fleetbase.io/docs/fleet-ops/getting-started/quickstart)
|
|
224
|
+
- [Fleet-Ops core concepts](https://www.fleetbase.io/docs/fleet-ops/getting-started/core-concepts)
|
|
225
|
+
- [Navigator app setup](https://www.fleetbase.io/docs/fleet-ops/getting-started/navigator-app-setup)
|
|
226
|
+
- [Fleetbase docs](https://www.fleetbase.io/docs)
|
|
227
|
+
|
|
118
228
|
## Contributing
|
|
119
|
-
|
|
229
|
+
|
|
230
|
+
Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
|
|
231
|
+
|
|
232
|
+
Useful project files:
|
|
233
|
+
|
|
234
|
+
- [package.json](package.json) for frontend scripts and package metadata.
|
|
235
|
+
- [composer.json](composer.json) for backend scripts and package metadata.
|
|
236
|
+
- [extension.json](extension.json) for Fleetbase extension metadata.
|
|
120
237
|
|
|
121
238
|
## License
|
|
122
|
-
|
|
239
|
+
|
|
240
|
+
Fleet-Ops is open-source software licensed under the [GNU Affero General Public License v3.0 or later](LICENSE.md).
|
|
@@ -13,55 +13,18 @@
|
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
15
15
|
<div class="next-view-header-right">
|
|
16
|
-
<
|
|
16
|
+
<Layout::Resource::Panel::HeaderActions
|
|
17
|
+
@resource={{@resource}}
|
|
18
|
+
@saveTask={{@saveTask}}
|
|
19
|
+
@saveOptions={{@saveOptions}}
|
|
20
|
+
@saveDisabled={{@saveDisabled}}
|
|
21
|
+
@pojoResource={{@pojoResource}}
|
|
22
|
+
@authSchema={{@authSchema}}
|
|
23
|
+
@actionButtons={{@actionButtons}}
|
|
24
|
+
@onPressCancel={{@onPressCancel}}
|
|
25
|
+
>
|
|
17
26
|
{{yield}}
|
|
18
|
-
|
|
19
|
-
<Button
|
|
20
|
-
@type="primary"
|
|
21
|
-
@icon={{if @resource.isNew "check" "save"}}
|
|
22
|
-
@text={{if @resource.isNew (concat "Create " this.modelName) "Save Changes"}}
|
|
23
|
-
@onClick={{perform @saveTask @resource}}
|
|
24
|
-
@disabled={{cannot-write @resource schema=@authSchema}}
|
|
25
|
-
@isLoading={{@saveTask.isRunning}}
|
|
26
|
-
/>
|
|
27
|
-
{{/if}}
|
|
28
|
-
{{#each @actionButtons as |actionButton|}}
|
|
29
|
-
<Button
|
|
30
|
-
@type={{actionButton.type}}
|
|
31
|
-
@text={{actionButton.text}}
|
|
32
|
-
@onClick={{if actionButton.perform (perform actionButton.perform) (or actionButton.onClick actionButton.fn)}}
|
|
33
|
-
@size={{actionButton.size}}
|
|
34
|
-
@buttonType={{actionButton.buttonType}}
|
|
35
|
-
@disabled={{actionButton.disabled}}
|
|
36
|
-
@exampleText={{actionButton.exampleText}}
|
|
37
|
-
@helpText={{actionButton.helpText}}
|
|
38
|
-
@icon={{actionButton.icon}}
|
|
39
|
-
@iconClass={{actionButton.iconClass}}
|
|
40
|
-
@iconFlip={{actionButton.iconFlip}}
|
|
41
|
-
@iconPrefix={{actionButton.iconPrefix}}
|
|
42
|
-
@iconRotation={{actionButton.iconRotation}}
|
|
43
|
-
@iconSize={{actionButton.iconSize}}
|
|
44
|
-
@isLoading={{actionButton.isLoading}}
|
|
45
|
-
@outline={{actionButton.outline}}
|
|
46
|
-
@permission={{actionButton.permission}}
|
|
47
|
-
@wrapperClass={{actionButton.wrapperClass}}
|
|
48
|
-
@textClass={{actionButton.textClass}}
|
|
49
|
-
@tooltipPlacement={{actionButton.tooltipPlacement}}
|
|
50
|
-
@visible={{actionButton.visible}}
|
|
51
|
-
/>
|
|
52
|
-
{{/each}}
|
|
53
|
-
{{#if @onPressCancel}}
|
|
54
|
-
<button
|
|
55
|
-
type="button"
|
|
56
|
-
class="next-content-overlay-panel-cancel-button {{@cancelButtonClass}}"
|
|
57
|
-
{{set-height @cancelButtonHeight}}
|
|
58
|
-
{{set-width @cancelButtonWidth}}
|
|
59
|
-
{{on "click" @onPressCancel}}
|
|
60
|
-
>
|
|
61
|
-
<FaIcon @icon={{or @cancelIcon "times"}} @size={{@iconSize}} @prefix={{or @iconPrefix "fas"}} class={{@iconClass}} />
|
|
62
|
-
</button>
|
|
63
|
-
{{/if}}
|
|
64
|
-
</div>
|
|
27
|
+
</Layout::Resource::Panel::HeaderActions>
|
|
65
28
|
</div>
|
|
66
29
|
</div>
|
|
67
30
|
</div>
|
|
@@ -335,7 +335,7 @@
|
|
|
335
335
|
{{#each serviceQuote.items as |item|}}
|
|
336
336
|
<tr>
|
|
337
337
|
<td>
|
|
338
|
-
<span class="font-semibold">{{
|
|
338
|
+
<span class="font-semibold">{{item.details}}</span>
|
|
339
339
|
</td>
|
|
340
340
|
<td>
|
|
341
341
|
<span>{{format-currency item.amount serviceQuote.currency}}</span>
|
|
@@ -449,4 +449,4 @@
|
|
|
449
449
|
|
|
450
450
|
<Spacer @height="300px" />
|
|
451
451
|
</Overlay::Body>
|
|
452
|
-
</Overlay>
|
|
452
|
+
</Overlay>
|
|
@@ -1,53 +1,4 @@
|
|
|
1
1
|
<div class="form-wrapper" ...attributes>
|
|
2
|
-
<ContentPanel @title={{t "customer.fields.user-account"}} @open={{true}} @actionButtons={{this.userAccountActionButtons}} @wrapperClass="bordered-top">
|
|
3
|
-
<div class="space-y-2">
|
|
4
|
-
<InputGroup @name={{t "customer.fields.user-account"}} @helpText={{t "customer.fields.user-account-help-text"}}>
|
|
5
|
-
<ModelSelect
|
|
6
|
-
@modelName="user"
|
|
7
|
-
@selectedModel={{@resource.user}}
|
|
8
|
-
@placeholder={{t "customer.fields.select-user"}}
|
|
9
|
-
@query={{hash doesnt_have_contact=true}}
|
|
10
|
-
@triggerClass="form-select form-input"
|
|
11
|
-
@infiniteScroll={{false}}
|
|
12
|
-
@renderInPlace={{true}}
|
|
13
|
-
@onChange={{fn (mut @resource.user)}}
|
|
14
|
-
@permission="fleet-ops update-user-for customer"
|
|
15
|
-
as |model|
|
|
16
|
-
>
|
|
17
|
-
<div class="flex flex-row">
|
|
18
|
-
<div class="mr-2 w-6">
|
|
19
|
-
<Image src={{model.avatar_url}} @fallbackSrc={{config "defaultValues.userImage"}} alt={{this.user.name}} class="w-6 h-6 rounded-md" />
|
|
20
|
-
</div>
|
|
21
|
-
<div class="flex flex-col">
|
|
22
|
-
<div class="font-semibold">{{model.name}}</div>
|
|
23
|
-
<div class="text-xs flex flex-row items-center leading-4">
|
|
24
|
-
<FaIcon @icon="envelope" @size="sm" class="mr-1 opacity-75" />
|
|
25
|
-
<span>{{n-a model.email}}</span>
|
|
26
|
-
</div>
|
|
27
|
-
<div class="text-xs flex flex-row items-center leading-4">
|
|
28
|
-
<FaIcon @icon="phone" @size="sm" class="mr-1 opacity-75" />
|
|
29
|
-
<span>{{n-a model.phone}}</span>
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
</div>
|
|
33
|
-
</ModelSelect>
|
|
34
|
-
</InputGroup>
|
|
35
|
-
{{#if @resource.user}}
|
|
36
|
-
<div class="grid grid-cols-1 lg:grid-cols-2 gap-2 no-input-group-padding">
|
|
37
|
-
<InputGroup @name={{t "common.name"}} @wrapperClass="col-span-2 mb-0i">
|
|
38
|
-
<Input @value={{@resource.user.name}} @type="text" class="w-full form-input" placeholder={{t "common.name"}} disabled={{true}} />
|
|
39
|
-
</InputGroup>
|
|
40
|
-
<InputGroup @name={{t "common.email"}} @wrapperClass="mb-0i">
|
|
41
|
-
<Input @value={{@resource.user.email}} @type="text" class="w-full form-input" placeholder={{t "common.email"}} disabled={{true}} />
|
|
42
|
-
</InputGroup>
|
|
43
|
-
<InputGroup @name={{t "common.phone"}} @wrapperClass="mb-0i">
|
|
44
|
-
<PhoneInput @value={{@resource.user.phone}} @onInput={{fn (mut @resource.phone)}} class="form-input w-full" disabled={{true}} />
|
|
45
|
-
</InputGroup>
|
|
46
|
-
</div>
|
|
47
|
-
{{/if}}
|
|
48
|
-
</div>
|
|
49
|
-
</ContentPanel>
|
|
50
|
-
|
|
51
2
|
<ContentPanel @title={{t "customer.fields.customer-details"}} @open={{true}} @wrapperClass="bordered-top">
|
|
52
3
|
<div class="flex flex-row space-x-3 mb-3">
|
|
53
4
|
<div class="flex items-center justify-start rounded-full">
|
|
@@ -125,17 +76,78 @@
|
|
|
125
76
|
as |model|
|
|
126
77
|
>
|
|
127
78
|
<div class="flex items-center flex-row justify-between">
|
|
128
|
-
<div class="truncate flex-1">{{
|
|
79
|
+
<div class="truncate flex-1">{{place-address-html model}}</div>
|
|
129
80
|
<Badge @hideStatusDot={{true}} @status="info">{{model.public_id}}</Badge>
|
|
130
81
|
</div>
|
|
131
82
|
</ModelSelect>
|
|
132
83
|
</InputGroup>
|
|
84
|
+
{{#if this.showWelcomeEmailOption}}
|
|
85
|
+
<div class="col-span-2 mt-3">
|
|
86
|
+
<Checkbox
|
|
87
|
+
@value={{this.sendWelcomeEmail}}
|
|
88
|
+
@label={{t "customer.fields.send-welcome-email"}}
|
|
89
|
+
@helpText={{t "customer.fields.send-welcome-email-help-text"}}
|
|
90
|
+
@onToggle={{this.toggleWelcomeEmail}}
|
|
91
|
+
@alignItems="center"
|
|
92
|
+
@labelClass="mb-0i"
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
{{/if}}
|
|
133
96
|
<RegistryYield @registry="fleet-ops:component:customer:form:details" as |RegistryComponent|>
|
|
134
97
|
<RegistryComponent @resource={{@resource}} @controller={{@controller}} @permission={{get-write-permission @resource}} />
|
|
135
98
|
</RegistryYield>
|
|
136
99
|
</div>
|
|
137
100
|
</ContentPanel>
|
|
138
101
|
|
|
102
|
+
<ContentPanel @title={{t "customer.fields.user-account"}} @open={{true}} @actionButtons={{this.userAccountActionButtons}} @wrapperClass="bordered-top">
|
|
103
|
+
<div class="space-y-2">
|
|
104
|
+
<InputGroup @name={{t "customer.fields.user-account"}} @helpText={{t "customer.fields.user-account-help-text"}}>
|
|
105
|
+
<ModelSelect
|
|
106
|
+
@modelName="user"
|
|
107
|
+
@selectedModel={{@resource.user}}
|
|
108
|
+
@placeholder={{t "customer.fields.select-user"}}
|
|
109
|
+
@query={{hash doesnt_have_contact=true is_customer=true}}
|
|
110
|
+
@triggerClass="form-select form-input"
|
|
111
|
+
@infiniteScroll={{false}}
|
|
112
|
+
@renderInPlace={{true}}
|
|
113
|
+
@onChange={{fn (mut @resource.user)}}
|
|
114
|
+
@permission="fleet-ops update-user-for customer"
|
|
115
|
+
as |model|
|
|
116
|
+
>
|
|
117
|
+
<div class="flex flex-row">
|
|
118
|
+
<div class="mr-2 w-6">
|
|
119
|
+
<Image src={{model.avatar_url}} @fallbackSrc={{config "defaultValues.userImage"}} alt={{this.user.name}} class="w-6 h-6 rounded-md" />
|
|
120
|
+
</div>
|
|
121
|
+
<div class="flex flex-col">
|
|
122
|
+
<div class="font-semibold">{{model.name}}</div>
|
|
123
|
+
<div class="text-xs flex flex-row items-center leading-4">
|
|
124
|
+
<FaIcon @icon="envelope" @size="sm" class="mr-1 opacity-75" />
|
|
125
|
+
<span>{{n-a model.email}}</span>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="text-xs flex flex-row items-center leading-4">
|
|
128
|
+
<FaIcon @icon="phone" @size="sm" class="mr-1 opacity-75" />
|
|
129
|
+
<span>{{n-a model.phone}}</span>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</ModelSelect>
|
|
134
|
+
</InputGroup>
|
|
135
|
+
{{#if @resource.user}}
|
|
136
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-2 no-input-group-padding">
|
|
137
|
+
<InputGroup @name={{t "common.name"}} @wrapperClass="col-span-2 mb-0i">
|
|
138
|
+
<Input @value={{@resource.user.name}} @type="text" class="w-full form-input" placeholder={{t "common.name"}} disabled={{true}} />
|
|
139
|
+
</InputGroup>
|
|
140
|
+
<InputGroup @name={{t "common.email"}} @wrapperClass="mb-0i">
|
|
141
|
+
<Input @value={{@resource.user.email}} @type="text" class="w-full form-input" placeholder={{t "common.email"}} disabled={{true}} />
|
|
142
|
+
</InputGroup>
|
|
143
|
+
<InputGroup @name={{t "common.phone"}} @wrapperClass="mb-0i">
|
|
144
|
+
<PhoneInput @value={{@resource.user.phone}} @onInput={{fn (mut @resource.phone)}} class="form-input w-full" disabled={{true}} />
|
|
145
|
+
</InputGroup>
|
|
146
|
+
</div>
|
|
147
|
+
{{/if}}
|
|
148
|
+
</div>
|
|
149
|
+
</ContentPanel>
|
|
150
|
+
|
|
139
151
|
<CustomField::Yield @subject={{@resource}} @wrapperClass="bordered-top" />
|
|
140
152
|
|
|
141
153
|
<RegistryYield @registry="fleet-ops:component:customer:form" as |RegistryComponent|>
|
|
@@ -11,12 +11,17 @@ export default class CustomerFormComponent extends Component {
|
|
|
11
11
|
@service currentUser;
|
|
12
12
|
@service notifications;
|
|
13
13
|
@service modalsManager;
|
|
14
|
+
@service('universe/extension-manager') extensionManager;
|
|
15
|
+
|
|
14
16
|
@tracked userAccountActionButtons = [
|
|
15
17
|
{
|
|
16
18
|
icon: 'user-plus',
|
|
17
19
|
size: 'xs',
|
|
18
20
|
permission: 'iam create user',
|
|
19
|
-
onClick: () => {
|
|
21
|
+
onClick: async () => {
|
|
22
|
+
// Load IAM engine for user-form modal component
|
|
23
|
+
await this.extensionManager.ensureEngineLoaded('@fleetbase/iam-engine');
|
|
24
|
+
|
|
20
25
|
const user = this.store.createRecord('user', {
|
|
21
26
|
status: 'pending',
|
|
22
27
|
type: 'user',
|
|
@@ -61,6 +66,27 @@ export default class CustomerFormComponent extends Component {
|
|
|
61
66
|
},
|
|
62
67
|
];
|
|
63
68
|
|
|
69
|
+
get showWelcomeEmailOption() {
|
|
70
|
+
return this.args.resource?.isNew && this.extensionManager.isInstalled('@fleetbase/customer-portal-engine');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get sendWelcomeEmail() {
|
|
74
|
+
return Boolean(this.args.resource?.meta?.customer_portal?.send_welcome_email);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@action toggleWelcomeEmail(value = !this.sendWelcomeEmail) {
|
|
78
|
+
const meta = this.args.resource.meta ?? {};
|
|
79
|
+
const customerPortal = meta.customer_portal ?? {};
|
|
80
|
+
|
|
81
|
+
this.args.resource.set('meta', {
|
|
82
|
+
...meta,
|
|
83
|
+
customer_portal: {
|
|
84
|
+
...customerPortal,
|
|
85
|
+
send_welcome_email: value,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
64
90
|
@action selectPlace(place) {
|
|
65
91
|
if (!place) return;
|
|
66
92
|
this.args.resource.setProperties({
|
|
@@ -351,7 +351,7 @@
|
|
|
351
351
|
{{#each serviceQuote.items as |item|}}
|
|
352
352
|
<tr>
|
|
353
353
|
<td>
|
|
354
|
-
<span class="font-semibold">{{
|
|
354
|
+
<span class="font-semibold">{{item.details}}</span>
|
|
355
355
|
</td>
|
|
356
356
|
<td>
|
|
357
357
|
<span>{{format-currency item.amount serviceQuote.currency}}</span>
|
|
@@ -473,4 +473,4 @@
|
|
|
473
473
|
|
|
474
474
|
<Spacer @height="300px" />
|
|
475
475
|
</Overlay::Body>
|
|
476
|
-
</Overlay>
|
|
476
|
+
</Overlay>
|