From adb0da365bf76e4b3113b7e97c81b12bc0b68bd9 Mon Sep 17 00:00:00 2001 From: Hannes Hansen Date: Mon, 18 Dec 2023 11:37:34 +0100 Subject: [PATCH] fixed connection state widget and added filter for unknown connection; fix #SNRGY-3030 --- .../device-instances.component.ts | 9 ++-- ...evice-instances-filter-dialog.component.ts | 11 +++-- .../shared/device-instances.model.ts | 11 ++--- .../shared/device-instances.service.ts | 43 ++++++++++++++----- .../devices-state/devices-state.component.ts | 8 ++-- 5 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/app/modules/devices/device-instances/device-instances.component.ts b/src/app/modules/devices/device-instances/device-instances.component.ts index e45e0b68..63ad760b 100644 --- a/src/app/modules/devices/device-instances/device-instances.component.ts +++ b/src/app/modules/devices/device-instances/device-instances.component.ts @@ -39,9 +39,9 @@ import { SearchbarService } from 'src/app/core/components/searchbar/shared/searc import { DeviceInstancesFilterDialogComponent } from './dialogs/device-instances-filter-dialog/device-instances-filter-dialog.component'; import { MatDialog } from '@angular/material/dialog'; import { ExportDataService } from 'src/app/widgets/shared/export-data.service'; + export interface DeviceInstancesRouterState { type: DeviceInstancesRouterStateTypesEnum | undefined | null; - tab: DeviceInstancesRouterStateTabEnum | undefined | null; value: any; } @@ -50,7 +50,8 @@ export enum DeviceInstancesRouterStateTypesEnum { NETWORK, DEVICE_TYPE, LOCATION, - DEVICE_GROUP + DEVICE_GROUP, + CONNECTION_STATE } // eslint-disable-next-line no-shadow @@ -102,7 +103,7 @@ export class DeviceInstancesComponent implements OnInit, AfterViewInit { routerDeviceType: string[] | undefined = undefined; routerLocation: string | undefined = undefined; routerDeviceIds: string[] | undefined = undefined; - routerConnectionState: boolean | undefined = undefined; + routerConnectionState: DeviceInstancesRouterStateTabEnum | undefined = undefined; private searchSub: Subscription = new Subscription(); sortBy: string = "display_name" @@ -304,6 +305,8 @@ export class DeviceInstancesComponent implements OnInit, AfterViewInit { case DeviceInstancesRouterStateTypesEnum.DEVICE_GROUP: this.routerDeviceIds = state.value as string[]; break; + case DeviceInstancesRouterStateTypesEnum.CONNECTION_STATE: + this.routerConnectionState = state.value } } } diff --git a/src/app/modules/devices/device-instances/dialogs/device-instances-filter-dialog/device-instances-filter-dialog.component.ts b/src/app/modules/devices/device-instances/dialogs/device-instances-filter-dialog/device-instances-filter-dialog.component.ts index 851c40d1..d2415b29 100644 --- a/src/app/modules/devices/device-instances/dialogs/device-instances-filter-dialog/device-instances-filter-dialog.component.ts +++ b/src/app/modules/devices/device-instances/dialogs/device-instances-filter-dialog/device-instances-filter-dialog.component.ts @@ -9,6 +9,7 @@ import { LocationModel } from '../../../locations/shared/locations.model'; import { LocationsService } from '../../../locations/shared/locations.service'; import { NetworksModel } from '../../../networks/shared/networks.model'; import { NetworksService } from '../../../networks/shared/networks.service'; +import { DeviceInstancesRouterStateTabEnum } from '../../device-instances.component'; import { DeviceConnectionState, FilterSelection } from '../../shared/device-instances.model'; import { DeviceInstancesService } from '../../shared/device-instances.service'; @@ -22,13 +23,17 @@ export class DeviceInstancesFilterDialogComponent implements OnInit { locationOptions: LocationModel[] = []; networkOptions: NetworksModel[] = []; deviceTypeOptions: DeviceTypeBaseModel[] = []; - connectionOptions: DeviceConnectionState[] = [{"name": "connected", "value": true}, {"name": "unconnected", "value": false}] + connectionOptions: DeviceConnectionState[] = [ + {"name": "connected", "value": DeviceInstancesRouterStateTabEnum.ONLINE}, + {"name": "unconnected", "value": DeviceInstancesRouterStateTabEnum.OFFLINE}, + {"name": "unknown", "value": DeviceInstancesRouterStateTabEnum.UNKNOWN} + ] form = new FormGroup({ location: new FormControl(undefined), network: new FormControl(undefined), deviceTypes: new FormControl([]), - connectionState: new FormControl(undefined), + connectionState: new FormControl(DeviceInstancesRouterStateTabEnum.ALL), }); savedFilterSelection!: FilterSelection | undefined @@ -107,7 +112,7 @@ export class DeviceInstancesFilterDialogComponent implements OnInit { } resetConnectionFilter() { - this.form.controls.connectionState.patchValue(undefined) + this.form.controls.connectionState.patchValue(DeviceInstancesRouterStateTabEnum.ALL) } resetLocationFilter() { diff --git a/src/app/modules/devices/device-instances/shared/device-instances.model.ts b/src/app/modules/devices/device-instances/shared/device-instances.model.ts index 52cdb2dd..debdd4cb 100644 --- a/src/app/modules/devices/device-instances/shared/device-instances.model.ts +++ b/src/app/modules/devices/device-instances/shared/device-instances.model.ts @@ -18,6 +18,7 @@ import { DeviceTypePermSearchModel, PermissionsModel } from '../../../metadata/d import { DeviceTypeServiceModel } from '../../../metadata/device-types-overview/shared/device-type.model'; import { ImportInstancesModel } from '../../../imports/import-instances/shared/import-instances.model'; import { ImportTypeModel } from '../../../imports/import-types/shared/import-types.model'; +import { DeviceInstancesRouterStateTabEnum } from '../device-instances.component'; export interface Attribute { key: string; @@ -85,7 +86,7 @@ export interface DeviceSelectablesFullModel { } export interface DeviceConnectionState { - value: boolean; + value: DeviceInstancesRouterStateTabEnum; name: string; } @@ -96,8 +97,8 @@ export interface SelectedTag { } export interface FilterSelection { - connectionState: boolean | undefined; - deviceTypes: string[] | undefined; - location: string | undefined; - network: string | undefined; + connectionState?: DeviceInstancesRouterStateTabEnum; + deviceTypes?: string[]; + location?: string; + network?: string; } \ No newline at end of file diff --git a/src/app/modules/devices/device-instances/shared/device-instances.service.ts b/src/app/modules/devices/device-instances/shared/device-instances.service.ts index 2aa61920..e5add9ca 100644 --- a/src/app/modules/devices/device-instances/shared/device-instances.service.ts +++ b/src/app/modules/devices/device-instances/shared/device-instances.service.ts @@ -40,6 +40,7 @@ import { DeviceTypePermSearchModel } from 'src/app/modules/metadata/device-types import { PermissionQueryRequest, Selection } from 'src/app/core/model/permissions/permissions'; import { LocationsService } from '../../locations/shared/locations.service'; import { NetworksService } from '../../networks/shared/networks.service'; +import { DeviceInstancesRouterStateTabEnum } from '../device-instances.component'; @Injectable({ providedIn: 'root', @@ -186,7 +187,7 @@ export class DeviceInstancesService { sortDesc: boolean = false, searchText?: string, deviceTypeIds?: string[], - connectionState?: boolean, + connectionState?: DeviceInstancesRouterStateTabEnum, deviceIds?: string[], ): Observable { var queryRequest: PermissionQueryRequest = { @@ -199,23 +200,42 @@ export class DeviceInstancesService { sort_by: sortBy, } } + var optionalFilters: Selection[] = [] + var optionalNotFilter: Selection = {"not": {}} - if(searchText != null) { + if(searchText != null && searchText != "") { if(queryRequest.find) { queryRequest.find.search = searchText } } if(connectionState != null) { - optionalFilters.push( - { - condition: { - feature: 'annotations.connected', operation: '==', value: connectionState + if(connectionState == DeviceInstancesRouterStateTabEnum.ONLINE) { + optionalFilters.push( + { + condition: { + feature: 'annotations.connected', operation: '==', value: true + } } + ) + } else if(connectionState == DeviceInstancesRouterStateTabEnum.OFFLINE) { + optionalFilters.push( + { + condition: { + feature: 'annotations.connected', operation: '==', value: false + } + } + ) + } else if(connectionState == DeviceInstancesRouterStateTabEnum.UNKNOWN) { + // filter for unknown connection state + optionalNotFilter.not!.condition = { + feature: 'annotations.connected', operation: "any_value_in_feature", value: [true, false] } - ) - } + optionalFilters.push(optionalNotFilter) + } + + } if(deviceTypeIds != null && deviceTypeIds.length > 0) { optionalFilters.push( @@ -240,6 +260,7 @@ export class DeviceInstancesService { if(optionalFilters.length > 0 && queryRequest.find) { queryRequest.find.filter = {"and": optionalFilters} } + return this.queryPermissionSearch(queryRequest).pipe( map((resp) => resp || []), concatMap(result => { @@ -265,7 +286,7 @@ export class DeviceInstancesService { locationId?: string, hubId?: string, deviceTypeIds?: string[], - connectionState?: boolean, + connectionState?: DeviceInstancesRouterStateTabEnum, ): Observable { if(hubId != null || locationId != null) { return this.getDeviceIds(hubId, locationId).pipe( @@ -296,7 +317,7 @@ export class DeviceInstancesService { locationId?: string, hubId?: string, deviceTypeIds?: string[], - connectionState?: boolean, + connectionState?: DeviceInstancesRouterStateTabEnum, ): Observable { return this.loadDeviceInstances(limit, offset, sortBy, sortDesc, searchText, locationId, hubId, deviceTypeIds, connectionState) } @@ -310,7 +331,7 @@ export class DeviceInstancesService { locationId?: string, hubId?: string, deviceTypeIds?: string[], - connectionState?: boolean, + connectionState?: DeviceInstancesRouterStateTabEnum, ): Observable { return this.loadDeviceInstances(limit, offset, sortBy, sortDesc, searchText, locationId, hubId, deviceTypeIds, connectionState).pipe( map((result) => result.result) diff --git a/src/app/widgets/devices-state/devices-state.component.ts b/src/app/widgets/devices-state/devices-state.component.ts index 3af97061..89dc9233 100644 --- a/src/app/widgets/devices-state/devices-state.component.ts +++ b/src/app/widgets/devices-state/devices-state.component.ts @@ -21,7 +21,7 @@ import { DevicesStateModel } from './shared/devices-state.model'; import { DashboardService } from '../../modules/dashboard/shared/dashboard.service'; import { Subscription } from 'rxjs'; import { Router } from '@angular/router'; -import { DeviceInstancesRouterState, DeviceInstancesRouterStateTabEnum } from 'src/app/modules/devices/device-instances/device-instances.component'; +import { DeviceInstancesRouterState, DeviceInstancesRouterStateTabEnum, DeviceInstancesRouterStateTypesEnum } from 'src/app/modules/devices/device-instances/device-instances.component'; @Component({ selector: 'senergy-devices-state', @@ -73,21 +73,21 @@ export class DevicesStateComponent implements OnInit, OnDestroy { showOnlineDevices() { this.router.navigate(['devices/deviceinstances'], { - state: { tab: DeviceInstancesRouterStateTabEnum.ONLINE } as DeviceInstancesRouterState, + state: { type: DeviceInstancesRouterStateTypesEnum.CONNECTION_STATE, value: DeviceInstancesRouterStateTabEnum.ONLINE } as DeviceInstancesRouterState, }); return false; } showOfflineDevices() { this.router.navigate(['devices/deviceinstances'], { - state: { tab: DeviceInstancesRouterStateTabEnum.OFFLINE } as DeviceInstancesRouterState, + state: { type: DeviceInstancesRouterStateTypesEnum.CONNECTION_STATE, value: DeviceInstancesRouterStateTabEnum.OFFLINE } as DeviceInstancesRouterState, }); return false; } showUnknownDevices() { this.router.navigate(['devices/deviceinstances'], { - state: { tab: DeviceInstancesRouterStateTabEnum.UNKNOWN } as DeviceInstancesRouterState, + state: { type: DeviceInstancesRouterStateTypesEnum.CONNECTION_STATE, value: DeviceInstancesRouterStateTabEnum.UNKNOWN } as DeviceInstancesRouterState, }); return false; }