@fleetbase/fleetops-engine 0.6.53 → 0.6.55
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/addon/components/admin/routing-settings.hbs +2 -1
- package/addon/components/cell/attached-vehicle.hbs +10 -0
- package/addon/components/cell/attached-vehicle.js +58 -0
- package/addon/components/cell/device-identity.hbs +24 -0
- package/addon/components/cell/device-identity.js +129 -0
- package/addon/components/cell/driver-identity.hbs +33 -0
- package/addon/components/cell/driver-identity.js +143 -0
- package/addon/components/cell/equipment-identity.hbs +5 -0
- package/addon/components/cell/equipment-identity.js +48 -0
- package/addon/components/cell/part-identity.hbs +5 -0
- package/addon/components/cell/part-identity.js +63 -0
- package/addon/components/cell/telematic-device.hbs +38 -0
- package/addon/components/cell/telematic-device.js +44 -0
- package/addon/components/cell/telematic-provider.hbs +33 -16
- package/addon/components/cell/telematic-provider.js +50 -8
- package/addon/components/cell/vehicle-identity.hbs +33 -0
- package/addon/components/cell/vehicle-identity.js +138 -0
- package/addon/components/device/details.hbs +106 -135
- package/addon/components/device/details.js +174 -1
- package/addon/components/device/form.hbs +2 -2
- package/addon/components/device/form.js +7 -0
- package/addon/components/device/panel-header.hbs +46 -21
- package/addon/components/device/panel-header.js +49 -1
- package/addon/components/device/panel-tabs/events.hbs +30 -0
- package/addon/components/device/panel-tabs/events.js +128 -0
- package/addon/components/device/panel-tabs/sensors.hbs +30 -0
- package/addon/components/device/panel-tabs/sensors.js +93 -0
- package/addon/components/device/panel-tabs/vehicle.hbs +68 -0
- package/addon/components/device/panel-tabs/vehicle.js +90 -0
- package/addon/components/equipment/form.js +8 -1
- package/addon/components/layout/fleet-ops-sidebar/operations-monitor.js +76 -11
- package/addon/components/layout/fleet-ops-sidebar.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +101 -17
- package/addon/components/map/drawer/device-event-listing.js +2 -0
- package/addon/components/map/drawer/driver-listing.js +2 -0
- package/addon/components/map/drawer/place-listing.js +2 -0
- package/addon/components/map/drawer/position-listing.hbs +11 -6
- package/addon/components/map/drawer/position-listing.js +17 -4
- package/addon/components/map/drawer/vehicle-listing.js +2 -0
- package/addon/components/order/form/details.hbs +1 -43
- package/addon/components/order/form/details.js +18 -53
- package/addon/components/order/form/orchestrator-constraints.hbs +40 -0
- package/addon/components/order/form/orchestrator-constraints.js +61 -0
- package/addon/components/order/form/payload.js +48 -2
- package/addon/components/order/form/route.js +15 -0
- package/addon/components/order/form/service-rate.hbs +62 -11
- package/addon/components/order/form/service-rate.js +124 -2
- package/addon/components/order/form.hbs +2 -0
- package/addon/components/sensor/panel-header.hbs +47 -15
- package/addon/components/sensor/panel-header.js +59 -1
- package/addon/components/table/cell/dropdown/action-item.hbs +31 -0
- package/addon/components/table/cell/dropdown/action-item.js +62 -0
- package/addon/components/table/cell/dropdown.hbs +28 -0
- package/addon/components/table/cell/dropdown.js +91 -0
- package/addon/components/telematic/details.hbs +7 -1
- package/addon/components/telematic/form.js +16 -8
- package/addon/components/vendor/panel-header.hbs +82 -0
- package/addon/components/vendor/panel-header.js +48 -0
- package/addon/components/work-order/details.hbs +5 -1
- package/addon/components/work-order/form.hbs +26 -4
- package/addon/components/work-order/form.js +5 -1
- package/addon/controllers/connectivity/devices/index/details/events.js +244 -1
- package/addon/controllers/connectivity/devices/index/details/sensors.js +199 -0
- package/addon/controllers/connectivity/devices/index/details/vehicle.js +122 -0
- package/addon/controllers/connectivity/devices/index/details.js +12 -0
- package/addon/controllers/connectivity/devices/index.js +144 -129
- package/addon/controllers/connectivity/events/details.js +3 -0
- package/addon/controllers/connectivity/events/index.js +187 -11
- package/addon/controllers/connectivity/sensors/index.js +156 -14
- package/addon/controllers/connectivity/telematics/details/attachments.js +220 -54
- package/addon/controllers/connectivity/telematics/details/devices.js +170 -129
- package/addon/controllers/connectivity/telematics/details/events.js +39 -11
- package/addon/controllers/connectivity/telematics/details/sensors.js +39 -19
- package/addon/controllers/maintenance/equipment/index.js +1 -2
- package/addon/controllers/maintenance/parts/index.js +1 -2
- package/addon/controllers/maintenance/work-orders/index.js +18 -1
- package/addon/controllers/management/drivers/index.js +82 -42
- package/addon/controllers/management/fuel-reports/index.js +63 -4
- package/addon/controllers/management/issues/index.js +63 -4
- package/addon/controllers/management/vehicles/index.js +33 -6
- package/addon/routes/connectivity/devices/index/details/events.js +37 -1
- package/addon/routes/connectivity/devices/index/details/sensors.js +35 -0
- package/addon/routes/connectivity/devices/index/details/vehicle.js +29 -0
- package/addon/routes/connectivity/devices/index.js +7 -0
- package/addon/routes/connectivity/events/details.js +3 -0
- package/addon/routes/connectivity/events/index.js +6 -2
- package/addon/routes/connectivity/sensors/index.js +7 -2
- package/addon/routes/connectivity/telematics/details/attachments.js +72 -9
- package/addon/routes/connectivity/telematics/details/devices.js +6 -0
- package/addon/routes/connectivity/telematics/details/sensors.js +1 -0
- package/addon/routes/connectivity/telematics/details.js +1 -1
- package/addon/routes/connectivity/telematics/edit.js +1 -1
- package/addon/routes/maintenance/work-orders/index.js +1 -0
- package/addon/routes.js +2 -0
- package/addon/services/device-actions.js +30 -0
- package/addon/services/device-event-actions.js +1 -1
- package/addon/services/equipment-actions.js +1 -0
- package/addon/services/order-creation.js +54 -1
- package/addon/services/order-validation.js +3 -2
- package/addon/services/sensor-actions.js +3 -0
- package/addon/services/service-rate-actions.js +40 -1
- package/addon/services/vehicle-actions.js +24 -12
- package/addon/services/vendor-actions.js +3 -0
- package/addon/styles/fleetops-engine.css +28 -4
- package/addon/templates/connectivity/devices/index/details/events.hbs +85 -1
- package/addon/templates/connectivity/devices/index/details/sensors.hbs +73 -0
- package/addon/templates/connectivity/devices/index/details/vehicle.hbs +147 -0
- package/addon/templates/connectivity/telematics/details/attachments.hbs +198 -121
- package/addon/templates/connectivity/telematics/details/devices.hbs +4 -1
- package/addon/templates/connectivity/telematics/details/events.hbs +4 -1
- package/addon/templates/connectivity/telematics/details/sensors.hbs +3 -0
- package/addon/templates/management/vehicles/index/edit.hbs +1 -1
- package/addon/templates/management/vendors/index/details.hbs +2 -2
- package/addon/templates/settings/notifications.hbs +2 -1
- package/addon/templates/settings/routing.hbs +1 -0
- package/addon/utils/device-table-columns.js +288 -0
- package/addon/utils/fleet-ops-options.js +38 -0
- package/addon/utils/identity-cell-resource.js +20 -0
- package/addon/utils/map-drawer-dropdown-position.js +47 -0
- package/addon/utils/trackable-option.js +93 -0
- package/app/components/cell/attached-vehicle.js +1 -0
- package/app/components/cell/device-identity.js +1 -0
- package/app/components/cell/driver-identity.js +1 -0
- package/app/components/cell/equipment-identity.js +1 -0
- package/app/components/cell/part-identity.js +1 -0
- package/app/components/cell/telematic-device.js +1 -0
- package/app/components/cell/vehicle-identity.js +1 -0
- package/app/components/device/panel-tabs/events.hbs +30 -0
- package/app/components/device/panel-tabs/events.js +128 -0
- package/app/components/device/panel-tabs/sensors.hbs +30 -0
- package/app/components/device/panel-tabs/sensors.js +93 -0
- package/app/components/device/panel-tabs/vehicle.hbs +68 -0
- package/app/components/device/panel-tabs/vehicle.js +90 -0
- package/app/components/order/form/orchestrator-constraints.js +1 -0
- package/app/components/table/cell/dropdown/action-item.js +1 -0
- package/app/components/table/cell/dropdown.js +1 -0
- package/app/components/vendor/panel-header.js +1 -0
- package/app/controllers/connectivity/devices/index/details/sensors.js +1 -0
- package/app/controllers/connectivity/devices/index/details/vehicle.js +1 -0
- package/app/controllers/connectivity/events/{index/details.js → details.js} +1 -1
- package/app/routes/connectivity/devices/index/details/sensors.js +1 -0
- package/app/routes/connectivity/devices/index/details/vehicle.js +1 -0
- package/app/routes/connectivity/events/{index/details.js → details.js} +1 -1
- package/app/templates/connectivity/devices/index/details/sensors.js +1 -0
- package/app/templates/connectivity/devices/index/details/vehicle.js +1 -0
- package/app/templates/connectivity/events/{index/details.js → details.js} +1 -1
- package/app/utils/map-drawer-dropdown-position.js +1 -0
- package/app/utils/trackable-option.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +4 -4
- package/server/migrations/2025_08_28_054930_create_work_orders_table.php +1 -0
- package/server/migrations/2026_06_18_000001_add_category_to_work_orders_table.php +32 -0
- package/server/seeders/Testing/MaintenanceSeeder.php +5 -4
- package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +1 -0
- package/server/src/Console/Commands/SyncTelematics.php +89 -0
- package/server/src/Exceptions/TelematicProviderException.php +13 -2
- package/server/src/Http/Controllers/Api/v1/OrderController.php +6 -21
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +55 -1
- package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +17 -6
- package/server/src/Http/Controllers/Internal/v1/FleetController.php +9 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +178 -1
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +1 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +4 -32
- package/server/src/Http/Controllers/Internal/v1/SearchController.php +2 -2
- package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +4 -4
- package/server/src/Http/Controllers/Internal/v1/ServiceRateController.php +82 -13
- package/server/src/Http/Filter/DeviceEventFilter.php +65 -0
- package/server/src/Http/Filter/DeviceFilter.php +80 -0
- package/server/src/Http/Filter/SensorFilter.php +125 -0
- package/server/src/Http/Filter/VehicleFilter.php +13 -0
- package/server/src/Http/Requests/CreateDriverRequest.php +14 -13
- package/server/src/Http/Requests/Internal/CreateDriverRequest.php +1 -0
- package/server/src/Http/Resources/v1/Driver.php +11 -2
- package/server/src/Http/Resources/v1/Index/Vehicle.php +19 -0
- package/server/src/Http/Resources/v1/WorkOrder.php +1 -0
- package/server/src/Jobs/FinalizeApiOrderCreation.php +47 -0
- package/server/src/Jobs/FinalizeInternalOrderCreation.php +35 -0
- package/server/src/Jobs/NotifyBulkAssignedDriver.php +47 -0
- package/server/src/Jobs/SyncTelematicDevicesJob.php +180 -123
- package/server/src/Models/Device.php +17 -1
- package/server/src/Models/DeviceEvent.php +82 -1
- package/server/src/Models/Driver.php +16 -0
- package/server/src/Models/Equipment.php +55 -0
- package/server/src/Models/Sensor.php +15 -2
- package/server/src/Models/Telematic.php +1 -1
- package/server/src/Models/Vehicle.php +5 -1
- package/server/src/Models/WorkOrder.php +5 -2
- package/server/src/Observers/DriverObserver.php +3 -3
- package/server/src/Observers/FleetObserver.php +23 -0
- package/server/src/Observers/VehicleObserver.php +3 -3
- package/server/src/Providers/FleetOpsServiceProvider.php +2 -0
- package/server/src/Support/LiveCacheService.php +1 -1
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +143 -20
- package/server/src/Support/Telematics/Providers/FlespiProvider.php +89 -15
- package/server/src/Support/Telematics/Providers/GeotabProvider.php +123 -35
- package/server/src/Support/Telematics/Providers/SafeeProvider.php +70 -5
- package/server/src/Support/Telematics/Providers/SamsaraProvider.php +122 -14
- package/server/src/Support/Telematics/TelematicService.php +330 -30
- package/server/src/routes.php +1 -1
- package/server/tests/DeviceFilterTest.php +45 -0
- package/server/tests/DriverVehicleStatusDefaultTest.php +19 -2
- package/server/tests/EquipmentAssignmentMorphTypeTest.php +35 -0
- package/server/tests/OperationsMonitorEndpointTest.php +38 -0
- package/server/tests/OrderQueuedClosureRegressionTest.php +36 -0
- package/server/tests/ServiceRateRouteValidationTest.php +101 -0
- package/server/tests/TelematicsHardeningTest.php +598 -6
- package/server/tests/VehicleDriverAssignmentTest.php +27 -0
- package/translations/en-us.yaml +1 -0
- package/addon/controllers/connectivity/events/index/details.js +0 -3
- package/addon/routes/connectivity/events/index/details.js +0 -3
- /package/addon/templates/connectivity/events/{index/details.hbs → details.hbs} +0 -0
|
@@ -5,78 +5,136 @@ import { tracked } from '@glimmer/tracking';
|
|
|
5
5
|
|
|
6
6
|
export default class ConnectivityTelematicsDetailsAttachmentsController extends Controller {
|
|
7
7
|
@service deviceActions;
|
|
8
|
+
@service fetch;
|
|
8
9
|
@service hostRouter;
|
|
9
10
|
@service intl;
|
|
10
11
|
@service modalsManager;
|
|
11
12
|
@service notifications;
|
|
12
13
|
|
|
13
|
-
@tracked queryParams = ['query', 'status', '
|
|
14
|
+
@tracked queryParams = ['query', 'status', 'vehicle', 'sort'];
|
|
14
15
|
@tracked telematic;
|
|
15
16
|
@tracked query;
|
|
16
17
|
@tracked status;
|
|
17
|
-
@tracked attachment_state;
|
|
18
18
|
@tracked vehicle;
|
|
19
19
|
@tracked sort = '-updated_at';
|
|
20
|
+
@tracked selectedDevice = null;
|
|
21
|
+
@tracked selectedVehicle = null;
|
|
22
|
+
@tracked isRefreshing = false;
|
|
20
23
|
|
|
21
24
|
get syncedDevices() {
|
|
22
|
-
return Array.from(this.model ?? []);
|
|
25
|
+
return Array.from(this.model?.devices ?? this.model ?? []);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
get
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.toLowerCase();
|
|
29
|
-
|
|
30
|
-
return this.syncedDevices.filter((device) => {
|
|
31
|
-
const matchesQuery =
|
|
32
|
-
!query ||
|
|
33
|
-
[device.displayName, device.name, device.device_id, device.serial_number, device.imei, device.attached_to_name, device.status, device.connection_status]
|
|
34
|
-
.filter(Boolean)
|
|
35
|
-
.some((value) => String(value).toLowerCase().includes(query));
|
|
28
|
+
get loadError() {
|
|
29
|
+
return this.model?.error;
|
|
30
|
+
}
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const matchesVehicle = !this.vehicle || device.attachable_uuid === this.vehicle;
|
|
32
|
+
get totalSyncedDevices() {
|
|
33
|
+
return this.model?.meta?.total ?? this.syncedDevices.length;
|
|
34
|
+
}
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
get devices() {
|
|
37
|
+
return [...this.unattachedDevices, ...this.attachedDevices];
|
|
44
38
|
}
|
|
45
39
|
|
|
46
40
|
get unattachedDevices() {
|
|
47
|
-
return this.
|
|
41
|
+
return this.syncedDevices.filter((device) => !device.attachable_uuid && this.deviceMatchesQuery(device) && this.deviceMatchesStatus(device));
|
|
48
42
|
}
|
|
49
43
|
|
|
50
44
|
get attachedDevices() {
|
|
51
|
-
return this.
|
|
45
|
+
return this.syncedDevices.filter((device) => device.attachable_uuid && this.deviceMatchesQuery(device) && this.deviceMatchesStatus(device) && this.deviceMatchesVehicle(device));
|
|
52
46
|
}
|
|
53
47
|
|
|
54
48
|
get onlineDevicesCount() {
|
|
55
|
-
return this.
|
|
49
|
+
return this.syncedDevices.filter((device) => device.is_online || device.connection_status === 'online' || device.status === 'online' || device.status === 'active').length;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get attachedDevicesCount() {
|
|
53
|
+
return this.syncedDevices.filter((device) => device.attachable_uuid).length;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get unattachedDevicesCount() {
|
|
57
|
+
return this.syncedDevices.filter((device) => !device.attachable_uuid).length;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get mappedVehiclesCount() {
|
|
61
|
+
const vehicleIds = new Set(this.syncedDevices.filter((device) => device.attachable_uuid).map((device) => device.attachable_uuid));
|
|
62
|
+
|
|
63
|
+
return vehicleIds.size;
|
|
56
64
|
}
|
|
57
65
|
|
|
58
66
|
get vehicleGroups() {
|
|
59
67
|
const groups = new Map();
|
|
60
68
|
|
|
61
69
|
for (const device of this.attachedDevices) {
|
|
62
|
-
|
|
70
|
+
this.addDeviceToVehicleGroup(groups, device);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return this.sortVehicleGroups(groups);
|
|
74
|
+
}
|
|
63
75
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
id: key,
|
|
67
|
-
name: device.attached_to_name ?? 'Unknown vehicle',
|
|
68
|
-
devices: [],
|
|
69
|
-
});
|
|
70
|
-
}
|
|
76
|
+
addDeviceToVehicleGroup(groups, device) {
|
|
77
|
+
const key = device.attachable_uuid;
|
|
71
78
|
|
|
72
|
-
|
|
79
|
+
if (!groups.has(key)) {
|
|
80
|
+
const vehicle = device.attachable;
|
|
81
|
+
|
|
82
|
+
groups.set(key, {
|
|
83
|
+
id: key,
|
|
84
|
+
name: this.getDeviceVehicleName(device),
|
|
85
|
+
vehicle,
|
|
86
|
+
devices: [],
|
|
87
|
+
});
|
|
73
88
|
}
|
|
74
89
|
|
|
90
|
+
groups.get(key).devices.push(device);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
sortVehicleGroups(groups) {
|
|
75
94
|
return Array.from(groups.values()).sort((a, b) => String(a.name).localeCompare(String(b.name)));
|
|
76
95
|
}
|
|
77
96
|
|
|
97
|
+
get normalizedQuery() {
|
|
98
|
+
return String(this.query ?? '')
|
|
99
|
+
.trim()
|
|
100
|
+
.toLowerCase();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
deviceMatchesQuery(device) {
|
|
104
|
+
const query = this.normalizedQuery;
|
|
105
|
+
|
|
106
|
+
if (!query) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return [
|
|
111
|
+
device.displayName,
|
|
112
|
+
device.name,
|
|
113
|
+
device.device_id,
|
|
114
|
+
device.serial_number,
|
|
115
|
+
device.imei,
|
|
116
|
+
device.public_id,
|
|
117
|
+
device.attached_to_name,
|
|
118
|
+
device.attachable?.displayName,
|
|
119
|
+
device.attachable?.display_name,
|
|
120
|
+
device.attachable?.name,
|
|
121
|
+
device.status,
|
|
122
|
+
device.connection_status,
|
|
123
|
+
]
|
|
124
|
+
.filter(Boolean)
|
|
125
|
+
.some((value) => String(value).toLowerCase().includes(query));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
deviceMatchesStatus(device) {
|
|
129
|
+
return !this.status || device.status === this.status || device.connection_status === this.status;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
deviceMatchesVehicle(device) {
|
|
133
|
+
return !this.vehicle || device.attachable_uuid === this.vehicle;
|
|
134
|
+
}
|
|
135
|
+
|
|
78
136
|
get hasActiveFilters() {
|
|
79
|
-
return Boolean(this.query || this.status || this.
|
|
137
|
+
return Boolean(this.query || this.status || this.vehicle);
|
|
80
138
|
}
|
|
81
139
|
|
|
82
140
|
get hasSyncedDevices() {
|
|
@@ -96,6 +154,10 @@ export default class ConnectivityTelematicsDetailsAttachmentsController extends
|
|
|
96
154
|
}
|
|
97
155
|
|
|
98
156
|
get emptyStateVariant() {
|
|
157
|
+
if (this.loadError) {
|
|
158
|
+
return 'error';
|
|
159
|
+
}
|
|
160
|
+
|
|
99
161
|
if (!this.hasSyncedDevices) {
|
|
100
162
|
return 'not_synced';
|
|
101
163
|
}
|
|
@@ -117,6 +179,19 @@ export default class ConnectivityTelematicsDetailsAttachmentsController extends
|
|
|
117
179
|
|
|
118
180
|
get emptyStateContent() {
|
|
119
181
|
switch (this.emptyStateVariant) {
|
|
182
|
+
case 'error':
|
|
183
|
+
return {
|
|
184
|
+
tone: 'danger',
|
|
185
|
+
icon: 'triangle-exclamation',
|
|
186
|
+
title: 'Unable to load device attachments',
|
|
187
|
+
message: 'Fleetbase could not load the full provider device list. Refresh the tab or review the connection logs.',
|
|
188
|
+
primaryText: 'Refresh',
|
|
189
|
+
primaryIcon: 'refresh',
|
|
190
|
+
primaryAction: this.refresh,
|
|
191
|
+
secondaryText: 'Go to Logs',
|
|
192
|
+
secondaryIcon: 'history',
|
|
193
|
+
secondaryAction: this.goToLogs,
|
|
194
|
+
};
|
|
120
195
|
case 'not_synced':
|
|
121
196
|
return {
|
|
122
197
|
tone: 'warning',
|
|
@@ -158,36 +233,96 @@ export default class ConnectivityTelematicsDetailsAttachmentsController extends
|
|
|
158
233
|
|
|
159
234
|
get metrics() {
|
|
160
235
|
return [
|
|
161
|
-
{ label: '
|
|
162
|
-
{ label: '
|
|
163
|
-
{ label: '
|
|
236
|
+
{ label: 'Synced devices', value: this.totalSyncedDevices, icon: 'microchip', accentClass: 'fleetops-connectivity-kpi-accent-blue' },
|
|
237
|
+
{ label: 'Vehicles mapped', value: this.mappedVehiclesCount, icon: 'truck', accentClass: 'fleetops-connectivity-kpi-accent-blue' },
|
|
238
|
+
{ label: 'Attached devices', value: this.attachedDevicesCount, icon: 'link', accentClass: 'fleetops-connectivity-kpi-accent-green' },
|
|
239
|
+
{ label: 'Unattached devices', value: this.unattachedDevicesCount, icon: 'link-slash', accentClass: 'fleetops-connectivity-kpi-accent-amber' },
|
|
164
240
|
{ label: 'Online devices', value: this.onlineDevicesCount, icon: 'signal', accentClass: 'fleetops-connectivity-kpi-accent-green' },
|
|
165
241
|
];
|
|
166
242
|
}
|
|
167
243
|
|
|
168
|
-
|
|
169
|
-
this.
|
|
244
|
+
get visibleDevicesCount() {
|
|
245
|
+
return this.devices.length;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
get filteredUnattachedCount() {
|
|
249
|
+
return this.unattachedDevices.length;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
get filteredAttachedCount() {
|
|
253
|
+
return this.attachedDevices.length;
|
|
170
254
|
}
|
|
171
255
|
|
|
172
|
-
|
|
173
|
-
this.
|
|
256
|
+
get selectedDeviceName() {
|
|
257
|
+
return this.selectedDevice?.displayName ?? this.selectedDevice?.name ?? this.selectedDevice?.device_id;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@action updateQuery(event) {
|
|
261
|
+
this.query = event.target.value;
|
|
174
262
|
}
|
|
175
263
|
|
|
176
264
|
@action updateStatus(event) {
|
|
177
265
|
this.status = event.target.value || null;
|
|
178
266
|
}
|
|
179
267
|
|
|
268
|
+
@action updateVehicle(valueOrEvent) {
|
|
269
|
+
const value = valueOrEvent?.target ? valueOrEvent.target.value : valueOrEvent;
|
|
270
|
+
|
|
271
|
+
this.vehicle = value || null;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@action updateSelectedVehicle(vehicle) {
|
|
275
|
+
this.selectedVehicle = vehicle;
|
|
276
|
+
this.vehicle = vehicle?.id ?? null;
|
|
277
|
+
}
|
|
278
|
+
|
|
180
279
|
@action clearFilters() {
|
|
181
280
|
this.query = null;
|
|
182
281
|
this.status = null;
|
|
183
|
-
this.attachment_state = null;
|
|
184
282
|
this.vehicle = null;
|
|
283
|
+
this.selectedVehicle = null;
|
|
185
284
|
}
|
|
186
285
|
|
|
187
286
|
@action goToDevices() {
|
|
188
287
|
return this.hostRouter.transitionTo('console.fleet-ops.connectivity.telematics.details.devices', this.telematic);
|
|
189
288
|
}
|
|
190
289
|
|
|
290
|
+
@action goToLogs() {
|
|
291
|
+
return this.hostRouter.transitionTo('console.fleet-ops.connectivity.telematics.details.logs', this.telematic);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@action async refresh() {
|
|
295
|
+
this.isRefreshing = true;
|
|
296
|
+
|
|
297
|
+
try {
|
|
298
|
+
return await this.hostRouter.refresh();
|
|
299
|
+
} finally {
|
|
300
|
+
this.isRefreshing = false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
@action selectUnattachedDevice(device) {
|
|
305
|
+
if (this.selectedDevice === device) {
|
|
306
|
+
this.selectedDevice = null;
|
|
307
|
+
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
this.selectedDevice = device;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
@action clearSelectedDevice() {
|
|
315
|
+
this.selectedDevice = null;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
@action attachSelectedDeviceToGroup(group) {
|
|
319
|
+
if (!this.selectedDevice) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return this.attachDeviceToVehicle(this.selectedDevice, group.vehicle ?? { id: group.id, name: group.name });
|
|
324
|
+
}
|
|
325
|
+
|
|
191
326
|
@action openAttachDeviceModal(device) {
|
|
192
327
|
this.modalsManager.show('modals/attach-telematic-device', {
|
|
193
328
|
title: this.intl.t('device.prompts.attach-device-to-vehicle-title', { deviceName: device.displayName ?? device.name ?? device.device_id ?? this.intl.t('resource.device') }),
|
|
@@ -200,20 +335,12 @@ export default class ConnectivityTelematicsDetailsAttachmentsController extends
|
|
|
200
335
|
return;
|
|
201
336
|
}
|
|
202
337
|
|
|
203
|
-
device.setProperties({
|
|
204
|
-
attachable_uuid: selectedVehicle.id,
|
|
205
|
-
attachable_type: 'fleet-ops:vehicle',
|
|
206
|
-
});
|
|
207
|
-
|
|
208
338
|
modal.startLoading();
|
|
209
339
|
|
|
210
340
|
try {
|
|
211
|
-
await
|
|
212
|
-
this.notifications.success(this.intl.t('device.prompts.attach-to-vehicle-success'));
|
|
213
|
-
await this.hostRouter.refresh();
|
|
341
|
+
await this.attachDeviceToVehicle(device, selectedVehicle);
|
|
214
342
|
modal.done();
|
|
215
343
|
} catch (error) {
|
|
216
|
-
device.rollbackAttributes();
|
|
217
344
|
this.notifications.serverError(error);
|
|
218
345
|
modal.stopLoading();
|
|
219
346
|
}
|
|
@@ -221,6 +348,14 @@ export default class ConnectivityTelematicsDetailsAttachmentsController extends
|
|
|
221
348
|
});
|
|
222
349
|
}
|
|
223
350
|
|
|
351
|
+
async attachDeviceToVehicle(device, selectedVehicle) {
|
|
352
|
+
const response = await this.fetch.post(`devices/${device.id}/attach`, { vehicle: selectedVehicle.id });
|
|
353
|
+
|
|
354
|
+
this.applyDeviceAttachment(device, selectedVehicle, response?.device);
|
|
355
|
+
this.selectedDevice = null;
|
|
356
|
+
this.notifications.success(this.intl.t('device.prompts.attach-to-vehicle-success'));
|
|
357
|
+
}
|
|
358
|
+
|
|
224
359
|
@action detachDevice(device) {
|
|
225
360
|
const deviceName = device.displayName ?? device.name ?? device.device_id ?? this.intl.t('resource.device');
|
|
226
361
|
|
|
@@ -229,19 +364,50 @@ export default class ConnectivityTelematicsDetailsAttachmentsController extends
|
|
|
229
364
|
body: this.intl.t('device.prompts.detach-telematic-device-body', { deviceName }),
|
|
230
365
|
confirm: async (modal) => {
|
|
231
366
|
modal.startLoading();
|
|
232
|
-
device.setProperties({ attachable_uuid: null, attachable_type: null });
|
|
233
367
|
|
|
234
368
|
try {
|
|
235
|
-
await device.
|
|
369
|
+
const response = await this.fetch.post(`devices/${device.id}/detach`);
|
|
370
|
+
|
|
371
|
+
this.applyDeviceDetachment(device, response?.device);
|
|
236
372
|
this.notifications.success(this.intl.t('device.prompts.detach-from-vehicle-success'));
|
|
237
|
-
await this.hostRouter.refresh();
|
|
238
373
|
modal.done();
|
|
239
374
|
} catch (error) {
|
|
240
|
-
device.rollbackAttributes();
|
|
241
375
|
this.notifications.serverError(error);
|
|
242
376
|
modal.stopLoading();
|
|
243
377
|
}
|
|
244
378
|
},
|
|
245
379
|
});
|
|
246
380
|
}
|
|
381
|
+
|
|
382
|
+
getDeviceVehicleName(device) {
|
|
383
|
+
return device.attached_to_name ?? device.attachable?.display_name ?? device.attachable?.name ?? 'Unknown vehicle';
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
applyDeviceAttachment(device, selectedVehicle, serverDevice = {}) {
|
|
387
|
+
this.updateDevice(device, {
|
|
388
|
+
attachable_uuid: serverDevice.attachable_uuid ?? selectedVehicle.id,
|
|
389
|
+
attachable_type: serverDevice.attachable_type ?? 'fleet-ops:vehicle',
|
|
390
|
+
attached_to_name: serverDevice.attached_to_name ?? selectedVehicle.displayName ?? selectedVehicle.display_name ?? selectedVehicle.name,
|
|
391
|
+
attachable: serverDevice.attachable ?? selectedVehicle,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
applyDeviceDetachment(device, serverDevice = {}) {
|
|
396
|
+
this.updateDevice(device, {
|
|
397
|
+
attachable_uuid: serverDevice.attachable_uuid ?? null,
|
|
398
|
+
attachable_type: serverDevice.attachable_type ?? null,
|
|
399
|
+
attached_to_name: serverDevice.attached_to_name ?? null,
|
|
400
|
+
attachable: serverDevice.attachable ?? null,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
updateDevice(device, properties) {
|
|
405
|
+
if (typeof device.setProperties === 'function') {
|
|
406
|
+
device.setProperties(properties);
|
|
407
|
+
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
Object.assign(device, properties);
|
|
412
|
+
}
|
|
247
413
|
}
|