@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
|
@@ -12,6 +12,7 @@ import generateUUID from '@fleetbase/ember-core/utils/generate-uuid';
|
|
|
12
12
|
import inlineTask from '@fleetbase/ember-core/utils/inline-task';
|
|
13
13
|
import createFlowActivity from '../../utils/create-flow-activity';
|
|
14
14
|
import contextComponentCallback from '@fleetbase/ember-core/utils/context-component-callback';
|
|
15
|
+
import normalizeOrderConfigFlow, { getOrderConfigFlowRootCode } from '../../utils/normalize-order-config-flow';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Manages the activity flow for order configuration, allowing users to create, edit, and view a sequence of activities.
|
|
@@ -53,6 +54,13 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
53
54
|
*/
|
|
54
55
|
@tracked graph;
|
|
55
56
|
|
|
57
|
+
/**
|
|
58
|
+
* True when the rendered graph is wider than the visible Activity Flow area.
|
|
59
|
+
*
|
|
60
|
+
* @type {Boolean}
|
|
61
|
+
*/
|
|
62
|
+
@tracked hasHorizontalOverflow = false;
|
|
63
|
+
|
|
56
64
|
/**
|
|
57
65
|
* Checks if listener pointerdown listener is called.
|
|
58
66
|
*
|
|
@@ -60,6 +68,14 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
60
68
|
*/
|
|
61
69
|
@tracked listeningForClicks = false;
|
|
62
70
|
|
|
71
|
+
graphScrollContainer;
|
|
72
|
+
horizontalScrollbar;
|
|
73
|
+
horizontalScrollbarContent;
|
|
74
|
+
isSyncingHorizontalScroll = false;
|
|
75
|
+
onGraphScroll;
|
|
76
|
+
onHorizontalScrollbarScroll;
|
|
77
|
+
onWindowResize;
|
|
78
|
+
|
|
63
79
|
/**
|
|
64
80
|
* Initializes the component with the given configuration.
|
|
65
81
|
* @param {Object} owner - The owner of the component instance.
|
|
@@ -85,6 +101,42 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
85
101
|
this.initializeActivityJointModel();
|
|
86
102
|
this.initializeActivityFlow();
|
|
87
103
|
this.listenForElementClicks();
|
|
104
|
+
this.updateHorizontalScrollbar();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@action setupGraphScrollContainer(element) {
|
|
108
|
+
this.graphScrollContainer = element;
|
|
109
|
+
this.onGraphScroll = () => this.syncHorizontalScrollbarFromGraph();
|
|
110
|
+
this.onWindowResize = () => this.updateHorizontalScrollbar();
|
|
111
|
+
|
|
112
|
+
element.addEventListener('scroll', this.onGraphScroll);
|
|
113
|
+
window.addEventListener('resize', this.onWindowResize);
|
|
114
|
+
this.updateHorizontalScrollbar();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@action setupHorizontalScrollbar(element) {
|
|
118
|
+
this.horizontalScrollbar = element;
|
|
119
|
+
this.horizontalScrollbarContent = element.firstElementChild;
|
|
120
|
+
this.onHorizontalScrollbarScroll = () => this.syncGraphFromHorizontalScrollbar();
|
|
121
|
+
|
|
122
|
+
element.addEventListener('scroll', this.onHorizontalScrollbarScroll);
|
|
123
|
+
this.updateHorizontalScrollbar();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
willDestroy() {
|
|
127
|
+
super.willDestroy(...arguments);
|
|
128
|
+
|
|
129
|
+
if (this.graphScrollContainer && this.onGraphScroll) {
|
|
130
|
+
this.graphScrollContainer.removeEventListener('scroll', this.onGraphScroll);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (this.horizontalScrollbar && this.onHorizontalScrollbarScroll) {
|
|
134
|
+
this.horizontalScrollbar.removeEventListener('scroll', this.onHorizontalScrollbarScroll);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (this.onWindowResize) {
|
|
138
|
+
window.removeEventListener('resize', this.onWindowResize);
|
|
139
|
+
}
|
|
88
140
|
}
|
|
89
141
|
|
|
90
142
|
/**
|
|
@@ -299,14 +351,20 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
299
351
|
* @param {Object} incomingFlow - The incoming serialized activity flow.
|
|
300
352
|
*/
|
|
301
353
|
deserializeFlow(incomingFlow) {
|
|
354
|
+
const normalizedFlow = normalizeOrderConfigFlow(incomingFlow);
|
|
302
355
|
const deserializedFlow = {};
|
|
303
|
-
const keys = Object.keys(
|
|
356
|
+
const keys = Object.keys(normalizedFlow);
|
|
304
357
|
keys.forEach((key) => {
|
|
305
|
-
const activity = this.deserializeActivity(
|
|
306
|
-
|
|
358
|
+
const activity = this.deserializeActivity(normalizedFlow[key], normalizedFlow, deserializedFlow);
|
|
359
|
+
if (activity) {
|
|
360
|
+
deserializedFlow[activity.get('code')] = activity;
|
|
361
|
+
}
|
|
307
362
|
});
|
|
308
363
|
|
|
309
|
-
|
|
364
|
+
const rootCode = getOrderConfigFlowRootCode(deserializedFlow);
|
|
365
|
+
if (rootCode && deserializedFlow[rootCode]) {
|
|
366
|
+
this.addDeserializedActivityToGraph(deserializedFlow[rootCode]);
|
|
367
|
+
}
|
|
310
368
|
}
|
|
311
369
|
|
|
312
370
|
/**
|
|
@@ -315,8 +373,21 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
315
373
|
* @param {Object} incomingFlow - The entire incoming serialized activity flow for reference.
|
|
316
374
|
* @returns {Object} Deserialized activity object.
|
|
317
375
|
*/
|
|
318
|
-
deserializeActivity(activityObject, incomingFlow) {
|
|
319
|
-
|
|
376
|
+
deserializeActivity(activityObject, incomingFlow, deserializedFlow = {}) {
|
|
377
|
+
if (!activityObject || typeof activityObject !== 'object') {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const code = activityObject.code ?? activityObject.key;
|
|
382
|
+
if (!code) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (deserializedFlow[code]) {
|
|
387
|
+
return deserializedFlow[code];
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const activity = createFlowActivity(code, activityObject.status, activityObject.details, activityObject.sequence, activityObject.color, {
|
|
320
391
|
key: activityObject.key,
|
|
321
392
|
logic: activityObject.logic ?? [],
|
|
322
393
|
events: activityObject.events ?? [],
|
|
@@ -327,13 +398,14 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
327
398
|
complete: activityObject.complete ?? false,
|
|
328
399
|
internalId: activityObject.internalId ?? generateUUID(),
|
|
329
400
|
});
|
|
401
|
+
deserializedFlow[code] = activity;
|
|
330
402
|
const { activities } = activityObject;
|
|
331
403
|
if (isArray(activities)) {
|
|
332
404
|
activity.set(
|
|
333
405
|
'activities',
|
|
334
406
|
activities
|
|
335
407
|
.map((activityKey) => {
|
|
336
|
-
return this.deserializeActivity(incomingFlow[activityKey], incomingFlow);
|
|
408
|
+
return this.deserializeActivity(incomingFlow[activityKey], incomingFlow, deserializedFlow);
|
|
337
409
|
})
|
|
338
410
|
.filter(Boolean)
|
|
339
411
|
);
|
|
@@ -347,6 +419,10 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
347
419
|
* @param {Object} activity - The activity to add to the graph.
|
|
348
420
|
*/
|
|
349
421
|
addDeserializedActivityToGraph(activity) {
|
|
422
|
+
if (!activity) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
350
426
|
const positionals = this.getActivityPositioning(activity);
|
|
351
427
|
const parentActivity = this.createActivityNode(activity, positionals);
|
|
352
428
|
const childActivities = activity.get('activities');
|
|
@@ -355,6 +431,7 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
355
431
|
this.addActivityNodeTools(parentActivity, positionals);
|
|
356
432
|
this.addChildActivities(parentActivity, childActivities);
|
|
357
433
|
this.repositionAllActivities();
|
|
434
|
+
this.resizePaperWidthToFitActivities();
|
|
358
435
|
}
|
|
359
436
|
|
|
360
437
|
/**
|
|
@@ -394,6 +471,79 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
394
471
|
});
|
|
395
472
|
}
|
|
396
473
|
|
|
474
|
+
/**
|
|
475
|
+
* Expands the JointJS paper width so wide activity flows can scroll horizontally.
|
|
476
|
+
*
|
|
477
|
+
* @returns {void}
|
|
478
|
+
*/
|
|
479
|
+
resizePaperWidthToFitActivities() {
|
|
480
|
+
if (!this.paper) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const nodes = Object.values(this.flow)
|
|
485
|
+
.map((activity) => activity.get('node'))
|
|
486
|
+
.filter(Boolean);
|
|
487
|
+
|
|
488
|
+
if (nodes.length === 0) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const padding = 150;
|
|
493
|
+
const viewportWidth = this.paper.el.parentElement?.clientWidth ?? this.paper.options.width;
|
|
494
|
+
const currentHeight = this.paper.options.height;
|
|
495
|
+
const contentWidth = nodes.reduce((width, node) => {
|
|
496
|
+
const position = node.position();
|
|
497
|
+
const size = node.size();
|
|
498
|
+
|
|
499
|
+
return Math.max(width, position.x + size.width + padding);
|
|
500
|
+
}, 0);
|
|
501
|
+
const paperWidth = Math.max(viewportWidth, contentWidth);
|
|
502
|
+
|
|
503
|
+
this.paper.setDimensions(paperWidth, currentHeight);
|
|
504
|
+
this.paper.el.style.width = contentWidth > viewportWidth ? `${paperWidth}px` : '100%';
|
|
505
|
+
this.paper.el.style.minWidth = '100%';
|
|
506
|
+
next(this, this.updateHorizontalScrollbar);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
updateHorizontalScrollbar() {
|
|
510
|
+
if (!this.graphScrollContainer || !this.horizontalScrollbar || !this.horizontalScrollbarContent) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
const scrollWidth = this.graphScrollContainer.scrollWidth;
|
|
515
|
+
const clientWidth = this.graphScrollContainer.clientWidth;
|
|
516
|
+
const hasOverflow = scrollWidth > clientWidth + 1;
|
|
517
|
+
|
|
518
|
+
this.hasHorizontalOverflow = hasOverflow;
|
|
519
|
+
this.horizontalScrollbarContent.style.width = hasOverflow ? `${scrollWidth}px` : '100%';
|
|
520
|
+
this.horizontalScrollbar.scrollLeft = this.graphScrollContainer.scrollLeft;
|
|
521
|
+
|
|
522
|
+
const { left, width } = this.graphScrollContainer.getBoundingClientRect();
|
|
523
|
+
this.horizontalScrollbar.style.left = `${left}px`;
|
|
524
|
+
this.horizontalScrollbar.style.width = `${width}px`;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
syncHorizontalScrollbarFromGraph() {
|
|
528
|
+
if (this.isSyncingHorizontalScroll || !this.horizontalScrollbar || !this.graphScrollContainer) {
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
this.isSyncingHorizontalScroll = true;
|
|
533
|
+
this.horizontalScrollbar.scrollLeft = this.graphScrollContainer.scrollLeft;
|
|
534
|
+
this.isSyncingHorizontalScroll = false;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
syncGraphFromHorizontalScrollbar() {
|
|
538
|
+
if (this.isSyncingHorizontalScroll || !this.horizontalScrollbar || !this.graphScrollContainer) {
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
this.isSyncingHorizontalScroll = true;
|
|
543
|
+
this.graphScrollContainer.scrollLeft = this.horizontalScrollbar.scrollLeft;
|
|
544
|
+
this.isSyncingHorizontalScroll = false;
|
|
545
|
+
}
|
|
546
|
+
|
|
397
547
|
/**
|
|
398
548
|
* Creates and adds a link between a parent activity and a child activity on the graph.
|
|
399
549
|
*
|
|
@@ -484,6 +634,7 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
484
634
|
const firstActivity = this.addActivityToGraph(activityObject);
|
|
485
635
|
lastActivity = firstActivity;
|
|
486
636
|
});
|
|
637
|
+
this.resizePaperWidthToFitActivities();
|
|
487
638
|
return;
|
|
488
639
|
}
|
|
489
640
|
|
|
@@ -550,6 +701,16 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
550
701
|
return this.flow;
|
|
551
702
|
}
|
|
552
703
|
|
|
704
|
+
/**
|
|
705
|
+
* Coerces activity label fields before passing them to JointJS text helpers.
|
|
706
|
+
*
|
|
707
|
+
* @param {*} value
|
|
708
|
+
* @returns {String}
|
|
709
|
+
*/
|
|
710
|
+
activityText(value) {
|
|
711
|
+
return typeof value === 'string' ? value : value == null ? '' : String(value);
|
|
712
|
+
}
|
|
713
|
+
|
|
553
714
|
/**
|
|
554
715
|
* Creates a new activity node based on the provided activity and positioning data.
|
|
555
716
|
* @param {Object} activity - The activity data.
|
|
@@ -558,14 +719,17 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
558
719
|
*/
|
|
559
720
|
createActivityNode(activity, positionals = {}) {
|
|
560
721
|
const { width, height, x, y } = positionals;
|
|
561
|
-
const
|
|
722
|
+
const code = this.activityText(activity.get('code'));
|
|
723
|
+
const status = this.activityText(activity.get('status'));
|
|
724
|
+
const details = this.activityText(activity.get('details'));
|
|
725
|
+
const wrappedDetails = this.activityText(joint.util.breakText(details, { width }));
|
|
562
726
|
const activityNode = new joint.shapes.fleetbase.Activity({
|
|
563
727
|
position: { x, y },
|
|
564
728
|
size: { width, height },
|
|
565
729
|
attrs: {
|
|
566
730
|
pill: {
|
|
567
731
|
ref: 'code',
|
|
568
|
-
refWidth:
|
|
732
|
+
refWidth: code.length * 1.35,
|
|
569
733
|
refHeight: 5,
|
|
570
734
|
refX: -5,
|
|
571
735
|
refY: -2,
|
|
@@ -575,8 +739,8 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
575
739
|
stroke: '#374151',
|
|
576
740
|
strokeWidth: 1,
|
|
577
741
|
},
|
|
578
|
-
code: { ref: 'pill', text:
|
|
579
|
-
status: { text:
|
|
742
|
+
code: { ref: 'pill', text: code, fill: 'white', fontSize: 14, textAnchor: 'left', refX: 15, refY: 20, yAlignment: 'middle' },
|
|
743
|
+
status: { text: status, fill: 'white', fontSize: 14, fontWeight: 'bold', refY: 40, refX: 10, textAnchor: 'left' },
|
|
580
744
|
details: {
|
|
581
745
|
text: wrappedDetails,
|
|
582
746
|
fill: 'white',
|
|
@@ -608,7 +772,8 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
608
772
|
const width = 250;
|
|
609
773
|
const baseHeight = 90;
|
|
610
774
|
const lineHeight = 10;
|
|
611
|
-
const
|
|
775
|
+
const details = this.activityText(activity.get('details'));
|
|
776
|
+
const wrappedDetails = this.activityText(joint.util.breakText(details, { width }));
|
|
612
777
|
const numberOfLines = wrappedDetails.split('\n').length;
|
|
613
778
|
const height = baseHeight + lineHeight * (numberOfLines - 1);
|
|
614
779
|
let x = 100;
|
|
@@ -933,6 +1098,7 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
|
|
|
933
1098
|
target: { id: newActivity.get('id') },
|
|
934
1099
|
});
|
|
935
1100
|
link.addTo(this.graph);
|
|
1101
|
+
this.resizePaperWidthToFitActivities();
|
|
936
1102
|
|
|
937
1103
|
return newActivity;
|
|
938
1104
|
}
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
</div>
|
|
10
10
|
<div class="order-route-location {{@routeLocationClass}} dark:text-gray-100">
|
|
11
11
|
<div class="mb-2 flex flex-wrap items-center gap-1.5">
|
|
12
|
-
{{#if this.firstStop.
|
|
13
|
-
<Badge @status={{this.firstStop.
|
|
12
|
+
{{#if this.firstStop.statusCode}}
|
|
13
|
+
<Badge @status={{this.firstStop.statusCode}} />
|
|
14
14
|
{{/if}}
|
|
15
|
-
{{#if this.firstStop.
|
|
15
|
+
{{#if this.firstStop.showCompletedFlagBadge}}
|
|
16
16
|
<Badge @status="success" @hideStatusDot={{true}}>Completed</Badge>
|
|
17
17
|
{{else if this.firstStop.active}}
|
|
18
18
|
<Badge @status="indigo" @hideStatusDot={{true}}>Current Stop</Badge>
|
|
@@ -20,11 +20,8 @@
|
|
|
20
20
|
{{#if this.firstStop.etaSeconds}}
|
|
21
21
|
<Badge @status="pending" @hideStatusDot={{true}}><span class="font-bold">ETA:</span> {{format-duration this.firstStop.etaSeconds}}</Badge>
|
|
22
22
|
{{/if}}
|
|
23
|
-
{{#if this.firstStop.etaAt}}
|
|
24
|
-
<Badge @status="pending" @hideStatusDot={{true}}>{{format-date-fns this.firstStop.etaAt "d MMM HH:mm"}}</Badge>
|
|
25
|
-
{{/if}}
|
|
26
23
|
</div>
|
|
27
|
-
<DisplayPlace @place={{this.firstStop.place}} @waypointActions={{@waypointActions}} @hideBadges={{true}} />
|
|
24
|
+
<DisplayPlace @place={{this.firstStop.place}} @waypointActions={{@waypointActions}} @waypointActionContext={{this.firstStop}} @hideBadges={{true}} />
|
|
28
25
|
</div>
|
|
29
26
|
</div>
|
|
30
27
|
{{/if}}
|
|
@@ -47,10 +44,10 @@
|
|
|
47
44
|
</div>
|
|
48
45
|
<div class="order-route-location {{@routeLocationClass}} dark:text-gray-100">
|
|
49
46
|
<div class="mb-2 flex flex-wrap items-center gap-1.5">
|
|
50
|
-
{{#if stop.
|
|
51
|
-
<Badge @status={{stop.
|
|
47
|
+
{{#if stop.statusCode}}
|
|
48
|
+
<Badge @status={{stop.statusCode}} />
|
|
52
49
|
{{/if}}
|
|
53
|
-
{{#if stop.
|
|
50
|
+
{{#if stop.showCompletedFlagBadge}}
|
|
54
51
|
<Badge @status="success" @hideStatusDot={{true}}>Completed</Badge>
|
|
55
52
|
{{else if stop.active}}
|
|
56
53
|
<Badge @status="indigo" @hideStatusDot={{true}}>Current Stop</Badge>
|
|
@@ -58,11 +55,8 @@
|
|
|
58
55
|
{{#if stop.etaSeconds}}
|
|
59
56
|
<Badge @status="pending" @hideStatusDot={{true}}><span class="font-bold">ETA:</span> {{format-duration stop.etaSeconds}}</Badge>
|
|
60
57
|
{{/if}}
|
|
61
|
-
{{#if stop.etaAt}}
|
|
62
|
-
<Badge @status="pending" @hideStatusDot={{true}}>{{format-date-fns stop.etaAt "d MMM HH:mm"}}</Badge>
|
|
63
|
-
{{/if}}
|
|
64
58
|
</div>
|
|
65
|
-
<DisplayPlace @place={{stop.place}} @waypointActions={{@waypointActions}} @hideBadges={{true}} />
|
|
59
|
+
<DisplayPlace @place={{stop.place}} @waypointActions={{@waypointActions}} @waypointActionContext={{stop}} @hideBadges={{true}} />
|
|
66
60
|
</div>
|
|
67
61
|
</div>
|
|
68
62
|
{{/each}}
|
|
@@ -75,10 +69,10 @@
|
|
|
75
69
|
</div>
|
|
76
70
|
<div class="order-route-location {{@routeLocationClass}} dark:text-gray-100">
|
|
77
71
|
<div class="mb-2 flex flex-wrap items-center gap-1.5">
|
|
78
|
-
{{#if stop.
|
|
79
|
-
<Badge @status={{stop.
|
|
72
|
+
{{#if stop.statusCode}}
|
|
73
|
+
<Badge @status={{stop.statusCode}} />
|
|
80
74
|
{{/if}}
|
|
81
|
-
{{#if stop.
|
|
75
|
+
{{#if stop.showCompletedFlagBadge}}
|
|
82
76
|
<Badge @status="success" @hideStatusDot={{true}}>Completed</Badge>
|
|
83
77
|
{{else if stop.active}}
|
|
84
78
|
<Badge @status="indigo" @hideStatusDot={{true}}>Current Stop</Badge>
|
|
@@ -86,11 +80,8 @@
|
|
|
86
80
|
{{#if stop.etaSeconds}}
|
|
87
81
|
<Badge @status="pending" @hideStatusDot={{true}}><span class="font-bold">ETA:</span> {{format-duration stop.etaSeconds}}</Badge>
|
|
88
82
|
{{/if}}
|
|
89
|
-
{{#if stop.etaAt}}
|
|
90
|
-
<Badge @status="pending" @hideStatusDot={{true}}>{{format-date-fns stop.etaAt "d MMM HH:mm"}}</Badge>
|
|
91
|
-
{{/if}}
|
|
92
83
|
</div>
|
|
93
|
-
<DisplayPlace @place={{stop.place}} @waypointActions={{@waypointActions}} @hideBadges={{true}} />
|
|
84
|
+
<DisplayPlace @place={{stop.place}} @waypointActions={{@waypointActions}} @waypointActionContext={{stop}} @hideBadges={{true}} />
|
|
94
85
|
</div>
|
|
95
86
|
</div>
|
|
96
87
|
{{/each}}
|
|
@@ -106,10 +97,10 @@
|
|
|
106
97
|
</div>
|
|
107
98
|
<div class="order-route-location {{@routeLocationClass}} dark:text-gray-100">
|
|
108
99
|
<div class="mb-2 flex flex-wrap items-center gap-1.5">
|
|
109
|
-
{{#if this.lastStop.
|
|
110
|
-
<Badge @status={{this.lastStop.
|
|
100
|
+
{{#if this.lastStop.statusCode}}
|
|
101
|
+
<Badge @status={{this.lastStop.statusCode}} />
|
|
111
102
|
{{/if}}
|
|
112
|
-
{{#if this.lastStop.
|
|
103
|
+
{{#if this.lastStop.showCompletedFlagBadge}}
|
|
113
104
|
<Badge @status="success" @hideStatusDot={{true}}>Completed</Badge>
|
|
114
105
|
{{else if this.lastStop.active}}
|
|
115
106
|
<Badge @status="indigo" @hideStatusDot={{true}}>Current Stop</Badge>
|
|
@@ -117,12 +108,9 @@
|
|
|
117
108
|
{{#if this.lastStop.etaSeconds}}
|
|
118
109
|
<Badge @status="pending" @hideStatusDot={{true}}><span class="font-bold">ETA:</span> {{format-duration this.lastStop.etaSeconds}}</Badge>
|
|
119
110
|
{{/if}}
|
|
120
|
-
{{#if this.lastStop.etaAt}}
|
|
121
|
-
<Badge @status="pending" @hideStatusDot={{true}}>{{format-date-fns this.lastStop.etaAt "d MMM HH:mm"}}</Badge>
|
|
122
|
-
{{/if}}
|
|
123
111
|
</div>
|
|
124
|
-
<DisplayPlace @place={{this.lastStop.place}} @waypointActions={{@waypointActions}} @hideBadges={{true}} />
|
|
112
|
+
<DisplayPlace @place={{this.lastStop.place}} @waypointActions={{@waypointActions}} @waypointActionContext={{this.lastStop}} @hideBadges={{true}} />
|
|
125
113
|
</div>
|
|
126
114
|
</div>
|
|
127
115
|
{{/if}}
|
|
128
|
-
</div>
|
|
116
|
+
</div>
|
|
@@ -17,20 +17,29 @@ export default class RouteListComponent extends Component {
|
|
|
17
17
|
const routePoints = buildRoutePointsFromPayload(this.args.order?.payload);
|
|
18
18
|
|
|
19
19
|
return routePoints
|
|
20
|
-
.map((routePoint) =>
|
|
21
|
-
routePoint
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
.map((routePoint) => {
|
|
21
|
+
const trackingStop = this.trackingStopFor(routePoint.place);
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
routePoint,
|
|
25
|
+
place: routePoint.place,
|
|
26
|
+
badgeStyle: this.badgeStyleForStop(routePoint),
|
|
27
|
+
trackingStop,
|
|
28
|
+
routeLeg: this.routeLegFor(routePoint.place),
|
|
29
|
+
trackingNumberUuid: routePoint.trackingNumberUuid ?? trackingStop?.tracking_number_uuid,
|
|
30
|
+
...describeRoutePoint(routePoint, this.routeColor),
|
|
31
|
+
};
|
|
32
|
+
})
|
|
28
33
|
.map((stop) => ({
|
|
29
34
|
...stop,
|
|
30
|
-
etaSeconds:
|
|
31
|
-
|
|
35
|
+
etaSeconds: this.shouldShowEtaForStop(stop)
|
|
36
|
+
? (stop.routeLeg?.eta_seconds ?? stop.routeLeg?.duration_in_traffic_s ?? stop.routeLeg?.duration_s ?? this.legacyEtaFor(stop.place))
|
|
37
|
+
: null,
|
|
38
|
+
etaAt: this.shouldShowEtaForStop(stop) ? stop.routeLeg?.eta_at : null,
|
|
32
39
|
completed: Boolean(stop.trackingStop?.completed),
|
|
33
40
|
active: this.matchesStop(stop.trackingStop, this.args.order?.tracker_data?.active_stop),
|
|
41
|
+
statusCode: stop.place?.status_code ?? stop.trackingStop?.status,
|
|
42
|
+
showCompletedFlagBadge: this.shouldShowCompletedFlagBadge(stop),
|
|
34
43
|
}));
|
|
35
44
|
}
|
|
36
45
|
|
|
@@ -54,6 +63,10 @@ export default class RouteListComponent extends Component {
|
|
|
54
63
|
return this.args.isCollapsible !== false && this.hasExtraStops;
|
|
55
64
|
}
|
|
56
65
|
|
|
66
|
+
get showEta() {
|
|
67
|
+
return this.args.showEta !== false;
|
|
68
|
+
}
|
|
69
|
+
|
|
57
70
|
badgeStyleForStop(routePoint) {
|
|
58
71
|
const { markerColor } = describeRoutePoint(routePoint, this.routeColor);
|
|
59
72
|
const isYellow = markerColor?.toLowerCase?.() === '#facc15' || markerColor?.toLowerCase?.() === '#ca8a04';
|
|
@@ -94,6 +107,25 @@ export default class RouteListComponent extends Component {
|
|
|
94
107
|
return stop.uuid === activeStop.uuid || stop.public_id === activeStop.public_id;
|
|
95
108
|
}
|
|
96
109
|
|
|
110
|
+
shouldShowCompletedFlagBadge(stop) {
|
|
111
|
+
if (!stop.trackingStop?.completed) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const visibleStatus = stop.statusCode ?? stop.place?.status_code ?? stop.trackingStop?.status_code ?? stop.trackingStop?.status ?? stop.place?.status;
|
|
116
|
+
if (typeof visibleStatus !== 'string') {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return visibleStatus.trim().toLowerCase() !== 'completed';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
shouldShowEtaForStop(stop) {
|
|
124
|
+
const status = this.args.order?.status;
|
|
125
|
+
|
|
126
|
+
return this.showEta && !['completed', 'canceled'].includes(status) && !stop.trackingStop?.completed;
|
|
127
|
+
}
|
|
128
|
+
|
|
97
129
|
@action toggleWaypointsCollapse() {
|
|
98
130
|
this.isWaypointsCollapsed = !this.isWaypointsCollapsed;
|
|
99
131
|
}
|
|
@@ -121,6 +121,47 @@
|
|
|
121
121
|
</table>
|
|
122
122
|
</div>
|
|
123
123
|
</ContentPanel>
|
|
124
|
+
{{else if @resource.isMultiZoneDistance}}
|
|
125
|
+
<ContentPanel @title="Multi-zone Distance" @open={{true}} @wrapperClass="bordered-top" @panelBodyWrapperClass="p-0i">
|
|
126
|
+
<div class="next-table-wrapper h-auto table-fluid rounded-none overflow-x-auto">
|
|
127
|
+
<table class="table table-fixed w-full">
|
|
128
|
+
<thead>
|
|
129
|
+
<tr>
|
|
130
|
+
<th>Label</th>
|
|
131
|
+
<th>Geography Type</th>
|
|
132
|
+
<th>Geography</th>
|
|
133
|
+
<th>Priority</th>
|
|
134
|
+
<th>Rate</th>
|
|
135
|
+
<th>Unit</th>
|
|
136
|
+
</tr>
|
|
137
|
+
</thead>
|
|
138
|
+
<tbody>
|
|
139
|
+
{{#each @resource.rateFees as |rateFee|}}
|
|
140
|
+
<tr>
|
|
141
|
+
<td>{{n-a rateFee.label}}</td>
|
|
142
|
+
<td>{{smart-humanize rateFee.geography_type}}</td>
|
|
143
|
+
<td>
|
|
144
|
+
{{#if (eq rateFee.geography_type "zone")}}
|
|
145
|
+
{{n-a rateFee.zone.name}}
|
|
146
|
+
{{else if (eq rateFee.geography_type "fallback")}}
|
|
147
|
+
Unmatched route distance
|
|
148
|
+
{{else}}
|
|
149
|
+
{{n-a rateFee.service_area.name}}
|
|
150
|
+
{{/if}}
|
|
151
|
+
</td>
|
|
152
|
+
<td>{{n-a rateFee.priority}}</td>
|
|
153
|
+
<td>{{format-currency (f-to-int rateFee.fee) @resource.currency}}</td>
|
|
154
|
+
<td>{{n-a rateFee.distance_unit}}</td>
|
|
155
|
+
</tr>
|
|
156
|
+
{{else}}
|
|
157
|
+
<tr>
|
|
158
|
+
<td colspan="6" class="text-center text-gray-500 italic">No geographic pricing rules defined</td>
|
|
159
|
+
</tr>
|
|
160
|
+
{{/each}}
|
|
161
|
+
</tbody>
|
|
162
|
+
</table>
|
|
163
|
+
</div>
|
|
164
|
+
</ContentPanel>
|
|
124
165
|
{{else if @resource.isPerMeter}}
|
|
125
166
|
<ContentPanel @title={{t "service-rate.fields.per-meter"}} @open={{true}} @wrapperClass="bordered-top">
|
|
126
167
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-2">
|
|
@@ -158,7 +199,7 @@
|
|
|
158
199
|
<div class="field-info-container">
|
|
159
200
|
<div class="field-name">Algorithm Code</div>
|
|
160
201
|
<div class="field-value">
|
|
161
|
-
<pre class="bg-gray-100 dark:bg-gray-900 font-mono p-3 rounded text-xs overflow-x-auto"><code class="font-mono text-xs">{{n-a @resource.algorithm}}</code></pre>
|
|
202
|
+
<pre class="bg-gray-100 dark:bg-gray-900 font-mono p-3 rounded text-xs overflow-x-auto"><code class="font-mono text-xs whitespace-break-spaces">{{n-a @resource.algorithm}}</code></pre>
|
|
162
203
|
</div>
|
|
163
204
|
</div>
|
|
164
205
|
</ContentPanel>
|