css generalized 'tile' (DeviceList)

This commit is contained in:
Patrick Haßel 2024-09-11 15:00:56 +02:00
parent 073c42002a
commit 44820f3201
15 changed files with 135 additions and 163 deletions

View File

@ -5,6 +5,8 @@ spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
#-
spring.jackson.serialization.indent_output=true
#-
spring.jpa.hibernate.ddl-auto=create
#-
de.ph87.homeautomation.insert-demo-data=true

View File

@ -8,10 +8,6 @@
Rollläden
</div>
<!-- <div class="item" [routerLink]="['/DeviceList', {'type': 'DeviceStateScene'}]" [class.itemActive]="isRouteActive('/DeviceList', 'DeviceStateScene')">-->
<!-- Gruppen-->
<!-- </div>-->
<div class="item" routerLink="/BulkList" routerLinkActive="itemActive">
Stapel
</div>
@ -21,11 +17,11 @@
</div>
<div class="item itemSecondary" routerLink="/PropertyList" routerLinkActive="itemActive">
Eigenschaften
P
</div>
<div class="item itemSecondary" routerLink="/ChannelList" routerLinkActive="itemActive">
Kanäle
C
</div>
</div>

View File

@ -1,15 +1,17 @@
@import "../config";
.menubar {
border-bottom: 1px solid black;
border-bottom: @border solid black;
.item {
float: left;
padding: 10px;
border-right: 1px solid black;
padding: @padding;
border-right: @border solid black;
}
.itemSecondary {
float: right;
border-left: 1px solid black;
border-left: @border solid black;
border-right: none;
}

View File

@ -1,76 +1,84 @@
<div class="tiles">
<ng-container *ngFor="let device of devices; trackBy: Device.trackBy">
<ng-container [ngSwitch]="device.type">
<div class="device" *ngSwitchCase="'DeviceSwitch'" [ngClass]="getSwitchClassList(device)">
<div class="tileHeadTitle">
<div class="tile" *ngIf="device.type == 'DeviceSwitch'" [ngClass]="getSwitchClassList(device)">
<div class="tileHead">
<div class="flexGrow">
<app-text [initial]="device.title" (valueChange)="set(device, 'title', $event)"></app-text>
</div>
<div class="edit" [routerLink]="['/Device', {id: device.id}]">
<div class="tileHeadRight" [routerLink]="['/Device', {id: device.id}]">
<fa-icon [icon]="faEdit"></fa-icon>
</div>
<div class="controls">
<img alt="An" class="control" src="../../../../assets/switch-on.svg" (click)="deviceService.setSwitchState(device, true)"/>
<img alt="Aus" class="control" src="../../../../assets/switch-off.svg" (click)="deviceService.setSwitchState(device, false)"/>
</div>
<div class="tileBody">
<img alt="An" class="control" src="assets/switch-on.svg" (click)="deviceService.setSwitchState(device, true)"/>
<img alt="Aus" class="control" src="assets/switch-off.svg" (click)="deviceService.setSwitchState(device, false)"/>
</div>
</div>
<div class="device" *ngSwitchCase="'DeviceStateScene'" [ngClass]="getStateSceneClassList(device)">
<div class="tileHeadTitle">
<div class="tile" *ngIf="device.type === 'DeviceStateScene'" [ngClass]="getStateSceneClassList(device)">
<div class="tileHead">
<div class="flexGrow">
<app-text [initial]="device.title" (valueChange)="set(device, 'title', $event)"></app-text>
</div>
<div class="edit" [routerLink]="['/Device', {id: device.id}]">
<div class="tileHeadRight" [routerLink]="['/Device', {id: device.id}]">
<fa-icon [icon]="faEdit"></fa-icon>
</div>
<div class="controls">
<div *ngFor="let scene of getStateScenes(device)" class="control button" (click)="deviceService.setStateScene(device, scene.number)">
<span class="center">{{scene.title}}</span>
</div>
<div class="tileBody">
<div class="control" *ngFor="let scene of getStateScenes(device)" (click)="deviceService.setStateScene(device, scene.number)">
{{ scene.title }}
</div>
</div>
</div>
<div class="device" *ngSwitchCase="'DeviceShutter'" [ngClass]="getShutterClassList(device)">
<div class="tileHeadTitle">
<div class="tile" *ngIf="device.type === 'DeviceShutter'" [ngClass]="getShutterClassList(device)">
<div class="tileHead">
<div class="flexGrow">
<app-text [initial]="device.title" (valueChange)="set(device, 'title', $event)"></app-text>
</div>
<div class="edit" [routerLink]="['/Device', {id: device.id}]">
<div class="tileHeadRight" [routerLink]="['/Device', {id: device.id}]">
<fa-icon [icon]="faEdit"></fa-icon>
</div>
<div class="controls">
<div class="control button" (click)="deviceService.setShutterPosition(device, 0)">
<span class="center">Auf</span>
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 20)">
<span class="center">20%</span>
<div class="tileBody">
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 0)">
Auf
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 30)">
<span class="center">30%</span>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 20)">
20%
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 40)">
<span class="center">40%</span>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 30)">
30%
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 50)">
<span class="center">50%</span>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 40)">
40%
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 60)">
<span class="center">60%</span>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 50)">
50%
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 70)">
<span class="center">70%</span>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 60)">
60%
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 80)">
<span class="center">80%</span>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 70)">
70%
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 90)">
<span class="center">90%</span>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 80)">
80%
</div>
<div class="control button" (click)="deviceService.setShutterPosition(device, 100)">
<span class="center">Zu</span>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 90)">
90%
</div>
<div class="control controlShutter" (click)="deviceService.setShutterPosition(device, 100)">
Zu
</div>
</div>
</div>
</ng-container>
</ng-container>
</div>
<div class="config">
<button (click)="create()">+ Hinzufügen</button>

View File

@ -1,71 +1,17 @@
.device {
padding: 5px;
margin-bottom: 5px;
border-radius: 10px;
@media (min-width: 1000px) {
float: left;
width: 400px;
margin-right: 5px;
}
.tileHeadTitle {
float: left;
font-weight: bold;
}
.edit {
float: right;
}
.controls {
clear: both;
@import "../../../../config";
.control {
position: relative;
float: left;
width: 60px;
height: 60px;
padding: 5px;
margin: 5px;
width: 4em;
aspect-ratio: 1;
margin: @margin;
border-radius: 25%;
}
.button {
background-color: lightblue;
}
.control:hover {
background-color: lightskyblue;
}
}
}
.switchOn {
background-color: palegreen;
}
.switchOff {
background-color: indianred;
}
.switchUnknown {
background-color: gray;
}
.shutterOpen {
background-color: palegreen;
}
.shutterBetween {
background-color: yellow;
}
.shutterClosed {
background-color: indianred;
}
.shutterUnknown {
background-color: gray;
.controlShutter {
width: 17.3%;
padding-top: 1.1em;
text-align: center;
margin: calc(@margin / 2);
background-color: lightsteelblue;
}

View File

@ -81,9 +81,9 @@ export class DeviceListComponent implements OnInit {
getSwitchClassList(device: Device): object {
const value: number | null | undefined = (device as DeviceSwitch).stateProperty?.readChannel?.value;
return {
switchOn: value === 1,
switchOff: value === 0,
switchUnknown: value === null || value === undefined,
deviceSwitchOnBack: value === 1,
deviceSwitchOffBack: value === 0,
disabledBack: value === null || value === undefined,
};
}
@ -94,10 +94,10 @@ export class DeviceListComponent implements OnInit {
getShutterClassList(device: Device): object {
const value: number | null | undefined = (device as DeviceShutter).positionProperty?.readChannel?.value;
return {
shutterOpen: value === 0,
shutterBetween: value !== null && value !== undefined && value > 0 && value < 100,
shutterClosed: value === 100,
shutterUnknown: value === null || value === undefined,
deviceShutterOpenBack: value === 0,
deviceShutterIntermediateBack: value !== null && value !== undefined && value > 0 && value < 100,
deviceShutterClosedBack: value === 100,
disabledBack: value === null || value === undefined,
};
}

View File

@ -13,12 +13,15 @@
<fa-icon *ngIf="entry.enabled" [icon]="faCheckCircle"></fa-icon>
<fa-icon *ngIf="!entry.enabled" [icon]="faCircle"></fa-icon>
</div>
<div class="tileHeadTitle">
<div class="flexGrow">
<select [ngModel]="entry.bulk?.id" (ngModelChange)="entryService.set(entry, 'bulk', $event)">
<option [ngValue]="null">-</option>
<option [ngValue]="bulk.id" *ngFor="let bulk of bulks.sort(Bulk.compareName)">{{ bulk.name }}</option>
</select>
</div>
<div class="tileHeadDelete">
<fa-icon [icon]="faTimesCircle" (click)="delete(entry)"></fa-icon>
</div>
</div>
<div class="tileBodyFlex">
@ -116,4 +119,8 @@
</div>
<div class="config">
<button (click)="create()">+ Hinzufügen</button>
</div>
</ng-container>

View File

@ -12,7 +12,7 @@ import {Bulk} from "../../../api/bulk/Bulk";
import {BulkService} from "../../../api/bulk/BulkService";
import {Zenith} from "../../../api/schedule/entry/Zenith";
import {TimeService} from "../../../api/time.service";
import {faCheckCircle, faCircle} from "@fortawesome/free-regular-svg-icons";
import {faCheckCircle, faCircle, faTimesCircle} from "@fortawesome/free-regular-svg-icons";
const DAY_MINUTES: number = 24 * 60;
@ -134,4 +134,6 @@ export class ScheduleEditorComponent implements OnInit {
protected readonly faCheckCircle = faCheckCircle;
protected readonly faCircle = faCircle;
protected readonly faTimesCircle = faTimesCircle;
}

View File

@ -9,7 +9,7 @@
<fa-icon *ngIf="!schedule.enabled" [icon]="faCircle"></fa-icon>
</div>
<div class="tileHeadTitle" [routerLink]="['/Schedule', {id: schedule.id}]">
<div class="flexGrow" [routerLink]="['/Schedule', {id: schedule.id}]">
{{ schedule.title }}
</div>

View File

@ -1,7 +1,9 @@
@import "../../../config";
input {
outline: none;
border: none;
padding: 5px;
padding: @padding;
margin: 0;
width: 100%;
background-color: transparent;

View File

@ -1,22 +1,24 @@
@import "../../../config";
.all {
.initial {
padding: 5px;
padding: @padding;
height: 100%;
}
.selected {
font-weight: bold;
border-bottom: 1px solid black;
border-bottom: @border solid black;
}
.resultList {
position: absolute;
background-color: lightgray;
min-width: 200px;
border: 1px solid black;
min-width: 10em;
border: @border solid black;
.result {
padding: 5px;
padding: @padding;
}
.result:hover {

View File

@ -3,18 +3,10 @@
@border: 0.05em;
@border-radius: 0.2em;
.disabledFont {
color: gray;
}
.disabledBack {
background-color: gray;
}
.enabledFont {
color: #8fbc8f;
}
.enabledBack {
background-color: #8fbc8f;
}
@ -34,3 +26,23 @@
.fuzzyBack {
background-color: #88c0ff;
}
.deviceSwitchOnBack {
background-color: #8fbc8f;
}
.deviceSwitchOffBack {
background-color: #bc8f8f;
}
.deviceShutterOpenBack {
background-color: #8fbc8f;
}
.deviceShutterIntermediateBack {
background-color: #e4db9c;
}
.deviceShutterClosedBack {
background-color: #bc8f8f;
}

View File

@ -1,3 +1,5 @@
@import "config";
* {
box-sizing: border-box;
}
@ -54,11 +56,11 @@ table {
td, th {
height: 0; // (=> auto growth) enables use of height percent for children
padding: 5px;
border: 1px solid black;
padding: @padding;
border: @border solid black;
img.fullCell {
margin: -5px;
margin: calc(-@margin);
}
}
@ -70,14 +72,6 @@ table.vertical {
}
}
.center {
position: absolute;
margin: 0;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.empty {
text-align: center;
color: gray;

View File

@ -1,5 +1,6 @@
package de.ph87.homeautomation.web;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
@ -27,7 +28,7 @@ public class WebConfig implements WebMvcConfigurer {
.addResourceLocations("classpath:/resources/")
.resourceChain(true)
.addResolver(new PathResourceResolver() {
protected Resource getResource(String resourcePath, Resource roomLocation) throws IOException {
protected Resource getResource(@NonNull String resourcePath, @NonNull Resource roomLocation) throws IOException {
Resource requestedResource = roomLocation.createRelative(resourcePath);
return requestedResource.exists() && requestedResource.isReadable() ? requestedResource : new ClassPathResource("/resources/index.html");
}

View File

@ -5,6 +5,4 @@ spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.Im
spring.jpa.hibernate.ddl-auto=update
spring.jpa.open-in-view=false
#-
spring.jackson.serialization.indent_output=true
#-
spring.main.banner-mode=off