-
-
- {{ 'device-profile.schedule-day.monday' | translate }}
-
-
-
- device-profile.schedule-time-from
-
-
-
-
-
- device-profile.schedule-time-to
-
-
-
-
-
-
-
-
-
-
- {{ 'device-profile.schedule-day.tuesday' | translate }}
-
-
-
- device-profile.schedule-time-from
-
-
-
-
-
- device-profile.schedule-time-to
-
-
-
-
-
-
-
-
-
-
- {{ 'device-profile.schedule-day.wednesday' | translate }}
-
-
-
- device-profile.schedule-time-from
-
-
-
-
-
- device-profile.schedule-time-to
-
-
-
-
-
-
-
-
-
-
- {{ 'device-profile.schedule-day.thursday' | translate }}
-
-
-
- device-profile.schedule-time-from
-
-
-
-
-
- device-profile.schedule-time-to
-
-
-
-
-
-
-
-
-
-
- {{ 'device-profile.schedule-day.friday' | translate }}
-
-
-
- device-profile.schedule-time-from
-
-
-
-
-
- device-profile.schedule-time-to
-
-
-
-
-
-
-
-
-
-
- {{ 'device-profile.schedule-day.saturday' | translate }}
-
-
-
- device-profile.schedule-time-from
-
-
-
-
-
- device-profile.schedule-time-to
-
-
-
-
-
-
-
-
-
-
- {{ 'device-profile.schedule-day.sunday' | translate }}
+
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts
index 0062687d5d..65009dbd0b 100644
--- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts
+++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts
@@ -28,7 +28,12 @@ import {
Validator,
Validators
} from '@angular/forms';
-import { AlarmSchedule, AlarmScheduleType, AlarmScheduleTypeTranslationMap } from '@shared/models/device.models';
+import {
+ AlarmSchedule,
+ AlarmScheduleType,
+ AlarmScheduleTypeTranslationMap,
+ dayOfWeekTranslations, getAlarmScheduleRangeText, timeOfDayToUTCTimestamp, utcTimestampToTimeOfDay
+} from '@shared/models/device.models';
import { isDefined, isDefinedAndNotNull } from '@core/utils';
import * as _moment from 'moment-timezone';
import { MatCheckboxChange } from '@angular/material/checkbox';
@@ -59,11 +64,18 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator,
alarmScheduleType = AlarmScheduleType;
alarmScheduleTypeTranslate = AlarmScheduleTypeTranslationMap;
+ dayOfWeekTranslationsArray = dayOfWeekTranslations;
+
+ allDays = Array(7).fill(0).map((x, i) => i);
+
+ firstRowDays = Array(4).fill(0).map((x, i) => i);
+ secondRowDays = Array(3).fill(0).map((x, i) => i + 4);
+
private modelValue: AlarmSchedule;
private defaultItems = Array.from({length: 7}, (value, i) => ({
enabled: true,
- dayOfWeek: i
+ dayOfWeek: i + 1
}));
private propagateChange = (v: any) => { };
@@ -75,10 +87,10 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator,
this.alarmScheduleForm = this.fb.group({
type: [AlarmScheduleType.ANY_TIME, Validators.required],
timezone: [null, Validators.required],
- daysOfWeek: this.fb.array(new Array(7).fill(false)),
+ daysOfWeek: this.fb.array(new Array(7).fill(false), this.validateDayOfWeeks),
startsOn: [0, Validators.required],
endsOn: [0, Validators.required],
- items: this.fb.array(Array.from({length: 7}, (value, i) => this.defaultItemsScheduler(i)))
+ items: this.fb.array(Array.from({length: 7}, (value, i) => this.defaultItemsScheduler(i)), this.validateItems)
});
this.alarmScheduleForm.get('type').valueChanges.subscribe((type) => {
this.alarmScheduleForm.reset({type, items: this.defaultItems, timezone: this.defaultTimezone}, {emitEvent: false});
@@ -90,6 +102,26 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator,
});
}
+ validateDayOfWeeks(control: AbstractControl): ValidationErrors | null {
+ const dayOfWeeks: boolean[] = control.value;
+ if (!dayOfWeeks || !dayOfWeeks.length || !dayOfWeeks.find(v => v === true)) {
+ return {
+ dayOfWeeks: true
+ };
+ }
+ return null;
+ }
+
+ validateItems(control: AbstractControl): ValidationErrors | null {
+ const items: any[] = control.value;
+ if (!items || !items.length || !items.find(v => v.enabled === true)) {
+ return {
+ dayOfWeeks: true
+ };
+ }
+ return null;
+ }
+
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
@@ -123,8 +155,8 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator,
type: this.modelValue.type,
timezone: this.modelValue.timezone,
daysOfWeek,
- startsOn: this.timestampToTime(this.modelValue.startsOn),
- endsOn: this.timestampToTime(this.modelValue.endsOn)
+ startsOn: utcTimestampToTimeOfDay(this.modelValue.startsOn),
+ endsOn: utcTimestampToTimeOfDay(this.modelValue.endsOn)
}, {emitEvent: false});
break;
case AlarmScheduleType.CUSTOM:
@@ -136,8 +168,8 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator,
this.disabledSelectedTime(item.enabled, index);
alarmDays.push({
enabled: item.enabled,
- startsOn: this.timestampToTime(item.startsOn),
- endsOn: this.timestampToTime(item.endsOn)
+ startsOn: utcTimestampToTimeOfDay(item.startsOn),
+ endsOn: utcTimestampToTimeOfDay(item.endsOn)
});
});
this.alarmScheduleForm.patchValue({
@@ -202,15 +234,15 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator,
.filter(day => !!day);
}
if (isDefined(value.startsOn) && value.startsOn !== 0) {
- value.startsOn = this.timeToTimestampUTC(value.startsOn);
+ value.startsOn = timeOfDayToUTCTimestamp(value.startsOn);
}
if (isDefined(value.endsOn) && value.endsOn !== 0) {
- value.endsOn = this.timeToTimestampUTC(value.endsOn);
+ value.endsOn = timeOfDayToUTCTimestamp(value.endsOn);
}
if (isDefined(value.items)){
value.items = this.alarmScheduleForm.getRawValue().items;
value.items = value.items.map((item) => {
- return { ...item, startsOn: this.timeToTimestampUTC(item.startsOn), endsOn: this.timeToTimestampUTC(item.endsOn)};
+ return { ...item, startsOn: timeOfDayToUTCTimestamp(item.startsOn), endsOn: timeOfDayToUTCTimestamp(item.endsOn)};
});
}
this.modelValue = value;
@@ -218,21 +250,11 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator,
}
}
- private timeToTimestampUTC(date: Date | number): number {
- if (typeof date === 'number' || date === null) {
- return 0;
- }
- return _moment.utc([1970, 0, 1, date.getHours(), date.getMinutes(), date.getSeconds(), 0]).valueOf();
- }
-
- private timestampToTime(time = 0): Date {
- return new Date(time + new Date().getTimezoneOffset() * 60 * 1000);
- }
private defaultItemsScheduler(index): FormGroup {
return this.fb.group({
enabled: [true],
- dayOfWeek: [index],
+ dayOfWeek: [index + 1],
startsOn: [0, Validators.required],
endsOn: [0, Validators.required]
});
@@ -253,23 +275,8 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator,
}
}
- private timeToMoment(date: Date | number): _moment.Moment {
- if (typeof date === 'number' || date === null) {
- return _moment([1970, 0, 1, 0, 0, 0, 0]);
- }
- return _moment([1970, 0, 1, date.getHours(), date.getMinutes(), 0, 0]);
- }
-
getSchedulerRangeText(control: FormGroup | AbstractControl): string {
- const start = this.timeToMoment(control.get('startsOn').value);
- const end = this.timeToMoment(control.get('endsOn').value);
- if (start < end) {
- return `
${start.format('hh:mm A')} – ${end.format('hh:mm A')}`;
- } else if (start.valueOf() === 0 && end.valueOf() === 0 || start.isSame(_moment([1970, 0])) && end.isSame(_moment([1970, 0]))) {
- return '
12:00 AM – 12:00 PM';
- }
- return `
12:00 AM – ${end.format('hh:mm A')}` +
- ` and ${start.format('hh:mm A')} – 12:00 PM`;
+ return getAlarmScheduleRangeText(control.get('startsOn').value, control.get('endsOn').value);
}
get itemsSchedulerForm(): FormArray {
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.scss b/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.scss
index eedaac2ca1..91335f53a4 100644
--- a/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.scss
+++ b/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.scss
@@ -19,6 +19,7 @@
border: 2px groove rgba(0, 0, 0, .45);
border-radius: 4px;
padding: 8px;
+ min-width: 0;
}
}
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.html
index 7d2ad8b75d..f1322ef9a9 100644
--- a/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.html
+++ b/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.html
@@ -56,7 +56,7 @@
{{ 'device-profile.propagate-alarm' | translate }}
-
+
device-profile.alarm-rule-relation-types-list
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.ts
index 7fa60e79d5..116d9a2a9c 100644
--- a/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.ts
+++ b/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarm.component.ts
@@ -57,6 +57,7 @@ export class DeviceProfileAlarmComponent implements ControlValueAccessor, OnInit
separatorKeysCodes = [ENTER, COMMA, SEMICOLON];
+ @Input()
expanded = false;
private modelValue: DeviceProfileAlarm;
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarms.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarms.component.html
index 7bd7c546db..e1b446c65a 100644
--- a/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarms.component.html
+++ b/ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarms.component.html
@@ -21,6 +21,7 @@
let $index = index; last as isLast;"
fxLayout="column" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}">
@@ -29,7 +30,7 @@