ScheduleEntry.skip
This commit is contained in:
parent
4cdb051e17
commit
bb972283a3
@ -125,5 +125,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"cli": {
|
||||||
|
"analytics": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import {validateBooleanNotNull, validateDateAllowNull, validateNumberNotNull, validateStringNotEmptyNotNull} from "../../validators";
|
import {validateBooleanNotNull, validateDateAllowNull, validateNumberAllowNull, validateNumberNotNull, validateStringNotEmptyNotNull} from "../../validators";
|
||||||
import {Timestamp} from "../../Timestamp";
|
import {Timestamp} from "../../Timestamp";
|
||||||
import {Property} from "../../property/Property";
|
import {Property} from "../../property/Property";
|
||||||
import {Bulk} from "../../bulk/Bulk";
|
import {Bulk} from "../../bulk/Bulk";
|
||||||
@ -26,6 +26,7 @@ export class ScheduleEntry {
|
|||||||
readonly minute: number,
|
readonly minute: number,
|
||||||
readonly second: number,
|
readonly second: number,
|
||||||
readonly fuzzySeconds: number,
|
readonly fuzzySeconds: number,
|
||||||
|
readonly skip: number,
|
||||||
readonly lastClearTimestamp: Timestamp | null,
|
readonly lastClearTimestamp: Timestamp | null,
|
||||||
readonly nextClearTimestamp: Timestamp | null,
|
readonly nextClearTimestamp: Timestamp | null,
|
||||||
readonly nextFuzzyTimestamp: Timestamp | null,
|
readonly nextFuzzyTimestamp: Timestamp | null,
|
||||||
@ -55,6 +56,7 @@ export class ScheduleEntry {
|
|||||||
validateNumberNotNull(json['minute']),
|
validateNumberNotNull(json['minute']),
|
||||||
validateNumberNotNull(json['second']),
|
validateNumberNotNull(json['second']),
|
||||||
validateNumberNotNull(json['fuzzySeconds']),
|
validateNumberNotNull(json['fuzzySeconds']),
|
||||||
|
validateNumberAllowNull(json['skip']) || 0,
|
||||||
Timestamp.fromDateOrNull(validateDateAllowNull(json['lastClearTimestamp'])),
|
Timestamp.fromDateOrNull(validateDateAllowNull(json['lastClearTimestamp'])),
|
||||||
Timestamp.fromDateOrNull(validateDateAllowNull(json['nextClearTimestamp'])),
|
Timestamp.fromDateOrNull(validateDateAllowNull(json['nextClearTimestamp'])),
|
||||||
Timestamp.fromDateOrNull(validateDateAllowNull(json['nextFuzzyTimestamp'])),
|
Timestamp.fromDateOrNull(validateDateAllowNull(json['nextFuzzyTimestamp'])),
|
||||||
|
|||||||
@ -6,13 +6,18 @@
|
|||||||
<div class="scheduleBox" *ngFor="let schedule of schedules; trackBy: Schedule.trackBy">
|
<div class="scheduleBox" *ngFor="let schedule of schedules; trackBy: Schedule.trackBy">
|
||||||
<div class="schedule" [class.scheduleEnabled]="schedule.enabled">
|
<div class="schedule" [class.scheduleEnabled]="schedule.enabled">
|
||||||
|
|
||||||
<div class="header">
|
<div class="header" [class.skipActive]="schedule.next?.skip">
|
||||||
|
|
||||||
<div class="enabled" (click)="set(schedule, 'enabled', !schedule.enabled)" [class.true]="schedule.enabled" [class.false]="!schedule.enabled">
|
<div class="enabled" (click)="set(schedule, 'enabled', !schedule.enabled)" [class.true]="schedule.enabled" [class.false]="!schedule.enabled">
|
||||||
<fa-icon *ngIf="schedule.enabled" [icon]="faCheckCircle"></fa-icon>
|
<fa-icon *ngIf="schedule.enabled" [icon]="faCheckCircle"></fa-icon>
|
||||||
<fa-icon *ngIf="!schedule.enabled" [icon]="faCircle"></fa-icon>
|
<fa-icon *ngIf="!schedule.enabled" [icon]="faCircle"></fa-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="skip" (click)="skip(schedule.next)">
|
||||||
|
<img src="assets/skip.svg" [alt]="schedule.next?.skip">
|
||||||
|
{{ schedule.next?.skip }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="title" [routerLink]="['/Schedule', {id: schedule.id}]">
|
<div class="title" [routerLink]="['/Schedule', {id: schedule.id}]">
|
||||||
{{ schedule.title }}
|
{{ schedule.title }}
|
||||||
</div>
|
</div>
|
||||||
@ -24,13 +29,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="timestampBox timestampBoxNext">
|
<div class="timestampBox timestampBoxNext">
|
||||||
<div class="timestampTitle">
|
|
||||||
Nächste Ausführung:
|
|
||||||
</div>
|
|
||||||
<div class="timestampTimestamp">
|
<div class="timestampTimestamp">
|
||||||
<ng-container *ngIf="schedule.next">{{ schedule.next?.nextFuzzyTimestamp.dayName }}: {{ schedule.next?.nextFuzzyTimestamp.timeString }}</ng-container>
|
<ng-container *ngIf="schedule.next">{{ schedule.next?.nextFuzzyTimestamp.dayName }}: {{ schedule.next?.nextFuzzyTimestamp.timeString }}</ng-container>
|
||||||
<ng-container *ngIf="!schedule.next">- - -</ng-container>
|
<ng-container *ngIf="!schedule.next">- - -</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="timestampTitle">
|
||||||
|
Nächste Ausführung:
|
||||||
|
</div>
|
||||||
<div class="timestampBulk" [class.timestampBulkEmpty]="!schedule.next?.bulk" *ngIf="schedule.next?.bulk">
|
<div class="timestampBulk" [class.timestampBulkEmpty]="!schedule.next?.bulk" *ngIf="schedule.next?.bulk">
|
||||||
{{ schedule.next?.bulk?.name }}
|
{{ schedule.next?.bulk?.name }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -24,6 +24,17 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.skip {
|
||||||
|
padding: 0.45em;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: inline;
|
||||||
|
vertical-align: bottom;
|
||||||
|
height: 1.3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.delete {
|
.delete {
|
||||||
float: right;
|
float: right;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
@ -110,6 +121,10 @@
|
|||||||
background-color: #F0FFF0;
|
background-color: #F0FFF0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.skipActive {
|
||||||
|
background-color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 1000px) {
|
@media (min-width: 1000px) {
|
||||||
float: left;
|
float: left;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import {Schedule} from "../../../api/schedule/Schedule";
|
|||||||
import {faCheckCircle, faCircle, faTimesCircle} from '@fortawesome/free-regular-svg-icons';
|
import {faCheckCircle, faCircle, faTimesCircle} from '@fortawesome/free-regular-svg-icons';
|
||||||
import {NO_OP} from "../../../api/api.service";
|
import {NO_OP} from "../../../api/api.service";
|
||||||
import {Update} from "../../../api/Update";
|
import {Update} from "../../../api/Update";
|
||||||
|
import {ScheduleEntryService} from "../../../api/schedule/entry/schedule-entry.service";
|
||||||
|
import {ScheduleEntry} from "../../../api/schedule/entry/ScheduleEntry";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-schedule-list',
|
selector: 'app-schedule-list',
|
||||||
@ -24,6 +26,7 @@ export class ScheduleListComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly scheduleService: ScheduleService,
|
readonly scheduleService: ScheduleService,
|
||||||
|
readonly entryService: ScheduleEntryService,
|
||||||
) {
|
) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
@ -63,4 +66,12 @@ export class ScheduleListComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip(entry: ScheduleEntry) {
|
||||||
|
let skip = entry.skip + 1;
|
||||||
|
if (skip > 7) {
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
this.entryService.set(entry, 'skip', skip);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
7
src/main/angular/src/assets/skip.svg
Normal file
7
src/main/angular/src/assets/skip.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle cx="8" cy="37" r="6"/>
|
||||||
|
<path d="M24,31a6,6,0,1,0,6,6A6,6,0,0,0,24,31Zm0,8a2,2,0,1,1,2-2A2,2,0,0,1,24,39Z"/>
|
||||||
|
<circle cx="40" cy="37" r="6"/>
|
||||||
|
<path d="M37.4,19.6a1.9,1.9,0,0,0-3,.2,2.1,2.1,0,0,0,.2,2.7l4,3.9a1.9,1.9,0,0,0,2.8,0l4-3.9a2.3,2.3,0,0,0,.3-2.7,2,2,0,0,0-3.1-.2l-.6.6A18,18,0,0,0,6,21v2a2,2,0,0,0,4,0V21a14,14,0,0,1,28-.9Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 486 B |
@ -1,22 +1,9 @@
|
|||||||
// This file can be replaced during build by using the `fileReplacements` array.
|
|
||||||
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
|
||||||
// The list of file replacements can be found in `angular.json`.
|
|
||||||
|
|
||||||
import {getBaseUrl} from "./UrlHelper";
|
import {getBaseUrl} from "./UrlHelper";
|
||||||
|
|
||||||
const PROD: boolean = true;
|
const PROD: boolean = false;
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false,
|
||||||
restBase: PROD ? 'http://10.0.0.50:8082' : getBaseUrl('http', 8080),
|
restBase: PROD ? 'http://10.0.0.50:8082' : getBaseUrl('http', 8080),
|
||||||
websocketBase: PROD ? 'ws://10.0.0.50:8082' : getBaseUrl('ws', 8080),
|
websocketBase: PROD ? 'ws://10.0.0.50:8082' : getBaseUrl('ws', 8080),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* For easier debugging in development mode, you can import the following file
|
|
||||||
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
|
||||||
*
|
|
||||||
* This import should be commented out in production mode because it will have a negative impact
|
|
||||||
* on performance if an error is thrown.
|
|
||||||
*/
|
|
||||||
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
|
||||||
|
|||||||
@ -91,6 +91,7 @@ public class DemoDataService {
|
|||||||
scheduleEntryController.setProperty(id, property == null ? null : property.getId());
|
scheduleEntryController.setProperty(id, property == null ? null : property.getId());
|
||||||
scheduleEntryController.setValue(id, value);
|
scheduleEntryController.setValue(id, value);
|
||||||
scheduleEntryController.setBulk(id, bulk == null ? null : bulk.getId());
|
scheduleEntryController.setBulk(id, bulk == null ? null : bulk.getId());
|
||||||
|
scheduleEntryController.setSkip(id, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ public class ScheduleExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void executeEntry(final Schedule schedule, final ScheduleEntry entry) {
|
private void executeEntry(final Schedule schedule, final ScheduleEntry entry) {
|
||||||
|
if (entry.getSkip() <= 0) {
|
||||||
log.info("Executing Schedule \"{}\" Entry {}", schedule.getTitle(), entry);
|
log.info("Executing Schedule \"{}\" Entry {}", schedule.getTitle(), entry);
|
||||||
if (entry.getProperty() != null) {
|
if (entry.getProperty() != null) {
|
||||||
log.debug("Schedule setting property: {} = {}", entry.getProperty().getTitle(), entry.getValue());
|
log.debug("Schedule setting property: {} = {}", entry.getProperty().getTitle(), entry.getValue());
|
||||||
@ -47,6 +48,10 @@ public class ScheduleExecutor {
|
|||||||
log.debug("Schedule executing Bulk: {}", entry.getBulk());
|
log.debug("Schedule executing Bulk: {}", entry.getBulk());
|
||||||
bulkExecutor.execute(entry.getBulk());
|
bulkExecutor.execute(entry.getBulk());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.info("Skipping Schedule \"{}\" Entry {}", schedule.getTitle(), entry);
|
||||||
|
entry.setSkip(entry.getSkip() - 1);
|
||||||
|
}
|
||||||
entry.setLastClearTimestamp(entry.getNextClearTimestamp());
|
entry.setLastClearTimestamp(entry.getNextClearTimestamp());
|
||||||
entry.setLastFuzzyTimestamp(entry.getNextFuzzyTimestamp());
|
entry.setLastFuzzyTimestamp(entry.getNextFuzzyTimestamp());
|
||||||
scheduleWriter.notifyChanged(schedule);
|
scheduleWriter.notifyChanged(schedule);
|
||||||
|
|||||||
@ -63,6 +63,9 @@ public class ScheduleEntry {
|
|||||||
|
|
||||||
private int fuzzySeconds = 0;
|
private int fuzzySeconds = 0;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private int skip = 0;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
private Property property;
|
private Property property;
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,11 @@ public class ScheduleEntryController {
|
|||||||
return scheduleEntryWriter.setFuzzySeconds(id, value);
|
return scheduleEntryWriter.setFuzzySeconds(id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/skip")
|
||||||
|
public ScheduleEntryDto setSkip(@PathVariable final long id, @RequestBody final int value) {
|
||||||
|
return scheduleEntryWriter.setSkip(id, value);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("set/{id}/property")
|
@PostMapping("set/{id}/property")
|
||||||
public ScheduleEntryDto setProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) {
|
public ScheduleEntryDto setProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) {
|
||||||
return scheduleEntryWriter.setProperty(id, propertyId);
|
return scheduleEntryWriter.setProperty(id, propertyId);
|
||||||
|
|||||||
@ -42,6 +42,8 @@ public class ScheduleEntryDto implements Serializable {
|
|||||||
|
|
||||||
public final int fuzzySeconds;
|
public final int fuzzySeconds;
|
||||||
|
|
||||||
|
public final int skip;
|
||||||
|
|
||||||
public final ZonedDateTime nextClearTimestamp;
|
public final ZonedDateTime nextClearTimestamp;
|
||||||
|
|
||||||
public final ZonedDateTime lastClearTimestamp;
|
public final ZonedDateTime lastClearTimestamp;
|
||||||
@ -73,6 +75,7 @@ public class ScheduleEntryDto implements Serializable {
|
|||||||
this.minute = entry.getMinute();
|
this.minute = entry.getMinute();
|
||||||
this.second = entry.getSecond();
|
this.second = entry.getSecond();
|
||||||
this.fuzzySeconds = entry.getFuzzySeconds();
|
this.fuzzySeconds = entry.getFuzzySeconds();
|
||||||
|
this.skip = entry.getSkip();
|
||||||
this.nextClearTimestamp = entry.getNextClearTimestamp();
|
this.nextClearTimestamp = entry.getNextClearTimestamp();
|
||||||
this.lastClearTimestamp = entry.getLastClearTimestamp();
|
this.lastClearTimestamp = entry.getLastClearTimestamp();
|
||||||
this.nextFuzzyTimestamp = entry.getNextFuzzyTimestamp();
|
this.nextFuzzyTimestamp = entry.getNextFuzzyTimestamp();
|
||||||
|
|||||||
@ -130,6 +130,10 @@ public class ScheduleEntryWriter {
|
|||||||
return modifyValue(id, ScheduleEntry::setFuzzySeconds, value);
|
return modifyValue(id, ScheduleEntry::setFuzzySeconds, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ScheduleEntryDto setSkip(final long id, final int value) {
|
||||||
|
return modifyValue(id, ScheduleEntry::setSkip, value);
|
||||||
|
}
|
||||||
|
|
||||||
public ScheduleEntryDto setValue(final long id, final double value) {
|
public ScheduleEntryDto setValue(final long id, final double value) {
|
||||||
return modifyValue(id, ScheduleEntry::setValue, value);
|
return modifyValue(id, ScheduleEntry::setValue, value);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user