Browse Source

Merge remote-tracking branch 'origin/improvements/notification-system' into improvements/notification-system

pull/8265/head
ViacheslavKlimov 3 years ago
parent
commit
20a2e14dc1
  1. 36
      ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html
  2. 31
      ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts
  3. 10
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html
  4. 5
      ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.ts
  5. 47
      ui-ngx/src/app/shared/models/api-usage.models.ts
  6. 24
      ui-ngx/src/app/shared/models/notification.models.ts
  7. 1
      ui-ngx/src/app/shared/models/public-api.ts
  8. 11
      ui-ngx/src/assets/locale/locale.constant-en_US.json

36
ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html

@ -441,6 +441,42 @@
</form>
</mat-step>
<mat-step *ngIf="ruleNotificationForm.get('triggerType').value === triggerType.API_USAGE_LIMIT"
[stepControl]="apiUsageLimitTemplateForm">
<ng-template matStepLabel>{{ 'notification.api-usage-trigger-settings' | translate }}</ng-template>
<form [formGroup]="apiUsageLimitTemplateForm">
<section formGroupName="triggerConfig">
<mat-form-field fxFlex class="mat-block" subscriptSizing="dynamic">
<mat-label translate>api-usage.api-features</mat-label>
<mat-select formControlName="apiFeatures" multiple>
<mat-option *ngFor="let apiFeature of apiFeatures" [value]="apiFeature">
{{ apiFeatureTranslationMap.get(apiFeature) | translate }}
</mat-option>
</mat-select>
<mat-hint>{{ 'notification.api-feature-hint' | translate }}</mat-hint>
</mat-form-field>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>notification.notify-on</mat-label>
<mat-select formControlName="notifyOn" multiple>
<mat-option *ngFor="let apiUsageStateValue of apiUsageStateValues" [value]="apiUsageStateValue">
{{ apiUsageStateValueTranslationMap.get(apiUsageStateValue) | translate }}
</mat-option>
</mat-select>
<mat-error *ngIf="apiUsageLimitTemplateForm.get('triggerConfig.notifyOn').hasError('required')">
{{ 'notification.notify-on-required' | translate }}
</mat-error>
</mat-form-field>
</section>
</form>
<form [formGroup]="ruleNotificationForm">
<section formGroupName="additionalConfig">
<mat-form-field class="mat-block">
<mat-label translate>notification.description</mat-label>
<input matInput formControlName="description">
</mat-form-field>
</section>
</form>
</mat-step>
</mat-horizontal-stepper>
</div>
<mat-divider></mat-divider>

31
ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts

@ -20,7 +20,9 @@ import {
AlarmAssignmentAction,
AlarmAssignmentActionTranslationMap,
ComponentLifecycleEvent,
ComponentLifecycleEventTranslationMap, DeviceEvent, DeviceEventTranslationMap,
ComponentLifecycleEventTranslationMap,
DeviceEvent,
DeviceEventTranslationMap,
NotificationRule,
NotificationTarget,
TriggerType,
@ -58,6 +60,12 @@ import { AuthState } from '@core/auth/auth.models';
import { getCurrentAuthState } from '@core/auth/auth.selectors';
import { AuthUser } from '@shared/models/user.model';
import { Authority } from '@shared/models/authority.enum';
import {
ApiFeature,
ApiFeatureTranslationMap,
ApiUsageStateValue,
ApiUsageStateValueTranslationMap
} from '@shared/models/api-usage.models';
export interface RuleNotificationDialogData {
rule?: NotificationRule;
@ -85,6 +93,7 @@ export class RuleNotificationDialogComponent extends
alarmAssignmentTemplateForm: FormGroup;
ruleEngineEventsTemplateForm: FormGroup;
entitiesLimitTemplateForm: FormGroup;
apiUsageLimitTemplateForm: FormGroup;
triggerType = TriggerType;
triggerTypes: TriggerType[];
@ -113,6 +122,12 @@ export class RuleNotificationDialogComponent extends
deviceEvents: DeviceEvent[] = Object.values(DeviceEvent);
deviceEventTranslationMap = DeviceEventTranslationMap;
apiUsageStateValues: ApiUsageStateValue[] = Object.values(ApiUsageStateValue);
apiUsageStateValueTranslationMap = ApiUsageStateValueTranslationMap;
apiFeatures: ApiFeature[] = Object.values(ApiFeature);
apiFeatureTranslationMap = ApiFeatureTranslationMap;
entityType = EntityType;
entityTypes = Array.from(entityTypeTranslations.keys()).filter(type => !!this.entityType[type]);
isAdd = true;
@ -263,6 +278,13 @@ export class RuleNotificationDialogComponent extends
})
});
this.apiUsageLimitTemplateForm = this.fb.group({
triggerConfig: this.fb.group({
apiFeatures: [[]],
notifyOn: [[ApiUsageStateValue.WARNING], Validators.required]
})
});
this.triggerTypeFormsMap = new Map<TriggerType, FormGroup>([
[TriggerType.ALARM, this.alarmTemplateForm],
[TriggerType.ALARM_COMMENT, this.alarmCommentTemplateForm],
@ -270,7 +292,8 @@ export class RuleNotificationDialogComponent extends
[TriggerType.ENTITY_ACTION, this.entityActionTemplateForm],
[TriggerType.ALARM_ASSIGNMENT, this.alarmAssignmentTemplateForm],
[TriggerType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, this.ruleEngineEventsTemplateForm],
[TriggerType.ENTITIES_LIMIT, this.entitiesLimitTemplateForm]
[TriggerType.ENTITIES_LIMIT, this.entitiesLimitTemplateForm],
[TriggerType.API_USAGE_LIMIT, this.apiUsageLimitTemplateForm]
]);
if (data.isAdd || data.isCopy) {
@ -401,8 +424,8 @@ export class RuleNotificationDialogComponent extends
private allowTriggerTypes(): TriggerType[] {
if (this.isSysAdmin()) {
return [TriggerType.ENTITIES_LIMIT];
return [TriggerType.ENTITIES_LIMIT, TriggerType.API_USAGE_LIMIT];
}
return Object.values(TriggerType).filter(type => type !== TriggerType.ENTITIES_LIMIT);
return Object.values(TriggerType).filter(type => type !== TriggerType.ENTITIES_LIMIT && type !== TriggerType.API_USAGE_LIMIT);
}
}

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

@ -342,14 +342,14 @@
</div>
</div>
<mat-divider class="divider"></mat-divider>
<div class="details-recipients">
<div *ngFor="let user of preview.recipientsPreview" class="details-recipient">
<span *ngIf="(user.firstName || user.lastName); else email">{{ user.firstName }}&nbsp;{{ user.lastName }} ({{ user.email }})</span>
<mat-chip-listbox>
<mat-chip *ngFor="let user of preview.recipientsPreview">
<span *ngIf="(user.firstName || user.lastName); else email">{{ user.firstName }}&nbsp;{{ user.lastName }}</span>
<ng-template #email>
{{ user.email }}
</ng-template>
</div>
</div>
</mat-chip>
</mat-chip-listbox>
</section>
</div>
</mat-step>

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

@ -176,8 +176,9 @@ export class TemplateNotificationDialogComponent
private allowNotificationType(): NotificationType[] {
if (this.isSysAdmin()) {
return [NotificationType.GENERAL, NotificationType.ENTITIES_LIMIT];
return [NotificationType.GENERAL, NotificationType.ENTITIES_LIMIT, NotificationType.API_USAGE_LIMIT];
}
return Object.values(NotificationType).filter(type => type !== NotificationType.ENTITIES_LIMIT);
return Object.values(NotificationType)
.filter(type => type !== NotificationType.ENTITIES_LIMIT && type !== NotificationType.API_USAGE_LIMIT);
}
}

47
ui-ngx/src/app/shared/models/api-usage.models.ts

@ -0,0 +1,47 @@
///
/// Copyright © 2016-2023 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
export enum ApiUsageStateValue {
ENABLED = 'ENABLED',
WARNING = 'WARNING',
DISABLED = 'DISABLED'
}
export const ApiUsageStateValueTranslationMap = new Map<ApiUsageStateValue, string>([
[ApiUsageStateValue.ENABLED, 'notification.enabled'],
[ApiUsageStateValue.WARNING, 'notification.warning'],
[ApiUsageStateValue.DISABLED, 'notification.disabled'],
]);
export enum ApiFeature {
TRANSPORT = 'TRANSPORT',
DB = 'DB',
RE = 'RE',
JS = 'JS',
EMAIL = 'EMAIL',
SMS = 'SMS',
ALARM = 'ALARM'
}
export const ApiFeatureTranslationMap = new Map<ApiFeature, string>([
[ApiFeature.TRANSPORT, 'api-usage.device-api'],
[ApiFeature.DB, 'api-usage.telemetry-persistence'],
[ApiFeature.RE, 'api-usage.rule-engine-executions'],
[ApiFeature.JS, 'api-usage.javascript-executions'],
[ApiFeature.EMAIL, 'api-usage.email-messages'],
[ApiFeature.SMS, 'api-usage.sms-messages'],
[ApiFeature.ALARM, 'api-usage.alarm'],
]);

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

@ -26,6 +26,7 @@ import { NotificationRuleId } from '@shared/models/id/notification-rule-id';
import { AlarmSearchStatus, AlarmSeverity, AlarmStatus } from '@shared/models/alarm.models';
import { EntityType } from '@shared/models/entity-type.models';
import { User } from '@shared/models/user.model';
import { ApiFeature, ApiUsageStateValue } from '@shared/models/api-usage.models';
export interface Notification {
readonly id: NotificationId;
@ -113,7 +114,8 @@ export interface NotificationRule extends Omit<BaseData<NotificationRuleId>, 'la
export type NotificationRuleTriggerConfig = Partial<AlarmNotificationRuleTriggerConfig & DeviceInactivityNotificationRuleTriggerConfig &
EntityActionNotificationRuleTriggerConfig & AlarmCommentNotificationRuleTriggerConfig & AlarmAssignmentNotificationRuleTriggerConfig &
RuleEngineLifecycleEventNotificationRuleTriggerConfig & EntitiesLimitNotificationRuleTriggerConfig>;
RuleEngineLifecycleEventNotificationRuleTriggerConfig & EntitiesLimitNotificationRuleTriggerConfig &
ApiUsageLimitNotificationRuleTriggerConfig>;
export interface AlarmNotificationRuleTriggerConfig {
alarmTypes?: Array<string>;
@ -132,7 +134,7 @@ export interface DeviceInactivityNotificationRuleTriggerConfig {
}
export interface EntityActionNotificationRuleTriggerConfig {
entityType: EntityType;
entityTypes: EntityType[];
created: boolean;
updated: boolean;
deleted: boolean;
@ -167,6 +169,11 @@ export interface EntitiesLimitNotificationRuleTriggerConfig {
threshold: number;
}
export interface ApiUsageLimitNotificationRuleTriggerConfig {
apiFeatures: ApiFeature[];
notifyOn: ApiUsageStateValue[];
}
export enum ComponentLifecycleEvent {
STARTED = 'STARTED',
UPDATED = 'UPDATED',
@ -430,7 +437,8 @@ export enum NotificationType {
ALARM_COMMENT = 'ALARM_COMMENT',
ALARM_ASSIGNMENT = 'ALARM_ASSIGNMENT',
RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT = 'RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT',
ENTITIES_LIMIT = 'ENTITIES_LIMIT'
ENTITIES_LIMIT = 'ENTITIES_LIMIT',
API_USAGE_LIMIT = 'API_USAGE_LIMIT'
}
export const NotificationTypeIcons = new Map<NotificationType, string | null>([
@ -441,6 +449,7 @@ export const NotificationTypeIcons = new Map<NotificationType, string | null>([
[NotificationType.ALARM_ASSIGNMENT, 'assignment_turned_in'],
[NotificationType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, 'settings_ethernet'],
[NotificationType.ENTITIES_LIMIT, 'data_thresholding'],
[NotificationType.API_USAGE_LIMIT, 'insert_chart'],
]);
export const AlarmSeverityNotificationColors = new Map<AlarmSeverity, string>(
@ -515,6 +524,11 @@ export const NotificationTemplateTypeTranslateMap = new Map<NotificationType, No
{
name: 'notification.template-type.entities-limit',
helpId: 'notification/entities_limit'
}],
[NotificationType.API_USAGE_LIMIT,
{
name: 'notification.template-type.api-usage-limit',
helpId: 'notification/api_usage_limit'
}]
]);
@ -525,7 +539,8 @@ export enum TriggerType {
ALARM_COMMENT = 'ALARM_COMMENT',
ALARM_ASSIGNMENT = 'ALARM_ASSIGNMENT',
RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT = 'RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT',
ENTITIES_LIMIT = 'ENTITIES_LIMIT'
ENTITIES_LIMIT = 'ENTITIES_LIMIT',
API_USAGE_LIMIT = 'API_USAGE_LIMIT'
}
export const TriggerTypeTranslationMap = new Map<TriggerType, string>([
@ -536,4 +551,5 @@ export const TriggerTypeTranslationMap = new Map<TriggerType, string>([
[TriggerType.ALARM_ASSIGNMENT, 'notification.trigger.alarm-assignment'],
[TriggerType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, 'notification.trigger.rule-engine-lifecycle-event'],
[TriggerType.ENTITIES_LIMIT, 'notification.trigger.entities-limit'],
[TriggerType.API_USAGE_LIMIT, 'notification.trigger.api-usage-limit'],
]);

1
ui-ngx/src/app/shared/models/public-api.ts

@ -20,6 +20,7 @@ export * from './telemetry/telemetry.models';
export * from './time/time.models';
export * from './alarm.models';
export * from './alias.models';
export * from './api-usage.models';
export * from './asset.models';
export * from './audit-log.models';
export * from './authority.enum';

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

@ -673,6 +673,7 @@
"no-telemetry-text": "No telemetry found"
},
"api-usage": {
"api-features": "API features",
"api-usage": "Api Usage",
"alarm": "Alarm",
"alarms-created": "Alarms created",
@ -681,6 +682,7 @@
"alarms-created-monthly-activity": "Alarms created monthly activity",
"data-points": "Data points",
"data-points-storage-days": "Data points storage days",
"device-api": "Device API",
"email": "Email",
"email-messages": "Email messages",
"email-messages-daily-activity": "Email messages daily activity",
@ -2742,6 +2744,8 @@
"alarm-comment-trigger-settings": "Alarm comment trigger settings",
"alarm-trigger-settings": "Alarm trigger settings",
"all": "All",
"api-feature-hint": "If the field is empty, the trigger will be applied to all api features",
"api-usage-trigger-settings": "API usage trigger settings",
"at-least-one-should-be-selected": "At least one should be selected",
"basic-settings": "Basic settings",
"button-text": "Button text",
@ -2795,10 +2799,12 @@
"device-activity-trigger-settings": "Device active trigger settings",
"device-list-rule-hint": "If the field is empty, the trigger will be applied to all devices",
"device-profiles-list-rule-hint": "If the field is empty, the trigger will be applied to all device profiles",
"disabled": "Disabled",
"edit-notification-recipients-group": "Edit notification recipients group",
"edit-notification-template": "Edit notification template",
"edit-rule": "Edit rule",
"edit-template": "Edit template",
"enabled": "Enabled",
"entities-limit-trigger-settings": "Entities limit trigger settings",
"entity-action-trigger-settings": "Entity action trigger settings",
"entity-type": "Entity type",
@ -2921,6 +2927,7 @@
"alarm": "Alarm",
"alarm-assignment": "Alarm assignment",
"alarm-comment": "Alarm comment",
"api-usage-limit": "API usage limit",
"device-activity": "Device activity",
"entities-limit": "Entities limit",
"entity-action": "Entity action",
@ -2937,6 +2944,7 @@
"alarm": "Alarm",
"alarm-assignment": "Alarm assignment",
"alarm-comment": "Alarm comment",
"api-usage-limit": "API usage limit",
"device-activity": "Device activity",
"entities-limit": "Entities limit",
"entity-action": "Entity action",
@ -2948,7 +2956,8 @@
"unread": "Unread",
"updated": "Updated",
"use-template": "Use template",
"view-all": "View all"
"view-all": "View all",
"warning": "Warning"
},
"ota-update": {
"add": "Add package",

Loading…
Cancel
Save