css generalized 'tile' (PropertyList)
This commit is contained in:
parent
e991b23479
commit
1c0ffc7b64
@ -72,6 +72,38 @@ export abstract class Device {
|
||||
return d => d.areaId === areaId && d.roomId === roomId;
|
||||
}
|
||||
|
||||
getSwitchClassList(): object {
|
||||
if (!(this instanceof DeviceSwitch)) {
|
||||
throw Error();
|
||||
}
|
||||
const value: number | null | undefined = (this as DeviceSwitch).stateProperty?.readChannel?.value;
|
||||
return {
|
||||
deviceSwitchOnBack: value === 1,
|
||||
deviceSwitchOffBack: value === 0,
|
||||
disabledBack: value === null || value === undefined,
|
||||
};
|
||||
}
|
||||
|
||||
getStateSceneClassList(): object {
|
||||
if (!(this instanceof DeviceStateScene)) {
|
||||
throw Error();
|
||||
}
|
||||
return this.getSwitchClassList();
|
||||
}
|
||||
|
||||
getShutterClassList(): object {
|
||||
if (!(this instanceof DeviceShutter)) {
|
||||
throw Error();
|
||||
}
|
||||
const value: number | null | undefined = (this as DeviceShutter).positionProperty?.readChannel?.value;
|
||||
return {
|
||||
deviceShutterOpenBack: value === 0,
|
||||
deviceShutterIntermediateBack: value !== null && value !== undefined && value > 0 && value < 100,
|
||||
deviceShutterClosedBack: value === 100,
|
||||
disabledBack: value === null || value === undefined,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class DeviceSwitch extends Device {
|
||||
|
||||
@ -1,8 +1,16 @@
|
||||
import {validateListOrEmpty, validateNumberNotNull, validateStringEmptyToNull, validateStringNotEmptyNotNull} from "../validators";
|
||||
import {undefinedOrNull, validateListOrEmpty, validateNumberNotNull, validateStringEmptyToNull, validateStringNotEmptyNotNull} from "../validators";
|
||||
import {Channel} from "../channel/Channel";
|
||||
import {SearchResult} from "../SearchResult";
|
||||
import {environment} from "../../../environments/environment";
|
||||
|
||||
export enum PropertyType {
|
||||
BOOLEAN = 'BOOLEAN',
|
||||
SHUTTER = 'SHUTTER',
|
||||
BRIGHTNESS_PERCENT = 'BRIGHTNESS_PERCENT',
|
||||
COLOR_TEMPERATURE = 'COLOR_TEMPERATURE',
|
||||
LUX = 'LUX',
|
||||
}
|
||||
|
||||
export class Property {
|
||||
|
||||
readonly hrefId: string | null;
|
||||
@ -11,7 +19,7 @@ export class Property {
|
||||
|
||||
constructor(
|
||||
public id: number,
|
||||
public type: string,
|
||||
public type: PropertyType,
|
||||
public title: string,
|
||||
public slug: string | null,
|
||||
public readChannel: Channel | null,
|
||||
@ -36,7 +44,7 @@ export class Property {
|
||||
static fromJson(json: any): Property {
|
||||
return new Property(
|
||||
validateNumberNotNull(json['id']),
|
||||
validateStringNotEmptyNotNull(json['type']),
|
||||
validateStringNotEmptyNotNull(json['type']) as PropertyType,
|
||||
validateStringNotEmptyNotNull(json['title']),
|
||||
validateStringEmptyToNull(json['slug']),
|
||||
Channel.fromJsonAllowNull(json['readChannel']),
|
||||
@ -63,4 +71,32 @@ export class Property {
|
||||
}
|
||||
return a.title.localeCompare(b.title);
|
||||
}
|
||||
|
||||
getStateClassList() {
|
||||
const value = this.readChannel?.value;
|
||||
switch (this.type) {
|
||||
case PropertyType.BOOLEAN:
|
||||
return {
|
||||
propertyStateBooleanUnknown: undefinedOrNull(value),
|
||||
propertyStateBooleanTrue: value > 0,
|
||||
propertyStateBooleanFalse: value === 0,
|
||||
};
|
||||
case PropertyType.SHUTTER:
|
||||
return {
|
||||
propertyStatePercentUnknown: undefinedOrNull(value),
|
||||
propertyStatePercentActive: value === 0,
|
||||
propertyStatePercentBetween: value > 0 && value < 100,
|
||||
propertyStatePercentInactive: value === 100,
|
||||
};
|
||||
case PropertyType.BRIGHTNESS_PERCENT:
|
||||
return {
|
||||
propertyStatePercentUnknown: undefinedOrNull(value),
|
||||
propertyStatePercentActive: value === 100,
|
||||
propertyStatePercentBetween: value > 0 && value < 100,
|
||||
propertyStatePercentInactive: value === 0,
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -87,3 +87,7 @@ export function validateMap<T>(json: any, valueFromJson: (json: any) => T): Map<
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
export function undefinedOrNull(value: any) {
|
||||
return value === undefined || value === null;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
<ng-container *ngFor="let device of devices; trackBy: Device.trackBy">
|
||||
|
||||
<div class="tile" *ngIf="device.type == 'DeviceSwitch'" [ngClass]="getSwitchClassList(device)">
|
||||
<div class="tile" *ngIf="device.type == 'DeviceSwitch'" [ngClass]="device.getSwitchClassList()">
|
||||
<div class="tileHead">
|
||||
<div class="flexGrow">
|
||||
<app-text [initial]="device.title" (valueChange)="set(device, 'title', $event)"></app-text>
|
||||
@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tile" *ngIf="device.type === 'DeviceStateScene'" [ngClass]="getStateSceneClassList(device)">
|
||||
<div class="tile" *ngIf="device.type === 'DeviceStateScene'" [ngClass]="device.getStateSceneClassList()">
|
||||
<div class="tileHead">
|
||||
<div class="flexGrow">
|
||||
<app-text [initial]="device.title" (valueChange)="set(device, 'title', $event)"></app-text>
|
||||
@ -33,7 +33,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tile" *ngIf="device.type === 'DeviceShutter'" [ngClass]="getShutterClassList(device)">
|
||||
<div class="tile" *ngIf="device.type === 'DeviceShutter'" [ngClass]="device.getShutterClassList()">
|
||||
<div class="tileHead">
|
||||
<div class="flexGrow">
|
||||
<app-text [initial]="device.title" (valueChange)="set(device, 'title', $event)"></app-text>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {DeviceService} from "../../../api/device/device.service";
|
||||
import {PropertyService} from "../../../api/property/property.service";
|
||||
import {Device, DeviceShutter, DeviceStateScene, DeviceSwitch} from "../../../api/device/Device";
|
||||
import {Device, DeviceStateScene} from "../../../api/device/Device";
|
||||
import {faEdit} from '@fortawesome/free-regular-svg-icons';
|
||||
import {Scene} from "../../../api/scene/Scene";
|
||||
import {SceneService} from "../../../api/scene/scene.service";
|
||||
@ -78,32 +78,9 @@ export class DeviceListComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
getSwitchClassList(device: Device): object {
|
||||
const value: number | null | undefined = (device as DeviceSwitch).stateProperty?.readChannel?.value;
|
||||
return {
|
||||
deviceSwitchOnBack: value === 1,
|
||||
deviceSwitchOffBack: value === 0,
|
||||
disabledBack: value === null || value === undefined,
|
||||
};
|
||||
}
|
||||
|
||||
getStateSceneClassList(device: Device): object {
|
||||
return this.getSwitchClassList(device);
|
||||
}
|
||||
|
||||
getShutterClassList(device: Device): object {
|
||||
const value: number | null | undefined = (device as DeviceShutter).positionProperty?.readChannel?.value;
|
||||
return {
|
||||
deviceShutterOpenBack: value === 0,
|
||||
deviceShutterIntermediateBack: value !== null && value !== undefined && value > 0 && value < 100,
|
||||
deviceShutterClosedBack: value === 100,
|
||||
disabledBack: value === null || value === undefined,
|
||||
};
|
||||
}
|
||||
|
||||
getStateScenes(d: Device): Scene[] {
|
||||
const device: DeviceStateScene = d as DeviceStateScene;
|
||||
return device.sceneNumbers.map(sceneNumber => this.scenes.find(scene => scene.number === sceneNumber)).filter(scene => scene !== undefined).map(s => s as Scene);
|
||||
getStateScenes(device: Device): Scene[] {
|
||||
const casted: DeviceStateScene = device as DeviceStateScene;
|
||||
return casted.sceneNumbers.map(sceneNumber => this.scenes.find(scene => scene.number === sceneNumber)).filter(scene => scene !== undefined).map(s => s as Scene);
|
||||
}
|
||||
|
||||
set(device: Device, key: string, value: any): void {
|
||||
|
||||
@ -2,49 +2,17 @@
|
||||
<td class="empty">-</td>
|
||||
</ng-template>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Bezeichnung</th>
|
||||
<th>Slug</th>
|
||||
<th>Typ</th>
|
||||
<th>Wert</th>
|
||||
<th>Zeitstempel</th>
|
||||
<th>Lesekanal</th>
|
||||
<th>Schreibkanal</th>
|
||||
<th>
|
||||
<fa-icon title="Löschen" [icon]="faTimes"></fa-icon>
|
||||
</th>
|
||||
</tr>
|
||||
<ng-container *ngFor="let property of properties.sort(Property.compareTypeThenTitle)">
|
||||
<tr>
|
||||
<div class="tiles">
|
||||
|
||||
<td>
|
||||
<div *ngFor="let list of listLists()">
|
||||
<div class="tile" *ngFor="let property of list">
|
||||
|
||||
<div class="tileHead" [ngClass]="property.getStateClassList()">
|
||||
<app-text [initial]="property.title" (valueChange)="edit(property, 'title', $event)"></app-text>
|
||||
<div class="links" *ngIf="property.type === 'BOOLEAN'">
|
||||
<div *ngIf="property.hrefId">{{property.hrefId}}0</div>
|
||||
<div *ngIf="property.hrefId">{{property.hrefId}}1</div>
|
||||
</div>
|
||||
<div class="links" *ngIf="property.type === 'SHUTTER'">
|
||||
<div *ngIf="property.hrefId">{{property.hrefId}}0</div>
|
||||
<div *ngIf="property.hrefId">{{property.hrefId}}90</div>
|
||||
<div *ngIf="property.hrefId">{{property.hrefId}}100</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<app-text [initial]="property.slug" (valueChange)="edit(property, 'slug', $event)"></app-text>
|
||||
<div class="links" *ngIf="property.type === 'BOOLEAN'">
|
||||
<div *ngIf="property.hrefSlug">{{property.hrefSlug}}0</div>
|
||||
<div *ngIf="property.hrefSlug">{{property.hrefSlug}}1</div>
|
||||
</div>
|
||||
<div class="links" *ngIf="property.type === 'SHUTTER'">
|
||||
<div *ngIf="property.hrefSlug">{{property.hrefSlug}}0</div>
|
||||
<div *ngIf="property.hrefSlug">{{property.hrefSlug}}90</div>
|
||||
<div *ngIf="property.hrefSlug">{{property.hrefSlug}}100</div>
|
||||
</div>
|
||||
</td>
|
||||
<div class="tileBody">
|
||||
|
||||
<td>
|
||||
<select [(ngModel)]="property.type" (ngModelChange)="edit(property, 'type', property.type)">
|
||||
<option value="BOOLEAN">Schalter</option>
|
||||
<option value="SHUTTER">Rollladen</option>
|
||||
@ -53,47 +21,21 @@
|
||||
<option value="LUX">Helligkeit [lux]</option>
|
||||
<option value="SCENE">Szene</option>
|
||||
</select>
|
||||
</td>
|
||||
|
||||
<ng-container *ngIf="property.readChannel?.value !== null else empty">
|
||||
<td *ngIf="property.type === 'BOOLEAN'" class="boolean" [class.true]="property.readChannel?.value" [class.false]="!property.readChannel?.value" (click)="edit(property, 'value', property.readChannel?.value > 0 ? 0 : 1)">
|
||||
{{property.readChannel?.value ? "An" : "Aus"}}
|
||||
</td>
|
||||
<td *ngIf="property.type === 'SHUTTER'" class="number" [class.true]="property.readChannel?.value === 0" [class.false]="property.readChannel?.value === 100" [class.tristate]="0 < property.readChannel?.value && property.readChannel?.value < 100">
|
||||
{{property.readChannel?.value}} %
|
||||
</td>
|
||||
<td *ngIf="property.type === 'BRIGHTNESS_PERCENT'" class="number">
|
||||
{{property.readChannel?.value}} %
|
||||
</td>
|
||||
<td *ngIf="property.type === 'COLOR_TEMPERATURE'" class="number">
|
||||
{{property.readChannel?.value}} K
|
||||
</td>
|
||||
<td *ngIf="property.type === 'LUX'" class="number">
|
||||
{{property.readChannel?.value | number:'0.0-0'}} lux
|
||||
</td>
|
||||
<td *ngIf="property.type === 'SCENE'">
|
||||
{{findScene(property)?.title || "Unbekannt: " + property.readChannel?.value}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<td *ngIf="property.readChannel?.timestamp !== null else empty">
|
||||
{{property.readChannel?.timestamp | date:'yyyy-MM-dd HH:mm:ss'}}
|
||||
</td>
|
||||
|
||||
<td class="full">
|
||||
<app-search [searchService]="channelService" [initial]="property.readChannel?.id" (valueChange)="set(property, 'readChannel', $event)"></app-search>
|
||||
</td>
|
||||
<td class="full">
|
||||
|
||||
<app-search [searchService]="channelService" [initial]="property.writeChannel?.id" (valueChange)="set(property, 'writeChannel', $event)"></app-search>
|
||||
</td>
|
||||
|
||||
<td class="delete">
|
||||
<div class="delete">
|
||||
<fa-icon title="Löschen" *ngIf="property.usages.length === 0" [icon]="faTimes" (click)="delete(property)"></fa-icon>
|
||||
</td>
|
||||
</div>
|
||||
|
||||
</tr>
|
||||
</ng-container>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="config">
|
||||
<button (click)="create()">+ Hinzufügen</button>
|
||||
|
||||
@ -1,8 +1,29 @@
|
||||
table {
|
||||
width: 100%;
|
||||
@import "../../../../config";
|
||||
|
||||
.propertyStateBooleanUnknown {
|
||||
background-color: @COLOR_UNKNOWN;
|
||||
}
|
||||
|
||||
.links {
|
||||
color: gray;
|
||||
font-size: 80%;
|
||||
.propertyStateBooleanTrue {
|
||||
background-color: @COLOR_ACTIVE;
|
||||
}
|
||||
|
||||
.propertyStateBooleanFalse {
|
||||
background-color: @COLOR_INACTIVE;
|
||||
}
|
||||
|
||||
.propertyStatePercentUnknown {
|
||||
background-color: @COLOR_UNKNOWN;
|
||||
}
|
||||
|
||||
.propertyStatePercentActive {
|
||||
background-color: @COLOR_ACTIVE;
|
||||
}
|
||||
|
||||
.propertyStatePercentBetween {
|
||||
background-color: @COLOR_BETWEEN;
|
||||
}
|
||||
|
||||
.propertyStatePercentInactive {
|
||||
background-color: @COLOR_INACTIVE;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Property} from "../../../api/property/Property";
|
||||
import {Property, PropertyType} from "../../../api/property/Property";
|
||||
import {PropertyService} from "../../../api/property/property.service";
|
||||
import {Scene} from "../../../api/scene/Scene";
|
||||
import {SceneService} from "../../../api/scene/scene.service";
|
||||
@ -14,16 +14,18 @@ import {environment} from 'src/environments/environment';
|
||||
})
|
||||
export class PropertyListComponent implements OnInit {
|
||||
|
||||
readonly environment = environment;
|
||||
|
||||
readonly faTimes = faTimesCircle;
|
||||
|
||||
protected booleans: Property[] = [];
|
||||
|
||||
protected shutters: Property[] = [];
|
||||
|
||||
Property = Property;
|
||||
|
||||
properties: Property[] = [];
|
||||
|
||||
scenes: Scene[] = [];
|
||||
|
||||
readonly environment = environment;
|
||||
|
||||
constructor(
|
||||
readonly propertyService: PropertyService,
|
||||
readonly sceneService: SceneService,
|
||||
@ -33,7 +35,10 @@ export class PropertyListComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.propertyService.findAll(properties => this.properties = properties, Property.compareTypeThenTitle);
|
||||
this.propertyService.findAll(properties => {
|
||||
this.booleans = properties.filter(p => p.type === PropertyType.BOOLEAN).sort(Property.compareTypeThenTitle);
|
||||
this.shutters = properties.filter(p => p.type === PropertyType.SHUTTER).sort(Property.compareTypeThenTitle);
|
||||
}, Property.compareTypeThenTitle);
|
||||
this.propertyService.subscribe(update => this.updateProperty(update.payload, update.existing));
|
||||
|
||||
this.sceneService.findAll(scenes => this.scenes = scenes, Scene.compareNumber);
|
||||
@ -49,15 +54,20 @@ export class PropertyListComponent implements OnInit {
|
||||
}
|
||||
|
||||
private updateProperty(property: Property, existing: boolean): void {
|
||||
const index: number = this.properties.findIndex(p => p.id === property.id);
|
||||
this.updateProperty2(this.booleans, property, existing);
|
||||
this.updateProperty2(this.shutters, property, existing);
|
||||
}
|
||||
|
||||
private updateProperty2(properties: Property[], property: Property, existing: boolean) {
|
||||
const index: number = properties.findIndex(p => p.id === property.id);
|
||||
if (index >= 0) {
|
||||
if (existing) {
|
||||
this.properties[index] = property;
|
||||
properties[index] = property;
|
||||
} else {
|
||||
this.properties.slice(index, 1);
|
||||
properties.slice(index, 1);
|
||||
}
|
||||
} else if (existing) {
|
||||
this.properties.push(property);
|
||||
properties.push(property);
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,8 +98,22 @@ export class PropertyListComponent implements OnInit {
|
||||
|
||||
delete(property: Property): void {
|
||||
if (confirm(`Eigenschaft "${property.title}" wirklich löschen?`)) {
|
||||
this.propertyService.delete(property, () => this.properties.splice(this.properties.findIndex(p => p.id === property.id), 1));
|
||||
this.propertyService.delete(property, () => {
|
||||
this.delete2(this.booleans, property);
|
||||
this.delete2(this.shutters, property);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private delete2(properties: Property[], property: Property) {
|
||||
const index = properties.findIndex(p => p.id === property.id);
|
||||
if (index >= 0) {
|
||||
properties.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
listLists(): Property[][] {
|
||||
return [this.shutters, this.booleans];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@
|
||||
|
||||
<div class="tileBodyFlex" *ngIf="entry.type === 'SUNRISE' || entry.type === 'SUNSET'">
|
||||
<div class="flexGrow sun">
|
||||
<div *ngFor="let zenith of getZenithEntries(entry.type); trackBy: trackByZenith">
|
||||
<div *ngFor="let zenith of getZenithEntries(entry.type)">
|
||||
<app-bool [label]="zenith.title" [value]="entry.zenith === zenith.value" (onChange)="entryService.set(entry, 'zenith', zenith.value)"></app-bool>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@ -16,6 +16,18 @@ import {faCheckCircle, faCircle, faTimesCircle} from "@fortawesome/free-regular-
|
||||
|
||||
const DAY_MINUTES: number = 24 * 60;
|
||||
|
||||
const ZENITH_ENTRIES: Zenith[] = [
|
||||
new Zenith("Astr.", 107, true, true),
|
||||
new Zenith("Naut.", 102, true, true),
|
||||
new Zenith("Bürg.", 96, true, true),
|
||||
new Zenith("Aufg.", 90.8, true, false),
|
||||
new Zenith("Unterg.", 90.8, false, true),
|
||||
];
|
||||
|
||||
const ZENITH_SUNRISE = ZENITH_ENTRIES.filter(zenith => zenith.sunrise);
|
||||
|
||||
const ZENITH_SUNSET = ZENITH_ENTRIES.filter(zenith => zenith.sunset).reverse();
|
||||
|
||||
@Component({
|
||||
selector: 'app-schedule-editor',
|
||||
templateUrl: './schedule-editor.component.html',
|
||||
@ -23,6 +35,12 @@ const DAY_MINUTES: number = 24 * 60;
|
||||
})
|
||||
export class ScheduleEditorComponent implements OnInit {
|
||||
|
||||
protected readonly faCheckCircle = faCheckCircle;
|
||||
|
||||
protected readonly faTimesCircle = faTimesCircle;
|
||||
|
||||
protected readonly faCircle = faCircle;
|
||||
|
||||
protected readonly ScheduleEntry = ScheduleEntry;
|
||||
|
||||
protected readonly Schedule = Schedule;
|
||||
@ -39,14 +57,6 @@ export class ScheduleEditorComponent implements OnInit {
|
||||
|
||||
protected bulks: Bulk[] = [];
|
||||
|
||||
protected readonly ZENITH_ENTRIES: Zenith[] = [
|
||||
new Zenith("Astr.", 107, true, true),
|
||||
new Zenith("Naut.", 102, true, true),
|
||||
new Zenith("Bürg.", 96, true, true),
|
||||
new Zenith("Aufg.", 90.8, true, false),
|
||||
new Zenith("Unterg.", 90.8, false, true),
|
||||
];
|
||||
|
||||
constructor(
|
||||
readonly router: Router,
|
||||
readonly activatedRoute: ActivatedRoute,
|
||||
@ -99,17 +109,6 @@ export class ScheduleEditorComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
getZenithEntries(type: string): Zenith[] {
|
||||
if (type === 'SUNRISE') {
|
||||
return this.ZENITH_ENTRIES.filter(zenith => zenith.sunrise);
|
||||
}
|
||||
return this.ZENITH_ENTRIES.reverse().filter(zenith => zenith.sunset);
|
||||
}
|
||||
|
||||
trackByZenith(index: number, zenith: Zenith) {
|
||||
return zenith.value;
|
||||
}
|
||||
|
||||
timeFromString(entry: ScheduleEntry, time: string) {
|
||||
const parts = time.split(':');
|
||||
const hour = parseInt(parts[0]);
|
||||
@ -119,7 +118,6 @@ export class ScheduleEditorComponent implements OnInit {
|
||||
second = parseInt(parts[2]);
|
||||
}
|
||||
const daySecond = (hour * 24 + minute) * 60 + second;
|
||||
console.log(hour, minute, second, daySecond);
|
||||
this.entryService.set(entry, 'daySecond', daySecond);
|
||||
}
|
||||
|
||||
@ -131,9 +129,11 @@ export class ScheduleEditorComponent implements OnInit {
|
||||
this.entryService.set(entry, 'daySecond', newMinutes * 60);
|
||||
}
|
||||
|
||||
protected readonly faCheckCircle = faCheckCircle;
|
||||
getZenithEntries(type: string) {
|
||||
if (type === 'SUNRISE') {
|
||||
return ZENITH_SUNRISE;
|
||||
}
|
||||
return ZENITH_SUNSET;
|
||||
}
|
||||
|
||||
protected readonly faCircle = faCircle;
|
||||
|
||||
protected readonly faTimesCircle = faTimesCircle;
|
||||
}
|
||||
|
||||
@ -7,9 +7,8 @@
|
||||
<ng-container *ngIf="!selected">-</ng-container>
|
||||
</div>
|
||||
|
||||
<div *ngIf="searching" class="resultList">
|
||||
<input #input type="text" *ngIf="searching" [(ngModel)]="term" (ngModelChange)="changed()" (keydown.enter)="doSearch()" (keydown.escape)="cancelSearch()" (focus)="cancelOnBlur=true" (blur)="blur()">
|
||||
|
||||
<div #resultList *ngIf="searching" class="resultList">
|
||||
<div *ngIf="allowEmpty" class="result" (mousedown)="dontCancelOnBlur()" (click)="select(undefined)">
|
||||
-
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
@import "../../../config";
|
||||
|
||||
.all {
|
||||
|
||||
.initial {
|
||||
padding: @padding;
|
||||
height: 100%;
|
||||
@ -12,7 +13,12 @@
|
||||
}
|
||||
|
||||
.resultList {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: lightgray;
|
||||
min-width: 10em;
|
||||
border: @border solid black;
|
||||
|
||||
@ -7,7 +7,7 @@ import {ISearchService} from "../../api/ISearchService";
|
||||
templateUrl: './search.component.html',
|
||||
styleUrls: ['./search.component.less']
|
||||
})
|
||||
export class SearchComponent<T> implements OnInit {
|
||||
export class SearchComponent implements OnInit {
|
||||
|
||||
private changedTimeout: number | undefined;
|
||||
|
||||
@ -19,9 +19,6 @@ export class SearchComponent<T> implements OnInit {
|
||||
@ViewChild('input')
|
||||
input?: HTMLInputElement;
|
||||
|
||||
@ViewChild('resultList')
|
||||
resultList?: HTMLDivElement;
|
||||
|
||||
@Input()
|
||||
searchService!: ISearchService;
|
||||
|
||||
@ -75,9 +72,6 @@ export class SearchComponent<T> implements OnInit {
|
||||
|
||||
start(): void {
|
||||
this.term = this.selected?.title || "";
|
||||
if (this.resultList && this.input) {
|
||||
this.resultList.style.left = this.input.style.left;
|
||||
}
|
||||
this.searching = true;
|
||||
setTimeout(() => this.input2?.nativeElement.focus(), 0);
|
||||
this.doSearch();
|
||||
|
||||
@ -3,12 +3,17 @@
|
||||
@border: 0.05em;
|
||||
@border-radius: 0.2em;
|
||||
|
||||
@COLOR_UNKNOWN: gray;
|
||||
@COLOR_ACTIVE: #8fbc8f;
|
||||
@COLOR_BETWEEN: #e4db9c;
|
||||
@COLOR_INACTIVE: #bc8f8f;
|
||||
|
||||
.disabledBack {
|
||||
background-color: gray;
|
||||
background-color: @COLOR_UNKNOWN;
|
||||
}
|
||||
|
||||
.enabledBack {
|
||||
background-color: #8fbc8f;
|
||||
background-color: @COLOR_ACTIVE;
|
||||
}
|
||||
|
||||
.skipBack {
|
||||
@ -28,21 +33,21 @@
|
||||
}
|
||||
|
||||
.deviceSwitchOnBack {
|
||||
background-color: #8fbc8f;
|
||||
background-color: @COLOR_ACTIVE;
|
||||
}
|
||||
|
||||
.deviceSwitchOffBack {
|
||||
background-color: #bc8f8f;
|
||||
background-color: @COLOR_INACTIVE;
|
||||
}
|
||||
|
||||
.deviceShutterOpenBack {
|
||||
background-color: #8fbc8f;
|
||||
background-color: @COLOR_ACTIVE;
|
||||
}
|
||||
|
||||
.deviceShutterIntermediateBack {
|
||||
background-color: #e4db9c;
|
||||
background-color: @COLOR_BETWEEN;
|
||||
}
|
||||
|
||||
.deviceShutterClosedBack {
|
||||
background-color: #bc8f8f;
|
||||
background-color: @COLOR_INACTIVE;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user