diff options
Diffstat (limited to 'public/src/app/rule-engine/action')
-rw-r--r-- | public/src/app/rule-engine/action/action.component.html | 336 | ||||
-rw-r--r-- | public/src/app/rule-engine/action/action.component.scss | 25 | ||||
-rw-r--r-- | public/src/app/rule-engine/action/action.component.ts | 84 | ||||
-rw-r--r-- | public/src/app/rule-engine/action/metric.data.ts | 43 | ||||
-rw-r--r-- | public/src/app/rule-engine/action/papa.spec.ts | 84 |
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' + } + ]); + } + } + }); + }); +}); |