[SECARSP-311] Component for getting device reports in the time interval was implemented
authorArtem Motchanyi <a.motchanyi@samsung.com>
Fri, 6 Apr 2018 12:19:54 +0000 (15:19 +0300)
committerArtem Motchanyi <a.motchanyi@samsung.com>
Fri, 6 Apr 2018 12:19:54 +0000 (15:19 +0300)
14 files changed:
dashboard/package-lock.json
dashboard/package.json
dashboard/src/app/components/date-interval/date-interval.component.html [new file with mode: 0644]
dashboard/src/app/components/date-interval/date-interval.component.scss [new file with mode: 0644]
dashboard/src/app/components/date-interval/date-interval.component.ts [new file with mode: 0644]
dashboard/src/app/components/date-interval/date-interval.module.ts [new file with mode: 0644]
dashboard/src/app/components/device/device.component.html
dashboard/src/app/components/device/device.component.ts
dashboard/src/app/components/device/device.module.ts
dashboard/src/app/modals/modals.service.ts [new file with mode: 0644]
dashboard/src/app/modals/reports/reports-modal.component.html [new file with mode: 0644]
dashboard/src/app/modals/reports/reports-modal.component.scss [new file with mode: 0644]
dashboard/src/app/modals/reports/reports-modal.component.ts [new file with mode: 0644]
dashboard/src/app/modals/reports/reports-modal.module.ts [new file with mode: 0644]

index 53b5887..41f4a92 100644 (file)
         "duplexer2": "0.0.2"
       }
     },
+    "mydaterangepicker": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/mydaterangepicker/-/mydaterangepicker-4.2.1.tgz",
+      "integrity": "sha1-8GPkdHAWJZua2IIVnvwcffCSIc0="
+    },
     "nan": {
       "version": "2.8.0",
       "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
index c40a91b..0ee4102 100644 (file)
@@ -50,7 +50,8 @@
     "zone.js": "0.8.18",
     "ngx-logger": "1.1.2",
     "angular2-toaster": "5.0.0",
-    "ngx-toggle-switch": ""
+    "ngx-toggle-switch": "",
+    "mydaterangepicker": "4.2.1"
   },
   "devDependencies": {
     "@angular/cli": "1.6.3",
diff --git a/dashboard/src/app/components/date-interval/date-interval.component.html b/dashboard/src/app/components/date-interval/date-interval.component.html
new file mode 100644 (file)
index 0000000..d563e1c
--- /dev/null
@@ -0,0 +1,4 @@
+<form #myForm="ngForm" novalidate>
+    <my-date-range-picker name="mydaterange" [options]="myDateRangePickerOptions"
+                    [(ngModel)]="model" (dateRangeChanged)="onDateRangeChanged($event)" required></my-date-range-picker>
+</form>
diff --git a/dashboard/src/app/components/date-interval/date-interval.component.scss b/dashboard/src/app/components/date-interval/date-interval.component.scss
new file mode 100644 (file)
index 0000000..b6befe7
--- /dev/null
@@ -0,0 +1,3 @@
+@import '../../@theme/styles/themes';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+@import '~bootstrap/scss/mixins/breakpoints';
diff --git a/dashboard/src/app/components/date-interval/date-interval.component.ts b/dashboard/src/app/components/date-interval/date-interval.component.ts
new file mode 100644 (file)
index 0000000..99b609b
--- /dev/null
@@ -0,0 +1,57 @@
+import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
+import { IMyDrpOptions, IMyDateRangeModel } from 'mydaterangepicker';
+
+class DateInterval {
+  from: number;
+  to: number;
+}
+
+@Component({
+  selector: 'sam-date-interval',
+  templateUrl: './date-interval.component.html',
+  styleUrls: ['./date-interval.component.scss'],
+})
+export class DateIntervalComponent implements OnInit {
+  @Input() dateInterval: DateInterval;
+  @Output() dateIntervalChange = new EventEmitter();
+
+  private myDateRangePickerOptions: IMyDrpOptions = {
+    dateFormat: 'mmm-dd-yyyy',
+    showClearBtn: false,
+    showApplyBtn: false,
+    firstDayOfWeek: 'su',
+  };
+
+  private model: any = {};
+
+  ngOnInit() {
+    if (!this.dateInterval.from || !this.dateInterval.to) {
+      this.setCurrentDayRange();
+    }
+  }
+
+  private setCurrentDayRange(): void {
+    const date = new Date();
+    this.dateInterval = new DateInterval();
+    this.dateInterval.from = Math.trunc(date.getTime() / 1000);
+    this.dateInterval.to = this.dateInterval.from;
+    this.dateIntervalChange.emit(this.dateInterval);
+    this.model.beginDate = {
+      year: date.getFullYear(),
+      month: date.getMonth() + 1,
+      day: date.getDate(),
+    };
+    this.model.endDate = {
+      year: date.getFullYear(),
+      month: date.getMonth() + 1,
+      day: date.getDate(),
+    };
+
+  }
+
+  onDateRangeChanged(event: IMyDateRangeModel) {
+    this.dateInterval.from = event.beginEpoc;
+    this.dateInterval.to = event.endEpoc;
+    this.dateIntervalChange.emit(this.dateInterval);
+  }
+}
diff --git a/dashboard/src/app/components/date-interval/date-interval.module.ts b/dashboard/src/app/components/date-interval/date-interval.module.ts
new file mode 100644 (file)
index 0000000..0a6c8ec
--- /dev/null
@@ -0,0 +1,19 @@
+import { NgModule } from '@angular/core';
+import { ThemeModule } from '../../@theme/theme.module';
+import { DateIntervalComponent } from './date-interval.component';
+import { MyDateRangePickerModule } from 'mydaterangepicker';
+
+
+@NgModule({
+  imports: [
+    ThemeModule,
+    MyDateRangePickerModule,
+  ],
+  declarations: [
+    DateIntervalComponent,
+  ],
+  exports: [
+    DateIntervalComponent,
+  ],
+})
+export class DateIntervalModule { }
index 27a9764..c104af5 100644 (file)
@@ -1,27 +1,27 @@
 <nb-flip-card>
   <nb-card-front>
-    <nb-card size="xsmall" accent="{{(device.locked===0) ? 'success' : 'active'}}" class="device-card {{device.type.name}}">
+    <nb-card size="xsmall" accent="{{(device?.locked===0) ? 'success' : 'active'}}" class="device-card {{device?.type.name}}">
       <nb-card-body>
         <div cass="row">
-          <button class="btn btn-icon btn-hero-info" type="button" (click)=toggleLock(device.id,device.locked)>
+          <button class="btn btn-icon btn-hero-info" type="button" (click)=toggleLock(device?.id,device?.locked)>
             <div class="icon"></div>
           </button>
           <div class="info">
-            <div class="title font-w-bold">{{device.type.name | uppercase}}</div>
-            <div class="description font-w-light">{{device.model}}</div>
+            <div class="title font-w-bold">{{device?.type.name | uppercase}}</div>
+            <div class="description font-w-light">{{device?.model}}</div>
           </div>
-          <div *ngIf="device.locked===1" class="locked"><i class="nb-locked"></i></div>
+          <div *ngIf="device?.locked===1" class="locked"><i class="nb-locked"></i></div>
         </div>
       </nb-card-body>
       <nb-card-footer>
         <nb-actions size="small">
           <nb-action>
-            <a class="icon-container" href="#/home/reports/{{device.id}}">
-              <i class="control-icon nb-list"></i>
+            <a class="icon-container">
+              <i class="control-icon nb-list" (click)=showReportsModal()></i>
             </a>
           </nb-action>
           <nb-action>
-            <a class="icon-container" href="#/home/policies/{{device.id}}">
+            <a class="icon-container" href="#/home/policies/{{device?.id}}">
                 <i class="control-icon nb-gear"></i>
             </a>
           </nb-action>
@@ -30,7 +30,7 @@
     </nb-card>
   </nb-card-front>
   <nb-card-back>
-    <nb-card size="xsmall" accent="{{(device.locked===0) ? 'success' : 'active'}}">
+    <nb-card size="xsmall" accent="{{(device?.locked===0) ? 'success' : 'active'}}">
       <nb-card-body>
         <div class="row">
           <div class="col-xxxl-12 col-md-12">
         </div>
         <div class="row">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">Type:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.type.name}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.type.name}}</div>
         </div>
         <div class="row">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">Model:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.model}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.model}}</div>
         </div>
         <div class="row">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">SN:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.sn}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.sn}}</div>
         </div>
         <div class="row">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">Registered:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.ctime | date:'medium'}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.ctime | date:'medium'}}</div>
         </div>
         <div class="row">
           <div class="col-xxxl-12 col-md-12">
         </div>
         <div class="row">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">Name:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.os.name}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.os.name}}</div>
         </div>
         <div class="row">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">Version:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.os.version}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.os.version}}</div>
         </div>
         <div class="row">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">SW:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.os.sw}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.os.sw}}</div>
         </div>
         <div class="row">
           <div class="col-xxxl-12 col-md-12">
         </div>
         <div class="row">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">Country:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.geo.country_name}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.geo.country_name}}</div>
         </div>
         <div class="row mb-2">
           <div class="col-xxxl-3 col-md-3 col-sm-3"><span class="font-w-bold">City:</span></div>
-          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device.geo.city}}</div>
+          <div class="col-xxxl-9 col-md-9 col-sm-9">{{device?.geo.city}}</div>
         </div>
       </nb-card-body>
       <nb-card-footer>
index add0bd1..27152c8 100644 (file)
@@ -1,9 +1,9 @@
 import { Component, Input } from '@angular/core';
 import { DeviceService } from '../../services/device.service';
+import { ModalsService } from '../../modals/modals.service';
 import { Device, UpdateDevice } from '../../models';
 import { NotificationsService } from '../../@theme/components/notifications/notifications.service';
 
-
 @Component({
   selector: 'sam-device',
   templateUrl: './device.component.html',
@@ -12,7 +12,13 @@ import { NotificationsService } from '../../@theme/components/notifications/noti
 export class DeviceComponent {
   @Input() device: Device;
 
-  constructor(private deviceService: DeviceService, private notifications: NotificationsService) {
+  constructor(private deviceService: DeviceService,
+    private notifications: NotificationsService,
+    private modalsService: ModalsService) {
+  }
+
+  showReportsModal(): void {
+    this.modalsService.reportsModal(this.device.id);
   }
 
   toggleLock(): void {
index 74bf97a..71f7289 100644 (file)
@@ -3,20 +3,27 @@ import { NgModule } from '@angular/core';
 import { ThemeModule } from '../../@theme/theme.module';
 import { DeviceComponent } from './device.component';
 import { DeviceService } from '../../services/device.service';
-
+import { ModalsService } from '../../modals/modals.service';
+import { ReportsModalComponent } from '../../modals/reports/reports-modal.component';
+import { ReportsModalModule } from '../../modals/reports/reports-modal.module';
 
 @NgModule({
   imports: [
     ThemeModule,
+    ReportsModalModule,
   ],
   declarations: [
     DeviceComponent,
   ],
   providers: [
     DeviceService,
+    ModalsService,
   ],
   exports: [
     DeviceComponent,
   ],
+  entryComponents: [
+    ReportsModalComponent,
+  ],
 })
 export class DeviceModule { }
diff --git a/dashboard/src/app/modals/modals.service.ts b/dashboard/src/app/modals/modals.service.ts
new file mode 100644 (file)
index 0000000..2ba67bc
--- /dev/null
@@ -0,0 +1,16 @@
+import { Injectable } from '@angular/core';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { ReportsModalComponent } from './reports/reports-modal.component';
+
+@Injectable()
+export class ModalsService {
+  constructor(private modalService: NgbModal) { }
+
+  reportsModal(id: number): void {
+    const activeModal = this.modalService.open(ReportsModalComponent, {
+      size: 'sm',
+      container: 'nb-layout',
+    });
+    activeModal.componentInstance.deviceId = id;
+  }
+}
diff --git a/dashboard/src/app/modals/reports/reports-modal.component.html b/dashboard/src/app/modals/reports/reports-modal.component.html
new file mode 100644 (file)
index 0000000..9d2bf06
--- /dev/null
@@ -0,0 +1,12 @@
+<div class="modal-header">
+  <span>Audit reports</span>
+  <button class="close" aria-label="Close" (click)="closeModal()">
+    <span aria-hidden="true">&times;</span>
+  </button>
+</div>
+<div class="modal-body">
+    <sam-date-interval [(dateInterval)]="dateInterval"></sam-date-interval>
+</div>
+<div class="modal-footer">
+  <button *ngIf="dateInterval.from !== 0 && dateInterval.to !== 0" class="btn btn-md btn-success" (click)="downloadReports()">Download</button>
+</div>
diff --git a/dashboard/src/app/modals/reports/reports-modal.component.scss b/dashboard/src/app/modals/reports/reports-modal.component.scss
new file mode 100644 (file)
index 0000000..b083d5d
--- /dev/null
@@ -0,0 +1,7 @@
+@import '../../@theme/styles/themes';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+@import '~bootstrap/scss/mixins/breakpoints';
+
+button:hover {
+    cursor: pointer !important;
+}
diff --git a/dashboard/src/app/modals/reports/reports-modal.component.ts b/dashboard/src/app/modals/reports/reports-modal.component.ts
new file mode 100644 (file)
index 0000000..4bd38b8
--- /dev/null
@@ -0,0 +1,38 @@
+import { Component } from '@angular/core';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { ReportService } from '../../services';
+import { NGXLogger } from 'ngx-logger';
+
+@Component({
+  selector: 'sam-reports-modal',
+  templateUrl: './reports-modal.component.html',
+  styleUrls: ['./reports-modal.component.scss'],
+})
+export class ReportsModalComponent {
+  dateInterval: any = {};
+  deviceId: number;
+
+  constructor(private activeModal: NgbActiveModal,
+    private reportService: ReportService,
+    private logger: NGXLogger) { }
+
+  downloadReports(): void {
+    this.reportService.getDeviceReportsArchiveLink(
+      this.deviceId,
+      this.dateInterval.from,
+      this.dateInterval.to,
+    ).subscribe(
+      (response) => {
+        this.reportService.getDeviceReportsArchive(response.uri);
+        this.logger.info('Reports archive successfully downloaded');
+      },
+      (error) => {
+        this.logger.error('Cant download reports archive');
+      },
+    );
+  }
+
+  closeModal(): void {
+    this.activeModal.close();
+  }
+}
diff --git a/dashboard/src/app/modals/reports/reports-modal.module.ts b/dashboard/src/app/modals/reports/reports-modal.module.ts
new file mode 100644 (file)
index 0000000..7ddae72
--- /dev/null
@@ -0,0 +1,22 @@
+import { NgModule } from '@angular/core';
+import { ThemeModule } from '../../@theme/theme.module';
+import { ReportsModalComponent } from './reports-modal.component';
+import { DateIntervalModule } from '../../components/date-interval/date-interval.module';
+import { ReportService } from '../../services/report.service';
+
+@NgModule({
+  imports: [
+    ThemeModule,
+    DateIntervalModule,
+  ],
+  declarations: [
+    ReportsModalComponent,
+  ],
+  providers: [
+    ReportService,
+  ],
+  exports: [
+    ReportsModalComponent,
+  ],
+})
+export class ReportsModalModule { }