@fleetbase/fleetops-engine 0.6.70 → 0.6.71
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 +21 -47
- package/addon/components/order/details/activity.hbs +8 -6
- package/addon/components/order/details/activity.js +9 -0
- package/addon/components/order/details.hbs +29 -0
- package/addon/components/order/details.js +26 -0
- package/addon/components/order/form/details.hbs +30 -4
- package/addon/components/order/form/details.js +46 -0
- package/addon/components/order/form/route.hbs +4 -2
- package/addon/components/order/form/route.js +11 -0
- package/addon/components/order/form.hbs +12 -0
- package/addon/components/order/form.js +21 -1
- package/addon/components/order/kanban.js +72 -0
- package/addon/components/order-config-manager/activity-flow.js +45 -10
- package/addon/components/order-config-manager/lifecycle.hbs +250 -0
- package/addon/components/order-config-manager/lifecycle.js +358 -0
- package/addon/components/order-config-manager.js +5 -1
- package/addon/controllers/analytics/reports/index.js +10 -1
- package/addon/controllers/connectivity/devices/index/details.js +1 -0
- package/addon/controllers/connectivity/devices/index.js +8 -2
- package/addon/controllers/connectivity/events/index.js +31 -1
- package/addon/controllers/connectivity/sensors/index/details.js +1 -1
- package/addon/controllers/connectivity/sensors/index.js +37 -1
- package/addon/controllers/maintenance/equipment/index/details.js +2 -2
- package/addon/controllers/maintenance/equipment/index.js +28 -9
- package/addon/controllers/maintenance/inspection-forms/index.js +32 -12
- package/addon/controllers/maintenance/inspection-submissions/index/details.js +2 -1
- package/addon/controllers/maintenance/inspection-submissions/index.js +49 -9
- package/addon/controllers/maintenance/maintenances/index/details.js +2 -0
- package/addon/controllers/maintenance/maintenances/index.js +20 -1
- package/addon/controllers/maintenance/parts/index/details.js +2 -2
- package/addon/controllers/maintenance/parts/index.js +28 -8
- package/addon/controllers/maintenance/schedules/index.js +33 -4
- package/addon/controllers/maintenance/work-orders/index/details.js +3 -3
- package/addon/controllers/maintenance/work-orders/index.js +39 -8
- package/addon/controllers/management/contacts/customers.js +13 -0
- package/addon/controllers/management/contacts/index.js +43 -1
- package/addon/controllers/management/drivers/index/details.js +1 -0
- package/addon/controllers/management/drivers/index.js +32 -2
- package/addon/controllers/management/fleets/index/details.js +1 -0
- package/addon/controllers/management/fleets/index.js +39 -1
- package/addon/controllers/management/fuel-reports/index.js +22 -2
- package/addon/controllers/management/fuel-transactions/index.js +43 -7
- package/addon/controllers/management/issues/index/details.js +1 -0
- package/addon/controllers/management/issues/index.js +22 -2
- package/addon/controllers/management/places/index.js +36 -1
- package/addon/controllers/management/trailers/index/details.js +1 -0
- package/addon/controllers/management/trailers/index.js +50 -2
- package/addon/controllers/management/vehicles/index/details.js +1 -0
- package/addon/controllers/management/vehicles/index.js +33 -2
- package/addon/controllers/management/vendors/index.js +26 -2
- package/addon/controllers/operations/orders/index/details.js +31 -4
- package/addon/controllers/operations/orders/index.js +59 -4
- package/addon/controllers/operations/service-rates/index.js +15 -1
- package/addon/extension.js +32 -0
- package/addon/routes/operations/orders/index/details.js +1 -0
- package/addon/services/contact-actions.js +1 -0
- package/addon/services/customer-actions.js +2 -1
- package/addon/services/device-actions.js +1 -0
- package/addon/services/device-event-actions.js +1 -0
- package/addon/services/driver-actions.js +4 -13
- package/addon/services/equipment-actions.js +1 -0
- package/addon/services/fleet-actions.js +1 -0
- package/addon/services/fuel-report-actions.js +1 -0
- package/addon/services/inspection-form-actions.js +1 -0
- package/addon/services/inspection-submission-actions.js +1 -0
- package/addon/services/integrated-vendor-actions.js +1 -0
- package/addon/services/issue-actions.js +1 -0
- package/addon/services/maintenance-actions.js +1 -0
- package/addon/services/maintenance-schedule-actions.js +2 -1
- package/addon/services/order-actions.js +7 -0
- package/addon/services/order-presentation.js +129 -0
- package/addon/services/part-actions.js +1 -0
- package/addon/services/place-actions.js +1 -0
- package/addon/services/sensor-actions.js +1 -0
- package/addon/services/service-area-actions.js +1 -0
- package/addon/services/service-rate-actions.js +1 -0
- package/addon/services/telematic-actions.js +1 -0
- package/addon/services/trailer-actions.js +4 -14
- package/addon/services/vehicle-actions.js +4 -13
- package/addon/services/vendor-actions.js +1 -0
- package/addon/services/work-order-actions.js +1 -0
- package/addon/services/zone-actions.js +1 -0
- package/addon/templates/analytics/reports/index/details.hbs +1 -0
- package/addon/templates/analytics/reports/index.hbs +1 -0
- package/addon/templates/connectivity/devices/index/details.hbs +1 -0
- package/addon/templates/connectivity/devices/index.hbs +1 -0
- package/addon/templates/connectivity/events/index.hbs +1 -0
- package/addon/templates/connectivity/sensors/index/details.hbs +1 -0
- package/addon/templates/connectivity/sensors/index.hbs +1 -0
- package/addon/templates/maintenance/equipment/index/details.hbs +1 -0
- package/addon/templates/maintenance/equipment/index.hbs +2 -0
- package/addon/templates/maintenance/inspection-forms/index/details.hbs +1 -0
- package/addon/templates/maintenance/inspection-forms/index.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index/details.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index.hbs +1 -0
- package/addon/templates/maintenance/maintenances/index/details.hbs +1 -0
- package/addon/templates/maintenance/maintenances/index.hbs +1 -0
- package/addon/templates/maintenance/parts/index/details.hbs +1 -0
- package/addon/templates/maintenance/parts/index.hbs +2 -0
- package/addon/templates/maintenance/schedules/index/details.hbs +1 -0
- package/addon/templates/maintenance/schedules/index.hbs +2 -0
- package/addon/templates/maintenance/work-orders/index/details.hbs +1 -0
- package/addon/templates/maintenance/work-orders/index.hbs +1 -0
- package/addon/templates/management/contacts/customers/details.hbs +1 -0
- package/addon/templates/management/contacts/customers.hbs +1 -0
- package/addon/templates/management/contacts/index/details.hbs +1 -0
- package/addon/templates/management/contacts/index.hbs +1 -0
- package/addon/templates/management/contacts.hbs +1 -0
- package/addon/templates/management/drivers/index/details.hbs +1 -0
- package/addon/templates/management/drivers/index.hbs +2 -0
- package/addon/templates/management/fleets/index/details.hbs +1 -0
- package/addon/templates/management/fleets/index.hbs +1 -0
- package/addon/templates/management/fuel-reports/index/details.hbs +1 -0
- package/addon/templates/management/fuel-reports/index.hbs +1 -0
- package/addon/templates/management/fuel-transactions/index.hbs +1 -0
- package/addon/templates/management/issues/index/details.hbs +1 -0
- package/addon/templates/management/issues/index.hbs +1 -0
- package/addon/templates/management/places/index/details.hbs +1 -0
- package/addon/templates/management/places/index.hbs +1 -0
- package/addon/templates/management/trailers/index/details.hbs +1 -0
- package/addon/templates/management/trailers/index.hbs +2 -0
- package/addon/templates/management/vehicles/index/details.hbs +1 -0
- package/addon/templates/management/vehicles/index.hbs +2 -0
- package/addon/templates/management/vendors/index/details.hbs +1 -0
- package/addon/templates/management/vendors/index.hbs +2 -0
- package/addon/templates/management/vendors/integrated.hbs +1 -0
- package/addon/templates/operations/orders/index/details.hbs +1 -0
- package/addon/templates/operations/orders/index.hbs +1 -0
- package/addon/templates/operations/service-rates/index/details.hbs +1 -0
- package/addon/templates/operations/service-rates/index.hbs +1 -0
- package/addon/utils/normalize-order-config-flow.js +6 -1
- package/app/services/order-presentation.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +3 -3
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +34 -4
- package/server/src/Models/Order.php +35 -3
- package/server/src/Models/OrderConfig.php +129 -0
- package/server/src/Models/TrackingNumber.php +8 -4
- package/server/tests/Feature/Http/Internal/OrderControllerActivityFlowsTest.php +72 -0
- package/server/tests/Feature/Http/Internal/OrderControllerCreateRecordTest.php +26 -0
- package/server/tests/OrderConfigLifecycleTest.php +120 -0
- package/server/tests/Unit/Events/OrderDispatchFailedTest.php +2 -1
- package/translations/en-us.yaml +60 -0
|
@@ -10,7 +10,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
10
10
|
@service intl;
|
|
11
11
|
|
|
12
12
|
/** query params */
|
|
13
|
-
@tracked queryParams = ['page', 'query', 'limit', 'sort', 'zone', 'service_area'];
|
|
13
|
+
@tracked queryParams = this.serviceRateActions.queryParamsFor(['page', 'query', 'limit', 'sort', 'zone', 'service_area']);
|
|
14
14
|
@tracked page = 1;
|
|
15
15
|
@tracked limit;
|
|
16
16
|
@tracked query;
|
|
@@ -20,11 +20,13 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
20
20
|
get actionButtons() {
|
|
21
21
|
return [
|
|
22
22
|
{
|
|
23
|
+
id: 'refresh',
|
|
23
24
|
icon: 'refresh',
|
|
24
25
|
onClick: this.serviceRateActions.refresh,
|
|
25
26
|
helpText: this.intl.t('common.refresh'),
|
|
26
27
|
},
|
|
27
28
|
{
|
|
29
|
+
id: 'create',
|
|
28
30
|
text: this.intl.t('common.new'),
|
|
29
31
|
type: 'primary',
|
|
30
32
|
icon: 'plus',
|
|
@@ -32,6 +34,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
32
34
|
permission: 'fleet-ops create service-rate',
|
|
33
35
|
},
|
|
34
36
|
{
|
|
37
|
+
id: 'export',
|
|
35
38
|
text: this.intl.t('common.export'),
|
|
36
39
|
icon: 'long-arrow-up',
|
|
37
40
|
iconClass: 'rotate-icon-45',
|
|
@@ -46,6 +49,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
46
49
|
get bulkActions() {
|
|
47
50
|
return [
|
|
48
51
|
{
|
|
52
|
+
id: 'bulk-delete',
|
|
49
53
|
label: 'Delete selected...',
|
|
50
54
|
class: 'text-red-500',
|
|
51
55
|
fn: this.serviceRateActions.bulkDelete,
|
|
@@ -58,6 +62,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
58
62
|
get columns() {
|
|
59
63
|
return [
|
|
60
64
|
{
|
|
65
|
+
id: 'public-id',
|
|
61
66
|
sticky: true,
|
|
62
67
|
label: this.intl.t('column.id'),
|
|
63
68
|
valuePath: 'public_id',
|
|
@@ -70,6 +75,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
70
75
|
filterComponent: 'filter/string',
|
|
71
76
|
},
|
|
72
77
|
{
|
|
78
|
+
id: 'service-name',
|
|
73
79
|
label: this.intl.t('column.service'),
|
|
74
80
|
valuePath: 'service_name',
|
|
75
81
|
cellComponent: 'table/cell/base',
|
|
@@ -78,6 +84,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
78
84
|
filterable: false,
|
|
79
85
|
},
|
|
80
86
|
{
|
|
87
|
+
id: 'service-area-name',
|
|
81
88
|
label: this.intl.t('column.service-area'),
|
|
82
89
|
valuePath: 'service_area.name',
|
|
83
90
|
cellComponent: 'cell/service-area-identity',
|
|
@@ -93,6 +100,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
93
100
|
model: 'service-area',
|
|
94
101
|
},
|
|
95
102
|
{
|
|
103
|
+
id: 'zone-name',
|
|
96
104
|
label: this.intl.t('column.zone'),
|
|
97
105
|
valuePath: 'zone.name',
|
|
98
106
|
cellComponent: 'cell/zone-identity',
|
|
@@ -107,6 +115,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
107
115
|
model: 'zone',
|
|
108
116
|
},
|
|
109
117
|
{
|
|
118
|
+
id: 'created-at',
|
|
110
119
|
label: this.intl.t('column.created-at'),
|
|
111
120
|
valuePath: 'createdAt',
|
|
112
121
|
sortParam: 'created_at',
|
|
@@ -116,6 +125,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
116
125
|
filterComponent: 'filter/date',
|
|
117
126
|
},
|
|
118
127
|
{
|
|
128
|
+
id: 'updated-at',
|
|
119
129
|
label: this.intl.t('column.updated-at'),
|
|
120
130
|
valuePath: 'updatedAt',
|
|
121
131
|
sortParam: 'updated_at',
|
|
@@ -126,6 +136,7 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
126
136
|
filterComponent: 'filter/date',
|
|
127
137
|
},
|
|
128
138
|
{
|
|
139
|
+
id: 'row-actions',
|
|
129
140
|
label: '',
|
|
130
141
|
cellComponent: 'table/cell/dropdown',
|
|
131
142
|
ddButtonText: false,
|
|
@@ -137,18 +148,21 @@ export default class OperationsServiceRatesIndexController extends Controller {
|
|
|
137
148
|
width: 60,
|
|
138
149
|
actions: [
|
|
139
150
|
{
|
|
151
|
+
id: 'view',
|
|
140
152
|
label: this.intl.t('common.view-resource', { resource: this.intl.t('resource.service-rate') }),
|
|
141
153
|
icon: 'eye',
|
|
142
154
|
fn: this.serviceRateActions.transition.view,
|
|
143
155
|
permission: 'fleet-ops view service-rate',
|
|
144
156
|
},
|
|
145
157
|
{
|
|
158
|
+
id: 'edit',
|
|
146
159
|
label: this.intl.t('common.edit-resource', { resource: this.intl.t('resource.service-rate') }),
|
|
147
160
|
icon: 'pencil',
|
|
148
161
|
fn: this.serviceRateActions.transition.edit,
|
|
149
162
|
permission: 'fleet-ops view service-rate',
|
|
150
163
|
},
|
|
151
164
|
{
|
|
165
|
+
id: 'delete',
|
|
152
166
|
label: this.intl.t('common.delete-resource', { resource: this.intl.t('resource.service-rate') }),
|
|
153
167
|
icon: 'trash',
|
|
154
168
|
fn: this.serviceRateActions.delete,
|
package/addon/extension.js
CHANGED
|
@@ -162,6 +162,38 @@ export default {
|
|
|
162
162
|
|
|
163
163
|
// Create registries
|
|
164
164
|
this.createRegistries(registryService);
|
|
165
|
+
|
|
166
|
+
// Declare the registries extensions can add table columns, actions and
|
|
167
|
+
// buttons to, e.g. `fleet-ops:driver:table:columns` or `fleet-ops:order:details:menu`.
|
|
168
|
+
universe
|
|
169
|
+
.getService('universe/resource-view-service')
|
|
170
|
+
?.declare('fleet-ops', [
|
|
171
|
+
'contact',
|
|
172
|
+
'customer',
|
|
173
|
+
'device',
|
|
174
|
+
'device-event',
|
|
175
|
+
'driver',
|
|
176
|
+
'equipment',
|
|
177
|
+
'fleet',
|
|
178
|
+
'fuel-report',
|
|
179
|
+
'fuel-transaction',
|
|
180
|
+
'inspection-form',
|
|
181
|
+
'inspection-submission',
|
|
182
|
+
'integrated-vendor',
|
|
183
|
+
'issue',
|
|
184
|
+
'maintenance',
|
|
185
|
+
'order',
|
|
186
|
+
'part',
|
|
187
|
+
'place',
|
|
188
|
+
'report',
|
|
189
|
+
'schedule',
|
|
190
|
+
'sensor',
|
|
191
|
+
'service-rate',
|
|
192
|
+
'trailer',
|
|
193
|
+
'vehicle',
|
|
194
|
+
'vendor',
|
|
195
|
+
'work-order',
|
|
196
|
+
]);
|
|
165
197
|
registryService.registerRenderableComponent('ai:action-preview:fleet-ops.create_order', new ExtensionComponent('@fleetbase/fleetops-engine', 'ai/create-order-preview'));
|
|
166
198
|
|
|
167
199
|
// // Register console home guidance
|
|
@@ -48,6 +48,7 @@ export default class ContactActionsService extends ResourceActionService {
|
|
|
48
48
|
},
|
|
49
49
|
view: (contact, options = {}) => {
|
|
50
50
|
return this.resourceContextPanel.open({
|
|
51
|
+
registry: this.detailsRegistry,
|
|
51
52
|
contact,
|
|
52
53
|
title: contact?.name,
|
|
53
54
|
header: 'contact/panel-header',
|
|
@@ -4,7 +4,7 @@ import { PANEL_DEFAULTS, registeredPanelTabs } from '../utils/context-panel';
|
|
|
4
4
|
export default class CustomerActionsService extends ContactActionsService {
|
|
5
5
|
constructor() {
|
|
6
6
|
super(...arguments);
|
|
7
|
-
this.initialize('contact', { defaultAttributes: { type: 'customer', status: 'active' } });
|
|
7
|
+
this.initialize('contact', { defaultAttributes: { type: 'customer', status: 'active' }, registryResource: 'customer' });
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
transition = {
|
|
@@ -38,6 +38,7 @@ export default class CustomerActionsService extends ContactActionsService {
|
|
|
38
38
|
},
|
|
39
39
|
view: (customer, options = {}) => {
|
|
40
40
|
return this.resourceContextPanel.open({
|
|
41
|
+
registry: this.detailsRegistry,
|
|
41
42
|
customer,
|
|
42
43
|
title: customer?.name,
|
|
43
44
|
header: 'contact/panel-header',
|
|
@@ -48,6 +48,7 @@ export default class DeviceActionsService extends ResourceActionService {
|
|
|
48
48
|
const service = this;
|
|
49
49
|
|
|
50
50
|
return this.resourceContextPanel.open({
|
|
51
|
+
registry: this.detailsRegistry,
|
|
51
52
|
device,
|
|
52
53
|
header: 'device/panel-header',
|
|
53
54
|
title: device.name ?? device.serial_number,
|
|
@@ -2,9 +2,7 @@ import ResourceActionService, { inject as service } from '@fleetbase/ember-core/
|
|
|
2
2
|
import leafletIcon from '@fleetbase/ember-core/utils/leaflet-icon';
|
|
3
3
|
import config from 'ember-get-config';
|
|
4
4
|
import { action } from '@ember/object';
|
|
5
|
-
import {
|
|
6
|
-
import { dasherize } from '@ember/string';
|
|
7
|
-
import { PANEL_DEFAULTS, closePanelsThen } from '../utils/context-panel';
|
|
5
|
+
import { PANEL_DEFAULTS, closePanelsThen, registeredPanelTabs } from '../utils/context-panel';
|
|
8
6
|
import { confirmLoginAction, hasInactiveLogin, hasManagedLogin } from '../utils/profile-login-actions';
|
|
9
7
|
|
|
10
8
|
export default class DriverActionsService extends ResourceActionService {
|
|
@@ -13,16 +11,8 @@ export default class DriverActionsService extends ResourceActionService {
|
|
|
13
11
|
@service issueActions;
|
|
14
12
|
|
|
15
13
|
get registeredTabs() {
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
.map((tab) => {
|
|
19
|
-
delete tab.route;
|
|
20
|
-
if (!tab.key) {
|
|
21
|
-
tab.key = tab.id ?? dasherize(tab.label ?? tab.title);
|
|
22
|
-
}
|
|
23
|
-
return tab;
|
|
24
|
-
})
|
|
25
|
-
.filter((tab) => !tab.component);
|
|
14
|
+
// Copies, so the shared registry items keep the \`route\` their routed details view needs.
|
|
15
|
+
return registeredPanelTabs(this.menuService, 'fleet-ops:component:driver:details');
|
|
26
16
|
}
|
|
27
17
|
|
|
28
18
|
get panelTabs() {
|
|
@@ -125,6 +115,7 @@ export default class DriverActionsService extends ResourceActionService {
|
|
|
125
115
|
const service = this;
|
|
126
116
|
|
|
127
117
|
return this.resourceContextPanel.open({
|
|
118
|
+
registry: this.detailsRegistry,
|
|
128
119
|
driver,
|
|
129
120
|
header: 'driver/panel-header',
|
|
130
121
|
actionButtons: [
|
|
@@ -47,6 +47,7 @@ export default class EquipmentActionsService extends ResourceActionService {
|
|
|
47
47
|
},
|
|
48
48
|
view: (equipment, options = {}) => {
|
|
49
49
|
return this.resourceContextPanel.open({
|
|
50
|
+
registry: this.detailsRegistry,
|
|
50
51
|
equipment,
|
|
51
52
|
title: equipment?.name,
|
|
52
53
|
header: 'equipment/panel-header',
|
|
@@ -43,6 +43,7 @@ export default class FuelReportActionsService extends ResourceActionService {
|
|
|
43
43
|
},
|
|
44
44
|
view: (fuelReport, options = {}) => {
|
|
45
45
|
return this.resourceContextPanel.open({
|
|
46
|
+
registry: this.detailsRegistry,
|
|
46
47
|
fuelReport,
|
|
47
48
|
title: fuelReport?.name ?? `Fuel reported on ${fuelReport?.createdAt ?? ''}`.trim(),
|
|
48
49
|
actionButtons: [{ icon: 'pencil', permission: 'fleet-ops update fuel-report', fn: () => closePanelsThen(this.resourceContextPanel, () => this.panel.edit(fuelReport)) }],
|
|
@@ -44,6 +44,7 @@ export default class MaintenanceActionsService extends ResourceActionService {
|
|
|
44
44
|
},
|
|
45
45
|
view: (maintenance, options = {}) => {
|
|
46
46
|
return this.resourceContextPanel.open({
|
|
47
|
+
registry: this.detailsRegistry,
|
|
47
48
|
maintenance,
|
|
48
49
|
title: maintenance?.summary,
|
|
49
50
|
header: 'maintenance/panel-header',
|
|
@@ -11,7 +11,7 @@ export default class MaintenanceScheduleActionsService extends ResourceActionSer
|
|
|
11
11
|
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
14
|
-
this.initialize('maintenance-schedule');
|
|
14
|
+
this.initialize('maintenance-schedule', { registryResource: 'schedule' });
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
transition = {
|
|
@@ -43,6 +43,7 @@ export default class MaintenanceScheduleActionsService extends ResourceActionSer
|
|
|
43
43
|
},
|
|
44
44
|
view: (schedule, options = {}) => {
|
|
45
45
|
return this.resourceContextPanel.open({
|
|
46
|
+
registry: this.detailsRegistry,
|
|
46
47
|
schedule,
|
|
47
48
|
title: schedule?.name,
|
|
48
49
|
actionButtons: this.panelActionButtons(schedule, { onDeleted: () => this.resourceContextPanel.closeAll() }),
|
|
@@ -6,6 +6,7 @@ import { task } from 'ember-concurrency';
|
|
|
6
6
|
|
|
7
7
|
export default class OrderActionsService extends ResourceActionService {
|
|
8
8
|
@service store;
|
|
9
|
+
@service orderPresentation;
|
|
9
10
|
modelNamePath = 'tracking';
|
|
10
11
|
|
|
11
12
|
constructor() {
|
|
@@ -54,6 +55,7 @@ export default class OrderActionsService extends ResourceActionService {
|
|
|
54
55
|
},
|
|
55
56
|
view: (order, options = {}) => {
|
|
56
57
|
return this.resourceContextPanel.open({
|
|
58
|
+
registry: this.detailsRegistry,
|
|
57
59
|
order,
|
|
58
60
|
tabs: [
|
|
59
61
|
{
|
|
@@ -313,6 +315,11 @@ export default class OrderActionsService extends ResourceActionService {
|
|
|
313
315
|
@action editOrderDetails(order, options = {}) {
|
|
314
316
|
options = options === null ? {} : options;
|
|
315
317
|
|
|
318
|
+
// Orders with a presentation profile are edited in the profiled order form, not the fixed modal.
|
|
319
|
+
if (this.orderPresentation.profileFor(order)) {
|
|
320
|
+
return this.panel.edit(order, options);
|
|
321
|
+
}
|
|
322
|
+
|
|
316
323
|
this.modalsManager.show('modals/order-form', {
|
|
317
324
|
title: this.intl.t('order.actions.edit-order-details'),
|
|
318
325
|
acceptButtonText: this.intl.t('common.save-changes'),
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import Service, { inject as service } from '@ember/service';
|
|
2
|
+
import { isArray } from '@ember/array';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolves an extension-owned presentation profile for an order.
|
|
6
|
+
*
|
|
7
|
+
* A profile lets an extension compose the order form, details and actions for orders
|
|
8
|
+
* whose Order Config opts in via `order_config.meta.presentation_profile`. When no
|
|
9
|
+
* profile applies every consumer renders the standard Fleet-Ops presentation.
|
|
10
|
+
*
|
|
11
|
+
* Extensions register profiles through the registry service so registration does not
|
|
12
|
+
* depend on the Fleet-Ops engine having loaded:
|
|
13
|
+
*
|
|
14
|
+
* registryService.register('fleet-ops:order-presentation', 'profiles', 'my-profile', {
|
|
15
|
+
* id: 'my-profile',
|
|
16
|
+
* isEnabled() { return true; },
|
|
17
|
+
* form: { sections: ['details', 'route', new ExtensionComponent('@org/engine', 'my-section'), 'notes'] },
|
|
18
|
+
* details: { sections: [...] },
|
|
19
|
+
* hidden: { fields: ['driver', 'dispatch'], actions: ['dispatch', 'assign-driver'] },
|
|
20
|
+
* prepare(order) {},
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* Native section names — form: details, route, payload, service-rate, notes, documents,
|
|
24
|
+
* orchestrator-constraints, metadata, custom-fields. Details: activity, detail, custom-fields,
|
|
25
|
+
* purchase-rate, tracking, proof, notes, integrated-vendor-details, route, payload,
|
|
26
|
+
* documents, comments, metadata.
|
|
27
|
+
*
|
|
28
|
+
* `hidden.actions` takes built-in action ids, the same ids the order table and details use in
|
|
29
|
+
* the resource view registries: dispatch, assign-driver, unassign-driver, edit-order-details,
|
|
30
|
+
* update-activity, view-label, listen-to-socket-channel, view-metadata, cancel, delete.
|
|
31
|
+
*/
|
|
32
|
+
export const ORDER_PRESENTATION_REGISTRY = 'fleet-ops:order-presentation';
|
|
33
|
+
|
|
34
|
+
export default class OrderPresentationService extends Service {
|
|
35
|
+
@service('universe/registry-service') registryService;
|
|
36
|
+
|
|
37
|
+
get profiles() {
|
|
38
|
+
return this.registryService.getRegistry(ORDER_PRESENTATION_REGISTRY, 'profiles') ?? [];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns the presentation profile applying to an order or order config, or null.
|
|
43
|
+
*
|
|
44
|
+
* @param {Object} orderOrConfig an order (with `order_config`) or an order-config
|
|
45
|
+
* @returns {Object|null}
|
|
46
|
+
*/
|
|
47
|
+
profileFor(orderOrConfig) {
|
|
48
|
+
const orderConfig = this.#resolveOrderConfig(orderOrConfig);
|
|
49
|
+
const profileId = orderConfig?.meta?.presentation_profile;
|
|
50
|
+
if (!profileId) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const profile = this.profiles.find((candidate) => candidate?.id === profileId);
|
|
55
|
+
if (!profile) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (typeof profile.isEnabled === 'function' && profile.isEnabled(orderConfig) !== true) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return profile;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Returns the ordered sections of a profile surface ("form" or "details").
|
|
68
|
+
*/
|
|
69
|
+
sectionsFor(profile, surface) {
|
|
70
|
+
const sections = profile?.[surface]?.sections;
|
|
71
|
+
return isArray(sections) ? sections : [];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Returns renderable section descriptors for a surface ("form" or "details").
|
|
76
|
+
* Native sections resolve to `order/<surface>/<name>`; anything else is an ExtensionComponent.
|
|
77
|
+
*/
|
|
78
|
+
renderableSectionsFor(profile, surface) {
|
|
79
|
+
return this.sectionsFor(profile, surface).map((section, index) => {
|
|
80
|
+
if (typeof section === 'string') {
|
|
81
|
+
return { key: `native:${section}`, native: true, name: section, componentName: `order/${surface}/${section}` };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return { key: `extension:${section?.path ?? section?.name ?? index}`, native: false, component: section };
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Determines if a field or action is hidden by the profile applying to the subject.
|
|
90
|
+
*
|
|
91
|
+
* @param {Object} orderOrConfig
|
|
92
|
+
* @param {String} group "fields" or "actions"
|
|
93
|
+
* @param {String} key a field key, or a built-in action id
|
|
94
|
+
*/
|
|
95
|
+
isHidden(orderOrConfig, group, key) {
|
|
96
|
+
const profile = this.profileFor(orderOrConfig);
|
|
97
|
+
const hidden = profile?.hidden?.[group];
|
|
98
|
+
return isArray(hidden) && hidden.includes(key);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
hiddenFieldsFor(orderOrConfig) {
|
|
102
|
+
const hidden = this.profileFor(orderOrConfig)?.hidden?.fields;
|
|
103
|
+
return isArray(hidden) ? hidden : [];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Lets the profile normalize an order when it starts to apply (e.g. clear dispatch-only values).
|
|
108
|
+
*/
|
|
109
|
+
prepare(order) {
|
|
110
|
+
const profile = this.profileFor(order);
|
|
111
|
+
if (profile && typeof profile.prepare === 'function') {
|
|
112
|
+
profile.prepare(order);
|
|
113
|
+
}
|
|
114
|
+
return profile;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
#resolveOrderConfig(orderOrConfig) {
|
|
118
|
+
if (!orderOrConfig) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// An order-config has a flow; an order references its config.
|
|
123
|
+
if (orderOrConfig.flow !== undefined && orderOrConfig.order_config === undefined) {
|
|
124
|
+
return orderOrConfig;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return orderOrConfig.order_config ?? null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -52,6 +52,7 @@ export default class PlaceActionsService extends ResourceActionService {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
return this.resourceContextPanel.open({
|
|
55
|
+
registry: this.detailsRegistry,
|
|
55
56
|
place,
|
|
56
57
|
title: place?.name ?? place?.street1,
|
|
57
58
|
actionButtons: [{ icon: 'pencil', permission: 'fleet-ops update place', fn: () => closePanelsThen(this.resourceContextPanel, () => this.panel.edit(place)) }],
|
|
@@ -41,6 +41,7 @@ export default class ServiceAreaActionsService extends ResourceActionService {
|
|
|
41
41
|
},
|
|
42
42
|
view: (serviceArea, options = {}) => {
|
|
43
43
|
return this.resourceContextPanel.open({
|
|
44
|
+
registry: this.detailsRegistry,
|
|
44
45
|
serviceArea,
|
|
45
46
|
title: serviceArea?.name,
|
|
46
47
|
actionButtons: [
|
|
@@ -2,9 +2,7 @@ import ResourceActionService, { inject as service } from '@fleetbase/ember-core/
|
|
|
2
2
|
import leafletIcon from '@fleetbase/ember-core/utils/leaflet-icon';
|
|
3
3
|
import config from 'ember-get-config';
|
|
4
4
|
import { action } from '@ember/object';
|
|
5
|
-
import {
|
|
6
|
-
import { dasherize } from '@ember/string';
|
|
7
|
-
import { PANEL_DEFAULTS, closePanelsThen } from '../utils/context-panel';
|
|
5
|
+
import { PANEL_DEFAULTS, closePanelsThen, registeredPanelTabs } from '../utils/context-panel';
|
|
8
6
|
|
|
9
7
|
/**
|
|
10
8
|
* Trailer resource actions.
|
|
@@ -32,17 +30,8 @@ export default class TrailerActionsService extends ResourceActionService {
|
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
get registeredTabs() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return (isArray(registeredTabs) ? registeredTabs : [])
|
|
38
|
-
.map((tab) => {
|
|
39
|
-
delete tab.route;
|
|
40
|
-
if (!tab.key) {
|
|
41
|
-
tab.key = tab.id ?? dasherize(tab.label ?? tab.title);
|
|
42
|
-
}
|
|
43
|
-
return tab;
|
|
44
|
-
})
|
|
45
|
-
.filter((tab) => !tab.component);
|
|
33
|
+
// Copies, so the shared registry items keep the \`route\` their routed details view needs.
|
|
34
|
+
return registeredPanelTabs(this.menuService, 'fleet-ops:component:trailer:details');
|
|
46
35
|
}
|
|
47
36
|
|
|
48
37
|
get panelTabs() {
|
|
@@ -132,6 +121,7 @@ export default class TrailerActionsService extends ResourceActionService {
|
|
|
132
121
|
const service = this;
|
|
133
122
|
|
|
134
123
|
return this.resourceContextPanel.open({
|
|
124
|
+
registry: this.detailsRegistry,
|
|
135
125
|
trailer,
|
|
136
126
|
header: 'trailer/panel-header',
|
|
137
127
|
actionButtons: [
|
|
@@ -2,9 +2,7 @@ import ResourceActionService, { inject as service } from '@fleetbase/ember-core/
|
|
|
2
2
|
import leafletIcon from '@fleetbase/ember-core/utils/leaflet-icon';
|
|
3
3
|
import config from 'ember-get-config';
|
|
4
4
|
import { action } from '@ember/object';
|
|
5
|
-
import {
|
|
6
|
-
import { dasherize } from '@ember/string';
|
|
7
|
-
import { PANEL_DEFAULTS, closePanelsThen } from '../utils/context-panel';
|
|
5
|
+
import { PANEL_DEFAULTS, closePanelsThen, registeredPanelTabs } from '../utils/context-panel';
|
|
8
6
|
|
|
9
7
|
export default class VehicleActionsService extends ResourceActionService {
|
|
10
8
|
@service('universe/menu-service') menuService;
|
|
@@ -15,16 +13,8 @@ export default class VehicleActionsService extends ResourceActionService {
|
|
|
15
13
|
@service issueActions;
|
|
16
14
|
|
|
17
15
|
get registeredTabs() {
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
.map((tab) => {
|
|
21
|
-
delete tab.route;
|
|
22
|
-
if (!tab.key) {
|
|
23
|
-
tab.key = tab.id ?? dasherize(tab.label ?? tab.title);
|
|
24
|
-
}
|
|
25
|
-
return tab;
|
|
26
|
-
})
|
|
27
|
-
.filter((tab) => !tab.component);
|
|
16
|
+
// Copies, so the shared registry items keep the \`route\` their routed details view needs.
|
|
17
|
+
return registeredPanelTabs(this.menuService, 'fleet-ops:component:vehicle:details');
|
|
28
18
|
}
|
|
29
19
|
|
|
30
20
|
get panelTabs() {
|
|
@@ -148,6 +138,7 @@ export default class VehicleActionsService extends ResourceActionService {
|
|
|
148
138
|
const service = this;
|
|
149
139
|
|
|
150
140
|
return this.resourceContextPanel.open({
|
|
141
|
+
registry: this.detailsRegistry,
|
|
151
142
|
vehicle,
|
|
152
143
|
header: 'vehicle/panel-header',
|
|
153
144
|
actionButtons: [
|
|
@@ -43,6 +43,7 @@ export default class VendorActionsService extends ResourceActionService {
|
|
|
43
43
|
},
|
|
44
44
|
view: (vendor, options = {}) => {
|
|
45
45
|
return this.resourceContextPanel.open({
|
|
46
|
+
registry: this.detailsRegistry,
|
|
46
47
|
vendor,
|
|
47
48
|
title: vendor?.name,
|
|
48
49
|
header: 'vendor/panel-header',
|
|
@@ -41,6 +41,7 @@ export default class WorkOrderActionsService extends ResourceActionService {
|
|
|
41
41
|
},
|
|
42
42
|
view: (workOrder, options = {}) => {
|
|
43
43
|
return this.resourceContextPanel.open({
|
|
44
|
+
registry: this.detailsRegistry,
|
|
44
45
|
workOrder,
|
|
45
46
|
title: workOrder?.code ?? workOrder?.subject,
|
|
46
47
|
header: 'work-order/panel-header',
|