@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.
- package/addon/components/admin/map-settings.hbs +1 -1
- 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.js +1 -1
- package/addon/components/device/form.hbs +2 -2
- package/addon/components/device/form.js +7 -0
- package/addon/components/device/panel-header.hbs +45 -20
- 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/device-event/details.hbs +192 -0
- package/addon/components/device-event/details.js +151 -0
- package/addon/components/driver/schedule.js +1 -1
- package/addon/components/equipment/form.js +8 -1
- package/addon/components/layout/fleet-ops-sidebar.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +20 -6
- 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/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 +1 -1
- package/addon/components/telematic/form.hbs +2 -2
- package/addon/components/telematic/settings.hbs +1 -1
- package/addon/components/vendor/panel-header.hbs +82 -0
- package/addon/components/vendor/panel-header.js +48 -0
- package/addon/controllers/connectivity/devices/index/details/events.js +1 -1
- package/addon/controllers/connectivity/devices/index/details/vehicle.js +50 -2
- package/addon/controllers/connectivity/devices/index.js +144 -129
- package/addon/controllers/connectivity/events/details.js +70 -0
- package/addon/controllers/connectivity/events/index.js +187 -11
- package/addon/controllers/connectivity/sensors/index.js +160 -14
- package/addon/controllers/connectivity/telematics/details/devices.js +126 -134
- package/addon/controllers/connectivity/telematics/details/events.js +1 -1
- package/addon/controllers/connectivity/telematics/details/sensors.js +4 -0
- package/addon/controllers/maintenance/equipment/index.js +1 -2
- package/addon/controllers/maintenance/parts/index.js +1 -2
- 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/controllers/settings/map.js +15 -0
- package/addon/instance-initializers/register-vroom-allocation.js +1 -1
- package/addon/routes/connectivity/devices/index/details/vehicle.js +24 -2
- package/addon/routes/connectivity/devices/index.js +7 -0
- package/addon/routes/connectivity/events/details.js +28 -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/devices.js +2 -0
- package/addon/routes/management/vehicles/index/details.js +3 -1
- 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/map-adapter/google.js +25 -0
- package/addon/services/map-adapter/leaflet.js +1 -1
- package/addon/services/map-adapter-interface.js +1 -1
- package/addon/services/map-manager.js +4 -1
- package/addon/services/map-settings.js +15 -0
- package/addon/services/sensor-actions.js +3 -0
- package/addon/services/service-rate-actions.js +39 -1
- package/addon/services/vehicle-actions.js +24 -12
- package/addon/services/vendor-actions.js +3 -0
- package/addon/styles/fleetops-engine.css +9 -1
- package/addon/templates/connectivity/devices/index/details/vehicle.hbs +66 -2
- package/addon/templates/connectivity/events/details.hbs +40 -0
- package/addon/templates/management/vendors/index/details.hbs +2 -2
- package/addon/templates/settings/map.hbs +38 -9
- 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/identity-cell-resource.js +20 -0
- package/addon/utils/leaflet-plugin-loader.js +5 -5
- package/addon/utils/map-drawer-dropdown-position.js +47 -0
- package/addon/utils/route-colors.js +1 -1
- 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/device-event/details.hbs +192 -0
- package/app/components/device-event/details.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/events/{index/details.js → details.js} +1 -1
- package/app/routes/connectivity/events/{index/details.js → details.js} +1 -1
- 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/2026_06_23_000001_delete_bad_afaqy_telematics_sensors.php +34 -0
- package/server/src/Console/Commands/SyncTelematics.php +4 -4
- package/server/src/Exports/ContactExport.php +12 -5
- package/server/src/Exports/DeviceExport.php +92 -0
- package/server/src/Exports/DriverExport.php +28 -3
- package/server/src/Exports/EquipmentExport.php +94 -0
- package/server/src/Exports/FleetExport.php +22 -7
- package/server/src/Exports/FuelReportExport.php +16 -1
- package/server/src/Exports/IssueExport.php +25 -3
- package/server/src/Exports/MaintenanceExport.php +106 -0
- package/server/src/Exports/MaintenanceScheduleExport.php +99 -0
- package/server/src/Exports/OrderExport.php +24 -5
- package/server/src/Exports/PartExport.php +99 -0
- package/server/src/Exports/PlaceExport.php +33 -7
- package/server/src/Exports/SensorExport.php +94 -0
- package/server/src/Exports/ServiceAreaExport.php +31 -7
- package/server/src/Exports/ServiceRateExport.php +41 -1
- package/server/src/Exports/TelematicExport.php +90 -0
- package/server/src/Exports/VehicleExport.php +274 -8
- package/server/src/Exports/VendorExport.php +15 -2
- package/server/src/Exports/WorkOrderExport.php +92 -0
- package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +176 -0
- package/server/src/Http/Controllers/Api/v1/DeviceController.php +225 -0
- package/server/src/Http/Controllers/Api/v1/EquipmentController.php +114 -0
- package/server/src/Http/Controllers/Api/v1/FuelTransactionController.php +185 -0
- package/server/src/Http/Controllers/Api/v1/PartController.php +120 -0
- package/server/src/Http/Controllers/Api/v1/SensorController.php +132 -0
- package/server/src/Http/Controllers/Api/v1/WorkOrderController.php +161 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +36 -1
- package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/PartController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/SensorController.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/ServiceRateController.php +82 -13
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +29 -5
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +17 -0
- package/server/src/Http/Filter/DeviceEventFilter.php +21 -0
- package/server/src/Http/Filter/DeviceFilter.php +50 -4
- package/server/src/Http/Filter/EquipmentFilter.php +23 -0
- package/server/src/Http/Filter/FuelProviderTransactionFilter.php +57 -2
- package/server/src/Http/Filter/PartFilter.php +47 -0
- package/server/src/Http/Filter/SensorFilter.php +34 -6
- package/server/src/Http/Filter/WorkOrderFilter.php +23 -0
- package/server/src/Http/Requests/CreateDeviceRequest.php +51 -0
- package/server/src/Http/Requests/CreateEquipmentRequest.php +35 -0
- package/server/src/Http/Requests/CreateFuelTransactionRequest.php +50 -0
- package/server/src/Http/Requests/CreatePartRequest.php +40 -0
- package/server/src/Http/Requests/CreateSensorRequest.php +47 -0
- package/server/src/Http/Requests/CreateWorkOrderRequest.php +42 -0
- package/server/src/Http/Requests/UpdateDeviceRequest.php +7 -0
- package/server/src/Http/Requests/UpdateEquipmentRequest.php +7 -0
- package/server/src/Http/Requests/UpdateFuelTransactionRequest.php +7 -0
- package/server/src/Http/Requests/UpdatePartRequest.php +7 -0
- package/server/src/Http/Requests/UpdateSensorRequest.php +7 -0
- package/server/src/Http/Requests/UpdateWorkOrderRequest.php +7 -0
- package/server/src/Http/Resources/v1/Device.php +72 -0
- package/server/src/Http/Resources/v1/Equipment.php +57 -0
- package/server/src/Http/Resources/v1/FuelTransaction.php +69 -0
- package/server/src/Http/Resources/v1/Index/Vehicle.php +19 -0
- package/server/src/Http/Resources/v1/Part.php +64 -0
- package/server/src/Http/Resources/v1/Sensor.php +68 -0
- package/server/src/Jobs/SyncTelematicDevicesJob.php +194 -38
- package/server/src/Models/Device.php +2 -0
- package/server/src/Models/DeviceEvent.php +81 -0
- package/server/src/Models/Equipment.php +55 -0
- package/server/src/Models/Order.php +2 -1
- package/server/src/Observers/PurchaseRateObserver.php +2 -1
- package/server/src/Support/Analytics/RevenueTrend.php +3 -8
- package/server/src/Support/Metrics/ActiveRevenueQuery.php +121 -0
- package/server/src/Support/Metrics/AvgOrderValueMetric.php +1 -7
- package/server/src/Support/Metrics/EarningsMetric.php +1 -10
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +105 -5
- 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 +567 -47
- package/server/src/Support/Telematics/Providers/SamsaraProvider.php +122 -14
- package/server/src/Support/Telematics/TelematicService.php +28 -9
- package/server/src/routes.php +67 -15
- package/server/tests/DeviceFilterTest.php +9 -0
- package/server/tests/DriverVehicleStatusDefaultTest.php +19 -2
- package/server/tests/EquipmentAssignmentMorphTypeTest.php +35 -0
- package/server/tests/ExportCoverageTest.php +79 -0
- package/server/tests/MetricsRegistryTest.php +45 -5
- package/server/tests/PublicFleetOpsRestEndpointsTest.php +191 -0
- package/server/tests/ServiceRateRouteValidationTest.php +101 -0
- package/server/tests/TelematicsHardeningTest.php +873 -7
- 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 +0 -1
|
@@ -63,6 +63,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
63
63
|
icon: 'truck',
|
|
64
64
|
route: 'management',
|
|
65
65
|
defaultRoute: 'management.index',
|
|
66
|
+
requiresVisibleChildren: true,
|
|
66
67
|
keywords: ['drivers', 'vehicles', 'fleets', 'contacts', 'places'],
|
|
67
68
|
children: this.resourcesItems,
|
|
68
69
|
}),
|
|
@@ -72,6 +73,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
72
73
|
icon: 'cog',
|
|
73
74
|
route: 'maintenance',
|
|
74
75
|
defaultRoute: 'maintenance.index',
|
|
76
|
+
requiresVisibleChildren: true,
|
|
75
77
|
keywords: ['work orders', 'equipment', 'parts'],
|
|
76
78
|
children: this.maintenanceItems,
|
|
77
79
|
}),
|
|
@@ -81,6 +83,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
81
83
|
icon: 'satellite-dish',
|
|
82
84
|
route: 'connectivity',
|
|
83
85
|
defaultRoute: 'connectivity.telematics',
|
|
86
|
+
requiresVisibleChildren: true,
|
|
84
87
|
keywords: ['telematics', 'fuel integrations', 'devices', 'sensors'],
|
|
85
88
|
children: this.connectivityItems,
|
|
86
89
|
}),
|
|
@@ -90,6 +93,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
90
93
|
icon: 'chart-line',
|
|
91
94
|
route: 'analytics',
|
|
92
95
|
defaultRoute: 'analytics.index',
|
|
96
|
+
requiresVisibleChildren: true,
|
|
93
97
|
keywords: ['reports', 'metrics'],
|
|
94
98
|
children: this.analyticsItems,
|
|
95
99
|
}),
|
|
@@ -99,6 +103,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
99
103
|
icon: 'gear',
|
|
100
104
|
route: 'settings',
|
|
101
105
|
defaultRoute: 'settings.index',
|
|
106
|
+
requiresVisibleChildren: true,
|
|
102
107
|
keywords: ['configuration', 'navigator', 'map', 'routing', 'notifications'],
|
|
103
108
|
children: this.settingsItems,
|
|
104
109
|
}),
|
|
@@ -164,7 +169,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
164
169
|
|
|
165
170
|
get connectivityItems() {
|
|
166
171
|
return this.withRegistryItems('connectivity', [
|
|
167
|
-
this.
|
|
172
|
+
this.createHubItem(this.intl.t('menu.telematics'), 'satellite-dish', 'connectivity.telematics', 'fleet-ops list telematic', 'fleet-ops see telematic', ['connectivity hub']),
|
|
168
173
|
this.createItem('menu.fuel-providers', 'gas-pump', 'connectivity.fuel-providers', 'fleet-ops list fuel-report', 'fleet-ops see fuel-report', ['fuel integrations']),
|
|
169
174
|
this.createItem('menu.devices', 'hard-drive', 'connectivity.devices', 'fleet-ops list device', 'fleet-ops see device'),
|
|
170
175
|
this.createItem('menu.sensors', 'temperature-full', 'connectivity.sensors', 'fleet-ops list sensor', 'fleet-ops see sensor'),
|
|
@@ -247,13 +252,14 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
247
252
|
this.universeSettingsMenuItems = registeredMenuItems.filter((menuItem) => menuItem.section === 'settings');
|
|
248
253
|
}
|
|
249
254
|
|
|
250
|
-
createBranch({ id, label, icon, route, defaultRoute, children, keywords = [] }) {
|
|
255
|
+
createBranch({ id, label, icon, route, defaultRoute, requiresVisibleChildren = false, children, keywords = [] }) {
|
|
251
256
|
return {
|
|
252
257
|
id,
|
|
253
258
|
label,
|
|
254
259
|
icon,
|
|
255
260
|
route: this.fullRoute(route),
|
|
256
261
|
defaultRoute: this.fullRoute(defaultRoute),
|
|
262
|
+
requiresVisibleChildren,
|
|
257
263
|
children: children.filter((item) => item.visible !== false),
|
|
258
264
|
keywords,
|
|
259
265
|
};
|
|
@@ -267,12 +273,12 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
267
273
|
icon,
|
|
268
274
|
route: this.fullRoute(route),
|
|
269
275
|
permission,
|
|
270
|
-
|
|
276
|
+
visiblePermission: ability,
|
|
271
277
|
keywords: [intl, route, ...keywords].filter(Boolean),
|
|
272
278
|
};
|
|
273
279
|
}
|
|
274
280
|
|
|
275
|
-
createHubItem(label, icon, route,
|
|
281
|
+
createHubItem(label, icon, route, _permission, _ability, keywords = []) {
|
|
276
282
|
return {
|
|
277
283
|
pinnedFirst: true,
|
|
278
284
|
priority: this.defaultPriorityForRoute(route),
|
|
@@ -280,8 +286,7 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
280
286
|
description: label,
|
|
281
287
|
icon,
|
|
282
288
|
route: this.fullRoute(route),
|
|
283
|
-
|
|
284
|
-
visible: this.abilities.can(ability),
|
|
289
|
+
isNavigationHub: true,
|
|
285
290
|
keywords: [label, route, ...keywords].filter(Boolean),
|
|
286
291
|
};
|
|
287
292
|
}
|
|
@@ -390,6 +395,15 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
|
|
|
390
395
|
}
|
|
391
396
|
}
|
|
392
397
|
|
|
398
|
+
@action shouldSyncInitialActiveParent({ activePath = [], currentURL }) {
|
|
399
|
+
const [parent, child] = activePath;
|
|
400
|
+
const normalizedURL = (currentURL ?? '').split('?')[0].replace(/\/+$/, '') || '/';
|
|
401
|
+
const isFleetOpsRootURL = normalizedURL === '/fleet-ops';
|
|
402
|
+
const isDefaultOrdersLanding = parent?.id === 'operations' && child?.route === this.fullRoute('operations.orders') && isFleetOpsRootURL;
|
|
403
|
+
|
|
404
|
+
return !isDefaultOrdersLanding;
|
|
405
|
+
}
|
|
406
|
+
|
|
393
407
|
@action
|
|
394
408
|
async searchNavigation({ query, limit = 12 }) {
|
|
395
409
|
const trimmedQuery = query?.trim();
|
|
@@ -5,6 +5,7 @@ import { action } from '@ember/object';
|
|
|
5
5
|
import { task } from 'ember-concurrency';
|
|
6
6
|
import { isArray } from '@ember/array';
|
|
7
7
|
import { startOfWeek, endOfWeek, format } from 'date-fns';
|
|
8
|
+
import calculateMapDrawerDropdownPosition from '../../../utils/map-drawer-dropdown-position';
|
|
8
9
|
|
|
9
10
|
export default class MapDrawerDeviceEventListingComponent extends Component {
|
|
10
11
|
@service store;
|
|
@@ -115,6 +116,7 @@ export default class MapDrawerDeviceEventListingComponent extends Component {
|
|
|
115
116
|
ddMenuLabel: this.intl.t('common.resource-actions', { resource: this.intl.t('resource.device-event') }),
|
|
116
117
|
cellClassNames: 'overflow-visible',
|
|
117
118
|
wrapperClass: 'flex items-center justify-end mx-2',
|
|
119
|
+
calculatePosition: calculateMapDrawerDropdownPosition,
|
|
118
120
|
width: '10%',
|
|
119
121
|
actions: [
|
|
120
122
|
{
|
|
@@ -2,6 +2,7 @@ import Component from '@glimmer/component';
|
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
4
|
import { action } from '@ember/object';
|
|
5
|
+
import calculateMapDrawerDropdownPosition from '../../../utils/map-drawer-dropdown-position';
|
|
5
6
|
|
|
6
7
|
export default class MapDrawerDriverListingComponent extends Component {
|
|
7
8
|
@service driverActions;
|
|
@@ -71,6 +72,7 @@ export default class MapDrawerDriverListingComponent extends Component {
|
|
|
71
72
|
ddMenuLabel: this.intl.t('common.resource-actions', { resource: this.intl.t('resource.driver') }),
|
|
72
73
|
cellClassNames: 'overflow-visible',
|
|
73
74
|
wrapperClass: 'flex items-center justify-end mx-2',
|
|
75
|
+
calculatePosition: calculateMapDrawerDropdownPosition,
|
|
74
76
|
width: '90px',
|
|
75
77
|
actions: [
|
|
76
78
|
{
|
|
@@ -2,6 +2,7 @@ import Component from '@glimmer/component';
|
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
4
|
import { action } from '@ember/object';
|
|
5
|
+
import calculateMapDrawerDropdownPosition from '../../../utils/map-drawer-dropdown-position';
|
|
5
6
|
|
|
6
7
|
export default class MapDrawerPlaceListingComponent extends Component {
|
|
7
8
|
@service placeActions;
|
|
@@ -53,6 +54,7 @@ export default class MapDrawerPlaceListingComponent extends Component {
|
|
|
53
54
|
ddMenuLabel: this.intl.t('common.resource-actions', { resource: this.intl.t('resource.place') }),
|
|
54
55
|
cellClassNames: 'overflow-visible',
|
|
55
56
|
wrapperClass: 'flex items-center justify-end mx-2',
|
|
57
|
+
calculatePosition: calculateMapDrawerDropdownPosition,
|
|
56
58
|
width: '90px',
|
|
57
59
|
actions: [
|
|
58
60
|
{
|
|
@@ -4,23 +4,28 @@
|
|
|
4
4
|
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
5
5
|
<PowerSelect
|
|
6
6
|
@options={{this.trackables}}
|
|
7
|
-
@selected={{this.
|
|
7
|
+
@selected={{this.selectedTrackable}}
|
|
8
8
|
@onChange={{this.onResourceSelected}}
|
|
9
|
+
@searchEnabled={{true}}
|
|
10
|
+
@searchField="trackableSearchText"
|
|
9
11
|
@placeholder={{t "common.select-field" field="trackable"}}
|
|
10
12
|
@triggerClass="form-select form-input form-input-sm w-48"
|
|
11
13
|
as |option|
|
|
12
14
|
>
|
|
13
15
|
<div class="flex flex-row items-start space-x-2">
|
|
14
16
|
<div class="inline-block">
|
|
15
|
-
{{#if (eq
|
|
16
|
-
<Image src={{option.photo_url}} @fallbackSrc={{config "defaultValues.driverAvatar"}} class="w-4 h-4" />
|
|
17
|
+
{{#if (eq option.modelName "driver")}}
|
|
18
|
+
<Image src={{option.resource.photo_url}} @fallbackSrc={{config "defaultValues.driverAvatar"}} class="w-4 h-4" />
|
|
17
19
|
{{else}}
|
|
18
|
-
<Image src={{option.avatar_url}} @fallbackSrc={{config "defaultValues.vehicleAvatar"}} class="w-4 h-4" />
|
|
20
|
+
<Image src={{option.resource.avatar_url}} @fallbackSrc={{config "defaultValues.vehicleAvatar"}} class="w-4 h-4" />
|
|
19
21
|
{{/if}}
|
|
20
22
|
</div>
|
|
21
23
|
<div class="inline-block text-sm truncate">
|
|
22
|
-
<div class="font-semibold text-sm normalize-in-trigger">{{
|
|
23
|
-
<div class="hide-from-trigger text-xs">{{
|
|
24
|
+
<div class="font-semibold text-sm normalize-in-trigger">{{option.primaryLabel}}</div>
|
|
25
|
+
<div class="hide-from-trigger text-xs">{{option.secondaryLabel}}</div>
|
|
26
|
+
{{#if option.deviceLabel}}
|
|
27
|
+
<div class="hide-from-trigger text-xs text-gray-500 dark:text-gray-400 truncate">{{option.deviceLabel}}</div>
|
|
28
|
+
{{/if}}
|
|
24
29
|
</div>
|
|
25
30
|
</div>
|
|
26
31
|
</PowerSelect>
|
|
@@ -8,6 +8,7 @@ import { htmlSafe } from '@ember/template';
|
|
|
8
8
|
import { startOfWeek, endOfWeek, format } from 'date-fns';
|
|
9
9
|
import getModelName from '@fleetbase/ember-core/utils/get-model-name';
|
|
10
10
|
import ensureLeafletDrawEditNamespace from '../../../utils/leaflet-draw-namespace-guard';
|
|
11
|
+
import { buildTrackableOption } from '../../../utils/trackable-option';
|
|
11
12
|
|
|
12
13
|
const L = window.leaflet || window.L;
|
|
13
14
|
|
|
@@ -29,6 +30,7 @@ export default class MapDrawerPositionListingComponent extends Component {
|
|
|
29
30
|
@tracked replaySpeed = '1';
|
|
30
31
|
@tracked positionsLayer = null;
|
|
31
32
|
@tracked positionOverlayIds = [];
|
|
33
|
+
@tracked selectedTrackableModelName = null;
|
|
32
34
|
|
|
33
35
|
/** Computed properties - read state from service */
|
|
34
36
|
get isReplaying() {
|
|
@@ -47,7 +49,17 @@ export default class MapDrawerPositionListingComponent extends Component {
|
|
|
47
49
|
const vehicles = this.mapManager.livemap?.vehicles ?? [];
|
|
48
50
|
const drivers = this.mapManager.livemap?.drivers ?? [];
|
|
49
51
|
|
|
50
|
-
return [...vehicles, ...drivers];
|
|
52
|
+
return [...vehicles.map((vehicle) => buildTrackableOption(vehicle, 'vehicle')), ...drivers.map((driver) => buildTrackableOption(driver, 'driver'))];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get selectedTrackable() {
|
|
56
|
+
if (!this.resource) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const resourceType = this.resourceType;
|
|
61
|
+
|
|
62
|
+
return this.trackables.find((trackable) => trackable.resource?.id === this.resource?.id && trackable.modelName === resourceType) ?? null;
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
get replayProgressWidth() {
|
|
@@ -72,7 +84,7 @@ export default class MapDrawerPositionListingComponent extends Component {
|
|
|
72
84
|
if (!this.resource) {
|
|
73
85
|
return 'resource';
|
|
74
86
|
}
|
|
75
|
-
return getModelName(this.resource) || 'resource';
|
|
87
|
+
return this.selectedTrackableModelName || getModelName(this.resource) || 'resource';
|
|
76
88
|
}
|
|
77
89
|
|
|
78
90
|
get hasPositions() {
|
|
@@ -179,8 +191,9 @@ export default class MapDrawerPositionListingComponent extends Component {
|
|
|
179
191
|
this.positionOverlayIds = [];
|
|
180
192
|
}
|
|
181
193
|
|
|
182
|
-
@action onResourceSelected(
|
|
183
|
-
this.resource = resource;
|
|
194
|
+
@action onResourceSelected(trackable) {
|
|
195
|
+
this.resource = trackable?.resource ?? null;
|
|
196
|
+
this.selectedTrackableModelName = trackable?.modelName ?? null;
|
|
184
197
|
this.loadPositions.perform();
|
|
185
198
|
}
|
|
186
199
|
|
|
@@ -2,6 +2,7 @@ import Component from '@glimmer/component';
|
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
4
|
import { action } from '@ember/object';
|
|
5
|
+
import calculateMapDrawerDropdownPosition from '../../../utils/map-drawer-dropdown-position';
|
|
5
6
|
|
|
6
7
|
export default class MapDrawerVehicleListingComponent extends Component {
|
|
7
8
|
@service vehicleActions;
|
|
@@ -65,6 +66,7 @@ export default class MapDrawerVehicleListingComponent extends Component {
|
|
|
65
66
|
ddMenuLabel: this.intl.t('common.resource-actions', { resource: this.intl.t('resource.vehicle') }),
|
|
66
67
|
cellClassNames: 'overflow-visible',
|
|
67
68
|
wrapperClass: 'flex items-center justify-end mx-2',
|
|
69
|
+
calculatePosition: calculateMapDrawerDropdownPosition,
|
|
68
70
|
width: '90px',
|
|
69
71
|
actions: [
|
|
70
72
|
{
|
|
@@ -1,29 +1,61 @@
|
|
|
1
|
-
<div class="px-4 py-
|
|
2
|
-
<div class="flex flex-1 flex-row items-start justify-between">
|
|
3
|
-
<div class="flex flex-row
|
|
4
|
-
<div class="flex items-start justify-start
|
|
1
|
+
<div class="px-4 py-3" ...attributes>
|
|
2
|
+
<div class="flex flex-1 flex-row items-start justify-between gap-4">
|
|
3
|
+
<div class="flex min-w-0 flex-row items-start gap-3">
|
|
4
|
+
<div class="relative flex flex-shrink-0 items-start justify-start">
|
|
5
5
|
<Image
|
|
6
6
|
src={{@resource.photo_url}}
|
|
7
7
|
@fallbackSrc={{config "defaultValues.placeholderImage"}}
|
|
8
|
-
alt={{
|
|
8
|
+
alt={{this.name}}
|
|
9
9
|
height="48"
|
|
10
10
|
width="48"
|
|
11
|
-
class="h-14 w-14 rounded-
|
|
11
|
+
class="h-14 w-14 rounded-md border border-gray-200 object-cover shadow-sm dark:border-gray-700"
|
|
12
12
|
/>
|
|
13
13
|
<Attach::Tooltip @class="clean" @animation="scale" @placement="top">
|
|
14
|
-
<InputInfo @text={{
|
|
14
|
+
<InputInfo @text={{this.name}} />
|
|
15
15
|
</Attach::Tooltip>
|
|
16
16
|
</div>
|
|
17
|
-
<div class="flex flex-col">
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
|
|
17
|
+
<div class="flex min-w-0 flex-col">
|
|
18
|
+
<div class="flex min-w-0 flex-wrap items-center gap-2">
|
|
19
|
+
<h1 class="truncate text-base font-semibold leading-5 text-gray-900 dark:text-gray-100">{{this.name}}</h1>
|
|
20
|
+
<Badge @status={{this.status}} @size="xs">{{smart-humanize this.status}}</Badge>
|
|
21
|
+
{{#if this.thresholdStatus}}
|
|
22
|
+
<Badge @status={{if (eq this.thresholdStatus "normal") "success" "warning"}} @size="xs">{{smart-humanize this.thresholdStatus}}</Badge>
|
|
23
|
+
{{/if}}
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div class="mt-1 flex max-w-2xl flex-wrap items-center gap-1.5">
|
|
27
|
+
{{#if this.type}}
|
|
28
|
+
<span class="inline-flex max-w-[10rem] items-center gap-1 truncate rounded-md bg-gray-100 px-1.5 py-0.5 text-[11px] font-medium leading-4 text-gray-600 dark:bg-gray-700 dark:text-gray-200">
|
|
29
|
+
<FaIcon @icon="gauge-high" class="text-gray-400 dark:text-gray-300" />
|
|
30
|
+
<span class="truncate">{{n-a (get-fleet-ops-option-label "sensorTypes" this.type)}}</span>
|
|
31
|
+
</span>
|
|
32
|
+
{{/if}}
|
|
33
|
+
{{#if this.identifier}}
|
|
34
|
+
<span class="inline-flex max-w-[12rem] items-center gap-1 truncate rounded-md bg-gray-100 px-1.5 py-0.5 text-[11px] font-medium leading-4 text-gray-600 dark:bg-gray-700 dark:text-gray-200">
|
|
35
|
+
<FaIcon @icon="id-card" class="text-gray-400 dark:text-gray-300" />
|
|
36
|
+
<span class="truncate">{{this.identifier}}</span>
|
|
37
|
+
</span>
|
|
38
|
+
{{/if}}
|
|
39
|
+
{{#if this.reading}}
|
|
40
|
+
<span class="inline-flex max-w-[10rem] items-center gap-1 truncate rounded-md bg-gray-100 px-1.5 py-0.5 text-[11px] font-medium leading-4 text-gray-600 dark:bg-gray-700 dark:text-gray-200">
|
|
41
|
+
<FaIcon @icon="chart-line" class="text-gray-400 dark:text-gray-300" />
|
|
42
|
+
<span class="truncate">{{this.reading}}</span>
|
|
43
|
+
</span>
|
|
44
|
+
{{/if}}
|
|
45
|
+
{{#if this.deviceName}}
|
|
46
|
+
<span class="inline-flex max-w-[12rem] items-center gap-1 truncate rounded-md bg-gray-100 px-1.5 py-0.5 text-[11px] font-medium leading-4 text-gray-600 dark:bg-gray-700 dark:text-gray-200">
|
|
47
|
+
<FaIcon @icon="microchip" class="text-gray-400 dark:text-gray-300" />
|
|
48
|
+
<span class="truncate">{{this.deviceName}}</span>
|
|
49
|
+
</span>
|
|
50
|
+
{{/if}}
|
|
51
|
+
<span class="inline-flex max-w-[13rem] items-center gap-1 truncate rounded-md bg-gray-100 px-1.5 py-0.5 text-[11px] font-medium leading-4 text-gray-600 dark:bg-gray-700 dark:text-gray-200">
|
|
52
|
+
<FaIcon @icon="clock" class="text-gray-400 dark:text-gray-300" />
|
|
53
|
+
<span class="truncate">{{#if this.lastReadingAt}}{{format-date-fns this.lastReadingAt "dd MMM yyyy, HH:mm"}}{{else}}No reading yet{{/if}}</span>
|
|
54
|
+
</span>
|
|
22
55
|
</div>
|
|
23
|
-
<Badge @status={{if @resource.online "online" "offline"}}>{{if @resource.online (t "common.online") (t "common.offline")}}</Badge>
|
|
24
56
|
</div>
|
|
25
57
|
</div>
|
|
26
|
-
<div class="next-view-header-right">
|
|
58
|
+
<div class="next-view-header-right flex-shrink-0">
|
|
27
59
|
<Layout::Resource::Panel::HeaderActions
|
|
28
60
|
@resource={{@resource}}
|
|
29
61
|
@saveTask={{@saveTask}}
|
|
@@ -36,4 +68,4 @@
|
|
|
36
68
|
/>
|
|
37
69
|
</div>
|
|
38
70
|
</div>
|
|
39
|
-
</div>
|
|
71
|
+
</div>
|
|
@@ -1,3 +1,61 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
|
+
import { get } from '@ember/object';
|
|
2
3
|
|
|
3
|
-
export default class SensorPanelHeaderComponent extends Component {
|
|
4
|
+
export default class SensorPanelHeaderComponent extends Component {
|
|
5
|
+
get resource() {
|
|
6
|
+
return this.args.resource;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
get name() {
|
|
10
|
+
return (
|
|
11
|
+
get(this.resource, 'displayName') ??
|
|
12
|
+
get(this.resource, 'display_name') ??
|
|
13
|
+
get(this.resource, 'name') ??
|
|
14
|
+
get(this.resource, 'serial_number') ??
|
|
15
|
+
get(this.resource, 'imei') ??
|
|
16
|
+
get(this.resource, 'public_id') ??
|
|
17
|
+
'-'
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get status() {
|
|
22
|
+
return get(this.resource, 'status') ?? (get(this.resource, 'is_active') ? 'active' : 'inactive');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
get thresholdStatus() {
|
|
26
|
+
return get(this.resource, 'threshold_status');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get type() {
|
|
30
|
+
return get(this.resource, 'type');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get identifier() {
|
|
34
|
+
return get(this.resource, 'serial_number') ?? get(this.resource, 'imei') ?? get(this.resource, 'internal_id') ?? get(this.resource, 'public_id');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get reading() {
|
|
38
|
+
const value = get(this.resource, 'last_value');
|
|
39
|
+
const unit = get(this.resource, 'unit');
|
|
40
|
+
|
|
41
|
+
if (value === null || value === undefined || value === '') {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return unit ? `${value} ${unit}` : String(value);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get deviceName() {
|
|
49
|
+
return (
|
|
50
|
+
get(this.resource, 'device.displayName') ??
|
|
51
|
+
get(this.resource, 'device.display_name') ??
|
|
52
|
+
get(this.resource, 'device.name') ??
|
|
53
|
+
get(this.resource, 'device_name') ??
|
|
54
|
+
get(this.resource, 'device_uuid')
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get lastReadingAt() {
|
|
59
|
+
return get(this.resource, 'last_reading_at') ?? get(this.resource, 'lastReadingAt');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{{#if this.visible}}
|
|
2
|
+
{{#if @columnAction.separator}}
|
|
3
|
+
<div class="next-dd-menu-seperator"></div>
|
|
4
|
+
{{else}}
|
|
5
|
+
<div role="group" class="px-1">
|
|
6
|
+
<a
|
|
7
|
+
href="javascript:;"
|
|
8
|
+
role="menuitem"
|
|
9
|
+
class="next-dd-item {{@columnAction.class}} {{if this.disabled 'disabled'}}"
|
|
10
|
+
disabled={{this.disabled}}
|
|
11
|
+
{{on "click" (fn this.onClick @columnAction @row @dd)}}
|
|
12
|
+
>
|
|
13
|
+
{{#if @columnAction.icon}}
|
|
14
|
+
<div class="w-6">
|
|
15
|
+
<FaIcon class={{@columnAction.iconClass}} @icon={{@columnAction.icon}} @prefix={{@columnAction.iconPrefix}} />
|
|
16
|
+
</div>
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{@columnAction.label}}
|
|
19
|
+
{{#if this.doesntHavePermissions}}
|
|
20
|
+
<Attach::Tooltip @class="clean" @animation="scale" @placement={{or @columnAction.tooltipPlacement "right"}}>
|
|
21
|
+
<InputInfo @text={{t "common.unauthorized"}} />
|
|
22
|
+
</Attach::Tooltip>
|
|
23
|
+
{{else if @columnAction.helpText}}
|
|
24
|
+
<Attach::Tooltip @class="clean" @animation="scale" @placement={{or @columnAction.tooltipPlacement "right"}}>
|
|
25
|
+
<InputInfo @text={{@columnAction.helpText}} @exampleText={{@columnAction.exampleText}} />
|
|
26
|
+
</Attach::Tooltip>
|
|
27
|
+
{{/if}}
|
|
28
|
+
</a>
|
|
29
|
+
</div>
|
|
30
|
+
{{/if}}
|
|
31
|
+
{{/if}}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import { action } from '@ember/object';
|
|
5
|
+
import { isNone } from '@ember/utils';
|
|
6
|
+
|
|
7
|
+
export default class TableCellDropdownActionItemComponent extends Component {
|
|
8
|
+
@service abilities;
|
|
9
|
+
@tracked permissionRequired;
|
|
10
|
+
@tracked doesntHavePermissions = false;
|
|
11
|
+
@tracked disabled = false;
|
|
12
|
+
@tracked visible = true;
|
|
13
|
+
|
|
14
|
+
constructor(owner, { columnAction = {}, row = {}, disabled = false, permission = null }) {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
this.permissionRequired = columnAction.permission ?? permission;
|
|
17
|
+
this.disabled = this.disabledCheck(columnAction, this.permissionRequired, disabled);
|
|
18
|
+
this.visible = (columnAction.visible ?? true) && this.visibilityCheck(columnAction, row);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@action onClick(columnAction, row, dd) {
|
|
22
|
+
if (this.disabled) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (typeof dd?.actions?.close === 'function') {
|
|
27
|
+
dd.actions.close();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (typeof columnAction?.fn === 'function') {
|
|
31
|
+
columnAction.fn(row);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
disabledCheck(columnAction, permission, defaultValue = false) {
|
|
36
|
+
let disabled = columnAction.disabled ?? defaultValue;
|
|
37
|
+
if (!disabled) {
|
|
38
|
+
disabled = permission && this.abilities.cannot(permission);
|
|
39
|
+
this.doesntHavePermissions = disabled;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return disabled;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
visibilityCheck(columnAction, context) {
|
|
46
|
+
const isVisible = columnAction.isVisible;
|
|
47
|
+
|
|
48
|
+
if (isNone(context) || !isVisible) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof isVisible === 'boolean') {
|
|
53
|
+
return isVisible;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (typeof isVisible === 'function') {
|
|
57
|
+
return isVisible(context);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<div class="cell-dropdown-button overflow-visible {{@column.wrapperClass}}" {{did-insert this.setupComponent}} ...attributes>
|
|
2
|
+
<DropdownButton
|
|
3
|
+
@icon={{@column.ddButtonIcon}}
|
|
4
|
+
@iconPrefix={{@column.ddButtonIconPrefix}}
|
|
5
|
+
@text={{this.buttonText}}
|
|
6
|
+
@size="xs"
|
|
7
|
+
@horizontalPosition="left"
|
|
8
|
+
@calculatePosition={{this.calculatePosition}}
|
|
9
|
+
@renderInPlace={{true}}
|
|
10
|
+
@onOpen={{this.onOpen}}
|
|
11
|
+
@onClose={{this.onClose}}
|
|
12
|
+
as |dd|
|
|
13
|
+
>
|
|
14
|
+
<div class="next-dd-menu next-dd-menu-table-dd mt-0i {{@column.ddMenuWrapperClass}}" role="menu" aria-orientation="vertical" aria-labelledby="user-menu">
|
|
15
|
+
{{#if @column.ddMenuLabel}}
|
|
16
|
+
<div class="next-dd-menu-label-container px-1">
|
|
17
|
+
<div class="next-dd-menu-label {{@column.ddMenuLabelClass}}">
|
|
18
|
+
{{@column.ddMenuLabel}}
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="next-dd-menu-seperator"></div>
|
|
22
|
+
{{/if}}
|
|
23
|
+
{{#each @column.actions as |columnAction|}}
|
|
24
|
+
<Table::Cell::Dropdown::ActionItem @columnAction={{columnAction}} @row={{@row}} @column={{@column}} @dd={{dd}} />
|
|
25
|
+
{{/each}}
|
|
26
|
+
</div>
|
|
27
|
+
</DropdownButton>
|
|
28
|
+
</div>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { action, computed } from '@ember/object';
|
|
4
|
+
|
|
5
|
+
export default class TableCellDropdownComponent extends Component {
|
|
6
|
+
@tracked tableCellNode;
|
|
7
|
+
defaultButtonText = 'Actions';
|
|
8
|
+
|
|
9
|
+
@computed('args.column.ddButtonText', 'defaultButtonText') get buttonText() {
|
|
10
|
+
const { ddButtonText } = this.args.column;
|
|
11
|
+
|
|
12
|
+
if (ddButtonText === undefined) {
|
|
13
|
+
return this.defaultButtonText;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (ddButtonText === false) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return ddButtonText;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@action setupComponent(dropdownWrapperNode) {
|
|
24
|
+
const tableCellNode = this.getOwnerTableCell(dropdownWrapperNode);
|
|
25
|
+
|
|
26
|
+
if (tableCellNode) {
|
|
27
|
+
tableCellNode.style.overflow = 'visible';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
this.tableCellNode = tableCellNode;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@action onOpen() {
|
|
34
|
+
if (!this.tableCellNode) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const currentZIndex = Number.parseInt(this.tableCellNode.style.zIndex, 10) || 0;
|
|
39
|
+
this.tableCellNode.style.zIndex = currentZIndex + 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@action onClose() {
|
|
43
|
+
if (!this.tableCellNode) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const currentZIndex = Number.parseInt(this.tableCellNode.style.zIndex, 10) || 1;
|
|
48
|
+
this.tableCellNode.style.zIndex = currentZIndex - 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@action getOwnerTableCell(dropdownWrapperNode) {
|
|
52
|
+
while (dropdownWrapperNode) {
|
|
53
|
+
dropdownWrapperNode = dropdownWrapperNode.parentNode;
|
|
54
|
+
|
|
55
|
+
if (dropdownWrapperNode?.tagName?.toLowerCase() === 'td') {
|
|
56
|
+
return dropdownWrapperNode;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@action onDropdownItemClick(columnAction, row, dd) {
|
|
64
|
+
if (typeof dd?.actions?.close === 'function') {
|
|
65
|
+
dd.actions.close();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (typeof columnAction?.fn === 'function') {
|
|
69
|
+
columnAction.fn(row);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@action calculatePosition(trigger, content) {
|
|
74
|
+
if (typeof this.args.column?.calculatePosition === 'function') {
|
|
75
|
+
return this.args.column.calculatePosition(trigger, content);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
79
|
+
const contentRect = content?.getBoundingClientRect?.();
|
|
80
|
+
const contentWidth = contentRect?.width || 224;
|
|
81
|
+
|
|
82
|
+
const style = {
|
|
83
|
+
position: 'fixed',
|
|
84
|
+
marginTop: '0px',
|
|
85
|
+
left: `${triggerRect.left - contentWidth - 3}px`,
|
|
86
|
+
top: `${triggerRect.top}px`,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return { style };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
<div class="rounded-md border border-gray-200 p-3 dark:border-gray-700 md:col-span-2">
|
|
93
93
|
<div class="text-gray-400 dark:text-gray-500">Update Mode</div>
|
|
94
94
|
<div class="mt-1 font-semibold text-gray-900 dark:text-gray-100">Provider polling</div>
|
|
95
|
-
<div class="mt-1 text-gray-500 dark:text-gray-400">
|
|
95
|
+
<div class="mt-1 text-gray-500 dark:text-gray-400">Fleet-Ops polls this provider for device snapshots and telemetry updates.</div>
|
|
96
96
|
</div>
|
|
97
97
|
{{/if}}
|
|
98
98
|
</div>
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
<div class="mb-3">
|
|
71
71
|
<div>
|
|
72
72
|
<h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Credentials</h2>
|
|
73
|
-
<p class="text-xs text-gray-500 dark:text-gray-300">
|
|
73
|
+
<p class="text-xs text-gray-500 dark:text-gray-300">Fleet-Ops uses these credentials to test the connection and sync devices.</p>
|
|
74
74
|
</div>
|
|
75
75
|
</div>
|
|
76
76
|
|
|
@@ -266,7 +266,7 @@
|
|
|
266
266
|
</InputGroup>
|
|
267
267
|
{{else}}
|
|
268
268
|
<div class="rounded-md border border-dashed border-gray-300 p-3 text-xs text-gray-500 dark:border-gray-700 dark:text-gray-300 lg:col-span-2">
|
|
269
|
-
This provider does not require
|
|
269
|
+
This provider does not require Fleet-Ops webhook configuration.
|
|
270
270
|
</div>
|
|
271
271
|
{{/if}}
|
|
272
272
|
</div>
|