diff --git a/src/main/angular/src/app/api/Device/Device.ts b/src/main/angular/src/app/api/Device/Device.ts index f357ba7..718bba9 100644 --- a/src/main/angular/src/app/api/Device/Device.ts +++ b/src/main/angular/src/app/api/Device/Device.ts @@ -27,4 +27,8 @@ export class Device { return device.uuid; } + static equals(a: Device, b: Device): boolean { + return a.uuid !== b.uuid; + } + } diff --git a/src/main/angular/src/app/api/Device/DeviceFilter.ts b/src/main/angular/src/app/api/Device/DeviceFilter.ts index a52546e..265808d 100644 --- a/src/main/angular/src/app/api/Device/DeviceFilter.ts +++ b/src/main/angular/src/app/api/Device/DeviceFilter.ts @@ -2,4 +2,10 @@ export class DeviceFilter { search: string = ""; + stateTrue: boolean = true; + + stateFalse: boolean = true; + + stateNull: boolean = true; + } diff --git a/src/main/angular/src/app/api/Shutter/Shutter.ts b/src/main/angular/src/app/api/Shutter/Shutter.ts index 0ec8dda..ed304af 100644 --- a/src/main/angular/src/app/api/Shutter/Shutter.ts +++ b/src/main/angular/src/app/api/Shutter/Shutter.ts @@ -27,4 +27,8 @@ export class Shutter { return shutter.uuid; } + static equals(a: Shutter, b: Shutter): boolean { + return a.uuid !== b.uuid; + } + } diff --git a/src/main/angular/src/app/api/Shutter/ShutterFilter.ts b/src/main/angular/src/app/api/Shutter/ShutterFilter.ts index b2c8b87..d8e1662 100644 --- a/src/main/angular/src/app/api/Shutter/ShutterFilter.ts +++ b/src/main/angular/src/app/api/Shutter/ShutterFilter.ts @@ -2,4 +2,12 @@ export class ShutterFilter { search: string = ""; + positionOpen: boolean | null = null; + + positionBetween: boolean | null = null; + + positionClosed: boolean | null = null; + + stateNull: boolean | null = null; + } diff --git a/src/main/angular/src/app/api/Tunable/Tunable.ts b/src/main/angular/src/app/api/Tunable/Tunable.ts index ce3c142..bc1523a 100644 --- a/src/main/angular/src/app/api/Tunable/Tunable.ts +++ b/src/main/angular/src/app/api/Tunable/Tunable.ts @@ -2,6 +2,7 @@ import {Property} from "../Property/Property"; import {orNull, validateString} from "../common/validators"; export class Tunable { + constructor( readonly uuid: string, readonly name: string, @@ -34,4 +35,8 @@ export class Tunable { return tunable.uuid; } + static equals(a: Tunable, b: Tunable): boolean { + return a.uuid !== b.uuid; + } + } diff --git a/src/main/angular/src/app/api/Tunable/TunableFilter.ts b/src/main/angular/src/app/api/Tunable/TunableFilter.ts index 9e2bc67..58eb4c0 100644 --- a/src/main/angular/src/app/api/Tunable/TunableFilter.ts +++ b/src/main/angular/src/app/api/Tunable/TunableFilter.ts @@ -2,4 +2,10 @@ export class TunableFilter { search: string = ""; + stateTrue: boolean = true; + + stateFalse: boolean = true; + + stateNull: boolean = true; + } diff --git a/src/main/angular/src/app/api/common/CrudLiveList.ts b/src/main/angular/src/app/api/common/CrudLiveList.ts new file mode 100644 index 0000000..adba169 --- /dev/null +++ b/src/main/angular/src/app/api/common/CrudLiveList.ts @@ -0,0 +1,42 @@ +import {CrudService} from "./CrudService"; +import {Subscription} from "rxjs"; + +export class CrudLiveList extends Subscription { + + private readonly subs: Subscription[] = []; + + unfiltered: ENTITY[] = []; + + filtered: ENTITY[] = []; + + constructor( + crudService: CrudService, + readonly equals: (a: ENTITY, b: ENTITY) => boolean, + readonly filter: (item: ENTITY) => boolean = _ => true, + ) { + super(() => { + this.subs.forEach(sub => sub.unsubscribe()); + }); + crudService.all(list => this.unfiltered = list); + this.subs.push(crudService.subscribe(item => this.update(item))); + } + + private update(item: ENTITY) { + const index = this.unfiltered.findIndex(i => this.equals(i, item)); + if (index >= 0) { + this.unfiltered.splice(index, 1, item); + } else { + this.unfiltered.push(item); + } + this.filtered = this.unfiltered.filter(this.filter); + } + + get hasUnfiltered(): boolean { + return this.unfiltered.length > 0; + } + + get hasFiltered(): boolean { + return this.filtered.length > 0; + } + +} diff --git a/src/main/angular/src/app/api/common/CrudService.ts b/src/main/angular/src/app/api/common/CrudService.ts index 83c6319..e2dd345 100644 --- a/src/main/angular/src/app/api/common/CrudService.ts +++ b/src/main/angular/src/app/api/common/CrudService.ts @@ -13,6 +13,10 @@ export abstract class CrudService { // } + all(next: Next) { + this.getList(['list'], next); + } + subscribe(next: Next): Subscription { return this.api.subscribe([...this.path], this.fromJson, next); } @@ -48,5 +52,4 @@ export abstract class CrudService { protected postPage(path: any[], data: any, next?: Next>): void { this.api.postPage([...this.path, ...path], data, this.fromJson, next); } - } diff --git a/src/main/angular/src/app/app.component.html b/src/main/angular/src/app/app.component.html index f56d361..5625b3e 100644 --- a/src/main/angular/src/app/app.component.html +++ b/src/main/angular/src/app/app.component.html @@ -1,7 +1,8 @@
@@ -11,7 +12,7 @@
-
+
Nicht verbunden
diff --git a/src/main/angular/src/app/app.component.less b/src/main/angular/src/app/app.component.less index 7550b82..5426eb1 100644 --- a/src/main/angular/src/app/app.component.less +++ b/src/main/angular/src/app/app.component.less @@ -34,7 +34,7 @@ border: @space solid red; color: red; - div { + .text { text-align: center; margin: auto; font-size: 200%; diff --git a/src/main/angular/src/app/app.routes.ts b/src/main/angular/src/app/app.routes.ts index 5466694..29dbfbe 100644 --- a/src/main/angular/src/app/app.routes.ts +++ b/src/main/angular/src/app/app.routes.ts @@ -3,11 +3,13 @@ import {KnxGroupListPageComponent} from './pages/knx-group-list-page/knx-group-l import {DeviceListPageComponent} from './pages/device-list-page/device-list-page.component'; import {ShutterListPageComponent} from './pages/shutter-list-page/shutter-list-page.component'; import {TunableListPageComponent} from './pages/tunable-list-page/tunable-list-page.component'; +import {DashboardComponent} from './pages/dashboard/dashboard.component'; export const routes: Routes = [ + {path: 'Dashboard', component: DashboardComponent}, {path: 'DeviceList', component: DeviceListPageComponent}, {path: 'TunableList', component: TunableListPageComponent}, {path: 'ShutterList', component: ShutterListPageComponent}, {path: 'GroupList', component: KnxGroupListPageComponent}, - {path: '**', redirectTo: 'GroupList'}, + {path: '**', redirectTo: 'Dashboard'}, ]; diff --git a/src/main/angular/src/app/pages/dashboard/dashboard.component.html b/src/main/angular/src/app/pages/dashboard/dashboard.component.html new file mode 100644 index 0000000..9e7fb27 --- /dev/null +++ b/src/main/angular/src/app/pages/dashboard/dashboard.component.html @@ -0,0 +1,21 @@ +
+ +
+ Eingeschaltete Geräte: + {{ deviceList.filtered.length }} +
+ + +
+ Eingeschaltete Lichter: + {{ tunableList.filtered.length }} +
+ + +
+ {{ shutterSubheading }} Rollläden: + {{ shutterList.filtered.length }} +
+ + +
diff --git a/src/main/angular/src/app/pages/dashboard/dashboard.component.less b/src/main/angular/src/app/pages/dashboard/dashboard.component.less new file mode 100644 index 0000000..35804d8 --- /dev/null +++ b/src/main/angular/src/app/pages/dashboard/dashboard.component.less @@ -0,0 +1,7 @@ +@import "../../../config"; + +.subheading { + font-size: 65%; + font-style: italic; + color: gray; +} diff --git a/src/main/angular/src/app/pages/dashboard/dashboard.component.ts b/src/main/angular/src/app/pages/dashboard/dashboard.component.ts new file mode 100644 index 0000000..5e964ee --- /dev/null +++ b/src/main/angular/src/app/pages/dashboard/dashboard.component.ts @@ -0,0 +1,76 @@ +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {DeviceService} from '../../api/Device/device.service'; +import {TunableService} from '../../api/Tunable/tunable.service'; +import {Device} from '../../api/Device/Device'; +import {Tunable} from '../../api/Tunable/Tunable'; +import {Shutter} from '../../api/Shutter/Shutter'; +import {ShutterService} from '../../api/Shutter/shutter.service'; +import {DeviceListComponent} from '../../shared/device-list/device-list.component'; +import {FormsModule} from '@angular/forms'; +import {CrudLiveList} from '../../api/common/CrudLiveList'; +import {TunableListComponent} from '../../shared/tunable-list/tunable-list.component'; +import {ShutterListComponent} from '../../shared/shutter-list/shutter-list.component'; +import {Subscription, timer} from 'rxjs'; + +@Component({ + selector: 'app-dashboard', + standalone: true, + imports: [ + DeviceListComponent, + FormsModule, + TunableListComponent, + ShutterListComponent, + ], + templateUrl: './dashboard.component.html', + styleUrl: './dashboard.component.less' +}) +export class DashboardComponent implements OnInit, OnDestroy { + + protected deviceList!: CrudLiveList; + + protected tunableList!: CrudLiveList; + + protected shutterList!: CrudLiveList; + + protected now: Date = new Date(); + + private subs: Subscription[] = []; + + protected shutterSubheading: string = ""; + + protected shuttersShouldBeOpen: boolean = false; + + constructor( + protected readonly deviceService: DeviceService, + protected readonly tunableService: TunableService, + protected readonly shutterService: ShutterService, + ) { + } + + ngOnInit(): void { + this.newDate(); + this.subs.push(timer(5000, 5000).subscribe(() => this.newDate())); + this.subs.push(this.deviceList = new CrudLiveList(this.deviceService, Device.equals, device => device.stateProperty?.state?.value === true)); + this.subs.push(this.tunableList = new CrudLiveList(this.tunableService, Tunable.equals, tunable => tunable.stateProperty?.state?.value === true)); + this.subs.push(this.shutterList = new CrudLiveList(this.shutterService, Shutter.equals, shutter => this.shutterFilter(shutter))); + } + + private newDate() { + this.now = new Date(); + this.shuttersShouldBeOpen = this.now.getHours() >= 7 && this.now.getHours() < 16; + this.shutterSubheading = this.shuttersShouldBeOpen ? "Geschlossene" : "Offene"; + } + + ngOnDestroy(): void { + this.subs.forEach(sub => sub.unsubscribe()); + } + + private shutterFilter(shutter: Shutter) { + if (this.shuttersShouldBeOpen) { + return shutter.positionProperty?.state?.value !== 0; + } else { + return shutter.positionProperty?.state?.value !== 100; + } + } + +} diff --git a/src/main/angular/src/app/pages/device-list-page/device-list-page.component.html b/src/main/angular/src/app/pages/device-list-page/device-list-page.component.html index 103ffac..803a3d9 100644 --- a/src/main/angular/src/app/pages/device-list-page/device-list-page.component.html +++ b/src/main/angular/src/app/pages/device-list-page/device-list-page.component.html @@ -2,7 +2,7 @@
-
- +
+
diff --git a/src/main/angular/src/app/pages/knx-group-list-page/knx-group-list-page.component.html b/src/main/angular/src/app/pages/knx-group-list-page/knx-group-list-page.component.html index 1ec261d..a5c3c4a 100644 --- a/src/main/angular/src/app/pages/knx-group-list-page/knx-group-list-page.component.html +++ b/src/main/angular/src/app/pages/knx-group-list-page/knx-group-list-page.component.html @@ -2,7 +2,7 @@
-
+
diff --git a/src/main/angular/src/app/pages/shutter-list-page/shutter-list-page.component.html b/src/main/angular/src/app/pages/shutter-list-page/shutter-list-page.component.html index b5cc55c..fb20acd 100644 --- a/src/main/angular/src/app/pages/shutter-list-page/shutter-list-page.component.html +++ b/src/main/angular/src/app/pages/shutter-list-page/shutter-list-page.component.html @@ -2,7 +2,7 @@
-
- +
+
diff --git a/src/main/angular/src/app/pages/tunable-list-page/tunable-list-page.component.html b/src/main/angular/src/app/pages/tunable-list-page/tunable-list-page.component.html index e256d68..868a31d 100644 --- a/src/main/angular/src/app/pages/tunable-list-page/tunable-list-page.component.html +++ b/src/main/angular/src/app/pages/tunable-list-page/tunable-list-page.component.html @@ -2,7 +2,7 @@
-
- +
+
diff --git a/src/main/angular/src/app/shared/checkbox/checkbox.component.html b/src/main/angular/src/app/shared/checkbox/checkbox.component.html new file mode 100644 index 0000000..4c56dbb --- /dev/null +++ b/src/main/angular/src/app/shared/checkbox/checkbox.component.html @@ -0,0 +1,9 @@ +
+
+
{{ labelTrue }}
+
{{ labelFalse }}
+
+
+ {{ label }} +
+
diff --git a/src/main/angular/src/app/shared/checkbox/checkbox.component.less b/src/main/angular/src/app/shared/checkbox/checkbox.component.less new file mode 100644 index 0000000..d3f450c --- /dev/null +++ b/src/main/angular/src/app/shared/checkbox/checkbox.component.less @@ -0,0 +1,15 @@ +@import '../../../config'; + +.all { + white-space: nowrap; + + .box { + float: left; + width: 1.5em; + aspect-ratio: 1; + margin-right: @space; + text-align: center; + border: @border solid gray; + } + +} diff --git a/src/main/angular/src/app/shared/checkbox/checkbox.component.ts b/src/main/angular/src/app/shared/checkbox/checkbox.component.ts new file mode 100644 index 0000000..54aa8ee --- /dev/null +++ b/src/main/angular/src/app/shared/checkbox/checkbox.component.ts @@ -0,0 +1,35 @@ +import {Component, EventEmitter, Input, Output} from '@angular/core'; +import {NgIf} from '@angular/common'; + +@Component({ + selector: 'app-checkbox', + standalone: true, + imports: [ + NgIf + ], + templateUrl: './checkbox.component.html', + styleUrl: './checkbox.component.less' +}) +export class CheckboxComponent { + + @Input() + label: string = ''; + + @Input() + labelFalse: string = ''; + + @Input() + labelTrue: string = 'X'; + + @Input() + model!: boolean; + + @Output() + modelChange: EventEmitter = new EventEmitter(); + + toggle() { + this.model = !this.model; + this.modelChange.emit(this.model); + } + +} diff --git a/src/main/angular/src/app/shared/device-list/device-list.component.html b/src/main/angular/src/app/shared/device-list/device-list.component.html index ca414fb..ea4b1b1 100644 --- a/src/main/angular/src/app/shared/device-list/device-list.component.html +++ b/src/main/angular/src/app/shared/device-list/device-list.component.html @@ -1,6 +1,6 @@
-
+
@@ -9,8 +9,8 @@
-
-
+
+
diff --git a/src/main/angular/src/app/shared/device-list/device-list.component.less b/src/main/angular/src/app/shared/device-list/device-list.component.less index b1287fc..58263fc 100644 --- a/src/main/angular/src/app/shared/device-list/device-list.component.less +++ b/src/main/angular/src/app/shared/device-list/device-list.component.less @@ -1,8 +1,6 @@ @import "../../../config"; .deviceList { - overflow-y: auto; - height: 100%; .device { @@ -19,7 +17,7 @@ .actions { float: right; - div { + .action { float: left; margin-left: @space; width: 4em; diff --git a/src/main/angular/src/app/shared/device-list/device-list.component.ts b/src/main/angular/src/app/shared/device-list/device-list.component.ts index d1c5037..0fe00af 100644 --- a/src/main/angular/src/app/shared/device-list/device-list.component.ts +++ b/src/main/angular/src/app/shared/device-list/device-list.component.ts @@ -25,7 +25,7 @@ export class DeviceListComponent implements OnInit, OnDestroy { protected now: Date = new Date(); @Input() - deviceList: Device[] = []; + list: Device[] = []; constructor( protected readonly deviceService: DeviceService, diff --git a/src/main/angular/src/app/shared/knx-group-list/knx-group-list.component.less b/src/main/angular/src/app/shared/knx-group-list/knx-group-list.component.less index b7b7eeb..fe7d093 100644 --- a/src/main/angular/src/app/shared/knx-group-list/knx-group-list.component.less +++ b/src/main/angular/src/app/shared/knx-group-list/knx-group-list.component.less @@ -1,8 +1,6 @@ @import "../../../config"; .groupList { - overflow-y: auto; - height: 100%; .group { diff --git a/src/main/angular/src/app/shared/shutter-list/shutter-list.component.html b/src/main/angular/src/app/shared/shutter-list/shutter-list.component.html index c6dc03f..afca00c 100644 --- a/src/main/angular/src/app/shared/shutter-list/shutter-list.component.html +++ b/src/main/angular/src/app/shared/shutter-list/shutter-list.component.html @@ -1,6 +1,6 @@
-
+
diff --git a/src/main/angular/src/app/shared/shutter-list/shutter-list.component.less b/src/main/angular/src/app/shared/shutter-list/shutter-list.component.less index ed2051e..4102efb 100644 --- a/src/main/angular/src/app/shared/shutter-list/shutter-list.component.less +++ b/src/main/angular/src/app/shared/shutter-list/shutter-list.component.less @@ -1,8 +1,6 @@ @import "../../../config"; .shutterList { - overflow-y: auto; - height: 100%; .shutter { @@ -26,7 +24,7 @@ clear: right; float: right; - div { + .action { float: left; margin-left: @space; width: 3em; diff --git a/src/main/angular/src/app/shared/shutter-list/shutter-list.component.ts b/src/main/angular/src/app/shared/shutter-list/shutter-list.component.ts index 9255641..a5a4bd4 100644 --- a/src/main/angular/src/app/shared/shutter-list/shutter-list.component.ts +++ b/src/main/angular/src/app/shared/shutter-list/shutter-list.component.ts @@ -26,7 +26,7 @@ export class ShutterListComponent implements OnInit, OnDestroy { protected now: Date = new Date(); @Input() - shutterList: Shutter[] = []; + list: Shutter[] = []; constructor( protected readonly shutterService: ShutterService, diff --git a/src/main/angular/src/app/shared/tristate/tristate.component.html b/src/main/angular/src/app/shared/tristate/tristate.component.html new file mode 100644 index 0000000..6938981 --- /dev/null +++ b/src/main/angular/src/app/shared/tristate/tristate.component.html @@ -0,0 +1,10 @@ +
+
+
{{labelFalse}}
+
{{labelTrue}}
+
{{labelNull}}
+
+
+ {{ label }} +
+
diff --git a/src/main/angular/src/app/shared/tristate/tristate.component.less b/src/main/angular/src/app/shared/tristate/tristate.component.less new file mode 100644 index 0000000..d3f450c --- /dev/null +++ b/src/main/angular/src/app/shared/tristate/tristate.component.less @@ -0,0 +1,15 @@ +@import '../../../config'; + +.all { + white-space: nowrap; + + .box { + float: left; + width: 1.5em; + aspect-ratio: 1; + margin-right: @space; + text-align: center; + border: @border solid gray; + } + +} diff --git a/src/main/angular/src/app/shared/tristate/tristate.component.ts b/src/main/angular/src/app/shared/tristate/tristate.component.ts new file mode 100644 index 0000000..efc936a --- /dev/null +++ b/src/main/angular/src/app/shared/tristate/tristate.component.ts @@ -0,0 +1,44 @@ +import {Component, EventEmitter, Input, Output} from '@angular/core'; +import {NgIf} from '@angular/common'; + +@Component({ + selector: 'app-tristate', + standalone: true, + imports: [ + NgIf + ], + templateUrl: './tristate.component.html', + styleUrl: './tristate.component.less' +}) +export class TristateComponent { + + @Input() + label: string = ''; + + @Input() + labelFalse: string = 'J'; + + @Input() + labelTrue: string = 'N'; + + @Input() + labelNull: string = ''; + + @Input() + model: boolean | null = null; + + @Output() + modelChange: EventEmitter = new EventEmitter(); + + toggle() { + if (this.model === true) { + this.model = false; + } else if (this.model === false) { + this.model = null; + } else { + this.model = true; + } + this.modelChange.emit(this.model); + } + +} diff --git a/src/main/angular/src/app/shared/tunable-list/tunable-list.component.html b/src/main/angular/src/app/shared/tunable-list/tunable-list.component.html index 996d333..9c22ff2 100644 --- a/src/main/angular/src/app/shared/tunable-list/tunable-list.component.html +++ b/src/main/angular/src/app/shared/tunable-list/tunable-list.component.html @@ -1,6 +1,6 @@
-
+
diff --git a/src/main/angular/src/app/shared/tunable-list/tunable-list.component.less b/src/main/angular/src/app/shared/tunable-list/tunable-list.component.less index 6a1e25b..d15b542 100644 --- a/src/main/angular/src/app/shared/tunable-list/tunable-list.component.less +++ b/src/main/angular/src/app/shared/tunable-list/tunable-list.component.less @@ -1,8 +1,6 @@ @import "../../../config"; .tunableList { - overflow-y: auto; - height: 100%; .tunable { diff --git a/src/main/angular/src/app/shared/tunable-list/tunable-list.component.ts b/src/main/angular/src/app/shared/tunable-list/tunable-list.component.ts index 07b685f..86407bf 100644 --- a/src/main/angular/src/app/shared/tunable-list/tunable-list.component.ts +++ b/src/main/angular/src/app/shared/tunable-list/tunable-list.component.ts @@ -21,7 +21,7 @@ import {FormsModule} from '@angular/forms'; export class TunableListComponent implements OnInit, OnDestroy { @Input() - tunableList: Tunable[] = []; + list: Tunable[] = []; protected readonly Tunable = Tunable; diff --git a/src/main/angular/src/config.less b/src/main/angular/src/config.less index c9d004d..c79c629 100644 --- a/src/main/angular/src/config.less +++ b/src/main/angular/src/config.less @@ -61,6 +61,11 @@ } +.verticalScroll { + height: 100%; + overflow-y: auto; +} + @media (min-width: 1000px) { .tileContainer { diff --git a/src/main/java/de/ph87/home/device/DeviceFilter.java b/src/main/java/de/ph87/home/device/DeviceFilter.java index 36ff93b..9ab3f79 100644 --- a/src/main/java/de/ph87/home/device/DeviceFilter.java +++ b/src/main/java/de/ph87/home/device/DeviceFilter.java @@ -3,7 +3,6 @@ package de.ph87.home.device; import com.fasterxml.jackson.annotation.JsonProperty; import de.ph87.home.common.crud.AbstractSearchFilter; import de.ph87.home.property.PropertyTypeMismatch; -import jakarta.annotation.Nullable; import lombok.Getter; import lombok.NonNull; import lombok.ToString; @@ -12,27 +11,24 @@ import lombok.ToString; @ToString public class DeviceFilter extends AbstractSearchFilter { - @Nullable @JsonProperty - private Boolean stateNull; + private boolean stateNull; - @Nullable @JsonProperty - private Boolean stateTrue; + private boolean stateTrue; - @Nullable @JsonProperty - private Boolean stateFalse; + private boolean stateFalse; public boolean filter(@NonNull final DeviceDto dto) throws PropertyTypeMismatch { - if (stateNull != null && stateNull != (dto.getStateProperty() == null)) { - return false; - } final Boolean value = dto.getStateValue(); - if (stateTrue != null && (value == null || stateTrue != value)) { + if (!stateNull && value == null) { return false; } - if (stateFalse != null && (value == null || stateFalse == value)) { + if (!stateTrue && Boolean.TRUE.equals(value)) { + return false; + } + if (!stateFalse == Boolean.FALSE.equals(value)) { return false; } return search(dto.getName()); diff --git a/src/main/java/de/ph87/home/tunable/TunableFilter.java b/src/main/java/de/ph87/home/tunable/TunableFilter.java index 1204705..558cb8c 100644 --- a/src/main/java/de/ph87/home/tunable/TunableFilter.java +++ b/src/main/java/de/ph87/home/tunable/TunableFilter.java @@ -3,7 +3,6 @@ package de.ph87.home.tunable; import com.fasterxml.jackson.annotation.JsonProperty; import de.ph87.home.common.crud.AbstractSearchFilter; import de.ph87.home.property.PropertyTypeMismatch; -import jakarta.annotation.Nullable; import lombok.Getter; import lombok.NonNull; import lombok.ToString; @@ -12,27 +11,24 @@ import lombok.ToString; @ToString public class TunableFilter extends AbstractSearchFilter { - @Nullable @JsonProperty - private Boolean stateNull; + private boolean stateNull; - @Nullable @JsonProperty - private Boolean stateTrue; + private boolean stateTrue; - @Nullable @JsonProperty - private Boolean stateFalse; + private boolean stateFalse; public boolean filter(@NonNull final TunableDto dto) throws PropertyTypeMismatch { - if (stateNull != null && stateNull != (dto.getStateProperty() == null)) { - return false; - } final Boolean value = dto.getStateValue(); - if (stateTrue != null && (value == null || stateTrue != value)) { + if (!stateNull && value == null) { return false; } - if (stateFalse != null && (value == null || stateFalse == value)) { + if (!stateTrue && Boolean.TRUE.equals(value)) { + return false; + } + if (!stateFalse == Boolean.FALSE.equals(value)) { return false; } return search(dto.getName());