@fleetbase/fleetops-engine 0.6.54 → 0.6.56

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.
Files changed (220) hide show
  1. package/addon/components/admin/map-settings.hbs +1 -1
  2. package/addon/components/admin/routing-settings.hbs +2 -1
  3. package/addon/components/cell/attached-vehicle.hbs +10 -0
  4. package/addon/components/cell/attached-vehicle.js +58 -0
  5. package/addon/components/cell/device-identity.hbs +24 -0
  6. package/addon/components/cell/device-identity.js +129 -0
  7. package/addon/components/cell/driver-identity.hbs +33 -0
  8. package/addon/components/cell/driver-identity.js +143 -0
  9. package/addon/components/cell/equipment-identity.hbs +5 -0
  10. package/addon/components/cell/equipment-identity.js +48 -0
  11. package/addon/components/cell/part-identity.hbs +5 -0
  12. package/addon/components/cell/part-identity.js +63 -0
  13. package/addon/components/cell/telematic-device.hbs +38 -0
  14. package/addon/components/cell/telematic-device.js +44 -0
  15. package/addon/components/cell/telematic-provider.hbs +33 -16
  16. package/addon/components/cell/telematic-provider.js +50 -8
  17. package/addon/components/cell/vehicle-identity.hbs +33 -0
  18. package/addon/components/cell/vehicle-identity.js +138 -0
  19. package/addon/components/device/details.js +1 -1
  20. package/addon/components/device/form.hbs +2 -2
  21. package/addon/components/device/form.js +7 -0
  22. package/addon/components/device/panel-header.hbs +45 -20
  23. package/addon/components/device/panel-header.js +49 -1
  24. package/addon/components/device/panel-tabs/events.hbs +30 -0
  25. package/addon/components/device/panel-tabs/events.js +128 -0
  26. package/addon/components/device/panel-tabs/sensors.hbs +30 -0
  27. package/addon/components/device/panel-tabs/sensors.js +93 -0
  28. package/addon/components/device/panel-tabs/vehicle.hbs +68 -0
  29. package/addon/components/device/panel-tabs/vehicle.js +90 -0
  30. package/addon/components/device-event/details.hbs +192 -0
  31. package/addon/components/device-event/details.js +151 -0
  32. package/addon/components/driver/schedule.js +1 -1
  33. package/addon/components/equipment/form.js +8 -1
  34. package/addon/components/layout/fleet-ops-sidebar.hbs +1 -1
  35. package/addon/components/layout/fleet-ops-sidebar.js +20 -6
  36. package/addon/components/map/drawer/device-event-listing.js +2 -0
  37. package/addon/components/map/drawer/driver-listing.js +2 -0
  38. package/addon/components/map/drawer/place-listing.js +2 -0
  39. package/addon/components/map/drawer/position-listing.hbs +11 -6
  40. package/addon/components/map/drawer/position-listing.js +17 -4
  41. package/addon/components/map/drawer/vehicle-listing.js +2 -0
  42. package/addon/components/sensor/panel-header.hbs +47 -15
  43. package/addon/components/sensor/panel-header.js +59 -1
  44. package/addon/components/table/cell/dropdown/action-item.hbs +31 -0
  45. package/addon/components/table/cell/dropdown/action-item.js +62 -0
  46. package/addon/components/table/cell/dropdown.hbs +28 -0
  47. package/addon/components/table/cell/dropdown.js +91 -0
  48. package/addon/components/telematic/details.hbs +1 -1
  49. package/addon/components/telematic/form.hbs +2 -2
  50. package/addon/components/telematic/settings.hbs +1 -1
  51. package/addon/components/vendor/panel-header.hbs +82 -0
  52. package/addon/components/vendor/panel-header.js +48 -0
  53. package/addon/controllers/connectivity/devices/index/details/events.js +1 -1
  54. package/addon/controllers/connectivity/devices/index/details/vehicle.js +50 -2
  55. package/addon/controllers/connectivity/devices/index.js +144 -129
  56. package/addon/controllers/connectivity/events/details.js +70 -0
  57. package/addon/controllers/connectivity/events/index.js +187 -11
  58. package/addon/controllers/connectivity/sensors/index.js +160 -14
  59. package/addon/controllers/connectivity/telematics/details/devices.js +126 -134
  60. package/addon/controllers/connectivity/telematics/details/events.js +1 -1
  61. package/addon/controllers/connectivity/telematics/details/sensors.js +4 -0
  62. package/addon/controllers/maintenance/equipment/index.js +1 -2
  63. package/addon/controllers/maintenance/parts/index.js +1 -2
  64. package/addon/controllers/management/drivers/index.js +82 -42
  65. package/addon/controllers/management/fuel-reports/index.js +63 -4
  66. package/addon/controllers/management/issues/index.js +63 -4
  67. package/addon/controllers/management/vehicles/index.js +33 -6
  68. package/addon/controllers/settings/map.js +15 -0
  69. package/addon/instance-initializers/register-vroom-allocation.js +1 -1
  70. package/addon/routes/connectivity/devices/index/details/vehicle.js +24 -2
  71. package/addon/routes/connectivity/devices/index.js +7 -0
  72. package/addon/routes/connectivity/events/details.js +28 -0
  73. package/addon/routes/connectivity/events/index.js +6 -2
  74. package/addon/routes/connectivity/sensors/index.js +7 -2
  75. package/addon/routes/connectivity/telematics/details/devices.js +2 -0
  76. package/addon/routes/management/vehicles/index/details.js +3 -1
  77. package/addon/services/device-actions.js +30 -0
  78. package/addon/services/device-event-actions.js +1 -1
  79. package/addon/services/equipment-actions.js +1 -0
  80. package/addon/services/map-adapter/google.js +25 -0
  81. package/addon/services/map-adapter/leaflet.js +1 -1
  82. package/addon/services/map-adapter-interface.js +1 -1
  83. package/addon/services/map-manager.js +4 -1
  84. package/addon/services/map-settings.js +15 -0
  85. package/addon/services/sensor-actions.js +3 -0
  86. package/addon/services/service-rate-actions.js +39 -1
  87. package/addon/services/vehicle-actions.js +24 -12
  88. package/addon/services/vendor-actions.js +3 -0
  89. package/addon/styles/fleetops-engine.css +9 -1
  90. package/addon/templates/connectivity/devices/index/details/vehicle.hbs +66 -2
  91. package/addon/templates/connectivity/events/details.hbs +40 -0
  92. package/addon/templates/management/vendors/index/details.hbs +2 -2
  93. package/addon/templates/settings/map.hbs +38 -9
  94. package/addon/templates/settings/notifications.hbs +2 -1
  95. package/addon/templates/settings/routing.hbs +1 -0
  96. package/addon/utils/device-table-columns.js +288 -0
  97. package/addon/utils/identity-cell-resource.js +20 -0
  98. package/addon/utils/leaflet-plugin-loader.js +5 -5
  99. package/addon/utils/map-drawer-dropdown-position.js +47 -0
  100. package/addon/utils/route-colors.js +1 -1
  101. package/addon/utils/trackable-option.js +93 -0
  102. package/app/components/cell/attached-vehicle.js +1 -0
  103. package/app/components/cell/device-identity.js +1 -0
  104. package/app/components/cell/driver-identity.js +1 -0
  105. package/app/components/cell/equipment-identity.js +1 -0
  106. package/app/components/cell/part-identity.js +1 -0
  107. package/app/components/cell/telematic-device.js +1 -0
  108. package/app/components/cell/vehicle-identity.js +1 -0
  109. package/app/components/device/panel-tabs/events.hbs +30 -0
  110. package/app/components/device/panel-tabs/events.js +128 -0
  111. package/app/components/device/panel-tabs/sensors.hbs +30 -0
  112. package/app/components/device/panel-tabs/sensors.js +93 -0
  113. package/app/components/device/panel-tabs/vehicle.hbs +68 -0
  114. package/app/components/device/panel-tabs/vehicle.js +90 -0
  115. package/app/components/device-event/details.hbs +192 -0
  116. package/app/components/device-event/details.js +1 -0
  117. package/app/components/table/cell/dropdown/action-item.js +1 -0
  118. package/app/components/table/cell/dropdown.js +1 -0
  119. package/app/components/vendor/panel-header.js +1 -0
  120. package/app/controllers/connectivity/events/{index/details.js → details.js} +1 -1
  121. package/app/routes/connectivity/events/{index/details.js → details.js} +1 -1
  122. package/app/templates/connectivity/events/{index/details.js → details.js} +1 -1
  123. package/app/utils/map-drawer-dropdown-position.js +1 -0
  124. package/app/utils/trackable-option.js +1 -0
  125. package/composer.json +1 -1
  126. package/extension.json +1 -1
  127. package/package.json +4 -4
  128. package/server/migrations/2026_06_23_000001_delete_bad_afaqy_telematics_sensors.php +34 -0
  129. package/server/src/Console/Commands/SyncTelematics.php +4 -4
  130. package/server/src/Exports/ContactExport.php +12 -5
  131. package/server/src/Exports/DeviceExport.php +92 -0
  132. package/server/src/Exports/DriverExport.php +28 -3
  133. package/server/src/Exports/EquipmentExport.php +94 -0
  134. package/server/src/Exports/FleetExport.php +22 -7
  135. package/server/src/Exports/FuelReportExport.php +16 -1
  136. package/server/src/Exports/IssueExport.php +25 -3
  137. package/server/src/Exports/MaintenanceExport.php +106 -0
  138. package/server/src/Exports/MaintenanceScheduleExport.php +99 -0
  139. package/server/src/Exports/OrderExport.php +24 -5
  140. package/server/src/Exports/PartExport.php +99 -0
  141. package/server/src/Exports/PlaceExport.php +33 -7
  142. package/server/src/Exports/SensorExport.php +94 -0
  143. package/server/src/Exports/ServiceAreaExport.php +31 -7
  144. package/server/src/Exports/ServiceRateExport.php +41 -1
  145. package/server/src/Exports/TelematicExport.php +90 -0
  146. package/server/src/Exports/VehicleExport.php +274 -8
  147. package/server/src/Exports/VendorExport.php +15 -2
  148. package/server/src/Exports/WorkOrderExport.php +92 -0
  149. package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +176 -0
  150. package/server/src/Http/Controllers/Api/v1/DeviceController.php +225 -0
  151. package/server/src/Http/Controllers/Api/v1/EquipmentController.php +114 -0
  152. package/server/src/Http/Controllers/Api/v1/FuelTransactionController.php +185 -0
  153. package/server/src/Http/Controllers/Api/v1/PartController.php +120 -0
  154. package/server/src/Http/Controllers/Api/v1/SensorController.php +132 -0
  155. package/server/src/Http/Controllers/Api/v1/WorkOrderController.php +161 -0
  156. package/server/src/Http/Controllers/Internal/v1/DeviceController.php +36 -1
  157. package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +1 -1
  158. package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +17 -0
  159. package/server/src/Http/Controllers/Internal/v1/LiveController.php +1 -1
  160. package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +17 -0
  161. package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +17 -0
  162. package/server/src/Http/Controllers/Internal/v1/PartController.php +17 -0
  163. package/server/src/Http/Controllers/Internal/v1/SensorController.php +18 -0
  164. package/server/src/Http/Controllers/Internal/v1/ServiceRateController.php +82 -13
  165. package/server/src/Http/Controllers/Internal/v1/SettingController.php +29 -5
  166. package/server/src/Http/Controllers/Internal/v1/TelematicController.php +18 -0
  167. package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +17 -0
  168. package/server/src/Http/Filter/DeviceEventFilter.php +21 -0
  169. package/server/src/Http/Filter/DeviceFilter.php +50 -4
  170. package/server/src/Http/Filter/EquipmentFilter.php +23 -0
  171. package/server/src/Http/Filter/FuelProviderTransactionFilter.php +57 -2
  172. package/server/src/Http/Filter/PartFilter.php +47 -0
  173. package/server/src/Http/Filter/SensorFilter.php +34 -6
  174. package/server/src/Http/Filter/WorkOrderFilter.php +23 -0
  175. package/server/src/Http/Requests/CreateDeviceRequest.php +51 -0
  176. package/server/src/Http/Requests/CreateEquipmentRequest.php +35 -0
  177. package/server/src/Http/Requests/CreateFuelTransactionRequest.php +50 -0
  178. package/server/src/Http/Requests/CreatePartRequest.php +40 -0
  179. package/server/src/Http/Requests/CreateSensorRequest.php +47 -0
  180. package/server/src/Http/Requests/CreateWorkOrderRequest.php +42 -0
  181. package/server/src/Http/Requests/UpdateDeviceRequest.php +7 -0
  182. package/server/src/Http/Requests/UpdateEquipmentRequest.php +7 -0
  183. package/server/src/Http/Requests/UpdateFuelTransactionRequest.php +7 -0
  184. package/server/src/Http/Requests/UpdatePartRequest.php +7 -0
  185. package/server/src/Http/Requests/UpdateSensorRequest.php +7 -0
  186. package/server/src/Http/Requests/UpdateWorkOrderRequest.php +7 -0
  187. package/server/src/Http/Resources/v1/Device.php +72 -0
  188. package/server/src/Http/Resources/v1/Equipment.php +57 -0
  189. package/server/src/Http/Resources/v1/FuelTransaction.php +69 -0
  190. package/server/src/Http/Resources/v1/Index/Vehicle.php +19 -0
  191. package/server/src/Http/Resources/v1/Part.php +64 -0
  192. package/server/src/Http/Resources/v1/Sensor.php +68 -0
  193. package/server/src/Jobs/SyncTelematicDevicesJob.php +194 -38
  194. package/server/src/Models/Device.php +2 -0
  195. package/server/src/Models/DeviceEvent.php +81 -0
  196. package/server/src/Models/Equipment.php +55 -0
  197. package/server/src/Models/Order.php +2 -1
  198. package/server/src/Observers/PurchaseRateObserver.php +2 -1
  199. package/server/src/Support/Analytics/RevenueTrend.php +3 -8
  200. package/server/src/Support/Metrics/ActiveRevenueQuery.php +121 -0
  201. package/server/src/Support/Metrics/AvgOrderValueMetric.php +1 -7
  202. package/server/src/Support/Metrics/EarningsMetric.php +1 -10
  203. package/server/src/Support/Telematics/Providers/AfaqyProvider.php +105 -5
  204. package/server/src/Support/Telematics/Providers/FlespiProvider.php +89 -15
  205. package/server/src/Support/Telematics/Providers/GeotabProvider.php +123 -35
  206. package/server/src/Support/Telematics/Providers/SafeeProvider.php +567 -47
  207. package/server/src/Support/Telematics/Providers/SamsaraProvider.php +122 -14
  208. package/server/src/Support/Telematics/TelematicService.php +28 -9
  209. package/server/src/routes.php +67 -15
  210. package/server/tests/DeviceFilterTest.php +9 -0
  211. package/server/tests/DriverVehicleStatusDefaultTest.php +19 -2
  212. package/server/tests/EquipmentAssignmentMorphTypeTest.php +35 -0
  213. package/server/tests/ExportCoverageTest.php +79 -0
  214. package/server/tests/MetricsRegistryTest.php +45 -5
  215. package/server/tests/PublicFleetOpsRestEndpointsTest.php +191 -0
  216. package/server/tests/ServiceRateRouteValidationTest.php +101 -0
  217. package/server/tests/TelematicsHardeningTest.php +873 -7
  218. package/addon/controllers/connectivity/events/index/details.js +0 -3
  219. package/addon/routes/connectivity/events/index/details.js +0 -3
  220. package/addon/templates/connectivity/events/index/details.hbs +0 -1
@@ -1,19 +1,96 @@
1
1
  import Controller from '@ember/controller';
2
+ import { action, get } from '@ember/object';
2
3
  import { inject as service } from '@ember/service';
3
4
  import { tracked } from '@glimmer/tracking';
4
5
 
6
+ const severityOptions = [
7
+ { label: 'Info', value: 'info' },
8
+ { label: 'Warning', value: 'warning' },
9
+ { label: 'Error', value: 'error' },
10
+ { label: 'Critical', value: 'critical' },
11
+ { label: 'High', value: 'high' },
12
+ ];
13
+
14
+ const processedOptions = [
15
+ { label: 'Processed', value: 'processed' },
16
+ { label: 'Unprocessed', value: 'unprocessed' },
17
+ ];
18
+
19
+ function eventDevice(event) {
20
+ const device = get(event, 'device');
21
+
22
+ if (device) {
23
+ return device;
24
+ }
25
+
26
+ const id = get(event, 'device_uuid');
27
+ const deviceId = get(event, 'device_id') ?? get(event, 'provider_device_id') ?? get(event, 'ident');
28
+ const name = get(event, 'device_name') ?? deviceId;
29
+ const imei = get(event, 'device_imei') ?? get(event, 'imei') ?? get(event, 'ident');
30
+
31
+ if (!id && !name && !imei && !deviceId) {
32
+ return null;
33
+ }
34
+
35
+ return {
36
+ id,
37
+ displayName: name,
38
+ name,
39
+ imei,
40
+ device_id: deviceId,
41
+ ident: get(event, 'ident'),
42
+ serial_number: get(event, 'device_serial_number'),
43
+ connection_status: get(event, 'device_connection_status'),
44
+ status: get(event, 'device_status'),
45
+ photo_url: get(event, 'device_photo_url') ?? get(event, 'photo_url'),
46
+ };
47
+ }
48
+
49
+ function eventTelematic(event) {
50
+ const telematic = get(event, 'device.telematic') ?? get(event, 'telematic');
51
+
52
+ if (telematic) {
53
+ return telematic;
54
+ }
55
+
56
+ const id = get(event, 'telematic_uuid');
57
+ const name = get(event, 'telematic_name');
58
+ const provider = get(event, 'provider');
59
+
60
+ if (!id && !name && !provider) {
61
+ return null;
62
+ }
63
+
64
+ return {
65
+ id,
66
+ name: name ?? provider,
67
+ provider,
68
+ provider_descriptor: get(event, 'provider_descriptor'),
69
+ };
70
+ }
71
+
5
72
  export default class ConnectivityEventsIndexController extends Controller {
6
73
  @service deviceEventActions;
7
74
  @service deviceActions;
75
+ @service hostRouter;
8
76
  @service intl;
77
+ @service store;
78
+ @service telematicActions;
9
79
 
10
80
  /** query params */
11
- @tracked queryParams = ['name', 'page', 'limit', 'sort', 'query', 'public_id', 'created_at', 'updated_at'];
81
+ @tracked queryParams = ['page', 'limit', 'sort', 'query', 'telematic', 'device', 'event_type', 'severity', 'processed', 'occurred_at', 'created_at', 'updated_at'];
12
82
  @tracked page = 1;
13
83
  @tracked limit;
14
84
  @tracked sort = '-created_at';
15
- @tracked public_id;
16
- @tracked name;
85
+ @tracked query;
86
+ @tracked telematic;
87
+ @tracked device;
88
+ @tracked event_type;
89
+ @tracked severity;
90
+ @tracked processed;
91
+ @tracked occurred_at;
92
+ @tracked created_at;
93
+ @tracked updated_at;
17
94
 
18
95
  /** action buttons */
19
96
  @tracked actionButtons = [
@@ -40,13 +117,17 @@ export default class ConnectivityEventsIndexController extends Controller {
40
117
  resizable: true,
41
118
  sortable: true,
42
119
  filterable: true,
120
+ filterParam: 'event_type',
43
121
  filterComponent: 'filter/string',
44
122
  },
45
123
  {
46
124
  label: 'Device',
47
125
  valuePath: 'device.displayName',
48
- cellComponent: 'table/cell/anchor',
49
- action: this.deviceActions.transition.view,
126
+ cellComponent: 'cell/device-identity',
127
+ resourcePath: eventDevice,
128
+ compact: true,
129
+ showStatus: false,
130
+ action: this.openDevice,
50
131
  permission: 'fleet-ops view device',
51
132
  resizable: true,
52
133
  sortable: true,
@@ -55,23 +136,50 @@ export default class ConnectivityEventsIndexController extends Controller {
55
136
  filterComponentPlaceholder: 'Select device',
56
137
  filterParam: 'device',
57
138
  model: 'device',
139
+ modelNamePath: 'displayName',
58
140
  },
59
141
  {
60
142
  label: 'Provider',
61
143
  valuePath: 'provider',
144
+ cellComponent: 'cell/telematic-provider',
145
+ resourcePath: eventTelematic,
146
+ compact: true,
147
+ action: this.openTelematic,
148
+ permission: 'fleet-ops view telematic',
62
149
  resizable: true,
63
150
  sortable: true,
64
151
  filterable: true,
65
- filterParam: 'provider',
66
- filterComponent: 'filter/string',
152
+ filterParam: 'telematic',
153
+ filterComponent: 'filter/model',
154
+ filterComponentPlaceholder: 'Select telematic',
155
+ model: 'telematic',
67
156
  },
68
157
  {
69
158
  label: 'Severity',
70
159
  valuePath: 'severity',
160
+ cellComponent: 'table/cell/status',
71
161
  resizable: true,
72
162
  sortable: true,
73
163
  filterable: true,
74
164
  filterParam: 'severity',
165
+ filterComponent: 'filter/multi-option',
166
+ filterOptions: severityOptions,
167
+ filterOptionLabel: 'label',
168
+ filterOptionValue: 'value',
169
+ },
170
+ {
171
+ label: 'Message',
172
+ valuePath: 'message',
173
+ resizable: true,
174
+ sortable: false,
175
+ },
176
+ {
177
+ label: 'Code',
178
+ valuePath: 'code',
179
+ resizable: true,
180
+ sortable: true,
181
+ filterable: true,
182
+ filterParam: 'code',
75
183
  filterComponent: 'filter/string',
76
184
  },
77
185
  {
@@ -96,13 +204,27 @@ export default class ConnectivityEventsIndexController extends Controller {
96
204
  sortable: true,
97
205
  },
98
206
  {
99
- label: 'Code',
100
- valuePath: 'code',
207
+ label: 'Processed',
208
+ valuePath: 'processedAt',
209
+ sortParam: 'processed_at',
101
210
  resizable: true,
102
211
  sortable: true,
103
212
  filterable: true,
104
- filterParam: 'code',
105
- filterComponent: 'filter/string',
213
+ filterParam: 'processed',
214
+ filterComponent: 'filter/multi-option',
215
+ filterOptions: processedOptions,
216
+ filterOptionLabel: 'label',
217
+ filterOptionValue: 'value',
218
+ },
219
+ {
220
+ label: 'Occurred',
221
+ valuePath: 'occurredAt',
222
+ sortParam: 'occurred_at',
223
+ resizable: true,
224
+ sortable: true,
225
+ filterable: true,
226
+ filterParam: 'occurred_at',
227
+ filterComponent: 'filter/date',
106
228
  },
107
229
  {
108
230
  label: this.intl.t('column.created-at'),
@@ -111,7 +233,19 @@ export default class ConnectivityEventsIndexController extends Controller {
111
233
  resizable: true,
112
234
  sortable: true,
113
235
  filterable: true,
236
+ filterParam: 'created_at',
237
+ filterComponent: 'filter/date',
238
+ },
239
+ {
240
+ label: this.intl.t('column.updated-at'),
241
+ valuePath: 'updatedAt',
242
+ sortParam: 'updated_at',
243
+ resizable: true,
244
+ sortable: true,
245
+ filterable: true,
246
+ filterParam: 'updated_at',
114
247
  filterComponent: 'filter/date',
248
+ hidden: true,
115
249
  },
116
250
  {
117
251
  label: '',
@@ -130,6 +264,11 @@ export default class ConnectivityEventsIndexController extends Controller {
130
264
  fn: this.deviceEventActions.transition.view,
131
265
  permission: 'fleet-ops view device-event',
132
266
  },
267
+ {
268
+ label: 'Mark processed',
269
+ fn: this.markProcessed,
270
+ permission: 'fleet-ops update device-event',
271
+ },
133
272
  ],
134
273
  sortable: false,
135
274
  filterable: false,
@@ -137,4 +276,41 @@ export default class ConnectivityEventsIndexController extends Controller {
137
276
  searchable: false,
138
277
  },
139
278
  ];
279
+
280
+ async resolveDevice(device) {
281
+ if (!device?.id) {
282
+ return null;
283
+ }
284
+
285
+ const cachedDevice = this.store.peekRecord('device', device.id);
286
+
287
+ if (cachedDevice) {
288
+ return cachedDevice;
289
+ }
290
+
291
+ try {
292
+ return await this.store.findRecord('device', device.id);
293
+ } catch (_) {
294
+ return device;
295
+ }
296
+ }
297
+
298
+ @action async openDevice(device) {
299
+ const resolvedDevice = await this.resolveDevice(device);
300
+
301
+ if (resolvedDevice?.id) {
302
+ return this.deviceActions.panel.view(resolvedDevice);
303
+ }
304
+ }
305
+
306
+ @action openTelematic(telematic) {
307
+ if (telematic?.id) {
308
+ return this.telematicActions.transition.view(telematic);
309
+ }
310
+ }
311
+
312
+ @action async markProcessed(deviceEvent) {
313
+ await this.deviceEventActions.markProcessed(deviceEvent);
314
+ await this.hostRouter.refresh();
315
+ }
140
316
  }
@@ -1,21 +1,84 @@
1
1
  import Controller from '@ember/controller';
2
+ import { action, get } from '@ember/object';
2
3
  import { inject as service } from '@ember/service';
3
4
  import { tracked } from '@glimmer/tracking';
4
5
  import fleetOpsOptions from '../../../utils/fleet-ops-options';
5
6
 
7
+ function sensorTelematic(sensor) {
8
+ const telematic = get(sensor, 'telematic');
9
+
10
+ if (telematic) {
11
+ return telematic;
12
+ }
13
+
14
+ const id = get(sensor, 'telematic_uuid');
15
+ const name = get(sensor, 'telematic_name');
16
+ const provider = get(sensor, 'provider');
17
+
18
+ if (!id && !name && !provider) {
19
+ return null;
20
+ }
21
+
22
+ return {
23
+ id,
24
+ name: name ?? provider,
25
+ provider,
26
+ provider_descriptor: get(sensor, 'provider_descriptor'),
27
+ };
28
+ }
29
+
30
+ function sensorDevice(sensor) {
31
+ const device = get(sensor, 'device');
32
+
33
+ if (device) {
34
+ return device;
35
+ }
36
+
37
+ const id = get(sensor, 'device_uuid');
38
+ const deviceId = get(sensor, 'device_id') ?? get(sensor, 'provider_device_id') ?? get(sensor, 'ident');
39
+ const name = get(sensor, 'device_name') ?? deviceId;
40
+ const imei = get(sensor, 'device_imei') ?? get(sensor, 'imei') ?? get(sensor, 'ident');
41
+
42
+ if (!id && !name && !imei && !deviceId) {
43
+ return null;
44
+ }
45
+
46
+ return {
47
+ id,
48
+ displayName: name,
49
+ name,
50
+ imei,
51
+ device_id: deviceId,
52
+ ident: get(sensor, 'ident'),
53
+ serial_number: get(sensor, 'device_serial_number'),
54
+ connection_status: get(sensor, 'device_connection_status'),
55
+ status: get(sensor, 'device_status'),
56
+ photo_url: get(sensor, 'device_photo_url') ?? get(sensor, 'photo_url'),
57
+ };
58
+ }
59
+
6
60
  export default class ConnectivitySensorsIndexController extends Controller {
7
61
  @service sensorActions;
8
62
  @service deviceActions;
9
63
  @service telematicActions;
10
64
  @service intl;
65
+ @service store;
11
66
 
12
67
  /** query params */
13
- @tracked queryParams = ['name', 'page', 'limit', 'sort', 'query', 'public_id', 'created_at', 'updated_at'];
68
+ @tracked queryParams = ['page', 'limit', 'sort', 'query', 'telematic', 'device', 'type', 'status', 'serial_number', 'imei', 'last_reading_at', 'created_at', 'updated_at'];
14
69
  @tracked page = 1;
15
70
  @tracked limit;
16
71
  @tracked sort = '-created_at';
17
- @tracked public_id;
18
- @tracked name;
72
+ @tracked query;
73
+ @tracked telematic;
74
+ @tracked device;
75
+ @tracked type;
76
+ @tracked status;
77
+ @tracked serial_number;
78
+ @tracked imei;
79
+ @tracked last_reading_at;
80
+ @tracked created_at;
81
+ @tracked updated_at;
19
82
 
20
83
  /** action buttons */
21
84
  @tracked actionButtons = [
@@ -67,14 +130,16 @@ export default class ConnectivitySensorsIndexController extends Controller {
67
130
  resizable: true,
68
131
  sortable: true,
69
132
  filterable: true,
70
- filterParam: 'name',
133
+ filterParam: 'query',
71
134
  filterComponent: 'filter/string',
72
135
  },
73
136
  {
74
137
  label: 'Telematic',
75
138
  valuePath: 'telematic.provider',
76
- cellComponent: 'table/cell/anchor',
77
- action: this.telematicActions.transition.view,
139
+ cellComponent: 'cell/telematic-provider',
140
+ resourcePath: sensorTelematic,
141
+ compact: true,
142
+ action: this.openTelematic,
78
143
  permission: 'fleet-ops view telematic',
79
144
  resizable: true,
80
145
  sortable: true,
@@ -87,8 +152,10 @@ export default class ConnectivitySensorsIndexController extends Controller {
87
152
  {
88
153
  label: 'Device',
89
154
  valuePath: 'device.displayName',
90
- cellComponent: 'table/cell/anchor',
91
- action: this.deviceActions.transition.view,
155
+ cellComponent: 'cell/device-identity',
156
+ resourcePath: sensorDevice,
157
+ showStatus: false,
158
+ action: this.openDevice,
92
159
  permission: 'fleet-ops view device',
93
160
  resizable: true,
94
161
  sortable: true,
@@ -97,25 +164,34 @@ export default class ConnectivitySensorsIndexController extends Controller {
97
164
  filterComponentPlaceholder: 'Select device',
98
165
  filterParam: 'device',
99
166
  model: 'device',
167
+ modelNamePath: 'displayName',
168
+ query: this.telematic ? { telematic_uuid: this.telematic } : undefined,
100
169
  },
101
170
  {
102
171
  label: 'Type',
103
172
  valuePath: 'type',
173
+ cellComponent: 'table/cell/base',
174
+ humanize: true,
104
175
  resizable: true,
105
176
  sortable: true,
106
177
  filterable: true,
107
178
  filterParam: 'type',
108
179
  filterComponent: 'filter/multi-option',
109
180
  filterOptions: fleetOpsOptions('sensorTypes'),
181
+ filterOptionLabel: 'label',
182
+ filterOptionValue: 'value',
110
183
  },
111
184
  {
112
- label: 'Serial Number',
113
- valuePath: 'serial_number',
185
+ label: 'Last Value',
186
+ valuePath: 'last_value',
187
+ resizable: true,
188
+ sortable: true,
189
+ },
190
+ {
191
+ label: 'Unit',
192
+ valuePath: 'unit',
114
193
  resizable: true,
115
194
  sortable: true,
116
- filterable: true,
117
- filterParam: 'serial_number',
118
- filterComponent: 'filter/string',
119
195
  },
120
196
  {
121
197
  label: this.intl.t('column.status'),
@@ -126,6 +202,43 @@ export default class ConnectivitySensorsIndexController extends Controller {
126
202
  filterable: true,
127
203
  filterComponent: 'filter/multi-option',
128
204
  filterOptions: fleetOpsOptions('sensorStatuses'),
205
+ filterOptionLabel: 'label',
206
+ filterOptionValue: 'value',
207
+ },
208
+ {
209
+ label: 'Threshold',
210
+ valuePath: 'threshold_status',
211
+ cellComponent: 'table/cell/status',
212
+ resizable: true,
213
+ sortable: true,
214
+ },
215
+ {
216
+ label: 'Serial Number',
217
+ valuePath: 'serial_number',
218
+ resizable: true,
219
+ sortable: true,
220
+ filterable: true,
221
+ filterParam: 'serial_number',
222
+ filterComponent: 'filter/string',
223
+ },
224
+ {
225
+ label: 'IMEI',
226
+ valuePath: 'imei',
227
+ resizable: true,
228
+ sortable: true,
229
+ filterable: true,
230
+ filterParam: 'imei',
231
+ filterComponent: 'filter/string',
232
+ },
233
+ {
234
+ label: 'Last Reading',
235
+ valuePath: 'lastReadingAt',
236
+ sortParam: 'last_reading_at',
237
+ resizable: true,
238
+ sortable: true,
239
+ filterable: true,
240
+ filterParam: 'last_reading_at',
241
+ filterComponent: 'filter/date',
129
242
  },
130
243
  {
131
244
  label: this.intl.t('column.created-at'),
@@ -134,6 +247,7 @@ export default class ConnectivitySensorsIndexController extends Controller {
134
247
  resizable: true,
135
248
  sortable: true,
136
249
  filterable: true,
250
+ filterParam: 'created_at',
137
251
  filterComponent: 'filter/date',
138
252
  },
139
253
  {
@@ -144,9 +258,9 @@ export default class ConnectivitySensorsIndexController extends Controller {
144
258
  sortable: true,
145
259
  hidden: true,
146
260
  filterable: true,
261
+ filterParam: 'updated_at',
147
262
  filterComponent: 'filter/date',
148
263
  },
149
-
150
264
  {
151
265
  label: '',
152
266
  cellComponent: 'table/cell/dropdown',
@@ -184,4 +298,36 @@ export default class ConnectivitySensorsIndexController extends Controller {
184
298
  searchable: false,
185
299
  },
186
300
  ];
301
+
302
+ async resolveDevice(device) {
303
+ if (!device?.id) {
304
+ return null;
305
+ }
306
+
307
+ const cachedDevice = this.store.peekRecord('device', device.id);
308
+
309
+ if (cachedDevice) {
310
+ return cachedDevice;
311
+ }
312
+
313
+ try {
314
+ return await this.store.findRecord('device', device.id);
315
+ } catch (_) {
316
+ return device;
317
+ }
318
+ }
319
+
320
+ @action async openDevice(device) {
321
+ const resolvedDevice = await this.resolveDevice(device);
322
+
323
+ if (resolvedDevice?.id) {
324
+ return this.deviceActions.panel.view(resolvedDevice);
325
+ }
326
+ }
327
+
328
+ @action openTelematic(telematic) {
329
+ if (telematic?.id) {
330
+ return this.telematicActions.transition.view(telematic);
331
+ }
332
+ }
187
333
  }