Deploy FIX, Java 17, Angular update, renaming Bulk

This commit is contained in:
Patrick Haßel 2022-10-25 11:00:55 +02:00
parent 82e8aa1712
commit af62576e14
39 changed files with 15318 additions and 7134 deletions

76
pom.xml
View File

@ -36,21 +36,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
@ -64,7 +54,7 @@
<dependency>
<groupId>com.github.calimero</groupId>
<artifactId>calimero-core</artifactId>
<version>2.5-rc1</version>
<version>2.5</version>
</dependency>
<dependency>
<groupId>com.luckycatlabs</groupId>
@ -72,55 +62,63 @@
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.10.3</version>
<configuration>
<workingDirectory>src/main/angular</workingDirectory>
</configuration>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>install-node-and-npm</id>
<id>npm-install</id>
<phase>generate-sources</phase>
<goals>
<goal>install-node-and-npm</goal>
<goal>exec</goal>
</goals>
<configuration>
<nodeVersion>v14.15.5</nodeVersion>
<workingDirectory>${project.basedir}/src/main/angular</workingDirectory>
<executable>npm</executable>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>npm install</id>
<id>ng-build</id>
<phase>generate-sources</phase>
<goals>
<goal>npm</goal>
<goal>exec</goal>
</goals>
<configuration>
<arguments>install</arguments>
<workingDirectory>${project.basedir}/src/main/angular</workingDirectory>
<executable>ng</executable>
<arguments>
<argument>build</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>npm build</id>
<phase>generate-resources</phase>
<id>deploy</id>
<phase>install</phase>
<goals>
<goal>npm</goal>
<goal>exec</goal>
</goals>
<configuration>
<arguments>run build</arguments>
<workingDirectory>${project.basedir}</workingDirectory>
<executable>/bin/bash</executable>
<arguments>
<argument>./upload.sh</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
@ -145,15 +143,15 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<release>11</release>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -14,4 +14,3 @@ last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

View File

@ -1,24 +1,18 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
### PATRICK
/node
### END
# compiled output
# Compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
# Node
/node_modules
# profiling files
chrome-profiler-events*.json
npm-debug.log
yarn-error.log
# IDEs and editors
/.idea
.idea/
.project
.classpath
.c9/
@ -26,7 +20,7 @@ chrome-profiler-events*.json
.settings/
*.sublime-workspace
# IDE - VSCode
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
@ -34,16 +28,15 @@ chrome-profiler-events*.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
# System files
.DS_Store
Thumbs.db

View File

@ -1,10 +1,10 @@
# Angular
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.0.
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.2.6.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
## Code scaffolding

View File

@ -7,10 +7,29 @@
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "less"
"style": "less",
"skipTests": true
},
"@schematics/angular:application": {
"strict": true
"@schematics/angular:class": {
"skipTests": true
},
"@schematics/angular:directive": {
"skipTests": true
},
"@schematics/angular:guard": {
"skipTests": true
},
"@schematics/angular:interceptor": {
"skipTests": true
},
"@schematics/angular:pipe": {
"skipTests": true
},
"@schematics/angular:resolver": {
"skipTests": true
},
"@schematics/angular:service": {
"skipTests": true
}
},
"root": "",
@ -106,6 +125,5 @@
}
}
}
},
"defaultProject": "angular"
}
}

View File

@ -2,5 +2,43 @@
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set();
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/angular'),
subdir: '.',
reporters: [
{type: 'html'},
{type: 'text-summary'}
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

File diff suppressed because it is too large Load Diff

View File

@ -4,40 +4,38 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --base-href /Homeautomation/",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "~12.2.0",
"@angular/common": "~12.2.0",
"@angular/compiler": "~12.2.0",
"@angular/core": "~12.2.0",
"@angular/forms": "~12.2.0",
"@angular/platform-browser": "~12.2.0",
"@angular/platform-browser-dynamic": "~12.2.0",
"@angular/router": "~12.2.0",
"@fortawesome/angular-fontawesome": "^0.9.0",
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-regular-svg-icons": "^5.15.4",
"rxjs": "~6.6.0",
"@angular/animations": "^14.2.0",
"@angular/common": "^14.2.0",
"@angular/compiler": "^14.2.0",
"@angular/core": "^14.2.0",
"@angular/forms": "^14.2.0",
"@angular/platform-browser": "^14.2.0",
"@angular/platform-browser-dynamic": "^14.2.0",
"@angular/router": "^14.2.0",
"@fortawesome/angular-fontawesome": "^0.11.1",
"@fortawesome/free-regular-svg-icons": "^6.2.0",
"@stomp/stompjs": "^6.1.2",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4",
"@stomp/stompjs": "^6.0.0"
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~12.2.0",
"@angular/cli": "~12.2.0",
"@angular/compiler-cli": "~12.2.0",
"@types/jasmine": "~3.8.0",
"@types/node": "^12.11.1",
"jasmine-core": "~3.8.0",
"karma": "~6.3.0",
"@angular-devkit/build-angular": "^14.2.6",
"@angular/cli": "~14.2.6",
"@angular/compiler-cli": "^14.2.0",
"@types/jasmine": "~4.0.0",
"jasmine-core": "~4.3.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.3.5"
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0",
"typescript": "~4.7.2"
}
}

View File

@ -68,8 +68,11 @@ export abstract class Channel {
export class KnxGroup extends Channel {
readonly addresMain: number;
readonly addresMid: number;
readonly addresSub: number;
readonly dpt: string;
constructor(

View File

@ -108,7 +108,7 @@ export class DeviceStateScene extends DeviceSwitch {
super(id, position, areaId, roomId, title, type, stateProperty);
}
updateProperty(property: Property): void {
override updateProperty(property: Property): void {
super.updateProperty(property);
if (this.sceneProperty?.id === property.id) {
this.sceneProperty = property;

View File

@ -1,35 +0,0 @@
import {TestBed} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {AppComponent} from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'angular'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('angular');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('angular app is running!');
});
});

View File

@ -1,5 +1,7 @@
<ng-container *ngIf="bulk">
<h1>{{bulk.name}}</h1>
<h1>
<app-edit-field [initial]="bulk.name" (valueChange)="set(bulk, 'name', $event)"></app-edit-field>
</h1>
<table>
<tr>
<th>Eigenschaft</th>

View File

@ -34,6 +34,10 @@ export class BulkComponent implements OnInit {
});
}
set(bulk: Bulk, property: string, value: any): void {
this.bulkService.set(bulk, property, value, result => this.bulk = result);
}
setEntry(entry: BulkEntry, property: string, value: any): void {
this.bulkService.setEntry(entry, property, value, result => this.update(result));
}

View File

@ -60,7 +60,6 @@ export class DeviceAllListComponent implements OnInit {
}
}
private updateScene(scene: Scene, existing: boolean): void {
const index: number = this.scenes.findIndex(p => p.id === scene.id);
if (index >= 0) {

View File

@ -32,7 +32,7 @@ export class DeviceComponent implements OnInit {
ngOnInit(): void {
this.dataService.device = undefined;
this.activatedRoute.params.subscribe(params => this.deviceService.getById(params.id, device => this.setDevice(device)));
this.activatedRoute.params.subscribe(params => this.deviceService.getById(params['id'], device => this.setDevice(device)));
}
private setDevice(device: Device): void {

View File

@ -12,6 +12,7 @@ import {STUB_AREAS, STUB_DEVICES} from "../../../../api/STUB";
export class AreaListComponent implements OnInit {
readonly faArrowAltCircleRight = faArrowAltCircleRight;
readonly faPlayCircle = faPlayCircle;
areas: Area[] = STUB_AREAS.sort(Area.comparePosition);

View File

@ -13,9 +13,13 @@ import {Room} from "../../../../api/room/Room";
export class DeviceListComponent implements OnInit {
readonly faArrowAltCircleLeft = faArrowAltCircleLeft;
readonly faArrowAltCircleRight = faArrowAltCircleRight;
readonly faPlayCircle = faPlayCircle;
readonly faCheckCircle = faCheckCircle;
readonly faTimesCircle = faTimesCircle;
room?: Room;

View File

@ -14,7 +14,9 @@ import {Area} from "../../../../api/area/Area";
export class RoomListComponent implements OnInit {
readonly faArrowAltCircleLeft = faArrowAltCircleLeft;
readonly faArrowAltCircleRight = faArrowAltCircleRight;
readonly faPlayCircle = faPlayCircle;
area?: Area;

View File

@ -11,7 +11,9 @@ import {faCheckCircle, faCircle, faTimesCircle} from '@fortawesome/free-regular-
export class ScheduleListComponent implements OnInit {
readonly faCheckCircle = faCheckCircle;
readonly faCircle = faCircle;
readonly faTimes = faTimesCircle;
readonly Schedule = Schedule;

View File

@ -45,7 +45,7 @@ export class ScheduleComponent implements OnInit {
ngOnInit(): void {
this.dataService.schedule = undefined;
this.sceneService.findAll(scenes => this.scenes = scenes);
this.activatedRoute.params.subscribe(params => this.scheduleService.getById(params.id, schedule => this.setSchedule(schedule)));
this.activatedRoute.params.subscribe(params => this.scheduleService.getById(params['id'], schedule => this.setSchedule(schedule)));
}
private setSchedule(schedule: Schedule): void {

View File

@ -1,4 +1,4 @@
<input #input *ngIf="editing" type="text" [(ngModel)]="value" (keypress)="keypress($event)" (blur)="finish()">
<input #input *ngIf="editing" type="text" [(ngModel)]="value" (keydown.enter)="finish()" (blur)="finish()">
<div *ngIf="!editing" [class.empty]="initial == ''" (click)="start()">
<ng-container *ngIf="initial != ''">{{initial}}</ng-container>
<ng-container *ngIf="initial == ''">-</ng-container>

View File

@ -1,25 +0,0 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {EditFieldComponent} from './edit-field.component';
describe('EditFieldComponent', () => {
let component: EditFieldComponent;
let fixture: ComponentFixture<EditFieldComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [EditFieldComponent]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(EditFieldComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -36,12 +36,6 @@ export class EditFieldComponent implements OnInit {
}
}
keypress($event: KeyboardEvent): void {
if ($event.key == "Enter") {
this.finish();
}
}
start(): void {
this.editing = true;
setTimeout(() => this.input?.nativeElement.focus(), 0);

View File

@ -1 +1 @@
<input type="number" [style]="{width: width}" [(ngModel)]="value" (change)="update()" (blur)="update()" (keypress)="$event.key === 'Enter' ? update() : {}">
<input type="number" [style]="{width: width}" [(ngModel)]="value" (change)="update()" (blur)="update()" (keydown.enter)="update()">

View File

@ -1,25 +0,0 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {NumberComponent} from './number.component';
describe('NumberComponent', () => {
let component: NumberComponent;
let fixture: ComponentFixture<NumberComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [NumberComponent]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(NumberComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -7,7 +7,7 @@
<ng-container *ngIf="!selected">-</ng-container>
</div>
<input #input type="text" *ngIf="searching" [(ngModel)]="term" (ngModelChange)="changed()" (keydown)="inputKeyPress($event)" (focus)="cancelOnBlur=true" (blur)="blur()">
<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)">

View File

@ -1,25 +0,0 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {SearchComponent} from './search.component';
describe('SearchComponent', () => {
let component: SearchComponent<any>;
let fixture: ComponentFixture<SearchComponent<any>>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [SearchComponent]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SearchComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -53,7 +53,7 @@ export class SearchComponent<T> implements OnInit {
changed(): void {
this.clearChangedTimeout();
this.changedTimeout = setTimeout(() => this.doSearch(), 400);
this.changedTimeout = window.setTimeout(() => this.doSearch(), 400);
}
private clearChangedTimeout(): void {
@ -73,17 +73,6 @@ export class SearchComponent<T> implements OnInit {
this.doSearch();
}
inputKeyPress($event: KeyboardEvent): void {
switch ($event.key) {
case 'Enter':
this.doSearch();
break;
case 'Escape':
this.cancelSearch();
break;
}
}
doSearch(): void {
this.clearChangedTimeout();
if (!this.term) {

View File

@ -59,7 +59,6 @@
*/
import 'zone.js'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/

View File

@ -5,7 +5,9 @@
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"strict": false,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
@ -14,10 +16,10 @@
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2017",
"target": "es2020",
"module": "es2020",
"lib": [
"es2018",
"es2020",
"dom"
]
},

View File

@ -34,7 +34,7 @@ public class ChannelService {
if (channel == null) {
return;
}
getByChannel(channel).write(property.getWriteChannel(), value);
getByChannel(channel).write(property.getWriteChannel().getId(), value);
}
public ChannelDto toDtoAllowNull(final Channel channel) {
@ -45,7 +45,7 @@ public class ChannelService {
}
public ChannelDto toDto(final Channel channel) {
return getByChannel(channel).toDto(channel);
return getByChannel(channel).toDto(channel.getId());
}
public List<? extends ChannelDto> findAllDto() {

View File

@ -6,9 +6,9 @@ public interface IChannelOwner {
void requestUpdate(final Channel channel);
void write(final Channel channel, final double value);
void write(final long id, final double value);
ChannelDto toDto(final Channel channel);
ChannelDto toDto(final long id);
List<? extends ChannelDto> findAllDto();

View File

@ -25,13 +25,17 @@ public class KnxGroupChannelOwnerService implements IChannelOwner {
}
@Override
public void write(final Channel channel, final double value) {
knxGroupWriteService.requestWrite((KnxGroup) channel, value);
public void write(final long id, final double value) {
knxGroupWriteService.requestWrite(knxGroupReadService.getById(id), value);
}
@Override
public KnxGroupDto toDto(final Channel channel) {
return new KnxGroupDto((KnxGroup) channel);
public KnxGroupDto toDto(final long id) {
return toDto(knxGroupReadService.getById(id));
}
public KnxGroupDto toDto(final KnxGroup knxGroup) {
return new KnxGroupDto(knxGroup);
}
@Override

View File

@ -29,4 +29,8 @@ public class KnxGroupReadService {
return knxGroupRepository.findAllByNameContainsIgnoreCaseOrAddressStrContainsIgnoreCase(term, term);
}
public KnxGroup getById(final long id) {
return knxGroupRepository.findById(id).orElseThrow(RuntimeException::new);
}
}

View File

@ -25,13 +25,13 @@ public class LogicChannelOwner implements IChannelOwner {
}
@Override
public void write(final Channel channel, final double value) {
public void write(final long id, final double value) {
throw new RuntimeException();
}
@Override
public LogicDto toDto(final Channel channel) {
return logicReader.toDto((Logic) channel);
public LogicDto toDto(final long id) {
return logicReader.toDto(logicReader.getById(id));
}
@Override

View File

@ -31,4 +31,8 @@ public class LogicReader {
return logicRepository.findAllByPropertyName(id);
}
public Logic getById(final long id) {
return logicRepository.findById(id).orElseThrow(RuntimeException::new);
}
}

View File

@ -17,7 +17,7 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowCredentials(true).allowedOrigins("http://localhost:4200").allowedMethods("*");
registry.addMapping("/**").allowedOrigins("*").allowedMethods("*");
}
@Override

View File

@ -2,6 +2,5 @@
cd "$(dirname "$0")" || exit 1
mvn clean package spring-boot:repackage && \
scp target/Homeautomation.jar media@10.0.0.50:/home/media/java/Homeautomation/Homeautomation.jar.update && \
scp target/Homeautomation-1.0-SNAPSHOT.jar media@10.0.0.50:/home/media/java/Homeautomation/Homeautomation.jar.update && \
curl -m 2 -s http://10.0.0.50:8082/server/shutdown && echo "Server restarting..." || echo "Failed to restart server!"