You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by sa...@apache.org on 2019/05/15 07:34:13 UTC

[metron] branch master updated: METRON-2089 [UI] Adding loading state to Alerts details view (tiborm via sardell) closes apache/metron#1390

This is an automated email from the ASF dual-hosted git repository.

sardell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/metron.git


The following commit(s) were added to refs/heads/master by this push:
     new adf477d  METRON-2089 [UI] Adding loading state to Alerts details view (tiborm via sardell) closes apache/metron#1390
adf477d is described below

commit adf477d90cf23bc757641b3e74bdb2ed9b242f04
Author: tiborm <ti...@gmail.com>
AuthorDate: Wed May 15 09:31:36 2019 +0200

    METRON-2089 [UI] Adding loading state to Alerts details view (tiborm via sardell) closes apache/metron#1390
---
 .../alert-details/alert-details.component.html     | 31 ++++++-----
 .../alert-details/alert-details.component.scss     | 11 ++--
 .../alert-details/alert-details.component.spec.ts  | 63 ++++++++++++++++++++++
 .../alert-details/alert-details.component.ts       |  9 +++-
 metron-interface/metron-alerts/src/slider.scss     |  1 +
 5 files changed, 96 insertions(+), 19 deletions(-)

diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.html b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.html
index c4bcc88..c013a70 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.html
+++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.html
@@ -11,8 +11,14 @@
 	OR CONDITIONS OF ANY KIND, either express or implied. See the License for
   the specific language governing permissions and limitations under the License.
   -->
-<div class="metron-slider-pane-details load-right-to-left dialog1x" [ngClass]="{'is-meta-alert': isMetaAlert}">
-    <div class="container-fluid pl-0 pr-0 h-100">
+<div class="metron-slider-pane-details d-flex load-right-to-left dialog1x" [ngClass]="{'is-meta-alert': isMetaAlert}">
+
+    <div data-qe-id="preloader" class="d-flex flex-column w-100 h-100 justify-content-center align-items-center" *ngIf="!alertSources.length">
+        <div class="spinner-border text-info" role="status"></div>
+        <div class="pt-2"><small>Loading...</small></div>
+    </div>
+
+    <div class="container-fluid pl-0 pr-0 h-100" *ngIf="alertSources.length">
         <div class="h-100 d-flex">
             <div class="nav-container" *ngIf="!isMetaAlert">
                 <ul class="nav flex-column">
@@ -39,15 +45,15 @@
                 </ul>
             </div>
             <div class="details-container">
-                <div class="container-fluid h-100">
-                    <div class="row title-container">
+                <div class="d-flex flex-column h-100">
+                    <div class="title-container d-flex flex-row">
                         <div class="col-md-10 px-0">
-                            <div class="form-title row ml-2">
-                                <div class="col px-0">
+                            <div class="form-title row mx-3">
+                                <div class="pr-3">
                                     <span appAlertSeverity [severity]="getScore(alertSource)"> </span>
                                     <span> {{ getScore(alertSource) }} </span>
                                 </div>
-                                <div class="px-0" style="width: 205px">
+                                <div class="px-0">
                                     <span [ngClass]="{'editable-text': alertSources.length > 1}" *ngIf="!showEditor" (click)="toggleNameEditor()"> {{ (alertSource.name && alertSource.name.length > 0)? alertSource.name : alertId | centerEllipses:20 }} </span>
                                     <div class="input-group" *ngIf="showEditor">
                                         <input type="text" class="form-control"  [(ngModel)]="alertName">
@@ -57,12 +63,12 @@
                                 </div>
                             </div>
                         </div>
-                        <div class="col-md-2 px-0">
+                        <div class="col-md-2 pr-3">
                             <i class="fa fa-times pull-right close-button" aria-hidden="true" (click)="goBack()"></i>
                         </div>
                     </div>
-                    <div class="row justify-content-center py-4 actions">
-                        <table>
+                    <div class="px-3 py-4 actions">
+                        <table class="w-100">
                             <tr>
                                 <td class="title"> Status</td>
                                 <td [ngClass]="{'primary': selectedAlertState === alertState.ESCALATE, 'secondary': selectedAlertState !== alertState.ESCALATE}" data-name="escalate" (click)="processEscalate()">ESCALATE</td>
@@ -82,7 +88,7 @@
                     </div>
 
                     <div class="tabContainer">
-                        <div *ngIf="activeTab === tabs.DETAILS" class="ml-1 my-3 form" >
+                        <div *ngIf="activeTab === tabs.DETAILS" class="mx-3 my-3 form" >
                             <ng-container *ngFor="let alert of alertSources; let i = index;" >
                                 <div class="pb-2 alert-details-title"> Alert {{ i + 1 }} of {{ alertSources.length }}</div>
                                 <ul>
@@ -94,12 +100,11 @@
                             </ng-container>
                         </div>
 
-                        <div *ngIf="activeTab === tabs.COMMENTS" class="my-4">
+                        <div *ngIf="activeTab === tabs.COMMENTS" class="mx-3 my-3">
                             <div> Comments <span *ngIf="alertCommentsWrapper.length > 0"> ({{alertCommentsWrapper.length}}) </span></div>
                             <textarea class="form-control" [(ngModel)]="alertCommentStr"> </textarea>
                             <button class="btn btn-mine_shaft_2" [disabled]="alertCommentStr.trim().length === 0" (click)="onAddComment()">ADD COMMENT</button>
                             <ng-container *ngFor="let alertCommentWrapper of alertCommentsWrapper; let i = index">
-                                <hr>
                                 <div class="comment-container" data-qe-id="comment">
                                     <i
                                         class="fa fa-trash-o"
diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.scss b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.scss
index 3373292..43bdcd6 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.scss
+++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.scss
@@ -116,7 +116,8 @@
   }
 
   .nav-link {
-    padding: 15px 1em;
+    padding: 15px 0;
+    text-align: center;
 
     &.active {
       border-left: 4px solid #31ABDF;
@@ -126,7 +127,7 @@
 }
 
 .details-container {
-  width: 340px;
+  width: 100%;
 }
 
 textarea {
@@ -145,14 +146,14 @@ textarea {
 
 .comment-container {
   font-size: 14px;
-  padding: 10px 0px;
+  padding: 10px;
+  border-top: 1px solid #4D4D4D;
 
   i {
-    right: 25px;
     display: none;
     cursor: pointer;
     font-size: 18px;
-    position: absolute;
+    float: right;
   }
 
   .comment {
diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.spec.ts b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.spec.ts
index 7800517..63c22e3 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.spec.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.spec.ts
@@ -39,6 +39,53 @@ import {CommentAddRemoveRequest} from "../../model/comment-add-remove-request";
 import {AlertSource} from "../../model/alert-source";
 import {of} from "rxjs/index";
 
+const alertDetail = {
+  'enrichments:geo:ip_dst_addr:locID': '5308655',
+  'bro_timestamp': '1554222181.202211',
+  'status_code': 404,
+  'enrichments:geo:ip_dst_addr:location_point': '33.4589,-112.0709',
+  'ip_dst_port': 80,
+  'enrichments:geo:ip_dst_addr:dmaCode': '753',
+  'adapter:geoadapter:begin:ts': '1554727717061',
+  'enrichments:geo:ip_dst_addr:latitude': '33.4589',
+  'parallelenricher:enrich:end:ts': '1554727717078',
+  'uid': 'CBt5FP2TVetZJjaZbi',
+  'resp_mime_types': ['text/html'],
+  'trans_depth': 1,
+  'protocol': 'http',
+  'source:type': 'bro',
+  'adapter:threatinteladapter:end:ts': '1554727717076',
+  'original_string': 'HTTP | id.orig_p:49199',
+  'ip_dst_addr': '204.152.254.221',
+  'adapter:hostfromjsonlistadapter:end:ts': '1554727717069',
+  'host': 'runlove.us',
+  'adapter:geoadapter:end:ts': '1554727717069',
+  'ip_src_addr': '192.168.138.158',
+  'enrichments:geo:ip_dst_addr:longitude': '-112.0709',
+  'user_agent': '',
+  'resp_fuids': ['FeDAUx1IIW621Aw6Y8'],
+  'timestamp': 1554222181202,
+  'method': 'POST',
+  'parallelenricher:enrich:begin:ts': '1554727717075',
+  'request_body_len': 96,
+  'enrichments:geo:ip_dst_addr:city': 'Phoenix',
+  'enrichments:geo:ip_dst_addr:postalCode': '85004',
+  'adapter:hostfromjsonlistadapter:begin:ts': '1554727717061',
+  'orig_mime_types': ['text/plain'],
+  'uri': '/wp-content/themes/twentyfifteen/img5.php?l=8r1gf1b2t1kuq42',
+  'tags': [],
+  'parallelenricher:splitter:begin:ts': '1554727717075',
+  'alert_status': 'RESOLVE',
+  'orig_fuids': ['FTTvSE5Asee5tJr99'],
+  'ip_src_port': 49199,
+  'parallelenricher:splitter:end:ts': '1554727717075',
+  'adapter:threatinteladapter:begin:ts': '1554727717075',
+  'status_msg': 'Not Found',
+  'guid': 'fe9e058e-6d5a-4ba5-8b79-d8e6a2792931',
+  'enrichments:geo:ip_dst_addr:country': 'US',
+  'response_body_len': 357
+};
+
 describe('AlertDetailsComponent', () => {
   let component: AlertDetailsComponent;
   let fixture: ComponentFixture<AlertDetailsComponent>;
@@ -91,6 +138,18 @@ describe('AlertDetailsComponent', () => {
     fixture.detectChanges();
   });
 
+  it('should be in a loading state if no alertSources loaded', () => {
+    component.alertSources = [];
+    fixture.detectChanges();
+    expect(fixture.debugElement.query(By.css('[data-qe-id="preloader"]'))).toBeTruthy();
+  });
+
+  it('should show details if alertSources loaded', () => {
+    component.alertSources = [alertDetail];
+    fixture.detectChanges();
+    expect(fixture.debugElement.query(By.css('[data-qe-id="preloader"]'))).toBeFalsy();
+  });
+
   it('should delete a comment.', fakeAsync(() => {
     const responseMock = new AlertSource();
     responseMock.guid = 'guid';
@@ -104,6 +163,10 @@ describe('AlertDetailsComponent', () => {
     component.alertSource.guid = 'guid';
     component.alertSourceType = 'sourceType';
     const now = Date.now();
+
+    component.alertSources = [alertDetail];
+    fixture.detectChanges();
+
     component.alertCommentsWrapper = [
       new AlertCommentWrapper(
         new AlertComment('lorem ipsum', 'user', now),
diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts
index f5c55fa..1b40de6 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 import {Component, OnInit} from '@angular/core';
-import {ActivatedRoute, Router} from '@angular/router';
+import {ActivatedRoute, Router, NavigationStart} from '@angular/router';
 import * as moment from 'moment/moment';
 import {Subscription} from 'rxjs';
 
@@ -87,6 +87,13 @@ export class AlertDetailsComponent implements OnInit {
               private dialogService: DialogService,
               globalConfigService: GlobalConfigService) {
     this.globalConfigService = globalConfigService;
+
+    router.events.subscribe(event => {
+      if (event instanceof NavigationStart && /\/alerts-list\(dialog:details\//.test(event.url)) {
+        this.alertSources = [];
+        this.alertSource = null;
+      }
+    });
   }
 
   goBack() {
diff --git a/metron-interface/metron-alerts/src/slider.scss b/metron-interface/metron-alerts/src/slider.scss
index ccb139f..9df9a0e 100644
--- a/metron-interface/metron-alerts/src/slider.scss
+++ b/metron-interface/metron-alerts/src/slider.scss
@@ -34,6 +34,7 @@ $dialog-4x-width: 1340px;
   z-index: 9;
 
   background: $edit-child-background;
+  border-left: 1px solid $edit-background-border;
 
   .close-button
   {