Browse Source

Merge pull request #8903 from ArtemDzhereleiko/AD/imp/user-notification-settings

Improvements for user notification settings
pull/9018/head
Vladyslav 3 years ago
committed by GitHub
parent
commit
714af4757b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      ui-ngx/src/app/modules/home/pages/notification/settings/notification-setting-form.component.html
  2. 26
      ui-ngx/src/app/modules/home/pages/notification/settings/notification-setting-form.component.ts
  3. 28
      ui-ngx/src/app/modules/home/pages/notification/settings/notification-settings.component.html
  4. 12
      ui-ngx/src/app/modules/home/pages/notification/settings/notification-settings.component.scss
  5. 28
      ui-ngx/src/app/modules/home/pages/notification/settings/notification-settings.component.ts
  6. 3
      ui-ngx/src/app/shared/models/notification.models.ts

22
ui-ngx/src/app/modules/home/pages/notification/settings/notification-setting-form.component.html

@ -18,19 +18,17 @@
<form [formGroup]="notificationSettingsFormGroup" fxLayout="column"> <form [formGroup]="notificationSettingsFormGroup" fxLayout="column">
<div fxLayout="row" style="height: 48px;"> <div fxLayout="row" style="height: 48px;">
<div fxFlex="50" fxLayoutAlign="start center"> <div fxFlex="50" fxLayoutAlign="start center">
<button mat-icon-button <mat-checkbox color="primary"
(click)="toggleEnabled()"> [checked]="notificationSettingsFormGroup.get('enabled').value"
<mat-icon style="color: rgba(0, 0, 0, 0.54);" (click)="toggleEnabled()">
[svgIcon]="notificationSettingsFormGroup.get('enabled').value ? 'mdi:toggle-switch': 'mdi:toggle-switch-off-outline'"> <span class="notification-type"
</mat-icon> [ngClass]="{'notification-type-disabled': !notificationSettingsFormGroup.get('enabled').value}">
</button> {{notificationTemplateTypeTranslateMap.get(notificationSettingsFormGroup.get('name').value)?.name | translate}}
<span class="notification-type" </span>
[ngClass]="{'notification-type-disabled': !notificationSettingsFormGroup.get('enabled').value}"> </mat-checkbox>
{{notificationTemplateTypeTranslateMap.get(notificationSettingsFormGroup.get('name').value)?.name | translate}}
</span>
</div> </div>
<div fxFlex fxLayout="row" *ngFor="let deliveryMethods of notificationDeliveryMethodMap"> <div fxFlex fxLayout="row" *ngFor="let deliveryMethods of deliveryMethods">
<div fxFlex fxLayoutAlign="center center"> <div fxFlex fxLayoutAlign="start center">
<mat-checkbox color="primary" <mat-checkbox color="primary"
[disabled]="!allowDeliveryMethods?.includes(deliveryMethods) || !notificationSettingsFormGroup.get('enabled').value" [disabled]="!allowDeliveryMethods?.includes(deliveryMethods) || !notificationSettingsFormGroup.get('enabled').value"
[checked]="getChecked(deliveryMethods)" [checked]="getChecked(deliveryMethods)"

26
ui-ngx/src/app/modules/home/pages/notification/settings/notification-setting-form.component.ts

@ -43,12 +43,13 @@ export class NotificationSettingFormComponent implements ControlValueAccessor, O
disabled: boolean; disabled: boolean;
@Input() @Input()
allowDeliveryMethods = []; deliveryMethods: NotificationDeliveryMethod[] = [];
@Input()
allowDeliveryMethods: NotificationDeliveryMethod[] = [];
notificationSettingsFormGroup: UntypedFormGroup; notificationSettingsFormGroup: UntypedFormGroup;
notificationDeliveryMethod = NotificationDeliveryMethod;
notificationDeliveryMethodMap = [NotificationDeliveryMethod.WEB, NotificationDeliveryMethod.SMS, NotificationDeliveryMethod.EMAIL];
notificationTemplateTypeTranslateMap = NotificationTemplateTypeTranslateMap; notificationTemplateTypeTranslateMap = NotificationTemplateTypeTranslateMap;
private propagateChange = null; private propagateChange = null;
@ -67,11 +68,17 @@ export class NotificationSettingFormComponent implements ControlValueAccessor, O
} }
ngOnInit() { ngOnInit() {
const deliveryMethod = {};
this.deliveryMethods.forEach(value => {
deliveryMethod[value] = true;
});
this.notificationSettingsFormGroup = this.fb.group( this.notificationSettingsFormGroup = this.fb.group(
{ {
name: [''], name: [''],
enabled: [true], enabled: [true],
enabledDeliveryMethods: [] enabledDeliveryMethods: this.fb.group({
...deliveryMethod
})
}); });
this.valueChange$ = this.notificationSettingsFormGroup.valueChanges.subscribe(() => { this.valueChange$ = this.notificationSettingsFormGroup.valueChanges.subscribe(() => {
this.updateModel(); this.updateModel();
@ -99,17 +106,12 @@ export class NotificationSettingFormComponent implements ControlValueAccessor, O
} }
getChecked(deliveryMethod: NotificationDeliveryMethod): boolean { getChecked(deliveryMethod: NotificationDeliveryMethod): boolean {
return this.notificationSettingsFormGroup.get('enabledDeliveryMethods').value.includes(deliveryMethod); return this.notificationSettingsFormGroup.get('enabledDeliveryMethods').get(deliveryMethod).value;
} }
toggleDeliviryMethod(deliveryMethod: NotificationDeliveryMethod) { toggleDeliviryMethod(deliveryMethod: NotificationDeliveryMethod) {
const enabledDeliveryMethods = this.notificationSettingsFormGroup.get('enabledDeliveryMethods').value; this.notificationSettingsFormGroup.get('enabledDeliveryMethods').get(deliveryMethod)
if (enabledDeliveryMethods.includes(deliveryMethod)) { .patchValue(!this.notificationSettingsFormGroup.get('enabledDeliveryMethods').get(deliveryMethod).value);
enabledDeliveryMethods.splice(enabledDeliveryMethods.indexOf(deliveryMethod), 1);
} else {
enabledDeliveryMethods.push(deliveryMethod);
}
this.notificationSettingsFormGroup.get('enabledDeliveryMethods').patchValue(enabledDeliveryMethods);
} }
writeValue(value: NotificationUserSetting): void { writeValue(value: NotificationUserSetting): void {

28
ui-ngx/src/app/modules/home/pages/notification/settings/notification-settings.component.html

@ -16,7 +16,7 @@
--> -->
<div> <div>
<mat-card appearance="outlined" class="settings-card"> <mat-card appearance="outlined" class="settings-card tb-absolute-fill">
<mat-card-header> <mat-card-header>
<div fxFlex fxLayout="row" fxLayout.xs="column" fxLayoutGap.xs="8px" <div fxFlex fxLayout="row" fxLayout.xs="column" fxLayoutGap.xs="8px"
fxLayoutAlign="space-between start" fxLayoutAlign.xs="start start"> fxLayoutAlign="space-between start" fxLayoutAlign.xs="start start">
@ -33,8 +33,8 @@
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async"> <mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
</mat-progress-bar> </mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div> <div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<mat-card-content style="padding-top: 16px;"> <mat-card-content style="padding-top: 16px; overflow: hidden;">
<form [formGroup]="notificationSettings" (ngSubmit)="save()"> <form [formGroup]="notificationSettings" class="notification-form">
<section class="notification-section"> <section class="notification-section">
<div class="notification-section-block"> <div class="notification-section-block">
<div fxLayout="row" fxLayoutAlign="start center" style="height: 44px;"> <div fxLayout="row" fxLayoutAlign="start center" style="height: 44px;">
@ -48,7 +48,7 @@
</mat-checkbox> </mat-checkbox>
</div> </div>
<div fxFlex *ngFor="let deliveryMethods of notificationDeliveryMethods"> <div fxFlex *ngFor="let deliveryMethods of notificationDeliveryMethods">
<div fxFlex fxLayoutAlign="center center"> <div fxFlex fxLayoutAlign="start center">
<mat-checkbox color="warn" <mat-checkbox color="warn"
[disabled]="!allowNotificationDeliveryMethods?.includes(deliveryMethods) || !getSomeChecked()" [disabled]="!allowNotificationDeliveryMethods?.includes(deliveryMethods) || !getSomeChecked()"
[checked]="getChecked(deliveryMethods)" [checked]="getChecked(deliveryMethods)"
@ -62,19 +62,23 @@
</div> </div>
<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" [allowDeliveryMethods]="allowNotificationDeliveryMethods"></tb-notification-setting-form> <tb-notification-setting-form [formControl]="settingsControl"
[deliveryMethods]="notificationDeliveryMethods"
[allowDeliveryMethods]="allowNotificationDeliveryMethods">
</tb-notification-setting-form>
<mat-divider *ngIf="!$last"></mat-divider> <mat-divider *ngIf="!$last"></mat-divider>
</div> </div>
</div> </div>
</section> </section>
<div fxLayout="row" fxLayoutAlign="end start">
<button mat-button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || notificationSettings.invalid || !notificationSettings.dirty">
{{ 'action.save' | translate }}
</button>
</div>
</form> </form>
</mat-card-content> </mat-card-content>
<div fxLayout="row" fxLayoutAlign="end start" style="padding: 16px;">
<button mat-button mat-raised-button color="primary"
type="button"
(click)="save()"
[disabled]="(isLoading$ | async) || notificationSettings.invalid || !notificationSettings.dirty">
{{ 'action.save' | translate }}
</button>
</div>
</mat-card> </mat-card>
</div> </div>

12
ui-ngx/src/app/modules/home/pages/notification/settings/notification-settings.component.scss

@ -24,13 +24,17 @@
.mat-headline-5 { .mat-headline-5 {
margin: 0; margin: 0;
} }
.notification-form {
height: 100%;
min-height: min-content;
max-height: min-content;
}
.notification-section { .notification-section {
margin-bottom: 16px; height: 100%;
border: 1px solid rgba(0, 0, 0, 0.12); border: 1px solid rgba(0, 0, 0, 0.12);
overflow-y: hidden; overflow: scroll;
overflow-x: scroll;
&-block { &-block {
min-width: 700px; min-width: 470px;
} }
} }
} }

28
ui-ngx/src/app/modules/home/pages/notification/settings/notification-settings.component.ts

@ -40,7 +40,7 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
notificationSettings: UntypedFormGroup; notificationSettings: UntypedFormGroup;
notificationDeliveryMethods = [NotificationDeliveryMethod.WEB, NotificationDeliveryMethod.SMS, NotificationDeliveryMethod.EMAIL]; notificationDeliveryMethods: NotificationDeliveryMethod[];
notificationDeliveryMethodTranslateMap = NotificationDeliveryMethodTranslateMap; notificationDeliveryMethodTranslateMap = NotificationDeliveryMethodTranslateMap;
allowNotificationDeliveryMethods: Array<NotificationDeliveryMethod>; allowNotificationDeliveryMethods: Array<NotificationDeliveryMethod>;
@ -55,6 +55,7 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
} }
ngOnInit() { ngOnInit() {
this.notificationDeliveryMethods = this.getNotificationDeliveryMethods();
this.notificationService.getAvailableDeliveryMethods({ignoreLoading: true}).subscribe(allowMethods => { this.notificationService.getAvailableDeliveryMethods({ignoreLoading: true}).subscribe(allowMethods => {
this.allowNotificationDeliveryMethods = allowMethods; this.allowNotificationDeliveryMethods = allowMethods;
@ -64,6 +65,13 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
this.patchNotificationSettings(this.route.snapshot.data.userSettings); this.patchNotificationSettings(this.route.snapshot.data.userSettings);
} }
private getNotificationDeliveryMethods(): NotificationDeliveryMethod[] {
const deliveryMethods = new Set([
NotificationDeliveryMethod.SLACK
]);
return Object.values(NotificationDeliveryMethod).filter(type => !deliveryMethods.has(type));
}
private buildNotificationSettingsForm() { private buildNotificationSettingsForm() {
this.notificationSettings = this.fb.group({ this.notificationSettings = this.fb.group({
prefs: this.fb.array([]) prefs: this.fb.array([])
@ -76,6 +84,10 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
if (settings.prefs) { if (settings.prefs) {
preparedSettings = this.prepareNotificationSettings(settings.prefs); preparedSettings = this.prepareNotificationSettings(settings.prefs);
preparedSettings.forEach((setting) => { preparedSettings.forEach((setting) => {
setting.enabledDeliveryMethods = Object.assign(
this.notificationDeliveryMethods.reduce((a, v) => ({ ...a, [v]: true}), {}),
setting.enabledDeliveryMethods
);
notificationSettingsControls.push(this.fb.control(setting, [Validators.required])); notificationSettingsControls.push(this.fb.control(setting, [Validators.required]));
}); });
} }
@ -105,7 +117,7 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
if (settings) { if (settings) {
settings.forEach((setting) => { settings.forEach((setting) => {
setting.enabled = true; setting.enabled = true;
setting.enabledDeliveryMethods = this.notificationDeliveryMethods; setting.enabledDeliveryMethods = this.notificationDeliveryMethods.reduce((a, v) => ({ ...a, [v]: true}), {});
notificationSettingsControls.push(this.fb.control(setting, [Validators.required])); notificationSettingsControls.push(this.fb.control(setting, [Validators.required]));
}); });
} }
@ -119,7 +131,7 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
getChecked = (method: NotificationDeliveryMethod = null): boolean => { getChecked = (method: NotificationDeliveryMethod = null): boolean => {
const type = this.notificationSettings.get('prefs').value; const type = this.notificationSettings.get('prefs').value;
if (isDefinedAndNotNull(method)) { if (isDefinedAndNotNull(method)) {
return isDefinedAndNotNull(type) && type.every(resource => resource.enabledDeliveryMethods.includes(method)); return isDefinedAndNotNull(type) && type.every(resource => resource.enabledDeliveryMethods[method]);
} }
return isDefinedAndNotNull(type) && type.every(resource => resource.enabled); return isDefinedAndNotNull(type) && type.every(resource => resource.enabled);
}; };
@ -133,7 +145,7 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
const type = this.notificationSettings.get('prefs').value; const type = this.notificationSettings.get('prefs').value;
if (isDefinedAndNotNull(type)) { if (isDefinedAndNotNull(type)) {
const checkedResource = isDefinedAndNotNull(deliveryMethod) ? const checkedResource = isDefinedAndNotNull(deliveryMethod) ?
type.filter(resource => resource.enabledDeliveryMethods.includes(deliveryMethod)) : type.filter(resource => resource.enabledDeliveryMethods[deliveryMethod]) :
type.filter(resource => resource.enabled); type.filter(resource => resource.enabled);
return checkedResource.length !== 0 && checkedResource.length !== type.length; return checkedResource.length !== 0 && checkedResource.length !== type.length;
} }
@ -143,13 +155,7 @@ export class NotificationSettingsComponent extends PageComponent implements OnIn
changeInstanceTypeCheckBox = (value: boolean, deliveryMethod: NotificationDeliveryMethod = null): void => { changeInstanceTypeCheckBox = (value: boolean, deliveryMethod: NotificationDeliveryMethod = null): void => {
const type = deepClone(this.notificationSettings.get('prefs').value); const type = deepClone(this.notificationSettings.get('prefs').value);
if (isDefinedAndNotNull(deliveryMethod)) { if (isDefinedAndNotNull(deliveryMethod)) {
type.forEach(notificationType => { type.forEach(notificationType => notificationType.enabledDeliveryMethods[deliveryMethod] = value);
if (value && !notificationType.enabledDeliveryMethods.includes(deliveryMethod)) {
notificationType.enabledDeliveryMethods.push(deliveryMethod);
} else if (!value && notificationType.enabledDeliveryMethods.includes(deliveryMethod)) {
notificationType.enabledDeliveryMethods.splice(notificationType.enabledDeliveryMethods.indexOf(deliveryMethod), 1);
}
});
} else { } else {
type.forEach(notificationType => notificationType.enabled = value); type.forEach(notificationType => notificationType.enabled = value);
} }

3
ui-ngx/src/app/shared/models/notification.models.ts

@ -596,6 +596,5 @@ export interface NotificationUserSettings {
export interface NotificationUserSetting { export interface NotificationUserSetting {
enabled: boolean; enabled: boolean;
enabledDeliveryMethods: Array<NotificationDeliveryMethod>; enabledDeliveryMethods: {[key: string]: boolean};
} }

Loading…
Cancel
Save