summaryrefslogtreecommitdiffstats
path: root/public/src/app/rule-engine/action
diff options
context:
space:
mode:
Diffstat (limited to 'public/src/app/rule-engine/action')
-rw-r--r--public/src/app/rule-engine/action/action.component.html336
-rw-r--r--public/src/app/rule-engine/action/action.component.scss25
-rw-r--r--public/src/app/rule-engine/action/action.component.ts84
-rw-r--r--public/src/app/rule-engine/action/metric.data.ts43
-rw-r--r--public/src/app/rule-engine/action/papa.spec.ts84
5 files changed, 511 insertions, 61 deletions
diff --git a/public/src/app/rule-engine/action/action.component.html b/public/src/app/rule-engine/action/action.component.html
index 250af34..38a9aa0 100644
--- a/public/src/app/rule-engine/action/action.component.html
+++ b/public/src/app/rule-engine/action/action.component.html
@@ -8,22 +8,238 @@
</div>
<!-- from component -->
- <app-from [hidden]="action.actionType === 'log event' || action.actionType === 'log text'" class="center-content-item" #from
- [actionType]="action.actionType" (onFromChange)="updateFrom($event)"></app-from>
+ <app-from [hidden]="action.actionType === 'log event' || action.actionType === 'log text' || action.actionType === 'hp metric' || action.actionType === 'Topology Search' || action.actionType === 'string transform'"
+ class="center-content-item" #from [actionType]="action.actionType" (onFromChange)="updateFrom($event)"></app-from>
<!-- target component -->
- <app-target [hidden]="action.actionType === 'clear' || action.actionType === 'replace text' || action.actionType === 'log text' || action.actionType === 'log event'"
+ <app-target [hidden]="action.actionType === 'clear' || action.actionType === 'clear nsf' || action.actionType === 'replace text' || action.actionType === 'log text' || action.actionType === 'log event' || action.actionType === 'hp metric' || action.actionType === 'string transform' || action.actionType === 'Topology Search' "
#target style="width: 100%" (onTargetChange)="updateTarget($event)" [nodes]="action.nodes">
</app-target>
+ <!-- search -->
+ <div *ngIf="action.actionType === 'Topology Search'" style="width: 100%;">
+ <div style="display:flex; margin-bottom:10px;">
+ <div class="from" style="width: 100%;">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; ">
+ Field
+ </span>
+ <input required name="searchField" class="input-text" data-tests-id="searchField" [(ngModel)]="action.search.searchField"
+ type="text" placeholder="Search Field">
+ </div>
+ </div>
+ </div>
+ <div class="from" style="width: 100%; padding-right: 0;">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px;">
+ Value
+ </span>
+ <input required class="input-text" data-tests-id="searchValue" [(ngModel)]="action.search.searchValue" type="text" name="searchValue"
+ placeholder="Search Value">
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="from" style="width: 100%; padding-right:0">
+ <!-- <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; width: 100px;">
+ Filter
+ </span>
+ <input required class="input-text" name="searchFilter" data-tests-id="searchFilter" [(ngModel)]="action.search.searchFilter"
+ type="text" placeholder="Search Filter">
+ </div>
+ </div> -->
+ <div class="from-conatiner">
+ <div style="display: flex;">
+ <div class="label" style="width:100%">
+ <span class="label" style="padding: 0 10px; border-left: none;">
+ Input
+ </span>
+ <input class="input-text" name="searchLeft" data-tests-id="searchLeft" [(ngModel)]="action.search.searchFilter.left" type="text">
+ </div>
+
+ <div style="margin: 0 1rem;">
+ <select style="height: 30px; padding: 0 10px;
+ border-color: #e0e0e0;" name="searchOperator" data-tests-id="searchOperator" [(ngModel)]="action.search.searchFilter.operator">
+ <option [ngValue]="null" disabled>Select operator</option>
+ <option value="contains">Contains</option>
+ <option value="endsWith">Ends with</option>
+ <option value="startsWith">Starts with</option>
+ <option value="equals">Equals</option>
+ <option value="notEqual">Not equal</option>
+ <option value="oneOf">One of</option>
+ <option value="NotOneOf">Not one of</option>
+ </select>
+ </div>
+
+ <div class="label" style="width:100%">
+ <span class="label" style="padding: 0 10px; border-left: none;">
+ Value
+ </span>
+ <input class="input-text" name="searchRight" data-tests-id="searchRight" [(ngModel)]="action.search.searchFilter.right" type="text">
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div style="margin: 15px 0;">
+ <p-radioButton name="searchRadio" label="Updates" value="updates" [ngModel]="action.search.radio" data-tests-id="radioUpdates"
+ (ngModelChange)="searchRadioChange($event)"></p-radioButton>
+ <span style="padding-left:15px;">
+ <p-radioButton name="searchRadio" label="Enrich" value="enrich" [ngModel]="action.search.radio" data-tests-id="radioEnrich"
+ (ngModelChange)="searchRadioChange($event)"></p-radioButton>
+ </span>
+ </div>
+
+ <div *ngIf="action.search.radio === 'enrich'" style="display:flex; margin-bottom:10px;">
+ <div>
+ <div>
+ <div style="display: flex; flex-direction: column; align-items: flex-start; width: 100%;">
+ <div *ngFor="let input of action.search.enrich.fields; let index = index;" data-tests-id="searchFields" (mouseleave)="hoveredIndex=-1"
+ (mouseover)="hoveredIndex=index" class="from" style="margin-bottom:1rem; display: flex; flex-direction: row; align-items: flex-start;">
+ <div class="from-container" style="display: flex; flex-direction: row;">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; width: 50px;">Fields</span>
+ <input class="input-text" [(ngModel)]="input.value" type="text" data-tests-id="searchFieldValue" required name="searchFeild[{{index}}]">
+ </div>
+
+ <button mat-icon-button class="button-remove" [ngStyle]="hoveredIndex === index ? {'opacity':'1'} : {'opacity':'0'}" (click)="removeSearchField(index)"
+ *ngIf="action.search.enrich.fields.length > 1" style="box-shadow: none; height: 24px; width: 24px; display:flex"
+ data-tests-id="btnDelete">
+ <mat-icon class="md-24">delete</mat-icon>
+ </button>
+ </div>
+
+ </div>
+ <div style="display:flex; justify-content: space-between;">
+ <div style="display: flex; align-items: center;">
+ <button mat-mini-fab color="primary" (click)="addSearchFeild()" style="box-shadow: none; height: 16px; width: 16px; display:flex"
+ data-tests-id="btnAddSearchFeild">
+ <span style="padding-left: 2px; display: flex; justify-content: center; align-items: center" [innerHTML]="'plus' | feather:12"></span>
+ </button>
+ <span style="color: #009FDB; display: flex; justify-content: center; padding-left: 6px">Add Fields</span>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ <div class="from">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px;">
+ Prefix
+ </span>
+ <input required class="input-text" name="searchPrefix" data-tests-id="searchPrefix" [(ngModel)]="action.search.enrich.prefix"
+ type="text" placeholder="Search prefix">
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div *ngIf="action.search.radio === 'updates'">
+ <table style="width: 100%; margin-bottom: 1rem;">
+ <thead style="background: #D2D2D2;">
+ <tr style="height: 30px;">
+ <th style="padding-left: 10px;">Key</th>
+ <th style="padding-left: 10px;">value</th>
+ </tr>
+ </thead>
+ <tbody ngModelGroup="searchUpdateKeyValue" #searchUpdateKeyValue="ngModelGroup">
+ <tr *ngFor="let item of action.search.updates; let index = index;" (mouseleave)="hoveredIndex=-1" (mouseover)="hoveredIndex=index">
+ <th style="height: 30px; border: 1px solid #F3F3F3;">
+ <input [(ngModel)]="item.key" required name="searchKey[{{index}}]" data-tests-id="updatesKey" type="text" style="width:97%; height: 100%;border: none; padding:0 5px;">
+ </th>
+ <th style="height: 30px; border: 1px solid #F3F3F3;">
+ <input [(ngModel)]="item.value" required name="searchValue[{{index}}]" data-tests-id="updatesValue" type="text" style="width:97%; height: 100%;border: none; padding:0 5px;">
+ </th>
+ <th style="height: 30px; display: flex; align-items: baseline;">
+ <button mat-icon-button data-tests-id="btn-remove-row" [ngStyle]="hoveredIndex === index ? {'opacity':'1'} : {'opacity':'0'}"
+ class="button-remove" (click)="removeSearchUpdatesRow(index)" *ngIf="action.search.updates.length > 1"
+ style="height: 24px; width: 24px; display:flex; box-shadow: none;">
+ <mat-icon class="md-24">delete</mat-icon>
+ </button>
+ </th>
+ </tr>
+ </tbody>
+ </table>
+ <div style="display:flex; justify-content: flex-start;">
+ <div style="display: flex; align-items: center;">
+ <button mat-mini-fab color="primary" (click)="addSearchUpdateRow()" data-tests-id="btn-add-row" style="height: 16px; width: 16px; display:flex; box-shadow: none;">
+ <span style="padding-left: 2px; display: flex; justify-content: center; align-items: center" [innerHTML]="'plus' | feather:12"></span>
+ </button>
+ <span style="color: #009FDB; display: flex; justify-content: center; padding-left: 6px">Add Row</span>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+ <!-- Hp Metric -->
+ <div *ngIf="action.actionType === 'hp metric'" class="center-content-item">
+ <ng-select name="hp-metric" [items]="metrics" required [virtualScroll]="true" placeholder="Select Parser Type" [(ngModel)]="action.selectedHpMetric"
+ (change)="metricChange($event)" data-tests-id="hp metric">
+ </ng-select>
+ </div>
+
+ <!-- string transform -->
+ <div *ngIf="action.actionType === 'string transform'" class="center-content-item">
+
+ <div style="display:flex; margin-bottom:10px;">
+ <div class="from">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; width: 100px;">
+ Start Value
+ </span>
+ <input required class="input-text" data-tests-id="startValue" name="title" [(ngModel)]="action.stringTransform.startValue"
+ type="text" placeholder="Select start value">
+ </div>
+ </div>
+ </div>
+
+ <app-target [hidden]="! (action.actionType === 'string transform')" #target style="width: 100%" (onTargetChange)="updateTarget($event)"
+ [nodes]="action.nodes">
+ </app-target>
+ </div>
+
+ <div class="from" style="padding-right:0">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; width: 100px;">
+ Target case
+ </span>
+ <input required class="input-text" data-tests-id="targetCase" name="title" [(ngModel)]="action.stringTransform.targetCase"
+ type="text" placeholder="Select target case">
+ </div>
+ </div>
+ </div>
+
+ <div class="pretty p-svg" style="margin: 1rem 0rem;">
+ <input type="checkbox" name="isTrimString" data-tests-id="isTrimString" [checked]="action.stringTransform.isTrimString" (change)="action.stringTransform.isTrimString = !action.stringTransform.isTrimString"
+ />
+ <div class="state">
+ <svg class="svg svg-icon" viewBox="0 0 20 20">
+ <path d="M7.629,14.566c0.125,0.125,0.291,0.188,0.456,0.188c0.164,0,0.329-0.062,0.456-0.188l8.219-8.221c0.252-0.252,0.252-0.659,0-0.911c-0.252-0.252-0.659-0.252-0.911,0l-7.764,7.763L4.152,9.267c-0.252-0.251-0.66-0.251-0.911,0c-0.252,0.252-0.252,0.66,0,0.911L7.629,14.566z"
+ style="stroke: #009fdb; fill:#009fdb;"></path>
+ </svg>
+ <label>Trim String</label>
+ </div>
+ </div>
+ </div>
+
<!-- log Event -->
<div *ngIf="action.actionType === 'log event'" class="center-content-item">
<div class="from">
<div class="from-container">
<div style="display: flex; align-items: center; width: 100%;" class="label">
<span class="label" style="padding: 0 5px; width: 100px;">Title</span>
- <input required class="input-text" data-tests-id="InputLogTitle" ngModel name="title" [(ngModel)]="action.logEvent.title"
- type="text" placeholder="The title for the log entry">
+ <input required class="input-text" data-tests-id="InputLogTitle" name="title" [(ngModel)]="action.logEvent.title" type="text"
+ placeholder="The title for the log entry">
</div>
</div>
</div>
@@ -35,8 +251,8 @@
<div class="from-container">
<div style="display: flex; align-items: center; width: 100%;" class="label">
<span class="label" style="padding: 0 5px; width: 100px;">Log Text</span>
- <input required class="input-text" data-tests-id="InputLogText" ngModel name="logText" [(ngModel)]="action.logText.text"
- type="text" placeholder="The title for the log entry">
+ <input required class="input-text" data-tests-id="InputLogText" name="logText" [(ngModel)]="action.logText.text" type="text"
+ placeholder="Text to log">
</div>
</div>
</div>
@@ -44,49 +260,53 @@
</div>
- <!-- dateFormatter -->
- <div *ngIf="action.actionType === 'date formatter'" style="flex-direction: column; margin-left: 156px; align-items: flex-end;">
- <div style="display: flex; margin: 0.5em 0; padding-left: 6px;">
- <div class="from" style="width:50%;">
- <div class="from-container">
- <div style="display: flex; align-items: center; width: 100%;" class="label">
- <span class="label" style="padding: 0 5px; width: 100px;">From Format</span>
- <input data-tests-id="InputFromFormat" class="input-text" ngModel required name="fromFormat" [(ngModel)]="action.dateFormatter.fromFormat" type="text">
- </div>
- </div>
+ <!-- dateFormatter -->
+ <div *ngIf="action.actionType === 'date formatter'" style="flex-direction: column; margin-left: 163px; align-items: flex-end;">
+ <div style="display: flex; margin: 0.5em 0; padding-left: 6px;">
+ <div class="from" style="width:50%;">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; width: 100px;">From Format</span>
+ <input data-tests-id="InputFromFormat" class="input-text" required name="fromFormat" [(ngModel)]="action.dateFormatter.fromFormat"
+ type="text">
</div>
- <div class="from" style="width:50%; padding: 0;">
- <div class="from-container">
- <div style="display: flex; align-items: center; width: 100%;" class="label">
- <span class="label" style="padding: 0 5px; width: 100px;">To Format</span>
- <input data-tests-id="InputToFormat" class="input-text" ngModel required name="toFormat" [(ngModel)]="action.dateFormatter.toFormat" type="text">
- </div>
- </div>
+ </div>
+ </div>
+ <div class="from" style="width:50%; padding: 0;">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; width: 100px;">To Format</span>
+ <input data-tests-id="InputToFormat" class="input-text" required name="toFormat" [(ngModel)]="action.dateFormatter.toFormat"
+ type="text">
</div>
</div>
-
- <div style="display: flex; margin: 0.5em 0; padding-left: 6px;">
- <div class="from" style="width:50%;">
- <div class="from-container">
- <div style="display: flex; align-items: center; width: 100%;" class="label">
- <span class="label" style="padding: 0 5px; width: 132px;">From Time-zone</span>
- <input class="input-text" data-tests-id="InputFromTimezone" ngModel required name="fromTimezone" [(ngModel)]="action.dateFormatter.fromTimezone" type="text">
- </div>
- </div>
+ </div>
+ </div>
+
+ <div style="display: flex; margin: 0.5em 0; padding-left: 6px;">
+ <div class="from" style="width:50%;">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; width: 132px;">From Time-zone</span>
+ <input class="input-text" data-tests-id="InputFromTimezone" required name="fromTimezone" [(ngModel)]="action.dateFormatter.fromTimezone"
+ type="text">
</div>
- <div class="from" style="width:50%; padding: 0;">
- <div class="from-container">
- <div style="display: flex; align-items: center; width: 100%;" class="label">
- <span class="label" style="padding: 0 5px; width: 100px;">To Time-zone</span>
- <input class="input-text" data-tests-id="InputToTimezone" ngModel required name="toTimezone" [(ngModel)]="action.dateFormatter.toTimezone" type="text">
- </div>
- </div>
+ </div>
+ </div>
+ <div class="from" style="width:50%; padding: 0;">
+ <div class="from-container">
+ <div style="display: flex; align-items: center; width: 100%;" class="label">
+ <span class="label" style="padding: 0 5px; width: 100px;">To Time-zone</span>
+ <input class="input-text" data-tests-id="InputToTimezone" required name="toTimezone" [(ngModel)]="action.dateFormatter.toTimezone"
+ type="text">
</div>
</div>
</div>
+ </div>
+ </div>
<!-- replace text -->
- <div *ngIf="action.actionType === 'replace text'" class="action-container" style="flex-direction: row; margin-left: 152px; padding: 0 0.8em;">
+ <div *ngIf="action.actionType === 'replace text'" class="action-container" style="flex-direction: row; margin-left: 160px; padding: 0 0.8em;">
<div class="action-item">
<div class="from" style="width:100%;">
@@ -94,8 +314,8 @@
<div class="label" style="width: 100%;">
<span class="label" style="padding: 0 5px; width: 100px;">Find what</span>
- <input data-tests-id="InputFindWhat" class="input-text" ngModel required name="findWhat" [(ngModel)]="action.replaceText.find"
- type="text" placeholder="Find text">
+ <input data-tests-id="InputFindWhat" class="input-text" required name="findWhat" [(ngModel)]="action.replaceText.find" type="text"
+ placeholder="Find text">
</div>
</div>
@@ -109,7 +329,7 @@
<div class="label" style="width: 100%;">
<span class="label" style="padding: 0 5px; width: 100px;">Replace with</span>
- <input data-tests-id="InputReplaceWith" class="input-text" ngModel required name="replaceWith" [(ngModel)]="action.replaceText.replace"
+ <input data-tests-id="InputReplaceWith" class="input-text" required name="replaceWith" [(ngModel)]="action.replaceText.replace"
type="text" placeholder="Replace with text">
</div>
@@ -120,15 +340,14 @@
</div>
<!-- log text -->
- <div *ngIf="action.actionType === 'log text'" class="action-container" style="flex-direction: row; margin-left: 152px; padding: 0 0.8em;">
+ <div *ngIf="action.actionType === 'log text'" class="action-container" style="flex-direction: row; margin-left: 160px; padding: 0 0.8em;">
<div class="action-item">
<div class="from" style="width: 100%;">
<div class="from-container" display="padding:0;">
<div class="label" style="width: 100%;">
<span class="label" style="padding: 0 5px; width: 100px;">Log Name</span>
- <input class="input-text" data-tests-id="InputLogName" ngModel name="logName" [(ngModel)]="action.logText.name"
- type="text" placeholder="Enter log name">
+ <input class="input-text" data-tests-id="InputLogName" name="logName" [(ngModel)]="action.logText.name" type="text" placeholder="Enter log name">
</div>
</div>
</div>
@@ -139,8 +358,8 @@
<div class="from-container">
<div class="label" style="width: 100%;">
<span class="label" style="padding: 0 5px; width: 100px;">Log Level</span>
- <input class="input-text" data-tests-id="InputLogLevel" ngModel required name="logLevel" [(ngModel)]="action.logText.level"
- type="text" placeholder="Text to log">
+ <input class="input-text" data-tests-id="InputLogLevel" required name="logLevel" [(ngModel)]="action.logText.level" type="text"
+ placeholder="The title for the log entry">
</div>
</div>
</div>
@@ -165,7 +384,7 @@
</div>
</div>
<div *ngIf="action.map.haveDefault" class="input-wrapper">
- <input type="text" ngModel required name="defaultInput" data-tests-id="defaultInput" [(ngModel)]="action.map.default" class="input">
+ <input type="text" required name="defaultInput" data-tests-id="defaultInput" [(ngModel)]="action.map.default" class="input">
</div>
</div>
@@ -179,10 +398,10 @@
<tbody ngModelGroup="mapKeyValue" #mapKeyValue="ngModelGroup">
<tr *ngFor="let item of action.map.values; let index = index;" (mouseleave)="hoveredIndex=-1" (mouseover)="hoveredIndex=index">
<th style="height: 30px; border: 1px solid #F3F3F3;">
- <input [(ngModel)]="item.key" ngModel required name="mapValue[{{index}}]" data-tests-id="key" type="text" style="width:97%; height: 100%;border: none; padding:0 5px;">
+ <input [(ngModel)]="item.key" required name="mapKey[{{index}}]" data-tests-id="key" type="text" style="width:97%; height: 100%;border: none; padding:0 5px;">
</th>
<th style="height: 30px; border: 1px solid #F3F3F3;">
- <input [(ngModel)]="item.value" ngModel required name="mapValue[{{index}}]" data-tests-id="value" type="text" style="width:97%; height: 100%;border: none; padding:0 5px;">
+ <input [(ngModel)]="item.value" required name="mapValue[{{index}}]" data-tests-id="value" type="text" style="width:97%; height: 100%;border: none; padding:0 5px;">
</th>
<th style="height: 30px; display: flex; align-items: baseline;">
<button mat-icon-button data-tests-id="btn-remove-row" [ngStyle]="hoveredIndex === index ? {'opacity':'1'} : {'opacity':'0'}"
@@ -195,7 +414,7 @@
</table>
- <div style="display:flex; justify-content: space-between;">
+ <div style="display:flex; justify-content: flex-start;">
<div style="display: flex; align-items: center;">
<button mat-mini-fab color="primary" (click)="addMapRow()" data-tests-id="btn-add-row" style="height: 16px; width: 16px; display:flex; box-shadow: none;">
<span style="padding-left: 2px; display: flex; justify-content: center; align-items: center" [innerHTML]="'plus' | feather:12"></span>
@@ -203,6 +422,17 @@
</button>
<span style="color: #009FDB; display: flex; justify-content: center; padding-left: 6px">Add Row</span>
</div>
+ <div class="btn-wrapper">
+ <div style="width: 36px; height: 36px; cursor: pointer;">
+ <span style="width: 100%;
+ color:#5a5a5a;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;" [innerHTML]="'download' | feather:20"></span>
+ </div>
+ <input type="file" id="file" accept=".csv" (change)="handleFileInput($event.target.files)">
+ </div>
</div>
</div>
diff --git a/public/src/app/rule-engine/action/action.component.scss b/public/src/app/rule-engine/action/action.component.scss
index fc36380..e25f0fd 100644
--- a/public/src/app/rule-engine/action/action.component.scss
+++ b/public/src/app/rule-engine/action/action.component.scss
@@ -11,6 +11,13 @@
.highlight {
color: #009fdb;
}
+ .input-text {
+ border: none;
+ flex: 1;
+ // width: 250px;
+ padding: 5px 0 5px 5px;
+ margin: 0;
+ }
.center-content {
display: flex;
width: 100%;
@@ -23,7 +30,7 @@
display: flex;
align-items: center;
justify-content: center;
- min-width: 142px;
+ min-width: 150px;
}
.center-content-item {
width: 100%;
@@ -84,7 +91,8 @@
.from {
display: flex;
flex-direction: column;
- padding: 0 10px;
+ // padding: 0 10px;
+ padding-right: 10px;
.from-container {
display: flex;
flex-direction: column;
@@ -131,3 +139,16 @@
padding: 0 5px;
width: 110px;
}
+
+.btn-wrapper {
+ position: relative;
+}
+.btn-wrapper input[type='file'] {
+ position: absolute;
+ left: 0;
+ top: 0;
+ opacity: 0;
+ width: 36px;
+ height: 36px;
+ cursor: pointer;
+}
diff --git a/public/src/app/rule-engine/action/action.component.ts b/public/src/app/rule-engine/action/action.component.ts
index 1a62e1a..6658d52 100644
--- a/public/src/app/rule-engine/action/action.component.ts
+++ b/public/src/app/rule-engine/action/action.component.ts
@@ -1,34 +1,51 @@
-import { Component, Inject, Input, OnInit, ViewChild } from '@angular/core';
+import {
+ Component,
+ Inject,
+ Input,
+ OnInit,
+ ViewChild,
+ AfterViewInit
+} from '@angular/core';
// import { Copy } from "../model";
import { Http, Response, Headers, RequestOptions } from '@angular/http';
-import { Observable } from 'rxjs/Rx';
+// import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Subject } from 'rxjs/Subject';
import { NgForm } from '@angular/forms';
+import * as Papa from 'papaparse';
+import { metricData } from './metric.data';
+import { Store } from '../../store/store';
+import { ToastrService } from 'ngx-toastr';
@Component({
selector: 'app-action',
templateUrl: './action.component.html',
styleUrls: ['./action.component.scss']
})
-export class ActionComponent implements OnInit {
+export class ActionComponent implements OnInit, AfterViewInit {
@Input() action;
@ViewChild('from') fromInstance;
@ViewChild('target') targetInstance;
@ViewChild('actionFrm') actionFrm: NgForm;
highlight = 'black';
hoveredIndex;
+ fileToUpload: File = null;
+ fileName = '';
+ metrics = metricData;
changeStyle($event) {
this.highlight = $event.type === 'mouseover' ? 'highlight' : 'black';
}
- ngOnInit(): void {
+ ngOnInit(): void {}
+ constructor(public store: Store, private toastr: ToastrService) {}
+
+ ngAfterViewInit(): void {
console.log(this.action.id);
- if (this.action.from !== '') {
+ if (this.action.from !== undefined && this.action.from !== '') {
console.log('Action %o', this.action);
this.fromInstance.updateMode(this.action.from);
}
- if (this.action.target !== '') {
+ if (this.action.target !== undefined && this.action.target !== '') {
this.targetInstance.updateMode(this.action);
}
}
@@ -47,8 +64,63 @@ export class ActionComponent implements OnInit {
this.action.map.values.splice(index, 1);
}
+ removeSearchField(index) {
+ this.action.search.enrich.fields.splice(index, 1);
+ }
+
+ addSearchFeild() {
+ this.action.search.enrich.fields.push('');
+ }
+
+ searchRadioChange(radioType) {
+ console.log(radioType);
+ this.action.search.radio = radioType;
+ console.log(this.action.search);
+ }
+
+ metricChange(metric) {
+ console.log('metric change:', metric);
+ }
+
changeCheckbox() {
console.log(this.action.id);
return (this.action.map.haveDefault = !this.action.map.haveDefault);
}
+ addSearchUpdateRow() {
+ this.action.search.updates.push({ key: '', value: '' });
+ }
+ removeSearchUpdatesRow(index) {
+ this.action.search.updates.splice(index, 1);
+ }
+
+ handleFileInput(files: FileList) {
+ this.fileToUpload = files.item(0);
+ console.log('file to load:', this.fileToUpload);
+ this.fileName = this.fileToUpload !== null ? this.fileToUpload.name : '';
+
+ this.store.loader = true;
+ Papa.parse(this.fileToUpload, {
+ complete: result => {
+ if (result.data) {
+ const mapConvert = result.data
+ .slice(0, 300)
+ .filter(item => item[0] !== undefined && item[1] !== undefined)
+ .map(item => {
+ console.log(`item 0: ${item[0]} item 1: ${item[1]}`);
+ return {
+ key: item[0].trim(),
+ value: item[1].trim()
+ };
+ });
+ this.store.loader = false;
+ this.action.map.values = mapConvert;
+ }
+ },
+ error: (err, file) => {
+ this.store.loader = false;
+ console.log(`error: ${err}, in file ${file}`);
+ this.toastr.error('', err);
+ }
+ });
+ }
}
diff --git a/public/src/app/rule-engine/action/metric.data.ts b/public/src/app/rule-engine/action/metric.data.ts
new file mode 100644
index 0000000..9f2e3e7
--- /dev/null
+++ b/public/src/app/rule-engine/action/metric.data.ts
@@ -0,0 +1,43 @@
+export const metricData = [
+ 'snmp_vHTTPPROXY',
+ 'JerichoStatusPoller',
+ 'Jericho_SYSLOG',
+ 'snmp_vJSALOGS',
+ 'StatusPoller',
+ 'SYSLOG',
+ 'snmp_vECA',
+ 'snmp_vEPDG_MME',
+ 'snmp_vEPDG',
+ 'snmp_vEricsson_HB',
+ 'snmp_vEricsson_ALR',
+ 'snmp_vEricsson_SBG',
+ 'snmp_vEricsson_MME',
+ 'snmp_vFAMP_MME',
+ 'snmp_vHSS',
+ 'snmp_vLSTM',
+ 'snmp_vMDNS',
+ 'snmp_Jericho',
+ 'snmp_vMMSC_CMAUI',
+ 'snmp_vNEMS',
+ 'snmp_vNokiaCTS',
+ 'snmp_vOTA',
+ 'snmp_vPCRF_MOG',
+ 'snmp_vPMS',
+ 'snmp_vSAE_GW',
+ 'snmp_vSAMnagios',
+ 'snmp_vSCP_Amdocs',
+ 'snmp_vSCP_ulticom',
+ 'snmp_vSRX',
+ 'snmp_vSeGW',
+ 'snmp_vVig',
+ 'SYSLOG_VCO',
+ 'VES_${event.commonEventHeader.domain}',
+ 'snmp_vF5',
+ 'CDAP_Enriched_Event',
+ 'CDAP_Enriched_Syslog_Event',
+ 'OaaSContrail',
+ 'GuestOs',
+ 'AIC_Infra_Nagios',
+ 'PMOSS_DCAE-KPI',
+ 'Sec_Syslog_Event'
+];
diff --git a/public/src/app/rule-engine/action/papa.spec.ts b/public/src/app/rule-engine/action/papa.spec.ts
new file mode 100644
index 0000000..864d581
--- /dev/null
+++ b/public/src/app/rule-engine/action/papa.spec.ts
@@ -0,0 +1,84 @@
+import * as Papa from 'papaparse';
+
+describe('parse CSV to JSON', () => {
+ it('should have only 2 attribute key and value', () => {
+ const stringAsCSV = 'liav,GL';
+ Papa.parse(stringAsCSV, {
+ complete: result => {
+ if (result.data) {
+ const parser = result.data
+ .slice(0, 300)
+ .filter(item => item[0] !== undefined && item[1] !== undefined)
+ .map(item => {
+ return {
+ key: item[0].trim(),
+ value: item[1].trim()
+ };
+ });
+ expect(parser).toEqual([
+ {
+ key: 'liav',
+ value: 'GL'
+ }
+ ]);
+ }
+ }
+ });
+ });
+
+ it('should have 2 attribute ignore 1', () => {
+ const stringAsCSV = 'liav,GL,DCAE';
+ Papa.parse(stringAsCSV, {
+ complete: result => {
+ if (result.data) {
+ const parser = result.data
+ .slice(0, 300)
+ .filter(item => item[0] !== undefined && item[1] !== undefined)
+ .map(item => {
+ return {
+ key: item[0].trim(),
+ value: item[1].trim()
+ };
+ });
+ expect(parser).toEqual([
+ {
+ key: 'liav',
+ value: 'GL'
+ }
+ ]);
+ }
+ }
+ });
+ });
+
+ it('should have 4 attribute', () => {
+ const stringAsCSV = `liav,GL
+ Vosk,Dev`;
+
+ Papa.parse(stringAsCSV, {
+ complete: result => {
+ if (result.data) {
+ const parser = result.data
+ .slice(0, 300)
+ .filter(item => item[0] !== undefined && item[1] !== undefined)
+ .map(item => {
+ return {
+ key: item[0].trim(),
+ value: item[1].trim()
+ };
+ });
+ expect(parser).toEqual([
+ {
+ key: 'liav',
+ value: 'GL'
+ },
+ {
+ key: 'Vosk',
+ value: 'Dev'
+ }
+ ]);
+ }
+ }
+ });
+ });
+});