UI: tagList, tagConfirm

This commit is contained in:
Patrick Haßel 2024-11-29 09:43:36 +01:00
parent dc6d19a633
commit a9394efc11
12 changed files with 50 additions and 21 deletions

View File

@ -1,7 +1,8 @@
import {Property} from "../Property/Property";
import {orNull, validateString} from "../api/validators";
import {orNull, validateList, validateString} from "../api/validators";
import {Area} from '../Area/Area';
import {Thing} from '../Thing/Thing';
import {Tag} from '../Tag/Tag';
export class Device extends Thing {
@ -10,10 +11,11 @@ export class Device extends Thing {
uuid: string,
name: string,
slug: string,
tagList: Tag[],
readonly statePropertyId: string,
readonly stateProperty: Property | null,
) {
super(area, uuid, name, slug);
super(area, uuid, name, slug, tagList);
}
static fromJson(json: any): Device {
@ -22,6 +24,7 @@ export class Device extends Thing {
validateString(json.uuid),
validateString(json.name),
validateString(json.slug),
validateList(json.tagList, Tag.fromJson),
validateString(json.statePropertyId),
orNull(json.stateProperty, Property.fromJson),
);

View File

@ -1,14 +1,14 @@
<div class="tile">
<div class="tileInner device" [ngClass]="ngClass(device)">
<div class="tileInner device" [ngClass]="ngClass()">
<div class="name">
{{ device.nameWithArea }}
</div>
<div class="actions">
<div class="action switchOn" (click)="deviceService.setState(device, true)"></div>
<div class="action switchOff" (click)="deviceService.setState(device, false)"></div>
<div class="action switchOn" (click)="setState(true)"></div>
<div class="action switchOff" (click)="setState(false)"></div>
</div>
<div class="timestamp details">

View File

@ -28,11 +28,17 @@ export class DeviceTileComponent {
//
}
ngClass(device: Device) {
ngClass() {
return {
"stateOn": device.stateProperty?.state?.value === true,
"stateOff": device.stateProperty?.state?.value === false,
"stateOn": this.device.stateProperty?.state?.value === true,
"stateOff": this.device.stateProperty?.state?.value === false,
};
}
setState(newState: boolean) {
if (!this.device.hasTagBySlug('confirm') || confirm("Sicher?")) {
this.deviceService.setState(this.device, newState);
}
}
}

View File

@ -1,8 +1,9 @@
import {Property} from "../Property/Property";
import {orNull, validateString} from "../api/validators";
import {orNull, validateList, validateString} from "../api/validators";
import {Area} from '../Area/Area';
import {Thing} from '../Thing/Thing';
import {Tag} from '../Tag/Tag';
export class Shutter extends Thing {
@ -11,10 +12,11 @@ export class Shutter extends Thing {
uuid: string,
name: string,
slug: string,
tagList: Tag[],
readonly positionPropertyId: string,
readonly positionProperty: Property | null,
) {
super(area, uuid, name, slug);
super(area, uuid, name, slug, tagList);
}
static fromJson(json: any): Shutter {
@ -23,6 +25,7 @@ export class Shutter extends Thing {
validateString(json.uuid),
validateString(json.name),
validateString(json.slug),
validateList(json.tagList, Tag.fromJson),
validateString(json.positionPropertyId),
orNull(json.positionProperty, Property.fromJson),
);

View File

@ -4,6 +4,7 @@ export class Tag {
constructor(
readonly uuid: string,
readonly slug: string,
readonly name: string,
) {
//
@ -12,6 +13,7 @@ export class Tag {
static fromJson(json: any): Tag {
return new Tag(
validateString(json.uuid),
validateString(json.slug),
validateString(json.name),
);
}

View File

@ -1,4 +1,5 @@
import {Area} from '../Area/Area';
import {Tag} from '../Tag/Tag';
export abstract class Thing {
@ -7,6 +8,7 @@ export abstract class Thing {
readonly uuid: string,
readonly name: string,
readonly slug: string,
readonly tagList: Tag[],
) {
//
}
@ -25,6 +27,11 @@ export abstract class Thing {
return this.area.name + ' ' + this.name;
}
hasTagBySlug(slug: string): boolean {
const slugLower = slug.toLowerCase();
return this.tagList.some(t => t.slug.toLocaleLowerCase() === slugLower);
}
static trackBy(index: number, thing: Thing) {
return thing.uuid;
}

View File

@ -1,7 +1,8 @@
import {Property} from "../Property/Property";
import {orNull, validateString} from "../api/validators";
import {orNull, validateList, validateString} from "../api/validators";
import {Area} from '../Area/Area';
import {Thing} from '../Thing/Thing';
import {Tag} from '../Tag/Tag';
export class Tunable extends Thing {
@ -10,6 +11,7 @@ export class Tunable extends Thing {
uuid: string,
name: string,
slug: string,
tagList: Tag[],
readonly statePropertyId: string,
readonly stateProperty: Property | null,
readonly brightnessPropertyId: string,
@ -17,7 +19,7 @@ export class Tunable extends Thing {
readonly coldnessPropertyId: string,
readonly coldnessProperty: Property | null,
) {
super(area, uuid, name, slug);
super(area, uuid, name, slug, tagList);
}
static fromJson(json: any): Tunable {
@ -26,6 +28,7 @@ export class Tunable extends Thing {
validateString(json.uuid),
validateString(json.name),
validateString(json.slug),
validateList(json.tagList, Tag.fromJson),
validateString(json.statePropertyId),
orNull(json.stateProperty, Property.fromJson),
validateString(json.brightnessPropertyId),

View File

@ -3,6 +3,7 @@
<div class="item itemLeft" routerLink="Dashboard" routerLinkActive="active">Dash</div>
<div class="item itemLeft" routerLink="ThingList/device" routerLinkActive="active">Geräte</div>
<div class="item itemLeft" routerLink="ThingList/light" routerLinkActive="active">Licht</div>
<div class="item itemLeft" routerLink="ThingList/decoration" routerLinkActive="active">Deko</div>
<div class="item itemLeft" routerLink="ThingList/shutter" routerLinkActive="active">Rollladen</div>
<div class="item itemRight" routerLink="GroupList" routerLinkActive="active">KNX</div>
</div>

View File

@ -3,7 +3,7 @@ package de.ph87.home.device;
import de.ph87.home.area.AreaDto;
import de.ph87.home.property.PropertyDto;
import de.ph87.home.property.PropertyTypeMismatch;
import de.ph87.home.tag.Tag;
import de.ph87.home.tag.TagDto;
import de.ph87.home.web.IWebSocketMessage;
import jakarta.annotation.Nullable;
import lombok.Getter;
@ -39,7 +39,7 @@ public class DeviceDto implements IWebSocketMessage {
private final PropertyDto<Boolean> stateProperty;
@NonNull
private final List<String> tagList;
private final List<TagDto> tagList;
public DeviceDto(@NonNull final Device device, @Nullable final PropertyDto<Boolean> stateProperty) {
this.area = new AreaDto(device.getArea());
@ -48,7 +48,7 @@ public class DeviceDto implements IWebSocketMessage {
this.slug = device.getSlug();
this.statePropertyId = device.getStatePropertyId();
this.stateProperty = stateProperty;
this.tagList = device.getTagList().stream().map(Tag::getName).toList();
this.tagList = device.getTagList().stream().map(TagDto::new).toList();
}
@Nullable

View File

@ -3,7 +3,7 @@ package de.ph87.home.shutter;
import de.ph87.home.area.AreaDto;
import de.ph87.home.property.PropertyDto;
import de.ph87.home.property.PropertyTypeMismatch;
import de.ph87.home.tag.Tag;
import de.ph87.home.tag.TagDto;
import de.ph87.home.web.IWebSocketMessage;
import jakarta.annotation.Nullable;
import lombok.Getter;
@ -39,7 +39,7 @@ public class ShutterDto implements IWebSocketMessage {
private final PropertyDto<Double> positionProperty;
@NonNull
private final List<String> tagList;
private final List<TagDto> tagList;
public ShutterDto(@NonNull final Shutter shutter, @Nullable final PropertyDto<Double> positionProperty) {
this.area = new AreaDto(shutter.getArea());
@ -48,7 +48,7 @@ public class ShutterDto implements IWebSocketMessage {
this.slug = shutter.getSlug();
this.positionPropertyId = shutter.getPositionPropertyId();
this.positionProperty = positionProperty;
this.tagList = shutter.getTagList().stream().map(Tag::getName).toList();
this.tagList = shutter.getTagList().stream().map(TagDto::new).toList();
}
@Nullable

View File

@ -9,11 +9,15 @@ public class TagDto {
@NonNull
private final String uuid;
@NonNull
private final String slug;
@NonNull
private final String name;
public TagDto(@NonNull final Tag tag) {
this.uuid = tag.getUuid();
this.slug = tag.getSlug();
this.name = tag.getName();
}

View File

@ -3,7 +3,7 @@ package de.ph87.home.tunable;
import de.ph87.home.area.AreaDto;
import de.ph87.home.property.PropertyDto;
import de.ph87.home.property.PropertyTypeMismatch;
import de.ph87.home.tag.Tag;
import de.ph87.home.tag.TagDto;
import de.ph87.home.web.IWebSocketMessage;
import jakarta.annotation.Nullable;
import lombok.Getter;
@ -53,7 +53,7 @@ public class TunableDto implements IWebSocketMessage {
private final PropertyDto<Double> coldnessProperty;
@NonNull
private final List<String> tagList;
private final List<TagDto> tagList;
public TunableDto(@NonNull final Tunable tunable, @Nullable final PropertyDto<Boolean> stateProperty, @Nullable final PropertyDto<Double> brightnessProperty, @Nullable final PropertyDto<Double> coldnessProperty) {
this.area = new AreaDto(tunable.getArea());
@ -66,7 +66,7 @@ public class TunableDto implements IWebSocketMessage {
this.stateProperty = stateProperty;
this.brightnessProperty = brightnessProperty;
this.coldnessProperty = coldnessProperty;
this.tagList = tunable.getTagList().stream().map(Tag::getName).toList();
this.tagList = tunable.getTagList().stream().map(TagDto::new).toList();
}
@Nullable