Browse Source

UI: Add allow delete notification and request notification

pull/7911/head
Vladyslav_Prykhodko 4 years ago
parent
commit
894b992196
  1. 4
      ui-ngx/src/app/core/http/notification.service.ts
  2. 16
      ui-ngx/src/app/modules/home/pages/notification/inbox/inbox-table-config.resolver.ts
  3. 8
      ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-table-config.resolver.ts
  4. 8
      ui-ngx/src/app/modules/home/pages/notification/rule/rule-table-config.resolver.ts
  5. 57
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html
  6. 2
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.scss
  7. 13
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts
  8. 15
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts
  9. 14
      ui-ngx/src/app/modules/home/pages/notification/template/template-configuration.ts
  10. 58
      ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.html
  11. 12
      ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.ts
  12. 16
      ui-ngx/src/app/modules/home/pages/notification/template/template-table-config.resolver.ts
  13. 3
      ui-ngx/src/app/shared/components/notification/notification.component.html
  14. 21
      ui-ngx/src/app/shared/models/entity-type.models.ts
  15. 2
      ui-ngx/src/app/shared/models/notification.models.ts
  16. 9
      ui-ngx/src/assets/locale/locale.constant-en_US.json

4
ui-ngx/src/app/core/http/notification.service.ts

@ -51,6 +51,10 @@ export class NotificationService {
defaultHttpOptionsFromConfig(config)); defaultHttpOptionsFromConfig(config));
} }
public deleteNotification(id: string, config?: RequestConfig): Observable<void> {
return this.http.delete<void>(`/api/notification/${id}`, defaultHttpOptionsFromConfig(config));
}
public markNotificationAsRead(id: string, config?: RequestConfig): Observable<void> { public markNotificationAsRead(id: string, config?: RequestConfig): Observable<void> {
return this.http.put<void>(`/api/notification/${id}/read`, defaultHttpOptionsFromConfig(config)); return this.http.put<void>(`/api/notification/${id}/read`, defaultHttpOptionsFromConfig(config));
} }

16
ui-ngx/src/app/modules/home/pages/notification/inbox/inbox-table-config.resolver.ts

@ -20,7 +20,7 @@ import {
EntityTableColumn, EntityTableColumn,
EntityTableConfig EntityTableConfig
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
import { EntityTypeResource } from '@shared/models/entity-type.models'; import { EntityType, EntityTypeResource, entityTypeTranslations } from '@shared/models/entity-type.models';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { import {
@ -50,17 +50,19 @@ export class InboxTableConfigResolver implements Resolve<EntityTableConfig<Notif
private dialog: MatDialog, private dialog: MatDialog,
private datePipe: DatePipe) { private datePipe: DatePipe) {
this.config.entityType = EntityType.NOTIFICATION;
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.selectionEnabled = false;
this.config.addEnabled = false; this.config.addEnabled = false;
this.config.entitiesDeleteEnabled = false;
this.config.rowPointer = true; this.config.rowPointer = true;
this.config.entityTranslations = { this.config.entityTranslations = entityTypeTranslations.get(EntityType.NOTIFICATION);
noEntities: 'notification.no-inbox-notification',
search: 'notification.search-notification'
};
this.config.entityResources = {} as EntityTypeResource<Notification>; this.config.entityResources = {} as EntityTypeResource<Notification>;
this.config.deleteEntityTitle = () => this.translate.instant('notification.delete-notification-title');
this.config.deleteEntityContent = () => this.translate.instant('notification.delete-notification-text');
this.config.deleteEntitiesTitle = count => this.translate.instant('notification.delete-notifications-title', {count});
this.config.deleteEntitiesContent = () => this.translate.instant('notification.delete-notifications-text');
this.config.deleteEntity = id => this.notificationService.deleteNotification(id.id);
this.config.entitiesFetchFunction = pageLink => this.config.entitiesFetchFunction = pageLink =>
this.notificationService.getNotifications(pageLink, this.config.componentsData.unreadOnly); this.notificationService.getNotifications(pageLink, this.config.componentsData.unreadOnly);

8
ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-table-config.resolver.ts

@ -20,7 +20,7 @@ import {
EntityTableColumn, EntityTableColumn,
EntityTableConfig EntityTableConfig
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
import { EntityTypeResource } from '@shared/models/entity-type.models'; import { EntityType, EntityTypeResource, entityTypeTranslations } from '@shared/models/entity-type.models';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { NotificationTarget, NotificationTargetTypeTranslationMap } from '@shared/models/notification.models'; import { NotificationTarget, NotificationTargetTypeTranslationMap } from '@shared/models/notification.models';
import { NotificationService } from '@core/http/notification.service'; import { NotificationService } from '@core/http/notification.service';
@ -46,15 +46,13 @@ export class RecipientTableConfigResolver implements Resolve<EntityTableConfig<N
private dialog: MatDialog, private dialog: MatDialog,
private datePipe: DatePipe) { private datePipe: DatePipe) {
this.config.entityType = EntityType.NOTIFICATION_TARGET;
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.selectionEnabled = false; this.config.selectionEnabled = false;
this.config.addEnabled = false; this.config.addEnabled = false;
this.config.rowPointer = true; this.config.rowPointer = true;
this.config.entityTranslations = { this.config.entityTranslations = entityTypeTranslations.get(EntityType.NOTIFICATION_TARGET);
noEntities: 'notification.no-targets-notification',
search: 'notification.search-targets'
};
this.config.entityResources = {} as EntityTypeResource<NotificationTarget>; this.config.entityResources = {} as EntityTypeResource<NotificationTarget>;
this.config.entitiesFetchFunction = pageLink => this.notificationService.getNotificationTargets(pageLink); this.config.entitiesFetchFunction = pageLink => this.notificationService.getNotificationTargets(pageLink);

8
ui-ngx/src/app/modules/home/pages/notification/rule/rule-table-config.resolver.ts

@ -20,7 +20,7 @@ import {
EntityTableColumn, EntityTableColumn,
EntityTableConfig EntityTableConfig
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
import { EntityTypeResource } from '@shared/models/entity-type.models'; import { EntityType, EntityTypeResource, entityTypeTranslations } from '@shared/models/entity-type.models';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { NotificationRule, TriggerTypeTranslationMap } from '@shared/models/notification.models'; import { NotificationRule, TriggerTypeTranslationMap } from '@shared/models/notification.models';
import { NotificationService } from '@core/http/notification.service'; import { NotificationService } from '@core/http/notification.service';
@ -46,15 +46,13 @@ export class RuleTableConfigResolver implements Resolve<EntityTableConfig<Notifi
private dialog: MatDialog, private dialog: MatDialog,
private datePipe: DatePipe) { private datePipe: DatePipe) {
this.config.entityType = EntityType.NOTIFICATION_RULE;
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.selectionEnabled = false; this.config.selectionEnabled = false;
this.config.addEnabled = false; this.config.addEnabled = false;
this.config.rowPointer = true; this.config.rowPointer = true;
this.config.entityTranslations = { this.config.entityTranslations = entityTypeTranslations.get(EntityType.NOTIFICATION_RULE);
noEntities: 'notification.no-rules-notification',
search: 'notification.search-rules'
};
this.config.entityResources = {} as EntityTypeResource<NotificationRule>; this.config.entityResources = {} as EntityTypeResource<NotificationRule>;
this.config.entitiesFetchFunction = pageLink => this.notificationService.getNotificationRules(pageLink); this.config.entitiesFetchFunction = pageLink => this.notificationService.getNotificationRules(pageLink);

57
ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html

@ -28,7 +28,8 @@
</mat-progress-bar> </mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div> <div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<div mat-dialog-content> <div mat-dialog-content>
<mat-horizontal-stepper [linear]="true" #createNotification <mat-horizontal-stepper linear #createNotification
[labelPosition]="(stepperLabelPosition | async)"
[orientation]="(stepperOrientation | async)" [orientation]="(stepperOrientation | async)"
(selectionChange)="changeStep($event)"> (selectionChange)="changeStep($event)">
<ng-template matStepperIcon="edit"> <ng-template matStepperIcon="edit">
@ -55,22 +56,6 @@
<ng-template #scratchTemplate> <ng-template #scratchTemplate>
<section formGroupName="template"> <section formGroupName="template">
<section formGroupName="configuration"> <section formGroupName="configuration">
<mat-form-field class="mat-block" subscriptSizing="dynamic">
<mat-label translate>notification.subject</mat-label>
<input matInput formControlName="notificationSubject" required>
<mat-error *ngIf="notificationRequestForm.get('template.configuration.notificationSubject').hasError('required')">
{{ 'notification.subject-required' | translate }}
</mat-error>
<mat-hint>{{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }}</mat-hint>
</mat-form-field>
<mat-form-field class="mat-block tb-form-fields" subscriptSizing="dynamic">
<mat-label translate>notification.message</mat-label>
<input matInput formControlName="defaultTextTemplate" required>
<mat-error *ngIf="notificationRequestForm.get('template.configuration.defaultTextTemplate').hasError('required')">
{{ 'notification.message-required' | translate }}
</mat-error>
<mat-hint>{{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }}</mat-hint>
</mat-form-field>
<label class="tb-title tb-required" <label class="tb-title tb-required"
[ngClass]="{'tb-error': notificationRequestForm.get('template.configuration.deliveryMethodsTemplates').hasError('atLeastOne')}"> [ngClass]="{'tb-error': notificationRequestForm.get('template.configuration.deliveryMethodsTemplates').hasError('atLeastOne')}">
{{ "notification.delivery-methods" | translate }} {{ "notification.delivery-methods" | translate }}
@ -127,19 +112,24 @@
{{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }} {{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }}
</div> </div>
<form [formGroup]="webTemplateForm"> <form [formGroup]="webTemplateForm">
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.subject</mat-label> <mat-label translate>notification.subject</mat-label>
<input matInput formControlName="subject" [placeholder]="notificationRequestForm.get('template.configuration.notificationSubject').value"> <input matInput formControlName="subject">
<mat-error *ngIf="webTemplateForm.get('subject').hasError('required')">
{{ 'notification.subject-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.message</mat-label> <mat-label translate>notification.message</mat-label>
<textarea matInput <textarea matInput
cdkTextareaAutosize cdkTextareaAutosize
cols="1" cols="1"
cdkAutosizeMinRows="1" cdkAutosizeMinRows="1"
formControlName="body" formControlName="body">
[placeholder]="notificationRequestForm.get('template.configuration.defaultTextTemplate').value">
</textarea> </textarea>
<mat-error *ngIf="webTemplateForm.get('body').hasError('required')">
{{ 'notification.message-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<section formGroupName="additionalConfig"> <section formGroupName="additionalConfig">
<section formGroupName="icon" class="additional-config-group"> <section formGroupName="icon" class="additional-config-group">
@ -215,9 +205,12 @@
{{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }} {{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }}
</div> </div>
<form [formGroup]="emailTemplateForm"> <form [formGroup]="emailTemplateForm">
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.subject</mat-label> <mat-label translate>notification.subject</mat-label>
<input matInput formControlName="subject" [placeholder]="notificationRequestForm.get('template.configuration.notificationSubject').value"> <input matInput formControlName="subject">
<mat-error *ngIf="emailTemplateForm.get('subject').hasError('required')">
{{ 'notification.subject-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<mat-label class="tb-title" translate>notification.message</mat-label> <mat-label class="tb-title" translate>notification.message</mat-label>
<editor [init]="tinyMceOptions" formControlName="body"></editor> <editor [init]="tinyMceOptions" formControlName="body"></editor>
@ -232,15 +225,17 @@
{{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }} {{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }}
</div> </div>
<form [formGroup]="smsTemplateForm"> <form [formGroup]="smsTemplateForm">
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.message</mat-label> <mat-label translate>notification.message</mat-label>
<textarea matInput <textarea matInput
cdkTextareaAutosize cdkTextareaAutosize
cols="1" cols="1"
cdkAutosizeMinRows="1" cdkAutosizeMinRows="1"
formControlName="body" formControlName="body">
[placeholder]="notificationRequestForm.get('template.configuration.defaultTextTemplate').value">
</textarea> </textarea>
<mat-error *ngIf="smsTemplateForm.get('body').hasError('required')">
{{ 'notification.message-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
</form> </form>
</mat-step> </mat-step>
@ -252,15 +247,17 @@
{{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }} {{ notificationTemplateTypeTranslateMap.get(notificationType.GENERAL).hint | translate }}
</div> </div>
<form [formGroup]="slackTemplateForm" fxLayoutGap="8px"> <form [formGroup]="slackTemplateForm" fxLayoutGap="8px">
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.message</mat-label> <mat-label translate>notification.message</mat-label>
<textarea matInput <textarea matInput
cdkTextareaAutosize cdkTextareaAutosize
cols="1" cols="1"
cdkAutosizeMinRows="1" cdkAutosizeMinRows="1"
formControlName="body" formControlName="body">
[placeholder]="notificationRequestForm.get('template.configuration.defaultTextTemplate').value">
</textarea> </textarea>
<mat-error *ngIf="slackTemplateForm.get('body').hasError('required')">
{{ 'notification.message-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
</form> </form>
</mat-step> </mat-step>

2
ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.scss

@ -17,7 +17,7 @@
@import "../../../../../../theme"; @import "../../../../../../theme";
:host-context(.tb-fullscreen-dialog .mat-mdc-dialog-container) { :host-context(.tb-fullscreen-dialog .mat-mdc-dialog-container) {
width: 800px; width: 1000px;
height: 100%; height: 100%;
max-width: 100%; max-width: 100%;
max-height: 100vh; max-height: 100vh;

13
ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts

@ -60,6 +60,8 @@ export class SentNotificationDialogComponent extends
@ViewChild('createNotification', {static: true}) createNotification: MatStepper; @ViewChild('createNotification', {static: true}) createNotification: MatStepper;
stepperOrientation: Observable<StepperOrientation>; stepperOrientation: Observable<StepperOrientation>;
stepperLabelPosition: Observable<'bottom' | 'end'>;
isAdd = true; isAdd = true;
entityType = EntityType; entityType = EntityType;
notificationType = NotificationType; notificationType = NotificationType;
@ -87,6 +89,9 @@ export class SentNotificationDialogComponent extends
this.stepperOrientation = this.breakpointObserver.observe(MediaBreakpoints['gt-sm']) this.stepperOrientation = this.breakpointObserver.observe(MediaBreakpoints['gt-sm'])
.pipe(map(({matches}) => matches ? 'horizontal' : 'vertical')); .pipe(map(({matches}) => matches ? 'horizontal' : 'vertical'));
this.stepperLabelPosition = this.breakpointObserver.observe(MediaBreakpoints['gt-md'])
.pipe(map(({matches}) => matches ? 'end' : 'bottom'));
this.notificationRequestForm = this.fb.group({ this.notificationRequestForm = this.fb.group({
useTemplate: [false], useTemplate: [false],
templateId: [{value: null, disabled: true}, Validators.required], templateId: [{value: null, disabled: true}, Validators.required],
@ -148,12 +153,8 @@ export class SentNotificationDialogComponent extends
} }
nextStepLabel(): string { nextStepLabel(): string {
if (this.selectedIndex !== 0) { if (this.selectedIndex >= this.maxStepperIndex) {
if (this.selectedIndex >= this.maxStepperIndex) { return 'action.send';
return 'action.send';
} else if (this.createNotification.selected.stepControl.pristine) {
return 'action.skip';
}
} }
return 'action.next'; return 'action.next';
} }

15
ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts

@ -32,7 +32,7 @@ import {
import { NotificationService } from '@core/http/notification.service'; import { NotificationService } from '@core/http/notification.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { EntityTypeResource } from '@shared/models/entity-type.models'; import { EntityType, EntityTypeResource, entityTypeTranslations } from '@shared/models/entity-type.models';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { EntityAction } from '@home/models/entity/entity-component.models'; import { EntityAction } from '@home/models/entity/entity-component.models';
@ -60,21 +60,20 @@ export class SentTableConfigResolver implements Resolve<EntityTableConfig<Notifi
private dialog: MatDialog, private dialog: MatDialog,
private datePipe: DatePipe) { private datePipe: DatePipe) {
this.config.entityType = EntityType.NOTIFICATION_REQUEST;
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.selectionEnabled = false;
this.config.addEnabled = false; this.config.addEnabled = false;
this.config.searchEnabled = false; this.config.searchEnabled = false;
this.config.entityTranslations = { this.config.entityTranslations = entityTypeTranslations.get(EntityType.NOTIFICATION_REQUEST);
noEntities: 'notification.no-notification-request',
};
this.config.entityResources = {} as EntityTypeResource<NotificationRequest>; this.config.entityResources = {} as EntityTypeResource<NotificationRequest>;
this.config.entitiesFetchFunction = pageLink => this.notificationService.getNotificationRequests(pageLink);
this.config.deleteEnabled = (request) => request.status === NotificationRequestStatus.SCHEDULED;
this.config.deleteEntityTitle = () => this.translate.instant('notification.delete-request-title'); this.config.deleteEntityTitle = () => this.translate.instant('notification.delete-request-title');
this.config.deleteEntityContent = () => this.translate.instant('notification.delete-request-text'); this.config.deleteEntityContent = () => this.translate.instant('notification.delete-request-text');
this.config.deleteEntitiesTitle = count => this.translate.instant('notification.delete-requests-title', {count});
this.config.deleteEntitiesContent = () => this.translate.instant('notification.delete-requests-text');
this.config.deleteEntity = id => this.notificationService.deleteNotificationRequest(id.id); this.config.deleteEntity = id => this.notificationService.deleteNotificationRequest(id.id);
this.config.entitiesFetchFunction = pageLink => this.notificationService.getNotificationRequests(pageLink);
this.config.cellActionDescriptors = this.configureCellActions(); this.config.cellActionDescriptors = this.configureCellActions();

14
ui-ngx/src/app/modules/home/pages/notification/template/template-configuration.ts

@ -79,8 +79,6 @@ export abstract class TemplateConfiguration<T, R = any> extends DialogComponent<
name: ['', Validators.required], name: ['', Validators.required],
notificationType: [NotificationType.GENERAL], notificationType: [NotificationType.GENERAL],
configuration: this.fb.group({ configuration: this.fb.group({
notificationSubject: ['', Validators.required],
defaultTextTemplate: ['', Validators.required],
deliveryMethodsTemplates: this.fb.group({}, {validators: this.atLeastOne()}) deliveryMethodsTemplates: this.fb.group({}, {validators: this.atLeastOne()})
}) })
}); });
@ -91,8 +89,8 @@ export abstract class TemplateConfiguration<T, R = any> extends DialogComponent<
}); });
this.webTemplateForm = this.fb.group({ this.webTemplateForm = this.fb.group({
subject: [''], subject: ['', Validators.required],
body: [''], body: ['', Validators.required],
additionalConfig: this.fb.group({ additionalConfig: this.fb.group({
icon: this.fb.group({ icon: this.fb.group({
enabled: [false], enabled: [false],
@ -153,16 +151,16 @@ export abstract class TemplateConfiguration<T, R = any> extends DialogComponent<
}); });
this.emailTemplateForm = this.fb.group({ this.emailTemplateForm = this.fb.group({
subject: [''], subject: ['', Validators.required],
body: [''] body: ['', Validators.required]
}); });
this.smsTemplateForm = this.fb.group({ this.smsTemplateForm = this.fb.group({
body: [''] body: ['', Validators.required]
}); });
this.slackTemplateForm = this.fb.group({ this.slackTemplateForm = this.fb.group({
body: [''] body: ['', Validators.required]
}); });
this.deliveryMethodFormsMap = new Map<NotificationDeliveryMethod, FormGroup>([ this.deliveryMethodFormsMap = new Map<NotificationDeliveryMethod, FormGroup>([

58
ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.html

@ -28,7 +28,9 @@
</mat-progress-bar> </mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div> <div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<div mat-dialog-content> <div mat-dialog-content>
<mat-horizontal-stepper linear labelPosition="end" #notificationTemplateStepper [orientation]="(stepperOrientation | async)" <mat-horizontal-stepper linear #notificationTemplateStepper
[labelPosition]="(stepperLabelPosition | async)"
[orientation]="(stepperOrientation | async)"
(selectionChange)="changeStep($event)"> (selectionChange)="changeStep($event)">
<ng-template matStepperIcon="edit"> <ng-template matStepperIcon="edit">
<mat-icon>check</mat-icon> <mat-icon>check</mat-icon>
@ -52,22 +54,6 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<section formGroupName="configuration"> <section formGroupName="configuration">
<mat-form-field class="mat-block" subscriptSizing="dynamic">
<mat-label translate>notification.subject</mat-label>
<input matInput formControlName="notificationSubject" required>
<mat-error *ngIf="templateNotificationForm.get('configuration.notificationSubject').hasError('required')">
{{ 'notification.subject-required' | translate }}
</mat-error>
<mat-hint>{{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }}</mat-hint>
</mat-form-field>
<mat-form-field class="mat-block tb-form-fields" subscriptSizing="dynamic">
<mat-label translate>notification.message</mat-label>
<input matInput formControlName="defaultTextTemplate" required>
<mat-error *ngIf="templateNotificationForm.get('configuration.defaultTextTemplate').hasError('required')">
{{ 'notification.message-required' | translate }}
</mat-error>
<mat-hint>{{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }}</mat-hint>
</mat-form-field>
<label class="tb-title tb-required" <label class="tb-title tb-required"
[ngClass]="{'tb-error': templateNotificationForm.get('configuration.deliveryMethodsTemplates').hasError('atLeastOne')}"> [ngClass]="{'tb-error': templateNotificationForm.get('configuration.deliveryMethodsTemplates').hasError('atLeastOne')}">
{{ "notification.delivery-methods" | translate }} {{ "notification.delivery-methods" | translate }}
@ -91,19 +77,24 @@
{{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }} {{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }}
</div> </div>
<form [formGroup]="webTemplateForm"> <form [formGroup]="webTemplateForm">
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.subject</mat-label> <mat-label translate>notification.subject</mat-label>
<input matInput formControlName="subject" [placeholder]="templateNotificationForm.get('configuration.notificationSubject').value"> <input matInput formControlName="subject">
<mat-error *ngIf="webTemplateForm.get('subject').hasError('required')">
{{ 'notification.subject-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.message</mat-label> <mat-label translate>notification.message</mat-label>
<textarea matInput <textarea matInput
cdkTextareaAutosize cdkTextareaAutosize
cols="1" cols="1"
cdkAutosizeMinRows="1" cdkAutosizeMinRows="1"
formControlName="body" formControlName="body">
[placeholder]="templateNotificationForm.get('configuration.defaultTextTemplate').value">
</textarea> </textarea>
<mat-error *ngIf="webTemplateForm.get('body').hasError('required')">
{{ 'notification.message-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<section formGroupName="additionalConfig"> <section formGroupName="additionalConfig">
<section formGroupName="icon" class="additional-config-group"> <section formGroupName="icon" class="additional-config-group">
@ -178,9 +169,12 @@
{{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }} {{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }}
</div> </div>
<form [formGroup]="emailTemplateForm"> <form [formGroup]="emailTemplateForm">
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.subject</mat-label> <mat-label translate>notification.subject</mat-label>
<input matInput formControlName="subject" [placeholder]="templateNotificationForm.get('configuration.notificationSubject').value"> <input matInput formControlName="subject">
<mat-error *ngIf="emailTemplateForm.get('subject').hasError('required')">
{{ 'notification.subject-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<mat-label class="tb-title" translate>notification.message</mat-label> <mat-label class="tb-title" translate>notification.message</mat-label>
<editor [init]="tinyMceOptions" formControlName="body"></editor> <editor [init]="tinyMceOptions" formControlName="body"></editor>
@ -194,15 +188,17 @@
{{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }} {{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }}
</div> </div>
<form [formGroup]="smsTemplateForm"> <form [formGroup]="smsTemplateForm">
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.message</mat-label> <mat-label translate>notification.message</mat-label>
<textarea matInput <textarea matInput
cdkTextareaAutosize cdkTextareaAutosize
cols="1" cols="1"
cdkAutosizeMinRows="1" cdkAutosizeMinRows="1"
formControlName="body" formControlName="body">
[placeholder]="templateNotificationForm.get('configuration.defaultTextTemplate').value">
</textarea> </textarea>
<mat-error *ngIf="smsTemplateForm.get('body').hasError('required')">
{{ 'notification.message-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
</form> </form>
</mat-step> </mat-step>
@ -213,15 +209,17 @@
{{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }} {{ notificationTemplateTypeTranslateMap.get(templateNotificationForm.get('notificationType').value).hint | translate }}
</div> </div>
<form [formGroup]="slackTemplateForm" fxLayoutGap="8px"> <form [formGroup]="slackTemplateForm" fxLayoutGap="8px">
<mat-form-field class="mat-block" floatLabel="always"> <mat-form-field class="mat-block">
<mat-label translate>notification.message</mat-label> <mat-label translate>notification.message</mat-label>
<textarea matInput <textarea matInput
cdkTextareaAutosize cdkTextareaAutosize
cols="1" cols="1"
cdkAutosizeMinRows="1" cdkAutosizeMinRows="1"
formControlName="body" formControlName="body">
[placeholder]="templateNotificationForm.get('configuration.defaultTextTemplate').value">
</textarea> </textarea>
<mat-error *ngIf="slackTemplateForm.get('body').hasError('required')">
{{ 'notification.message-required' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
</form> </form>
</mat-step> </mat-step>

12
ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.ts

@ -54,6 +54,7 @@ export class TemplateNotificationDialogComponent
@ViewChild('notificationTemplateStepper', {static: true}) notificationTemplateStepper: MatStepper; @ViewChild('notificationTemplateStepper', {static: true}) notificationTemplateStepper: MatStepper;
stepperOrientation: Observable<StepperOrientation>; stepperOrientation: Observable<StepperOrientation>;
stepperLabelPosition: Observable<'bottom' | 'end'>;
dialogTitle = 'notification.edit-notification-template'; dialogTitle = 'notification.edit-notification-template';
@ -81,6 +82,9 @@ export class TemplateNotificationDialogComponent
this.stepperOrientation = this.breakpointObserver.observe(MediaBreakpoints['gt-sm']) this.stepperOrientation = this.breakpointObserver.observe(MediaBreakpoints['gt-sm'])
.pipe(map(({matches}) => matches ? 'horizontal' : 'vertical')); .pipe(map(({matches}) => matches ? 'horizontal' : 'vertical'));
this.stepperLabelPosition = this.breakpointObserver.observe(MediaBreakpoints['gt-md'])
.pipe(map(({matches}) => matches ? 'end' : 'bottom'));
if (isDefinedAndNotNull(this.data?.predefinedType)) { if (isDefinedAndNotNull(this.data?.predefinedType)) {
this.hideSelectType = true; this.hideSelectType = true;
this.templateNotificationForm.get('notificationType').setValue(this.data.predefinedType, {emitEvents: false}); this.templateNotificationForm.get('notificationType').setValue(this.data.predefinedType, {emitEvents: false});
@ -132,12 +136,8 @@ export class TemplateNotificationDialogComponent
} }
nextStepLabel(): string { nextStepLabel(): string {
if (this.selectedIndex !== 0) { if (this.selectedIndex >= this.maxStepperIndex) {
if (this.selectedIndex >= this.maxStepperIndex) { return (this.data.isAdd || this.data.isCopy) ? 'action.add' : 'action.save';
return (this.data.isAdd || this.data.isCopy) ? 'action.add' : 'action.save';
} else if (this.notificationTemplateStepper.selected.stepControl.pristine) {
return 'action.skip';
}
} }
return 'action.next'; return 'action.next';
} }

16
ui-ngx/src/app/modules/home/pages/notification/template/template-table-config.resolver.ts

@ -20,7 +20,7 @@ import {
EntityTableColumn, EntityTableColumn,
EntityTableConfig EntityTableConfig
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
import { EntityTypeResource } from '@shared/models/entity-type.models'; import { EntityType, EntityTypeResource, entityTypeTranslations } from '@shared/models/entity-type.models';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { NotificationTemplate, NotificationTemplateTypeTranslateMap } from '@shared/models/notification.models'; import { NotificationTemplate, NotificationTemplateTypeTranslateMap } from '@shared/models/notification.models';
import { NotificationService } from '@core/http/notification.service'; import { NotificationService } from '@core/http/notification.service';
@ -46,15 +46,13 @@ export class TemplateTableConfigResolver implements Resolve<EntityTableConfig<No
private dialog: MatDialog, private dialog: MatDialog,
private datePipe: DatePipe) { private datePipe: DatePipe) {
this.config.entityType = EntityType.NOTIFICATION_TEMPLATE;
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.selectionEnabled = false; this.config.selectionEnabled = false;
this.config.addEnabled = false; this.config.addEnabled = false;
this.config.rowPointer = true; this.config.rowPointer = true;
this.config.entityTranslations = { this.config.entityTranslations = entityTypeTranslations.get(EntityType.NOTIFICATION_TEMPLATE);
noEntities: 'notification.no-notification-templates',
search: 'notification.search-templates'
};
this.config.entityResources = {} as EntityTypeResource<NotificationTemplate>; this.config.entityResources = {} as EntityTypeResource<NotificationTemplate>;
this.config.entitiesFetchFunction = pageLink => this.notificationService.getNotificationTemplates(pageLink); this.config.entitiesFetchFunction = pageLink => this.notificationService.getNotificationTemplates(pageLink);
@ -77,13 +75,9 @@ export class TemplateTableConfigResolver implements Resolve<EntityTableConfig<No
this.config.columns.push( this.config.columns.push(
new DateEntityTableColumn<NotificationTemplate>('createdTime', 'notification.created-time', this.datePipe, '170px'), new DateEntityTableColumn<NotificationTemplate>('createdTime', 'notification.created-time', this.datePipe, '170px'),
new EntityTableColumn<NotificationTemplate>('notificationType', 'notification.type', '15%', new EntityTableColumn<NotificationTemplate>('notificationType', 'notification.type', '20%',
(template) => this.translate.instant(NotificationTemplateTypeTranslateMap.get(template.notificationType).name)), (template) => this.translate.instant(NotificationTemplateTypeTranslateMap.get(template.notificationType).name)),
new EntityTableColumn<NotificationTemplate>('name', 'notification.template', '25%'), new EntityTableColumn<NotificationTemplate>('name', 'notification.template', '80%')
new EntityTableColumn<NotificationTemplate>('configuration.notificationSubject', 'notification.subject', '25%',
(template) => template.configuration.notificationSubject, () => ({}), false),
new EntityTableColumn<NotificationTemplate>('configuration.defaultTextTemplate', 'notification.message', '35%',
(template) => template.configuration.defaultTextTemplate, () => ({}), false)
); );
} }

3
ui-ngx/src/app/shared/components/notification/notification.component.html

@ -38,7 +38,8 @@
<div class="description" fxLayout="column" fxLayoutAlign="start end"> <div class="description" fxLayout="column" fxLayoutAlign="start end">
<div fxLayout="row" fxLayoutAlign="end center" class="mark-read"> <div fxLayout="row" fxLayoutAlign="end center" class="mark-read">
<span class="time">{{ notification.createdTime ?? currentDate | dateAgo }}</span> <span class="time">{{ notification.createdTime ?? currentDate | dateAgo }}</span>
<button mat-icon-button class="tb-mat-28" (click)="markRead($event)" *ngIf="!hideMarkAsReadButton"> <button mat-icon-button class="tb-mat-28" (click)="markRead($event)" *ngIf="!hideMarkAsReadButton"
matTooltip="{{ 'notification.mark-as-read' | translate }}" matTooltipPosition="above">
<mat-icon>check_circle_outline</mat-icon> <mat-icon>check_circle_outline</mat-icon>
</button> </button>
</div> </div>

21
ui-ngx/src/app/shared/models/entity-type.models.ts

@ -350,31 +350,42 @@ export const entityTypeTranslations = new Map<EntityType | AliasEntityType, Enti
[ [
EntityType.NOTIFICATION, EntityType.NOTIFICATION,
{ {
type: 'entity.type-notification' type: 'entity.type-notification',
noEntities: 'notification.no-inbox-notification',
search: 'notification.search-notification',
selectedEntities: 'notification.selected-notifications'
} }
], ],
[ [
EntityType.NOTIFICATION_REQUEST, EntityType.NOTIFICATION_REQUEST,
{ {
type: 'entity.type-notification-request' type: 'entity.type-notification-request',
noEntities: 'notification.no-notification-request',
selectedEntities: 'notification.selected-requests'
} }
], ],
[ [
EntityType.NOTIFICATION_RULE, EntityType.NOTIFICATION_RULE,
{ {
type: 'entity.type-notification-rule' type: 'entity.type-notification-rule',
noEntities: 'notification.no-rules-notification',
search: 'notification.search-rules'
} }
], ],
[ [
EntityType.NOTIFICATION_TARGET, EntityType.NOTIFICATION_TARGET,
{ {
type: 'entity.type-notification-target' type: 'entity.type-notification-target',
noEntities: 'notification.no-targets-notification',
search: 'notification.search-targets'
} }
], ],
[ [
EntityType.NOTIFICATION_TEMPLATE, EntityType.NOTIFICATION_TEMPLATE,
{ {
type: 'entity.type-notification-template' type: 'entity.type-notification-template',
noEntities: 'notification.no-notification-templates',
search: 'notification.search-templates'
} }
] ]
] ]

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

@ -263,8 +263,6 @@ export interface NotificationTemplate extends Omit<BaseData<NotificationTemplate
} }
interface NotificationTemplateConfig { interface NotificationTemplateConfig {
defaultTextTemplate: string;
notificationSubject: string;
deliveryMethodsTemplates: { deliveryMethodsTemplates: {
[key in NotificationDeliveryMethod]: DeliveryMethodNotificationTemplate [key in NotificationDeliveryMethod]: DeliveryMethodNotificationTemplate
}; };

9
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -2755,9 +2755,15 @@
"created": "Created", "created": "Created",
"created-time": "Created time", "created-time": "Created time",
"delete-request-text": "Be careful, after the confirmation the notification request will become unrecoverable.", "delete-request-text": "Be careful, after the confirmation the notification request will become unrecoverable.",
"delete-requests-text": "Be careful, after the confirmation the notification requests will become unrecoverable.",
"delete-request-title": "Are you sure you want to delete the notification request?", "delete-request-title": "Are you sure you want to delete the notification request?",
"delete-requests-title": "Are you sure you want to delete { count, plural, =1 {1 request} other {# requests} }?",
"delete-rule-text": "Be careful, after the confirmation the notification rule will become unrecoverable.", "delete-rule-text": "Be careful, after the confirmation the notification rule will become unrecoverable.",
"delete-rule-title": "Are you sure you want to delete the notification rule '{{ruleName}}'?", "delete-rule-title": "Are you sure you want to delete the notification rule '{{ruleName}}'?",
"delete-notification-title": "Are you sure you want to delete the notification?",
"delete-notifications-title": "Are you sure you want to delete { count, plural, =1 {1 notification} other {# notifications} }?",
"delete-notification-text": "Be careful, after the confirmation the notification will become unrecoverable.",
"delete-notifications-text": "Be careful, after the confirmation the notifications will become unrecoverable.",
"delete-target-text": "Be careful, after the confirmation the notification recipient will become unrecoverable.", "delete-target-text": "Be careful, after the confirmation the notification recipient will become unrecoverable.",
"delete-target-title": "Are you sure you want to delete the notification recipient '{{targetName}}'?", "delete-target-title": "Are you sure you want to delete the notification recipient '{{targetName}}'?",
"delete-template-text": "Be careful, after the confirmation the notification template will become unrecoverable.", "delete-template-text": "Be careful, after the confirmation the notification template will become unrecoverable.",
@ -2843,6 +2849,7 @@
"recipients": "Recipients", "recipients": "Recipients",
"recipient-type": "Recipient type", "recipient-type": "Recipient type",
"recipients-count": "{ count, plural, =1 {1 Recipient} other {# Recipients} }", "recipients-count": "{ count, plural, =1 {1 Recipient} other {# Recipients} }",
"request-search": "Request search",
"request-status": { "request-status": {
"processing": "Processing", "processing": "Processing",
"scheduled": "Scheduled", "scheduled": "Scheduled",
@ -2863,6 +2870,8 @@
"search-targets": "Search recipients", "search-targets": "Search recipients",
"search-templates": "Search templates", "search-templates": "Search templates",
"send-notification": "Send notification", "send-notification": "Send notification",
"selected-requests": "{ count, plural, =1 {1 request} other {# requests} } selected",
"selected-notifications": "{ count, plural, =1 {1 notification} other {# notifications} } selected",
"sent": "Sent", "sent": "Sent",
"settings": "Notification settings", "settings": "Notification settings",
"set-entity-from-notification": "Set entity from notification to dashboard state", "set-entity-from-notification": "Set entity from notification to dashboard state",

Loading…
Cancel
Save