Skip to content

Commit

Permalink
[feature] Add the editing mode of "complex rule nesting" to support "…
Browse files Browse the repository at this point in the history
…threshold rules" (#2315)

Co-authored-by: tomsun28 <[email protected]>
  • Loading branch information
kerwin612 and tomsun28 authored Jul 20, 2024
1 parent be0de49 commit 1a09611
Show file tree
Hide file tree
Showing 6 changed files with 12,465 additions and 12,256 deletions.
5 changes: 3 additions & 2 deletions web-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@delon/mock": "17.3.1",
"@delon/theme": "17.3.1",
"@delon/util": "17.3.1",
"@kerwin612/ngx-query-builder": "0.6.4",
"ajv": "8.12.0",
"ajv-formats": "2.1.1",
"angular-tag-cloud-module": "17.0.1",
Expand Down Expand Up @@ -88,9 +89,9 @@
"@types/node": "20.12.11",
"@typescript-eslint/eslint-plugin": "7.8.0",
"@typescript-eslint/parser": "7.8.0",
"eslint": "8.51.0",
"eslint": "8.56.0",
"eslint-config-prettier": "8.6.0",
"eslint-plugin-deprecation": "1.3.3",
"eslint-plugin-deprecation": "^3.0.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jsdoc": "48.2.5",
"eslint-plugin-prefer-arrow": "1.2.3",
Expand Down
186 changes: 73 additions & 113 deletions web-app/src/app/routes/alert/alert-setting/alert-setting.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
nzType="primary"
(click)="onEditOneAlertDefine(data.id)"
nz-tooltip
[nzLoading]="isLoadingEdit === data.id"
[nzTooltipTitle]="'alert.setting.edit' | i18n"
>
<i nz-icon nzType="edit" nzTheme="outline"></i>
Expand Down Expand Up @@ -203,7 +204,7 @@
></nz-cascader>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="cascadeValues.length != 2">
<nz-form-item *ngIf="cascadeValues.length > 0 && cascadeValues.length != 2">
<nz-form-label [nzSpan]="7" nzFor="rule" nzRequired="true" [nzTooltipTitle]="'alert.setting.rule.label' | i18n">
{{ 'alert.setting.rule' | i18n }}
</nz-form-label>
Expand All @@ -223,7 +224,7 @@
{{ 'alert.setting.rule.switch-expr.1' | i18n }}
</label>
</nz-radio-group>
<div *ngIf="isExpr" style="margin-top: 5px">
<div *ngIf="isExpr" id="rule" style="margin-top: 5px">
<nz-textarea-count [nzMaxCharacterCount]="100">
<textarea
[(ngModel)]="define.expr"
Expand Down Expand Up @@ -264,156 +265,115 @@
</nz-collapse-panel>
</nz-collapse>
</div>
<div *ngIf="!isExpr" style="margin-top: 5px">
<div id="rule">
<div style="width: 100%; margin-bottom: 2px" nz-row *ngFor="let alertRule of alertRules; let i = index">
<div *ngIf="!isExpr" id="rule" class="br-4" style="margin-top: 5px; background: ghostwhite">
<ngx-query-builder [classNames]="qbClassNames" [config]="qbConfig" [formControl]="qbFormCtrl">
<ng-container *querySwitchGroup="let rule; let onChange = onChange">
<nz-radio-group
style="white-space: nowrap"
[(ngModel)]="rule.condition"
(ngModelChange)="onChange(rule.condition)"
nzButtonStyle="solid"
[required]="true"
[ngModelOptions]="{ standalone: true }"
>
<label nz-radio-button [nzValue]="'and'">AND</label>
<label nz-radio-button [nzValue]="'or'">OR</label>
</nz-radio-group>
</ng-container>
<ng-container *queryRulesetAddRuleButton="let rule; let addRule = addRule">
<button style="margin-left: 0; flex-shrink: 0" nz-button (click)="addRule()">
<i nz-icon nzType="plus"></i>
{{ 'Rule' }}
</button>
</ng-container>
<ng-container *queryRulesetAddRulesetButton="let rule; let addRuleSet = addRuleSet">
<button style="margin-left: 0; flex-shrink: 0" nz-button (click)="addRuleSet()">
<i nz-icon nzType="plus"></i>
{{ 'Ruleset' }}
</button>
</ng-container>
<ng-container *queryRulesetRemoveButton="let rule; let removeRuleSet = removeRuleSet">
<button style="margin-left: 0; flex-shrink: 0" nz-button nzDanger (click)="removeRuleSet(rule)">
<i nz-icon nzType="minus"></i>
</button>
</ng-container>
<ng-container *queryRuleRemoveButton="let rule; let removeRule = removeRule">
<button style="flex-shrink: 0" nz-button nzDanger (click)="removeRule(rule)">
<i nz-icon nzType="minus"></i>
</button>
</ng-container>
<ng-container *queryField="let rule; let getFields = getFields; let onChange = onChange">
<nz-select
[(ngModel)]="alertRule.metric"
[(ngModel)]="rule.field"
(ngModelChange)="onChange($event, rule)"
[ngModelOptions]="{ standalone: true }"
nz-col
nzSpan="8"
[nzDropdownMatchSelectWidth]="false"
[nzPlaceHolder]="'alert.setting.rule.metric.place-holder' | i18n"
style="width: auto"
>
<nz-option
*ngFor="let item of currentMetrics"
[nzValue]="item"
[nzLabel]="item.label ? item.label : item.value"
*ngFor="let field of getFields(rule.entity || '')"
[nzValue]="field.value"
[nzLabel]="field.name ? field.name : field.value"
nzCustomContent
>
{{ item.label ? item.label : item.value }}
<nz-tag [nzColor]="item.type === 0 ? 'success' : 'processing'">
{{ field.name ? field.name : field.value }}
<nz-tag [nzColor]="field.type === 0 ? 'success' : 'processing'">
{{
item.type === 0
field.type === 0
? ('alert.setting.number' | i18n)
: item.type === 3
: field.type === 3
? ('alert.setting.time' | i18n)
: ('alert.setting.string' | i18n)
}}
</nz-tag>
<nz-tag *ngIf="item.unit">
{{ item.unit }}
<nz-tag *ngIf="field.unit">
{{ field.unit }}
</nz-tag>
</nz-option>
</nz-select>
</ng-container>
<ng-container *queryOperator="let rule; let operators = operators; let onChange = onChange">
<nz-select
[(ngModel)]="alertRule.operator"
[(ngModel)]="rule.operator"
(ngModelChange)="onChange(rule)"
[ngModelOptions]="{ standalone: true }"
nz-col
nzSpan="4"
[nzShowArrow]="false"
[nzDropdownMatchSelectWidth]="false"
style="text-align: center; font-weight: bolder"
style="text-align: center; font-weight: bolder; width: auto"
[nzDropdownStyle]="{ 'text-align': 'center', 'font-weight': 'bolder', 'font-size': 'larger' }"
[nzPlaceHolder]="'alert.setting.rule.operator' | i18n"
>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 0 || alertRule.metric.type === 3"
[nzValue]="'>'"
[nzLabel]="'>'"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 0 || alertRule.metric.type === 3"
[nzValue]="'<'"
[nzLabel]="'<'"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 0 || alertRule.metric.type === 3"
[nzValue]="'=='"
[nzLabel]="'=='"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 0 || alertRule.metric.type === 3"
[nzValue]="'!='"
[nzLabel]="'!='"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 0 || alertRule.metric.type === 3"
[nzValue]="'<='"
[nzLabel]="'<='"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 0 || alertRule.metric.type === 3"
[nzValue]="'>='"
[nzLabel]="'>='"
*ngFor="let operator of operators"
[nzValue]="operator"
[nzLabel]="getOperatorLabelByType(operator) | i18n"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 1"
[nzValue]="'equals'"
[nzLabel]="'alert.setting.rule.operator.str-equals' | i18n"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 1"
[nzValue]="'!equals'"
[nzLabel]="'alert.setting.rule.operator.str-no-equals' | i18n"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 1"
[nzValue]="'contains'"
[nzLabel]="'alert.setting.rule.operator.str-contains' | i18n"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 1"
[nzValue]="'!contains'"
[nzLabel]="'alert.setting.rule.operator.str-no-contains' | i18n"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 1"
[nzValue]="'matches'"
[nzLabel]="'alert.setting.rule.operator.str-matches' | i18n"
></nz-option>
<nz-option
*ngIf="!alertRule.metric || alertRule.metric.type === 1"
[nzValue]="'!matches'"
[nzLabel]="'alert.setting.rule.operator.str-no-matches' | i18n"
></nz-option>
<nz-option [nzValue]="'exists'" [nzLabel]="'alert.setting.rule.operator.exists' | i18n"></nz-option>
<nz-option [nzValue]="'!exists'" [nzLabel]="'alert.setting.rule.operator.no-exists' | i18n"></nz-option>
</nz-select>
</ng-container>
<ng-container *queryInput="let rule; let field = field; let onChange = onChange; type: 'custom'">
<input
nz-input
[disabled]="alertRule.operator == 'exists' || alertRule.operator == '!exists'"
[type]="alertRule.metric?.type === 0 ? 'number' : 'text'"
[(ngModel)]="alertRule.value"
[disabled]="rule.operator == 'exists' || rule.operator == '!exists'"
[type]="field.type === 0 ? 'number' : 'text'"
[(ngModel)]="rule.value"
(ngModelChange)="onChange($event)"
[ngModelOptions]="{ standalone: true }"
[placeholder]="
alertRule.operator == 'exists' || alertRule.operator == '!exists'
rule.operator == 'exists' || rule.operator == '!exists'
? ''
: alertRule.metric?.type === 0
: field.type === 0
? ('alert.setting.rule.numeric-value.place-holder' | i18n)
: ('alert.setting.rule.string-value.place-holder' | i18n)
"
nz-col
nzSpan="10"
style="flex: 1"
/>
<button
*ngIf="i != alertRules.length - 1 || i == 4"
nz-button
nz-col
nzSpan="2"
nzDanger
nzGhost="true"
(click)="onRemoveAlertRule(i)"
>
<span nz-icon nzType="minus"></span>
</button>
<button
*ngIf="i === alertRules.length - 1 && i < 4"
nz-button
nzType="primary"
nz-col
nzSpan="2"
nzGhost="true"
(click)="onAddNewAlertRule()"
>
<span nz-icon nzType="plus"></span>
</button>
</div>
</div>
</ng-container>
</ngx-query-builder>
</div>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="cascadeValues.length == 2">
<nz-form-item *ngIf="cascadeValues.length > 0 && cascadeValues.length == 2">
<nz-form-label [nzSpan]="7" nzFor="available">
{{ 'monitor.availability' | i18n }}
</nz-form-label>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
::ng-deep {

.row {
margin-top: 6px;

.ruleset {
border: 1px solid #CCC;
}
}

.ruleset-invalid {
border: none!important;

.ruleset {
border: 1px solid #ff4d4f !important;
}

>p {
margin: 0!important;
color: #ff4d4f !important;
}
}

.ruleset {
min-width: 400px;
overflow-x: auto;
padding: 6px 8px;
}

.rule {
display: flex;
gap: 10px;
min-width: 300px;
overflow-x: auto;
padding: 6px 8px;
border: 1px solid #CCC;

.q-rule-content {
flex: 1;
display: flex;
flex-wrap: wrap;
gap: 10px;
}

.q-rule-actions {
flex-shrink: 0;
}
}
}
Loading

0 comments on commit 1a09611

Please sign in to comment.