Projekt

Obecné

Profil

« Předchozí | Další » 

Revize cbb91c90

Přidáno uživatelem Jakub Hlaváč před téměř 4 roky(ů)

Re #8915 - Zapracování požadavků ze schůzky

+ sensor edit under edit button in menu
  • request for sensor data only for first time, then after button click
    + sensor group names
    + adding information to unit and sensor
    + commenting
    + code refactor

Zobrazit rozdíly:

src/app/administration/administration.module.ts
1
import { NgModule } from '@angular/core';
2
import { CommonModule } from '@angular/common';
3
import { AdministrationComponent } from './components/administration.component';
4
import {NavBarModule} from '../shared/nav-bar/nav-bar.module';
5

  
6

  
7

  
8
@NgModule({
9
  declarations: [AdministrationComponent],
10
  imports: [
11
    CommonModule,
12
    NavBarModule
13
  ]
14
})
15
export class AdministrationModule { }
src/app/administration/components/administration.component.html
1
<app-nav-bar></app-nav-bar>
2

  
3
<p>administration works!</p>
src/app/administration/components/administration.component.ts
1
import { Component, OnInit } from '@angular/core';
2

  
3
@Component({
4
  selector: 'app-administration',
5
  templateUrl: './administration.component.html',
6
  styleUrls: ['./administration.component.scss']
7
})
8
export class AdministrationComponent implements OnInit {
9

  
10
  constructor() { }
11

  
12
  ngOnInit(): void {
13
  }
14

  
15
}
src/app/app-routing.module.ts
4 4
import {DashboardComponent} from './dashboard/components/dashboard.component';
5 5
import {AuthGuard} from './auth/guards/auth.guard';
6 6
import {RoleGuard} from './auth/guards/role.guard';
7
import {AdministrationComponent} from './administration/components/administration.component';
8 7
import {SensorComponent} from './sensor/components/sensor.component';
9 8
import {UnitComponent} from './unit/components/unit.component';
10 9

  
......
35 34
      expectedRole: ['1', '0']
36 35
    }
37 36
  }, {
38
    canActivate: [AuthGuard, RoleGuard],
39
    path: 'administration',
40
    component: AdministrationComponent,
41
    pathMatch: 'full',
42
    data: {
43
      expectedRole: ['0']
44
    }
45
  },{
46 37
    path: 'login',
47 38
    component: LoginComponent,
48 39
    pathMatch: 'full',
src/app/app.module.ts
9 9
import {AuthModule} from './auth/auth.module';
10 10
import {LoginModule} from './login/login.module';
11 11
import {DashboardModule} from './dashboard/dashboard.module';
12
import {AdministrationModule} from './administration/administration.module';
13 12
import {SensorModule} from './sensor/sensor.module';
14 13
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
15 14
import {UnitModule} from './unit/unit.module';
......
29 28
    AuthModule,
30 29
    LoginModule,
31 30
    DashboardModule,
32
    AdministrationModule,
33 31
    SensorModule,
34 32
    FontAwesomeModule,
35 33
    UnitModule,
src/app/auth/interceptors/auth.interceptor.ts
23 23
  ) {
24 24
  }
25 25

  
26
  /**
27
   * Intercept every request to backend
28
   * @param request request
29
   * @param next next
30
   */
26 31
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
27

  
32
    // check if data in cookies
28 33
    if (!this.cookieService.get(GlobalVariable.SESSION_ID) && !request.url.includes('ControllerServlet')) {
29 34
      console.log('No sessionid!');
30 35
      this.cookieService.deleteAll();
......
32 37
      return of(null);
33 38
    }
34 39

  
35
    console.log('Sending request!', request);
40
    console.log('Sending request!', request.url);
36 41
    return next.handle(request)
37 42
      .pipe(
38 43
        catchError(err => {
src/app/auth/models/user.ts
3 3
import {UserInfo} from '../../shared/api/endpoints/models/user-info';
4 4
import {UserCookie} from '../../shared/api/endpoints/models/user-cookie';
5 5

  
6
/**
7
 * User state model
8
 */
6 9
export interface User {
7 10
  userInfo?: UserInfo;
8 11
  isLoggedIn?: boolean;
src/app/auth/services/auth.service.ts
24 24
  ) {
25 25
  }
26 26

  
27
  /**
28
   * Set state from saved cookies
29
   */
27 30
  setFromCookie() {
28 31
    const user: User = {
29 32
      userCookie: {
......
37 40
    this.userState.setUser(user);
38 41
  }
39 42

  
43
  /**
44
   * Get user from state
45
   */
40 46
  getUser() {
41 47
    console.log('Auth Service');
42 48
    if (!this.userState.getUser() && this.cookieService.get(GlobalVariable.SESSION_ID)) {
......
46 52
    return this.userState.getUser();
47 53
  }
48 54

  
55
  /**
56
   * Get user from state as observable
57
   */
49 58
  getUserState(): Observable<User> {
50 59
    return this.userState.getUser$();
51 60
  }
52 61

  
62
  /**
63
   * Login process with backend call
64
   * @param loginInput login form
65
   */
53 66
  doLogin(loginInput): Observable<boolean> {
54 67
    return this.loginService.login$Response(loginInput)
55 68
      .pipe(
......
61 74
      );
62 75
  }
63 76

  
77
  /**
78
   * Set user state, cookie and localStorage from server response
79
   * @param userCookie server response
80
   * @param username form username
81
   */
64 82
  setUserFromResponse(userCookie: UserCookie, username): UserCookie {
65 83
    console.log('Setting user from login!');
66 84
    this.userState.setUser({
......
71 89
    return userCookie;
72 90
  }
73 91

  
92
  /**
93
   * Logout user, clear user state and redirect to login
94
   */
74 95
  doLogout() {
75 96
    this.userState.setUser(null);
76 97
    this.cookieService.deleteAll();
......
79 100
    this.cookieService.deleteAll();
80 101
  }
81 102

  
103
  /**
104
   * Set localstorage and cookies
105
   * @param userCookie user obejct
106
   * @param username username from login form
107
   */
82 108
  setSessionStorage(userCookie: UserCookie, username) {
83 109
    localStorage.setItem(GlobalVariable.USER_NAME, username)
84 110
    localStorage.setItem(GlobalVariable.RIGHTS, userCookie.rightsID.toString());
src/app/auth/states/user.state.ts
1 1
import {Injectable} from '@angular/core';
2 2
import {BehaviorSubject, Observable} from 'rxjs';
3 3
import {User} from '../models/user';
4
import {AuthService} from '../services/auth.service';
5 4
import {LoginService} from '../../shared/api/endpoints/services/login.service';
6 5
import {ToastService} from '../../shared/services/toast.service';
7 6

  
......
28 27
    return this.userState$.getValue();
29 28
  }
30 29

  
30
  /**
31
   * Get user, if not exists fetch from server
32
   * @param refresh force refresh user status from backend
33
   */
31 34
  getUser$(refresh: boolean = false): Observable<User> {
32 35
   if (this.userState$.getValue()){
33 36
      this.loginService.getUserInfo$Response().subscribe(res => {
src/app/dashboard/components/dashboard.component.html
7 7
          <div [className]="'row dashboard-unit'">
8 8
            <div class="col-md-6"><h3>{{ unit.unit.description}}</h3></div>
9 9
            <div class="col-md-6 text-right">
10
              <p-button label="Sensors graph" icon="pi pi-chart-line" [routerLink]="['/dashboard/unit', unit.unit.unitId]"></p-button>
10
              <p-button label="Sensors graph" icon="pi pi-chart-line" [routerLink]="['/dashboard/unit', unit.unit.unitId]" [queryParams]="{unitDescription: unit.unit.description}"></p-button>
11 11
              <div class="dashboard-button-separator"></div>
12 12
              <p-button icon="pi pi-cog" styleClass="p-button-warning" (click)="showItems($event, unit.unit); menu.toggle($event)"></p-button>
13 13
              <p-menu #menu [popup]="true" [model]="items" [appendTo]="'body'" [baseZIndex]="50"></p-menu>
src/app/dashboard/components/dashboard.component.ts
1
import { Component, OnInit } from '@angular/core';
1
import {Component, OnDestroy, OnInit} from '@angular/core';
2 2
import {Group} from '../../shared/api/endpoints/models/group';
3 3
import {Drivers} from '../../shared/api/endpoints/models/drivers';
4 4
import {GeneralInfo} from '../../shared/api/endpoints/models/general-info';
......
16 16
import {AuthService} from '../../auth/services/auth.service';
17 17
import {User} from '../../auth/models/user';
18 18
import {SensorType} from '../../shared/api/endpoints/models/sensor-type';
19
import {Subscription} from 'rxjs';
19 20

  
20 21
@Component({
21 22
  selector: 'app-dashboard',
22 23
  templateUrl: './dashboard.component.html',
23 24
  styleUrls: ['./dashboard.component.scss']
24 25
})
25
export class DashboardComponent implements OnInit {
26
export class DashboardComponent implements OnInit, OnDestroy {
26 27

  
27 28
  loggedUser: User;
28 29
  items: MenuItem[] = [];
......
35 36
  showInsertPositionPopup = false;
36 37
  phenomenons: Phenomenon[];
37 38
  sensorTypes: SensorType[];
39
  subscription: Subscription[] = [];
38 40

  
39 41
  constructor(
40 42
    private dataService: DataService,
......
45 47
    private toastService: ToastService,
46 48
    private authService: AuthService
47 49
  ) {
50
    this.initData();
51
  }
52

  
53
  ngOnInit(): void {
54
  }
55

  
56
  /**
57
   * Unsubscribe after leaving
58
   */
59
  ngOnDestroy(): void {
60
    this.subscription.forEach(subs => subs.unsubscribe());
61
  }
62

  
63
  /**
64
   * Get necessary data from backend
65
   */
66
  initData() {
48 67
    this.sensorService.getPhenomenons().subscribe(
49 68
      response => this.phenomenons = response
50 69
    );
51 70
    this.sensorService.getSensorTypes().subscribe(
52 71
      response => this.sensorTypes = response
53 72
    );
54
  }
55

  
56
  ngOnInit(): void {
57 73
    this.setUser();
58 74
    this.getUnits();
59 75
  }
60 76

  
77
  /**
78
   * Get user from user state
79
   */
61 80
  setUser(){
62 81
    this.authService.getUserState().subscribe(res => {
63 82
      if(res){
......
66 85
    });
67 86
  }
68 87

  
88
  /**
89
   * Get all units and theirs sensors from backend
90
   */
69 91
  getUnits() {
70 92
    this.dataService.getData().subscribe(data => {
71 93
      this.units = data;
......
73 95
    }, err => this.toastService.showError(err.error.message));
74 96
  }
75 97

  
98
  /**
99
   * Show edit unit
100
   * @param $event click event
101
   * @param unit edited unit
102
   */
76 103
  editUnitPopup($event: MouseEvent, unit: Unit) {
77 104
    this.editedUnit = unit;
78 105
    this.showEditUnitPopup = true;
79 106
  }
80 107

  
108
  /**
109
   * Show insert unit
110
   * @param $event click event
111
   * @param unit unit for sensor insert
112
   */
81 113
  insertSensorPopup($event: any, unit: Unit) {
82 114
    this.showInsertSensorPopup = true;
83 115
    this.editedUnit = unit;
84 116
  }
85 117

  
118
  /**
119
   * Detele unit confirmation
120
   * @param $event click event
121
   * @param unit unit to delete
122
   */
86 123
  deleteUnit($event: any, unit: Unit) {
87 124
    this.confirmationService.confirm({
88 125
      message: 'Do you want to delete this unit?',
......
98 135
    });
99 136
  }
100 137

  
138
  /**
139
   * Send delete unit request to backend
140
   * @param unit to delete
141
   */
101 142
  processUnitDeletion(unit: Unit) {
102 143
    this.managementService.deleteUnit$Response({body: {
103 144
      unit: {
......
114 155
    ).toPromise().then().catch(err => this.toastService.showError(err.error.message));
115 156
  }
116 157

  
158
  /**
159
   * Show menu items to manipulate with unit
160
   * @param $event click event
161
   * @param unit unit we want edit
162
   */
117 163
  showItems($event: any, unit: Unit) {
118 164
    $event.stopPropagation();
119 165
    this.items = [
......
132 178
    ]
133 179
  }
134 180

  
181
  /**
182
   * Add created unit to memory so we do not need call backend
183
   * @param inserted unit
184
   */
135 185
  addUnit(inserted: any) {
136 186
    const sensors: Sensor[] = [];
137 187
    inserted.sensors.forEach(sens => {
......
153 203
    })
154 204
  }
155 205

  
206
  /**
207
   * Add created sensors to unit in memory so we do not need call backend
208
   * @param inserted sensors
209
   */
156 210
  addSensors(inserted: any) {
157 211
    inserted.sensors.forEach(sens => {
158 212
      this.units.find(un => un.unit.unitId === inserted.unit.unit_id).sensors.push({
......
166 220
    });
167 221
  }
168 222

  
223
  /**
224
   * Delete sensor from memory
225
   * @param unitId sensor unit
226
   * @param sensor sensor to delete
227
   */
169 228
  deleteSensor(unitId: number, sensor: Sensor) {
170 229
    this.units.find(unit => unit.unit.unitId === unitId).sensors =
171 230
      this.units.find(unit => unit.unit.unitId === unitId).sensors.filter(testedSensor => testedSensor.sensorId !== sensor.sensorId);
172 231
  }
173 232

  
174
  private insertPosition($event: any, unit: Unit) {
233
  /**
234
   * Show insert position popup
235
   * @param $event click event
236
   * @param unit unit to insert position for
237
   */
238
  insertPosition($event: any, unit: Unit) {
175 239
    $event.stopPropagation();
176 240
    this.showInsertPositionPopup = true;
177 241
    this.editedUnit = unit;
src/app/dashboard/components/position-insert-popup/position-insert-popup.component.ts
44 44
    this.insertForm.reset();
45 45
  }
46 46

  
47
  /**
48
   * Send insert position request to backend adn handle response.
49
   */
47 50
  processInsertion() {
48 51
    if (this.insertForm.valid) {
49 52
      const lat = this.insertForm.controls.lat.value;
......
67 70
    }
68 71
  }
69 72

  
73
  /**
74
   * Close popup
75
   */
70 76
  close() {
71 77
    this.isVisibleChange.emit(false);
72 78
  }
src/app/dashboard/components/sensor-insert-popup/sensor-insert-popup.component.ts
49 49
    });
50 50
  }
51 51

  
52
  /**
53
   * Prepare form object for sensor
54
   */
52 55
  createSensor(): FormGroup {
53 56
    return this.formBuilder.group({
54 57
      sensorId: ['', Validators.required],
......
58 61
    });
59 62
  }
60 63

  
64
  /**
65
   * Add sensor to form
66
   */
61 67
  addSensor(): void {
62 68
    this.items = this.insertForm.get('sensors') as FormArray;
63 69
    this.items.push(this.createSensor());
64 70
    this.sensors++;
65 71
  }
66 72

  
73
  /**
74
   * Remove last sensor from form
75
   */
67 76
  removeSensor() {
68 77
    this.items = this.insertForm.get('sensors') as FormArray;
69 78
    this.items.removeAt(this.items.length - 1);
70 79
    this.sensors--;
71 80
  }
72 81

  
82
  /**
83
   * Clearing form
84
   */
73 85
  clearFormArray() {
74 86
    const frmArray = this.insertForm?.get('sensors') as FormArray;
75 87
    if (frmArray) {
......
79 91
    this.insertForm.reset();
80 92
  }
81 93

  
94
  /**
95
   * Send insert sensors request to backend. Iterate over all sensors in form.
96
   */
82 97
  processSensorInsertion() {
83 98
    if (this.insertForm.valid) {
84 99
      const unit: InsertUnit = {
src/app/dashboard/components/sensor-popup/sensor-popup.component.ts
34 34
  ngOnInit(): void {
35 35
  }
36 36

  
37
  /**
38
   * Close popup
39
   */
37 40
  close() {
38 41
    this.isVisibleChange.emit(false);
39 42
  }
......
52 55
    }, 0);
53 56
  }
54 57

  
58
  /**
59
   * Send update sensor request to backend. Creates object from form input. Handle response.
60
   */
55 61
  processSensorEdition() {
56 62
    if (this.insertForm.valid) {
57 63
      this.managementService.updateSensor$Response({body: {
......
81 87
    }
82 88
  }
83 89

  
84
  private changeSensor() {
90
  /**
91
   * Change sensor data to memory
92
   */
93
  changeSensor() {
85 94
    this.sensor.sensorType = this.insertForm.controls.sensorType.value;
86 95
    this.sensor.sensorName = this.insertForm.controls.sensorName.value;
87 96
    this.sensor.phenomenon.phenomenonId = this.insertForm.controls.phenomenon.value;
src/app/dashboard/components/sensors/sensors.component.html
8 8
    <button pButton type="button" label="View graph" [routerLink]="['/dashboard/unit', unit.unitId, 'sensor', sensor.sensorId]" [queryParams]="{unitName: unit.description}" title="Sensor" icon="pi pi-chart-line"></button>
9 9
    <ng-container *ngIf="loggedUser?.userInfo?.rightsId == 0 || loggedUser?.userInfo?.rightsId == 1">
10 10
      <div class="dashboard-button-separator"></div>
11
      <button pButton type="button" label="Edit sensor" icon="pi pi-cog" (click)="editSensor($event, sensor)" [className]="'p-button-warning'"></button>
12
      <button pButton type="button" label="Delete sensor" icon="pi pi-times" (click)="deleteSensor($event, sensor)" [className]="'p-button-danger'"></button>
11
      <p-button icon="pi pi-cog" styleClass="p-button-warning" (click)="showItems($event, sensor); menu.toggle($event)"></p-button>
12
      <p-menu #menu [popup]="true" [model]="items" [appendTo]="'body'" [baseZIndex]="50"></p-menu>
13 13
    </ng-container>
14 14
  </div>
15 15
</div>
src/app/dashboard/components/sensors/sensors.component.ts
1 1
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
2 2
import {Sensor} from '../../../shared/api/endpoints/models/sensor';
3
import {ConfirmationService} from 'primeng/api';
3
import {ConfirmationService, MenuItem} from 'primeng/api';
4 4
import {ManagementService} from '../../../shared/api/endpoints/services/management.service';
5 5
import {map} from 'rxjs/operators';
6 6
import {HttpResponse} from '@angular/common/http';
......
24 24
  @Input() sensorTypes: SensorType[];
25 25
  showSensorPopup = false;
26 26
  editedSensor: Sensor;
27
  items: MenuItem[] = [];
28

  
27 29
  constructor(
28 30
    private confirmationService: ConfirmationService,
29 31
    private managementService: ManagementService,
......
33 35
  ngOnInit(): void {
34 36
  }
35 37

  
38
  /**
39
   * Show menu items to manipulate with sensor
40
   * @param $event click event
41
   * @param sensor sensor we want edit
42
   */
43
  showItems($event: any, sensor: Sensor) {
44
    $event.stopPropagation();
45
    this.items = [
46
      {label: 'Edit sensor', icon: 'pi pi-cog', command: () => {
47
          this.editSensor($event, sensor);
48
        }},
49
      {label: 'Delete sensor', icon: 'pi pi-times', command: () => {
50
          this.deleteSensor($event, sensor);
51
        }}
52
    ]
53
  }
54

  
55
  /**
56
   * Show edit sensor popup
57
   * @param $event click event
58
   * @param sensor sensor to edit
59
   */
36 60
  editSensor($event: MouseEvent, sensor: Sensor) {
37 61
    $event.stopPropagation();
38 62
    this.editedSensor = sensor;
39 63
    this.showSensorPopup = true;
40 64
  }
41 65

  
66
  /**
67
   * Selete sensor confirmation
68
   * @param $event click event
69
   * @param sensor sensor to delete
70
   */
42 71
  deleteSensor($event: any, sensor: Sensor) {
43 72
    this.confirmationService.confirm({
44 73
      message: 'Do you want to delete this sensor?',
......
54 83
    });
55 84
  }
56 85

  
86
  /**
87
   * Send deletion request to backend. Handle response.
88
   * @param sensor to delete
89
   */
57 90
  processSensorDeletion(sensor: Sensor) {
58 91
    this.managementService.deleteSensor$Response({body: {
59 92
      unit: {
src/app/dashboard/components/unit-popup/unit-popup.component.ts
36 36
  ngOnInit(): void {
37 37
  }
38 38

  
39

  
39
  /**
40
   * Send insert unit request to backend and handle it
41
   */
40 42
  saveUnit() {
41 43
    if (this.insertForm.controls.unitDescription.value && this.insertForm.controls.unitDescription.value !== this.unit.description) {
42 44
      this.unit.description = this.insertForm.controls.unitDescription.value;
src/app/login/components/login.component.ts
1
import {Component, OnInit} from '@angular/core';
1
import {Component, OnDestroy, OnInit} from '@angular/core';
2 2
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
3 3
import {switchMap} from 'rxjs/operators';
4 4
import {of, Subscription} from 'rxjs';
......
10 10
  templateUrl: './login.component.html',
11 11
  styleUrls: ['./login.component.scss']
12 12
})
13
export class LoginComponent implements OnInit {
13
export class LoginComponent implements OnInit, OnDestroy {
14 14

  
15 15
  loginForm: FormGroup;
16 16
  subscription: Subscription[] = [];
......
22 22
  ) {
23 23
  }
24 24

  
25
  /**
26
   * Unsubscribe after leaving
27
   */
28
  ngOnDestroy(): void {
29
    this.subscription.forEach(subs => subs.unsubscribe());
30
  }
31

  
25 32
  ngOnInit(): void {
26 33
    this.loginForm = this.formBuilder.group({
27 34
      username: ['', [Validators.required]],
......
30 37
    this.userRedirect();
31 38
  }
32 39

  
40
  /**
41
   * Process login
42
   */
33 43
  doLogin(): void {
34 44
    if (this.loginForm.valid) {
35 45
      this.subscription[2] = this.authService.doLogin({
......
38 48
      })
39 49
        .pipe(
40 50
          switchMap(res => {
41
            console.log(res);
42 51
            if (res) {
43 52
              console.log('Login getUserState');
44 53
              return this.authService.getUserState();
......
48 57
          })
49 58
        ).subscribe(
50 59
          res => {
51
            console.log(res);
52 60
            if (res) {
53 61
              this.subscription[2].unsubscribe();
54 62
              this.router.navigate(['/dashboard'])
......
58 66
    }
59 67
  }
60 68

  
69
  /**
70
   * If user already logged with valid sessionId redirect to dashboard
71
   */
61 72
  userRedirect(): void {
62 73
    console.log('Login redirect');
63 74
    if (this.authService.getUser()){
64
      console.log('Redirect to dashboard!');
65 75
      this.router.navigate(['/dashboard']);
66 76
    }
67 77
  }
src/app/sensor/components/sensor.component.html
3 3
<div class="container graph">
4 4
  <div class="row-2">
5 5
    <div class="col-xs-3">
6
      <h5><span class="text-color-sensor-unit">Unit name: <a [routerLink]="['/dashboard/unit', unitId]">{{unitName}}</a></span></h5>
6
      <h5><span class="text-color-sensor-unit">Unit name: <a [routerLink]="['/dashboard/unit', unitId]">{{unitDescription}}</a></span></h5>
7
    </div>
8
    <div class="col-xs-3">
9
      <h5><span class="text-color-sensor-unit">Sensor id: {{sensor?.sensorId}}</span></h5>
7 10
    </div>
8 11
    <div class="col-xs-3">
9 12
      <h5><span class="text-color-sensor-unit">Sensor name: {{sensor?.sensorName}}</span></h5>
......
34 37
      </div>
35 38
    </div>
36 39
    <div class="col-1"></div>
37
    <div *ngIf="showAggregation" class="col-xs-3">
40
    <div class="col-xs-3">
38 41
      <div class="input-group form-group">
39
        <!--<div class="input-group-prepend">
40
          <span class="input-group-text">Aggregation</span>
41
        </div>-->
42
        <p-listbox [options]="aggregationFunction" [(ngModel)]="selectedAggregationFunction" optionLabel="name" optionValue="code"></p-listbox>
42
        <p-listbox *ngIf="showAggregation" [options]="aggregationFunction" [(ngModel)]="selectedAggregationFunction" optionLabel="name" optionValue="code"></p-listbox>
43 43
      </div>
44 44
    </div>
45 45
    <div class="col-1"></div>
src/app/sensor/components/sensor.component.ts
1
import {Component, OnInit} from '@angular/core';
1
import {Component, OnDestroy, OnInit} from '@angular/core';
2 2
import {ActivatedRoute} from '@angular/router';
3 3
import * as moment from 'moment-timezone';
4 4
import {AnalyticsService} from '../../shared/api/endpoints/services/analytics.service';
......
10 10
import {ToastService} from '../../shared/services/toast.service';
11 11
import {Sensor} from '../../shared/api/endpoints/models/sensor';
12 12
import {SensorsService} from '../../shared/api/endpoints/services/sensors.service';
13
import {Subscription} from 'rxjs';
13 14

  
14 15
@Component({
15 16
  selector: 'app-sensor',
16 17
  templateUrl: './sensor.component.html',
17 18
  styleUrls: ['./sensor.component.scss']
18 19
})
19

  
20

  
21

  
22
export class SensorComponent implements OnInit {
20
export class SensorComponent implements OnInit, OnDestroy {
23 21

  
24 22
  sensorId: number;
25 23
  unitId: number;
......
32 30
  selectedAggregationFunction = 'HOUR';
33 31
  sensor: Sensor;
34 32
  dateChanged = false;
35
  unitName: string;
33
  unitDescription: string;
36 34
  today: Date = moment().toDate();
35
  subscription: Subscription[] = [];
37 36

  
38 37
  constructor(
39 38
    private activatedRoute: ActivatedRoute,
......
58 57
  getInitData() {
59 58
    this.route.queryParams.subscribe(params => {
60 59
      if(params.unitName)  {
61
        this.unitName = params.unitName;
60
        this.unitDescription = params.unitName;
62 61
      }
63 62
    });
64 63
    this.sensorId = parseInt(this.activatedRoute.snapshot.paramMap.get('sensorId'), 10);
......
71 70
    ];
72 71
  }
73 72

  
73
  /**
74
   * Unsubscribe after leaving
75
   */
76
  ngOnDestroy(): void {
77
    this.subscription.forEach(subs => subs.unsubscribe());
78
  }
79

  
74 80
  ngOnInit(): void {
75 81
  }
76 82

  
src/app/shared/models/vegaModel.ts
1
/* tslint:disable */
2
/* eslint-disable */
3
export interface VegaModel {
4
  sensordId?: string,
5
  data?: []
6
}
src/app/shared/nav-bar/components/nav-bar.component.ts
35 35
    this.setUser();
36 36
  }
37 37

  
38
  /**
39
   * Get user from state after logged
40
   */
38 41
  setUser(){
39 42
    this.authService.getUserState().subscribe(res => {
40 43
      if(res){
......
43 46
    });
44 47
  }
45 48

  
49
  /**
50
   * Show insert unit popup
51
   */
46 52
  insertUnitPopup() {
47 53
    this.sensorService.getPhenomenons().subscribe(
48 54
      response => this.phenomenons = response
......
54 60
    this.authService.doLogout();
55 61
  }
56 62

  
63
  /**
64
   * Unsubscribe after leaving
65
   */
57 66
  ngOnDestroy(): void {
58 67
    this.subscription.forEach(subs => subs.unsubscribe());
59 68
  }
60 69

  
70
  /**
71
   * Show add user popup
72
   */
61 73
  addUser() {
62 74
    this.showAddUserPopup = true;
63 75
  }
64 76

  
77
  /**
78
   * Emit inserted unit to add it to units
79
   * @param inserted inserted unit
80
   */
65 81
  addUnit(inserted: any) {
66 82
    this.emitNewUnit.emit(inserted);
67 83
  }
src/app/shared/nav-bar/components/unit-insert-popup/unit-insert-popup.component.ts
55 55
    });
56 56
  }
57 57

  
58
  /**
59
   * Create formBuilder for sensor
60
   */
58 61
  createSensor(): FormGroup {
59 62
    return this.formBuilder.group({
60 63
      sensorId: ['', Validators.required],
......
64 67
    });
65 68
  }
66 69

  
70
  /**
71
   * Add sensor to form
72
   */
67 73
  addSensor(): void {
68 74
    this.items = this.insertForm.get('sensors') as FormArray;
69 75
    this.items.push(this.createSensor());
70 76
    this.sensors++;
71 77
  }
72 78

  
79
  /**
80
   * Remove last sensor from form
81
   */
73 82
  removeSensor() {
74 83
    this.items = this.insertForm.get('sensors') as FormArray;
75 84
    this.items.removeAt(this.items.length - 1);
76 85
    this.sensors--;
77 86
  }
78 87

  
88
  /**
89
   * Clear form
90
   */
79 91
  clearFormArray() {
80 92
    const frmArray = this.insertForm?.get('sensors') as FormArray;
81 93
    if (frmArray) {
......
84 96
    this.insertForm.reset();
85 97
  }
86 98

  
99
  /**
100
   * Insert unit with sensor and position if form valid
101
   */
87 102
  processInsertion() {
88 103
    if (this.insertForm.valid) {
89 104
      const lat = this.insertForm.controls.lat.value;
......
95 110
      const sensors: InsertSensor[] = [];
96 111
      const frmArray = this.insertForm?.get('sensors') as FormArray;
97 112

  
113
      // get sensors from form
98 114
      frmArray.controls.forEach(control => {
99 115
        const sensor: InsertSensor = {
100 116
          sensor_id: control.get('sensorId').value,
......
107 123
        sensors.push(sensor);
108 124
      });
109 125

  
126
      // insert unit
110 127
      this.managementService.insertUnit$Response({ body: { unit, sensors}}).pipe(
111 128
        map((response: HttpResponse<any>) => {
112 129
          if (response.status === 200) {
130
            // insert position
113 131
            this.sensorService.insertPosition$Response( {lat, lon, unit_id: this.insertForm.controls.unitId.value, date: moment().format('yyyy-MM-DD HH:mm:ssZZ')}).pipe(
114 132
              map((response2: HttpResponse<any>) => {
115 133
                if (response2.status === 200) {
......
119 137
                  this.close();
120 138
                } else {
121 139
                  this.toastService.showError('Unit insertion ' + response2.body.unitId + ' caused error! Wrong position!');
140
                  // if position not added delete unit
122 141
                  this.managementService.deleteUnit({body: {unit}}).toPromise().then().catch(
123 142
                    err => this.toastService.showError(err.error.message));
124 143
                }
125 144
              })
126 145
            ).toPromise().then().catch(err => this.toastService.showError(err.error.message));
127 146
          } else {
147
            this.toastService.showError('Unit insertion ' + response.body.unitId + ' caused error!');
128 148
          }
129 149
        })
130 150
      ).toPromise().then().catch(err => this.toastService.showError(err.error.message));
src/app/shared/nav-bar/components/user-insert-popup/user-insert-popup.component.ts
1
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
1
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
2 2
import {map, tap} from 'rxjs/operators';
3 3
import {GroupService} from '../../../api/endpoints/services/group.service';
4 4
import {Group} from '../../../api/endpoints/models/group';
......
7 7
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
8 8
import {HttpResponse} from '@angular/common/http';
9 9
import {ToastService} from '../../../services/toast.service';
10
import {Subscription} from 'rxjs';
10 11

  
11 12
@Component({
12 13
  selector: 'app-user-insert-popup',
13 14
  templateUrl: './user-insert-popup.component.html',
14 15
  styleUrls: ['./user-insert-popup.component.scss']
15 16
})
16
export class UserInsertPopupComponent implements OnInit {
17
export class UserInsertPopupComponent implements OnInit, OnDestroy {
17 18

  
18 19
  groups: Group[];
19 20
  rights: Right[];
20 21
  insertForm: FormGroup;
22
  subscription: Subscription[] = [];
21 23
  @Input() isVisible;
22 24
  @Output() isVisibleChange: EventEmitter<boolean> = new EventEmitter<boolean>();
23 25

  
......
34 36
  ngOnInit(): void {
35 37
  }
36 38

  
39
  /**
40
   * Unsubscribe after leaving
41
   */
42
  ngOnDestroy(): void {
43
    this.subscription.forEach(subs => subs.unsubscribe());
44
  }
45

  
37 46
  getGroups() {
38 47
    this.groupService.getGroups({Operation: 'GetGroups'}).pipe(
39 48
      tap(data => this.groups = data)
......
46 55
    ).subscribe();
47 56
  }
48 57

  
58
  /**
59
   * Close popup
60
   */
49 61
  close() {
50 62
    this.isVisibleChange.emit(false);
51 63
  }
52 64

  
65
  /**
66
   * If valid form send request with new user to server
67
   */
53 68
  saveUser() {
54 69
    if (this.insertForm.valid) {
55 70
      this.administrationService.createUser$Response({body: {
src/app/shared/services/toast.service.ts
11 11
  ) {
12 12
  }
13 13

  
14
  /**
15
   * Error message
16
   * @param err error
17
   */
14 18
  showError(err: any) {
15 19
    this.messageService.add({key: 'mainToast', severity:'error', summary: 'Unsuccessful!', detail: err});
16 20
  }
17 21

  
22
  /**
23
   * Show warning NoData message
24
   */
18 25
  showWarningNoData() {
19 26
    this.messageService.add({key: 'mainToast', severity:'warn', summary: 'No data!', detail: 'Can not display any data for given interval and aggregation!'});
20 27
  }
21 28

  
29
  /**
30
   * Show success request message
31
   */
22 32
  showSuccess() {
23 33
    this.messageService.add({key: 'mainToast', severity:'success', summary: 'Success!', detail: 'Successful request!'});
24 34
  }
25 35

  
36
  /**
37
   * Show message as success
38
   * @param message message string
39
   */
26 40
  showSuccessMessage(message: any) {
27 41
    this.messageService.add({key: 'mainToast', severity:'success', summary: 'Success!', detail: message});
28 42
  }
29 43

  
44
  /**
45
   * Show operation rejected
46
   */
30 47
  operationRejected() {
31 48
    this.messageService.add({key: 'mainToast', severity:'warn', summary: 'Reject!', detail: 'Operation rejected!'});
32 49
  }
src/app/unit/components/unit.component.html
2 2

  
3 3
<div class="container">
4 4
  <div class="row-2">
5
      <h5><span class="text-color-sensor-unit">Unit ID: {{unitId}}</span></h5>
5
    <h5><span class="text-color-sensor-unit">Unit description: {{unitDescription}}</span></h5>
6 6
  </div>
7 7
  <div class="row">
8 8
    <div class="col">
9 9
      <div class="input-group form-group">
10 10
        <div class="input-group-prepend">
11
          <span class="input-group-text">From</span>
11
          <span class="input-group-text text-color-date background-date-color"><i class="fa fa-calendar-alt" aria-hidden="false"></i>From</span>
12 12
        </div>
13
        <p-calendar [style]="{'width':'100%'}" [inputStyle]="{'width':'100%'}" [(ngModel)]="from" [showTime]="true" (onSelect)="showGraph()" [maxDate]="today" showButtonBar="true"></p-calendar>
13
        <p-calendar [style]="{'width':'100%'}" [inputStyle]="{'width':'100%'}" [(ngModel)]="from" [showTime]="true" (onSelect)="aggregationShow()" [maxDate]="today" showButtonBar="true"></p-calendar>
14 14
      </div>
15 15
    </div>
16 16
    <div class="col">
17 17
      <div class="input-group form-group">
18 18
        <div class="input-group-prepend">
19
          <span class="input-group-text">To</span>
19
          <span class="input-group-text text-color-date background-date-color"><i class="fa fa-calendar-alt" aria-hidden="false"></i>To</span>
20 20
        </div>
21
        <p-calendar [style]="{'width':'100%'}" [inputStyle]="{'width':'100%'}" [(ngModel)]="to" [showTime]="true" (onSelect)="showGraph()" [maxDate]="today" showButtonBar="true"></p-calendar>
21
        <p-calendar [style]="{'width':'100%'}" [inputStyle]="{'width':'100%'}" [(ngModel)]="to" [showTime]="true" (onSelect)="aggregationShow()" [maxDate]="today" showButtonBar="true"></p-calendar>
22 22
      </div>
23 23
    </div>
24
    <div *ngIf="showAggregation" class="col">
24
    <div class="col">
25 25
      <div class="input-group form-group">
26
        <div class="input-group-prepend">
27
          <span class="input-group-text">Aggregation</span>
26
        <div class="input-group form-group">
27
          <p-listbox *ngIf="showAggregation" [options]="aggregationFunction" [(ngModel)]="selectedAggregationFunction" optionLabel="name" optionValue="code"></p-listbox>
28 28
        </div>
29
        <p-listbox [options]="aggregationFunction" [(ngModel)]="selectedAggregationFunction" optionLabel="name" optionValue="code" (onClick)="showGraph()" ></p-listbox>
30 29
      </div>
31 30
    </div>
31
    <div class="col-xs-3">
32
      <p-button *ngIf="dateChanged" label="Get data" icon="pi pi-cog" styleClass="p-button-success" (click)="showGraph()"></p-button>
33
    </div>
32 34
  </div>
33 35

  
34 36
  <ng-container *ngFor="let group of sensorGroups">
35 37
    <div class="row">
36
    Group of sensors:
38
    Group of
39
    <ng-container *ngFor="let sensorType of sensorTypes">
40
      <ng-container *ngIf="sensorType.sensorId.toString().slice(0, 5) === group">
41
        {{sensorType.sensorType}}
42
      </ng-container>
43
    </ng-container>
44
      sensors:
37 45
      <ng-container *ngFor="let sensor of sensors">
38 46
          <div *ngIf="sensor.sensorId.toString().slice(0, 5) === group" class="p-field-checkbox">
39 47
            <p-checkbox name="{{group}}" [value]="sensor.sensorId.toString()" [(ngModel)]="selectedSensors" [inputId]="sensor.sensorId.toString()" (onChange)="addSensorToGraph(sensor.sensorId.toString(), $event)"></p-checkbox>
src/app/unit/components/unit.component.ts
1
import {Component, OnInit} from '@angular/core';
1
import {Component, OnDestroy, OnInit} from '@angular/core';
2 2
import {ActivatedRoute} from '@angular/router';
3 3
import {AnalyticsService} from '../../shared/api/endpoints/services/analytics.service';
4 4
import {map, tap} from 'rxjs/operators';
......
10 10
import {ToastService} from '../../shared/services/toast.service';
11 11
import {Sensor} from '../../shared/api/endpoints/models/sensor';
12 12
import {ObservationService} from '../../shared/api/endpoints/services/observation.service';
13
import {SensorType} from '../../shared/api/endpoints/models/sensor-type';
14
import {Subscription} from 'rxjs';
13 15

  
14 16

  
15 17
@Component({
......
17 19
  templateUrl: './unit.component.html',
18 20
  styleUrls: ['./unit.component.scss']
19 21
})
20
export class UnitComponent implements OnInit {
22
export class UnitComponent implements OnInit, OnDestroy {
21 23

  
22 24
  preselectedSensors: string;
23 25
  unitId: number;
24 26
  viewCount = 0;
25 27
  data = [];
26 28
  time = [];
27
  from: Date;
28
  to: Date;
29
  today: Date;
29
  from: Date = moment().hour(0).minutes(0).subtract(7, 'days').toDate();
30
  to: Date = moment().toDate();
31
  today: Date = moment().toDate();
30 32
  analyticsData: any[] = [];
31 33
  observationsData: any[] = [];
32 34
  sensorGroups = [];
......
36 38
  aggregationFunction: AggregationModel[];
37 39
  selectedAggregationFunction = 'DAY';
38 40
  useAnalyticsData = false;
41
  dateChanged = false;
42
  sensorTypes: SensorType[];
43
  unitDescription: string;
44
  subscription: Subscription[] = [];
39 45

  
40 46
  constructor(
41 47
    private activatedRoute: ActivatedRoute,
42 48
    private analyticsService: AnalyticsService,
43 49
    private sensorService: SensorsService,
44 50
    private toastService: ToastService,
45
    private observationService: ObservationService
51
    private observationService: ObservationService,
52
    private route: ActivatedRoute,
46 53
  ) {
47
    this.unitId = parseInt(this.activatedRoute.snapshot.paramMap.get('unitId'), 10);
48
    this.aggregationFunction = [
49
      {name: 'Hour', code: 'HOUR'},
50
      {name: 'Day', code: 'DAY'},
51
      {name: 'Month', code: 'MONTH'},
52
      {name: 'Year', code: 'YEAR'}
53
    ];
54
    this.today = moment().toDate();
54
    this.getInitData();
55
    // get unit sensors and prepare them for view
55 56
    this.sensorService.getUnitSensors({unit_id: this.unitId}).pipe(
56 57
      tap(sens => {
57 58
        this.sensors = sens;
......
61 62
        if (this.sensors && this.sensors.length > 0) {
62 63
          this.sensors.forEach(sensor => {
63 64
            const sensorType = sensor.sensorId.toString().slice(0, 5);
64
            if (!this.sensorGroups.some(group => group === sensorType)) {
65
            if (!this.sensorGroups.some(group => group === sensorType)) { // create sensor groups only for unit sensors
65 66
              this.sensorGroups.push(sensorType);
66 67
              setTimeout(() => {
67
                // GraphLoader.getAnalyticsGraph(null, null, null, '#vega_container_' + sensor.sensorId.toString().slice(0, 5));
68
                GraphLoader.getGraph(null, null, null, '#vega_container_' + sensor.sensorId.toString().slice(0, 5),null );
68
                GraphLoader.getGraph(null, null, null, '#vega_container_' + sensor.sensorId.toString().slice(0, 5),null);
69 69
              }, 0);
70 70
            }
71 71
          });
......
74 74
    ).toPromise().then();
75 75
  }
76 76

  
77
  ngOnInit(): void {
77
  /**
78
   * Unsubscribe after leaving
79
   */
80
  ngOnDestroy(): void {
81
    this.subscription.forEach(subs => subs.unsubscribe());
78 82
  }
79 83

  
80
  showGraph(changedDate: boolean = true, changedSensor: string = null) {
81
    const range: Date[] = [moment().subtract(7, 'days').toDate(), moment().toDate()];
84
  /**
85
   * Sets up default data
86
   */
87
  getInitData() {
88
    this.route.queryParams.subscribe(params => {
89
      if(params.unitDescription)  {
90
        this.unitDescription = params.unitDescription;
91
      }
92
    });
93
    this.sensorService.getSensorTypes().toPromise().then(types => this.sensorTypes = types);
94
    this.unitId = parseInt(this.activatedRoute.snapshot.paramMap.get('unitId'), 10);
95
    this.aggregationFunction = [
96
      {name: 'Hour', code: 'HOUR'},
97
      {name: 'Day', code: 'DAY'},
98
      {name: 'Month', code: 'MONTH'},
99
      {name: 'Year', code: 'YEAR'}
100
    ];
101
  }
82 102

  
83
    if (this.from && !this.to || !this.from && this.to) {
84
      return;
85
    }
103
  ngOnInit(): void {
104
  }
86 105

  
87
    if (this.from && this.to) {
88
      range[0] = this.from;
89
      range[1] = this.to;
90
    }
106
  /**
107
   * Shows aggregation select box and get data button
108
   */
109
  aggregationShow() {
110
    this.dateChanged = true;
111
    this.showAggregation = moment(this.to).diff(moment(this.from), 'days') > 7;
112
  }
91 113

  
92
    if (moment(range[1]).diff(moment(range[0]), 'days') > 7) {
114
  /**
115
   * Gets data based on selected time range
116
   */
117
  showGraph(changedDate: boolean = true, changedSensor: string = null) {
118
    if (moment(this.to).diff(moment(this.from), 'days') > 7) {
93 119
      this.useAnalyticsData = true;
94 120
      this.showAggregation = true;
121
      const range: Date[] = [this.from, this.to];
95 122
      this.getAnalytics(range, changedDate, changedSensor);
96 123
    } else {
97 124
      this.useAnalyticsData = false;
98 125
      this.showAggregation = false;
126
      const range: Date[] = [this.from, this.to];
99 127
      this.getObservations(range, changedDate, changedSensor);
100 128
    }
101 129
  }
102 130

  
103
  getAnalytics(range: Date[], changedDate: boolean, changedSensor: string) {
104
    const groupId = changedSensor.toString().slice(0, 5);
105
    if (changedDate) {
131
  /**
132
   * Gets data from analytics endpoint
133
   * @param range from and to interval
134
   * @param changedDate determines if dates changed so we need refresh all data
135
   * @param changedSensorId if selecting sensor only fetch data for this server
136
   */
137
  getAnalytics(range: Date[], changedDate: boolean, changedSensorId: string) {
138
    if (changedDate) { // if changed date we need new data for all sensors
106 139
      this.selectedSensors.forEach(selectSens => {
107
        this.analyticsService.getAnalytics$Response({unit_id: this.unitId, sensor_id: parseInt(selectSens, 10),
108
          from: moment(range[0]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3),
109
          to: moment(range[1]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3), interval: this.selectedAggregationFunction}).pipe(
110
          map((response: HttpResponse<any>) => {
111
            if (response.status === 200) {
112
              return response.body;
113
            } else if (response.status === 204) {
114
              // GraphLoader.getAnalyticsGraph(null, null, null, '#vega_container_' + selectSens.toString().slice(0, 5));
115
              GraphLoader.getGraph(null, null, null, '#vega_container_' + selectSens.toString().slice(0, 5),null );
116
              this.toastService.showWarningNoData();
117
              return response.body;
118
            } else {
119
              return false;
120
            }
121
          })
122
        ).subscribe(data => {
123
          if (data) {
124
            this.analyticsData.push({sensorId: selectSens, data: data[selectSens].data, interval: data[selectSens].interval});
125
            const objectKeys = Object.keys(data);
126
            for(const key of objectKeys ) {
127
              if (data[key].data) {
128
                const view = '#vega_container_' + key.slice(0, 5);
129
                if (this.selectedSensors.some(sens => sens.toString() === key)) {
130
                  // GraphLoader.getAnalyticsGraph(key, data[key].data, data[key].interval, view);
131
                  // GraphLoader.getGraph(this.selectedSensors, this.filteredAnalyticsData(groupId), view, true);
132
                } else {
133
                  GraphLoader.getGraph(null, null, null, view, null);
134
                }
135
              }
136
            }
137
          }
138
        }, err => this.toastService.showError(err.error.message));
140
        this.analyticsEndpointRequest(selectSens, range);
139 141
      });
140
    } else  {
141
      this.analyticsService.getAnalytics$Response({unit_id: this.unitId, sensor_id: parseInt(changedSensor, 10),
142
        from: moment(range[0]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3),
143
        to: moment(range[1]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3), interval: this.selectedAggregationFunction}).pipe(
144
        map((response: HttpResponse<any>) => {
145
          if (response.status === 200) {
146
            return response.body;
147
          } else if (response.status === 204) {
148
            this.toastService.showWarningNoData();
149
            return response.body;
142
    } else  { // add data for selected sensor
143
      this.analyticsEndpointRequest(changedSensorId, range);
144
    }
145
  }
146

  
147
  /**
148
   * Endpoint request to get analytics data for sensor
149
   * @param sensorId sensor id to get data
150
   * @param range from and to interval
151
   */
152
  analyticsEndpointRequest(sensorId: string, range: Date[]) {
153
    this.analyticsService.getAnalytics$Response({unit_id: this.unitId, sensor_id: parseInt(sensorId, 10),
154
      from: moment(range[0]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3),
155
      to: moment(range[1]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3), interval: this.selectedAggregationFunction}).pipe(
156
      map((response: HttpResponse<any>) => {
157
        if (response.status === 200) {
158
          return response.body;
159
        } else if (response.status === 204) {
160
          this.toastService.showWarningNoData();
161
          return response.body;
162
        } else {
163
          return false;
164
        }
165
      })
166
    ).subscribe(data => {
167
      if (data) {
168
        this.analyticsData.push({sensorId, data: data[sensorId].data, interval: data[sensorId].interval});
169
        if (data[sensorId].data) {
170
          const groupId = sensorId.slice(0, 5);
171
          const view = '#vega_container_' + groupId;
172
          if (this.selectedSensors.some(sens => sens.toString() === sensorId)) {
173
            // GraphLoader.getAnalyticsGraph(key, data[key].data, data[key].interval, view);
174
            GraphLoader.getGraph(this.selectedSensors, this.analyticsData, this.filteredSensorsInfos(groupId), view, true);
150 175
          } else {
151
            return false;
152
          }
153
        })
154
      ).subscribe(data => {
155
        if (data) {
156
          this.analyticsData.push({sensorId: changedSensor, data: data[changedSensor].data, interval: data[changedSensor].interval});
157
          const objectKeys = Object.keys(data);
158
          for(const key of objectKeys ) {
159
            if (data[key].data) {
160
              const view = '#vega_container_' + key.slice(0, 5);
161
              if (this.selectedSensors.some(sens => sens.toString() === key)) {
162
               // GraphLoader.getAnalyticsGraph(key, data[key].data, data[key].interval, view);
163
                GraphLoader.getGraph(this.selectedSensors, this.analyticsData, this.filteredSensorsInfos(groupId), view, true);
164
              } else {
165
                // GraphLoader.getAnalyticsGraph(null, null, null, view);
166
                GraphLoader.getGraph(null, null, null, view, null);
167
              }
168
            }
176
            // GraphLoader.getAnalyticsGraph(null, null, null, view);
177
            GraphLoader.getGraph(null, null, null, view, null);
169 178
          }
170 179
        }
171
      }, err => this.toastService.showError(err.error.message));
172
    }
180
      }
181
    }, err => this.toastService.showError(err.error.message));
173 182
  }
174 183

  
175 184
  /**
......
205 214
          if (this.observationsData.some(sens => sens.sensorId.toString() === sensorId)) { // if already data for selected sensor in memory
206 215
            GraphLoader.getGraph(this.filteredSelectedSensors(groupId), this.filteredObservationData(groupId),
207 216
              this.filteredSensorsInfos(groupId), sensorGroupElement, false);
208
            // GraphLoader.getMultilineGraph(this.selectedSensors, this.filteredObservationData(groupId), sensorGroupElement)
209 217
          } else { // get data from server for added sensor and show graph for selected sensors
210 218
            this.showGraph(false, sensorId);
211 219
          }
212 220
        } else { // remove sensor from graph
213
          // GraphLoader.getMultilineGraph(this.selectedSensors, this.filteredObservationData(groupId), sensorGroupElement)
214
          GraphLoader.getGraph(this.filteredSelectedSensors(groupId), this.filteredObservationData(groupId),
221
            GraphLoader.getGraph(this.filteredSelectedSensors(groupId), this.filteredObservationData(groupId),
215 222
            this.filteredSensorsInfos(groupId), sensorGroupElement, false);
216

  
217 223
        }
218 224
      }
219 225
    }
......
236 242
      sen.sensorId.toString().slice(0, 5) === sensorGroupId);
237 243
  }
238 244

  
239

  
245
  /**
246
   * Filter only selected sensors for group of sensors
247
   * @param sensorGroupId group of sensors
248
   */
240 249
  filteredSelectedSensors(sensorGroupId: string): any {
241
    return this.selectedSensors.filter(sen => sen.toString().slice(0, 5) === sensorGroupId );
250
    return this.selectedSensors.filter(sen => sen.toString().slice(0, 5) === sensorGroupId);
242 251
  }
243 252

  
253
  /**
254
   * Get sensors only for group
255
   * @param sensorGroupId group id
256
   */
244 257
  filteredSensorsInfos(sensorGroupId: string): any {
245 258
    return this.sensors.filter(sen => this.selectedSensors.includes(sen.sensorId.toString()) &&
246 259
      sen.sensorId.toString().slice(0, 5) === sensorGroupId);
247 260
  }
248 261

  
249
  private getObservations(range: Date[], changedDate: boolean, changedSensorId: string) {
250
    const groupId = changedSensorId.toString().slice(0, 5);
262
  /**
263
   * Gets data from observation endpoint
264
   * @param range from and to interval
265
   * @param changedDate determines if dates changed so we need refresh all data
266
   * @param changedSensorId if selecting sensor only fetch data for this server
267
   */
268
  getObservations(range: Date[], changedDate: boolean, changedSensorId: string) {
251 269
    if (changedDate) { // if changed date we need new data for all sensors
252 270
      this.observationsData = []; // empty observation data
253 271
      this.selectedSensors.forEach(selectSens => {
254
        this.observationService.getObservation$Response({
255
          unit_id: this.unitId,
256
          sensor_id: parseInt(selectSens, 10),
257
          from: moment(range[0]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3),
258
          to: moment(range[1]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3)
259
        }).pipe(
260
          map((response: HttpResponse<any>) => {
261
            if (response.status === 200) {
262
              return response.body;
263
            } else if (response.status === 204) {
264
              this.toastService.showWarningNoData();
265
              return response.body;
266
            } else {
267
              return false;
268
            }
269
          }),
270
          tap((observations) => {
271
            if (observations) {
272
              this.observationsData.push({sensorId: selectSens, sensor:
273
                this.sensors.find(sens => sens.sensorId.toString() === selectSens.toString()), data: observations});
274
            }
275
          }),
276
          tap(() => {
277
            if (this.observationsData && this.observationsData.length > 1) {
278
              const view = '#vega_container_' + selectSens.toString().slice(0, 5);
279
              setTimeout(() => {
280
                console.log(this.selectedSensors);
... Rozdílový soubor je zkrácen, protože jeho délka přesahuje max. limit.

Také k dispozici: Unified diff