UI: Improvement for notification settings

This commit is contained in:
Artem Dzhereleiko 2023-10-09 15:33:43 +03:00
parent 79dbf41b9f
commit c39b731993
4 changed files with 55 additions and 40 deletions

View File

@ -19,20 +19,21 @@
<div fxLayout="row" style="height: 48px;"> <div fxLayout="row" style="height: 48px;">
<div fxFlex="50" fxLayoutAlign="start center"> <div fxFlex="50" fxLayoutAlign="start center">
<mat-checkbox color="primary" <mat-checkbox color="primary"
[checked]="notificationSettingsFormGroup.get('enabled').value" (click)="$event.stopPropagation()"
(click)="toggleEnabled()"> (change)="changeInstanceTypeCheckBox($event.checked)"
[checked]="getChecked()"
[indeterminate]="getIndeterminate()">
<span class="notification-type" <span class="notification-type"
[ngClass]="{'notification-type-disabled': !notificationSettingsFormGroup.get('enabled').value}"> [ngClass]="{'notification-type-disabled': !notificationSettingsFormGroup.get('enabled').value}">
{{notificationTemplateTypeTranslateMap.get(notificationSettingsFormGroup.get('name').value)?.name | translate}} {{notificationTemplateTypeTranslateMap.get(notificationSettingsFormGroup.get('name').value)?.name | translate}}
</span> </span>
</mat-checkbox> </mat-checkbox>
</div> </div>
<div fxFlex fxLayout="row" *ngFor="let deliveryMethods of deliveryMethods"> <div fxFlex fxLayout="row" *ngFor="let deliveryMethod of deliveryMethods">
<div fxFlex fxLayoutAlign="start center"> <div fxFlex fxLayoutAlign="start center">
<mat-checkbox color="primary" <mat-checkbox color="primary"
[disabled]="!allowDeliveryMethods?.includes(deliveryMethods) || !notificationSettingsFormGroup.get('enabled').value" [checked]="getChecked(deliveryMethod)"
[checked]="getChecked(deliveryMethods)" (click)="toggleDeliviryMethod(deliveryMethod)"
(click)="toggleDeliviryMethod(deliveryMethods)"
></mat-checkbox> ></mat-checkbox>
</div> </div>
</div> </div>

View File

@ -16,8 +16,7 @@
import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { UtilsService } from '@core/services/utils.service'; import { deepClone, isDefinedAndNotNull } from '@core/utils';
import { isDefinedAndNotNull } from '@core/utils';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { import {
NotificationDeliveryMethod, NotificationDeliveryMethod,
@ -45,9 +44,6 @@ export class NotificationSettingFormComponent implements ControlValueAccessor, O
@Input() @Input()
deliveryMethods: NotificationDeliveryMethod[] = []; deliveryMethods: NotificationDeliveryMethod[] = [];
@Input()
allowDeliveryMethods: NotificationDeliveryMethod[] = [];
notificationSettingsFormGroup: UntypedFormGroup; notificationSettingsFormGroup: UntypedFormGroup;
notificationTemplateTypeTranslateMap = NotificationTemplateTypeTranslateMap; notificationTemplateTypeTranslateMap = NotificationTemplateTypeTranslateMap;
@ -56,8 +52,7 @@ export class NotificationSettingFormComponent implements ControlValueAccessor, O
private valueChange$: Subscription = null; private valueChange$: Subscription = null;
constructor(private utils: UtilsService, constructor(private fb: UntypedFormBuilder) {
private fb: UntypedFormBuilder) {
} }
registerOnChange(fn: any): void { registerOnChange(fn: any): void {
@ -101,12 +96,17 @@ export class NotificationSettingFormComponent implements ControlValueAccessor, O
} }
} }
toggleEnabled() { getChecked(deliveryMethod?: NotificationDeliveryMethod): boolean {
this.notificationSettingsFormGroup.get('enabled').patchValue(!this.notificationSettingsFormGroup.get('enabled').value); if (deliveryMethod) {
} return this.notificationSettingsFormGroup.get('enabledDeliveryMethods').get(deliveryMethod).value;
} else {
getChecked(deliveryMethod: NotificationDeliveryMethod): boolean { const enabledDeliveryMethod = Object.values(this.notificationSettingsFormGroup.get('enabledDeliveryMethods').value);
return this.notificationSettingsFormGroup.get('enabledDeliveryMethods').get(deliveryMethod).value; const checked = enabledDeliveryMethod.some(value => value === true);
if (checked !== this.notificationSettingsFormGroup.get('enabled').value) {
setTimeout(() => this.notificationSettingsFormGroup.get('enabled').patchValue(checked), 0);
}
return enabledDeliveryMethod.every(value => value);
}
} }
toggleDeliviryMethod(deliveryMethod: NotificationDeliveryMethod) { toggleDeliviryMethod(deliveryMethod: NotificationDeliveryMethod) {
@ -114,6 +114,25 @@ export class NotificationSettingFormComponent implements ControlValueAccessor, O
.patchValue(!this.notificationSettingsFormGroup.get('enabledDeliveryMethods').get(deliveryMethod).value); .patchValue(!this.notificationSettingsFormGroup.get('enabledDeliveryMethods').get(deliveryMethod).value);
} }
changeInstanceTypeCheckBox(value: any) {
const enabledDeliveryMethod = deepClone(this.notificationSettingsFormGroup.get('enabledDeliveryMethods').value);
Object.keys(enabledDeliveryMethod).forEach(key => {
enabledDeliveryMethod[key] = value;
});
this.notificationSettingsFormGroup.get('enabled').patchValue(value, {emitEvent: false});
this.notificationSettingsFormGroup.get('enabledDeliveryMethods').patchValue(enabledDeliveryMethod);
this.notificationSettingsFormGroup.markAsDirty();
}
getIndeterminate() {
if (!this.notificationSettingsFormGroup.get('enabled').value) {
return false;
}
const enabledDeliveryMethod: Array<boolean> = Object.values(this.notificationSettingsFormGroup.get('enabledDeliveryMethods').value);
const checkedResource = enabledDeliveryMethod.filter(value => value);
return checkedResource.length !== 0 && checkedResource.length !== enabledDeliveryMethod.length;
}
writeValue(value: NotificationUserSetting): void { writeValue(value: NotificationUserSetting): void {
if (isDefinedAndNotNull(value)) { if (isDefinedAndNotNull(value)) {
this.notificationSettingsFormGroup.patchValue(value, {emitEvent: false}); this.notificationSettingsFormGroup.patchValue(value, {emitEvent: false});

View File

@ -50,7 +50,6 @@
<div fxFlex *ngFor="let deliveryMethods of notificationDeliveryMethods"> <div fxFlex *ngFor="let deliveryMethods of notificationDeliveryMethods">
<div fxFlex fxLayoutAlign="start center"> <div fxFlex fxLayoutAlign="start center">
<mat-checkbox color="warn" <mat-checkbox color="warn"
[disabled]="!allowNotificationDeliveryMethods?.includes(deliveryMethods) || !getSomeChecked()"
[checked]="getChecked(deliveryMethods)" [checked]="getChecked(deliveryMethods)"
(change)="changeInstanceTypeCheckBox($event.checked, deliveryMethods)" (change)="changeInstanceTypeCheckBox($event.checked, deliveryMethods)"
[indeterminate]="getIndeterminate(deliveryMethods)" [indeterminate]="getIndeterminate(deliveryMethods)"
@ -63,8 +62,7 @@
<mat-divider></mat-divider> <mat-divider></mat-divider>
<div *ngFor="let settingsControl of notificationSettingsFormArray.controls; let i = index; let $last = last;"> <div *ngFor="let settingsControl of notificationSettingsFormArray.controls; let i = index; let $last = last;">
<tb-notification-setting-form [formControl]="settingsControl" <tb-notification-setting-form [formControl]="settingsControl"
[deliveryMethods]="notificationDeliveryMethods" [deliveryMethods]="notificationDeliveryMethods">
[allowDeliveryMethods]="allowNotificationDeliveryMethods">
</tb-notification-setting-form> </tb-notification-setting-form>
<mat-divider *ngIf="!$last"></mat-divider> <mat-divider *ngIf="!$last"></mat-divider>
</div> </div>

View File

@ -43,7 +43,10 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
notificationDeliveryMethods: NotificationDeliveryMethod[]; notificationDeliveryMethods: NotificationDeliveryMethod[];
notificationDeliveryMethodTranslateMap = NotificationDeliveryMethodTranslateMap; notificationDeliveryMethodTranslateMap = NotificationDeliveryMethodTranslateMap;
allowNotificationDeliveryMethods: Array<NotificationDeliveryMethod>; private deliveryMethods = new Set([
NotificationDeliveryMethod.SLACK,
NotificationDeliveryMethod.MICROSOFT_TEAMS
]);
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
private route: ActivatedRoute, private route: ActivatedRoute,
@ -52,25 +55,15 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
private notificationService: NotificationService, private notificationService: NotificationService,
private fb: UntypedFormBuilder,) { private fb: UntypedFormBuilder,) {
super(store); super(store);
this.notificationService.getAvailableDeliveryMethods({ignoreLoading: true}).subscribe(
allowMethods => {
this.notificationDeliveryMethods = allowMethods.filter(value => !this.deliveryMethods.has(value));
this.patchNotificationSettings(this.route.snapshot.data.userSettings);
});
} }
ngOnInit() { ngOnInit() {
this.notificationDeliveryMethods = this.getNotificationDeliveryMethods();
this.notificationService.getAvailableDeliveryMethods({ignoreLoading: true}).subscribe(allowMethods => {
this.allowNotificationDeliveryMethods = allowMethods;
});
this.buildNotificationSettingsForm(); this.buildNotificationSettingsForm();
this.patchNotificationSettings(this.route.snapshot.data.userSettings);
}
private getNotificationDeliveryMethods(): NotificationDeliveryMethod[] {
const deliveryMethods = new Set([
NotificationDeliveryMethod.SLACK,
NotificationDeliveryMethod.MICROSOFT_TEAMS
]);
return Object.values(NotificationDeliveryMethod).filter(type => !deliveryMethods.has(type));
} }
private buildNotificationSettingsForm() { private buildNotificationSettingsForm() {
@ -158,9 +151,13 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
if (isDefinedAndNotNull(deliveryMethod)) { if (isDefinedAndNotNull(deliveryMethod)) {
type.forEach(notificationType => notificationType.enabledDeliveryMethods[deliveryMethod] = value); type.forEach(notificationType => notificationType.enabledDeliveryMethods[deliveryMethod] = value);
} else { } else {
type.forEach(notificationType => notificationType.enabled = value); type.forEach(notificationType => {
notificationType.enabled = value;
notificationType.enabledDeliveryMethods =
Object.keys(notificationType.enabledDeliveryMethods).reduce((a, v) => ({ ...a, [v]: value}), {});
});
} }
this.notificationSettings.get('prefs').patchValue(type); this.notificationSettings.get('prefs').patchValue(type, {emitEvent: false});
this.notificationSettings.markAsDirty(); this.notificationSettings.markAsDirty();
}; };