Project

General

Profile

1
import {
2
  AfterViewInit,
3
  ChangeDetectorRef,
4
  Component,
5
  Input,
6
  OnChanges,
7
  OnDestroy,
8
  OnInit,
9
  SimpleChanges,
10
  ViewChild
11
} from "@angular/core";
12
import {
13
  Indicator,
14
  IndicatorPath, IndicatorSize,
15
  IndicatorType,
16
  Section,
17
  Stakeholder,
18
  Visibility
19
} from "../openaireLibrary/monitor/entities/stakeholder";
20
import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils";
21
import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
22
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
23
import {StatisticsService} from "../utils/services/statistics.service";
24
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
25
import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser";
26
import {Reorder, StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
27
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
28
import {Subscriber} from "rxjs";
29
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
30
import {Router} from "@angular/router";
31
import {Session} from "../openaireLibrary/login/utils/helper.class";
32
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
33
import {StringUtils} from "../openaireLibrary/utils/string-utils.class";
34

    
35
declare var UIkit;
36

    
37
@Component({
38
  selector: 'indicators',
39
  templateUrl: './indicators.component.html',
40
  styleUrls: ['indicators.component.css']
41
})
42
export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
43
  
44
  @Input()
45
  public properties: EnvProperties = null;
46
  @Input()
47
  public topicIndex: number = 0;
48
  @Input()
49
  public categoryIndex: number = 0;
50
  @Input()
51
  public subcategoryIndex: number = 0;
52
  public stakeholder: Stakeholder = null;
53
  public user = null;
54
  public preview: string;
55
  public indicatorUtils: IndicatorUtils = new IndicatorUtils();
56
  public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
57
  public numberIndicatorFb: FormGroup;
58
  public chartIndicatorFb: FormGroup;
59
  public chartSections: FormArray;
60
  public numberSections: FormArray;
61
  /**
62
   * Editable indicator
63
   */
64
  public section: Section;
65
  public indicator: Indicator;
66
  public index: number = -1;
67
  /**
68
   * Displayed chart and numbers base on Top filters
69
   */
70
  public displayCharts: Section[] = [];
71
  public displayNumbers: Section[] = [];
72
  /**
73
   * Top filters
74
   */
75
  @Input()
76
  public filters: FormGroup;
77
  public editing: boolean = false;
78
  /** Safe Urls*/
79
  public safeUrls: Map<string, SafeResourceUrl> = new Map<string, SafeResourceUrl>([]);
80
  public numberResults: Map<string, number> = new Map<string, number>();
81
  private subscriptions: any[] = [];
82
  private urlSubscriptions: any[] = [];
83
  @ViewChild('editChartModal') editChartModal: AlertModal;
84
  @ViewChild('editNumberModal') editNumberModal: AlertModal;
85
  @ViewChild('deleteModal') deleteModal: AlertModal;
86
  //@ViewChild('deleteAllModal') deleteAllModal: AlertModal;
87
  //@ViewChild('deleteAndDisconnectModal') deleteAndDisconnectModal: AlertModal;
88
  //@ViewChild('deleteChartSectionModal') deleteChartSectionModal: AlertModal;
89
  //@ViewChild('deleteNumberSectionModal') deleteNumberSectionModal: AlertModal;
90
  @ViewChild('deleteSectionModal') deleteSectionModal: AlertModal;
91
  public sectionTypeToDelete: string;
92
  public sectionChildrenActionOnDelete: string;
93
  public indicatorChildrenActionOnDelete: string;
94
  private firstLoad: boolean = true;
95
  
96
  urlParameterizedMessage = null;
97
  showCheckForSchemaEnhancements:boolean = false;
98
  constructor(private layoutService: LayoutService,
99
              private stakeholderService: StakeholderService,
100
              private statisticsService: StatisticsService,
101
              private userManagementService: UserManagementService,
102
              private fb: FormBuilder,
103
              private router: Router,
104
              private cdr: ChangeDetectorRef,
105
              private sanitizer: DomSanitizer) {
106
  }
107
  
108
  ngOnInit(): void {
109
    this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
110
      this.user = user;
111
    }));
112
    this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
113
      this.stakeholder = stakeholder;
114
      if (this.stakeholder && this.firstLoad) {
115
        this.buildFilters();
116
        this.buildSections();
117
        this.filterCharts();
118
        this.filterNumbers();
119
        this.setPreview();
120
        this.firstLoad = false;
121
      }
122
    }));
123
  }
124
  
125
  ngOnDestroy(): void {
126
    this.subscriptions.forEach(value => {
127
      if (value instanceof Subscriber) {
128
        value.unsubscribe();
129
      } else if (value instanceof Function) {
130
        value();
131
      }
132
    });
133
    this.urlSubscriptions.forEach(value => {
134
      if (value instanceof Subscriber) {
135
        value.unsubscribe();
136
      }
137
    });
138
  }
139
  
140
  ngAfterViewInit(): void {
141
    this.initReorder();
142
  }
143
  
144
  ngOnChanges(changes: SimpleChanges): void {
145
    if (this.canEdit) {
146
      if (changes.topicIndex || changes.categoryIndex || changes.subcategoryIndex) {
147
        this.buildSections();
148
        this.buildFilters();
149
        this.initReorder();
150
      }
151
      this.filterCharts();
152
      this.filterNumbers();
153
    }
154
    this.setPreview();
155
  }
156
  
157
  setNumberIndicators() {
158
    this.numberResults.clear();
159
    let urls: Map<string, [number, number][]> = new Map<string, [number, number][]>();
160
    this.numbers.forEach((section, i) => {
161
      section.indicators.forEach((number, j) => {
162
        let url = this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, number.indicatorPaths[0]);
163
        const pair = JSON.stringify([number.indicatorPaths[0].source, url]);
164
        const indexes = urls.get(pair) ? urls.get(pair) : [];
165
        indexes.push([i, j]);
166
        urls.set(pair, indexes);
167
      });
168
    });
169
    urls.forEach((indexes, pair) => {
170
      pair = JSON.parse(pair);
171
      this.subscriptions.push(this.statisticsService.getNumbers(this.statisticsService.getSourceType(pair[0]), pair[1]).subscribe(response => {
172
        indexes.forEach(([i, j]) => {
173
          let result = JSON.parse(JSON.stringify(response));
174
          this.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => {
175
            if (result) {
176
              result = result[jsonPath];
177
            }
178
          });
179
          if (typeof result === 'string' || typeof result === 'number') {
180
            result = Number(result);
181
            if (result === Number.NaN) {
182
              result = 0;
183
            }
184
          } else {
185
            result = 0;
186
          }
187
          this.numberResults.set(i + '-' + j, result);
188
        });
189
      }));
190
    });
191
  }
192
  
193
  setPreview() {
194
    if (this.stakeholder) {
195
      this.preview = '/' + this.stakeholder.alias;
196
      if (this.stakeholder.topics[this.topicIndex]) {
197
        this.preview = '/' + this.stakeholder.alias + '/' + this.stakeholder.topics[this.topicIndex].alias;
198
        if (this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]) {
199
          this.preview += '/' + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].alias;
200
          if (this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) {
201
            this.preview += '/' + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].alias;
202
          }
203
        }
204
      }
205
    }
206
  }
207
  
208
  initReorder() {
209
    this.subscriptions.forEach(value => {
210
      if (value instanceof Function) {
211
        value();
212
      }
213
    });
214
    if (document !== undefined) {
215
      let callback = (list, type: IndicatorType, action: 'moved' | 'added' | 'removed'): void => {
216
        let items: HTMLCollection = list.current.children;
217
        let reordered = [];
218
        for (let i = 0; i < items.length; i++) {
219
          if (items.item(i).id) {
220
            reordered.push(items.item(i).id);
221
          }
222
        }
223
        let reorder: Reorder = {
224
          action: action,
225
          target: list.detail[1].id,
226
          ids: reordered
227
        }
228
        this.reorderIndicators(list.current.id.toString().split('-')[1], type, reorder);
229
      };
230
      this.numbers.forEach((section) => {
231
        this.subscriptions.push(UIkit.util.on(document, 'moved', '#number-' + section._id, (list): void => {
232
          callback(list, "number", 'moved');
233
        }));
234
        this.subscriptions.push(UIkit.util.on(document, 'added', '#number-' + section._id, (list): void => {
235
          callback(list, "number", 'added');
236
        }));
237
        this.subscriptions.push(UIkit.util.on(document, 'removed', '#number-' + section._id, (list): void => {
238
          callback(list, "number", 'removed');
239
        }));
240
      });
241
      this.charts.forEach((section) => {
242
        this.subscriptions.push(UIkit.util.on(document, 'moved', '#chart-' + section._id, (list): void => {
243
          callback(list, "chart", 'moved');
244
        }));
245
        this.subscriptions.push(UIkit.util.on(document, 'added', '#chart-' + section._id, (list): void => {
246
          callback(list, "chart", 'added');
247
        }));
248
        this.subscriptions.push(UIkit.util.on(document, 'removed', '#chart-' + section._id, (list): void => {
249
          callback(list, "chart", 'removed');
250
        }));
251
      });
252
    }
253
  }
254
  
255
  hide(element: any) {
256
    UIkit.dropdown(element).hide();
257
  }
258
  
259
  private buildFilters() {
260
    this.subscriptions.push(this.filters.get('chartType').valueChanges.subscribe(value => {
261
      this.onChartTypeChange(value);
262
    }));
263
    
264
    this.subscriptions.push(this.filters.get('status').valueChanges.subscribe(value => {
265
      this.onStatusChange(value);
266
    }));
267
    this.subscriptions.push(this.filters.get('keyword').valueChanges.subscribe(value => {
268
      this.onKeywordChange(value);
269
    }));
270
  }
271
  
272
  private buildSections() {
273
    this.numberSections = this.fb.array([]);
274
    this.numbers.forEach(section => {
275
      this.numberSections.push(this.fb.group({
276
        _id: this.fb.control(section._id),
277
        title: this.fb.control(section.title),
278
        creationDate: this.fb.control(section.creationDate),
279
        stakeholderAlias: this.fb.control(section.stakeholderAlias),
280
        defaultId: this.fb.control(section.defaultId),
281
        type: this.fb.control(section.type),
282
        indicators: this.fb.control(section.indicators)
283
      }));
284
    });
285
    this.chartSections = this.fb.array([]);
286
    this.charts.forEach(section => {
287
      this.chartSections.push(this.fb.group({
288
        _id: this.fb.control(section._id),
289
        title: this.fb.control(section.title),
290
        creationDate: this.fb.control(section.creationDate),
291
        stakeholderAlias: this.fb.control(section.stakeholderAlias),
292
        defaultId: this.fb.control(section.defaultId),
293
        type: this.fb.control(section.type),
294
        indicators: this.fb.control(section.indicators)
295
      }));
296
    });
297
  }
298
  
299
  filterCharts() {
300
    this.displayCharts = this.filterChartType(
301
      this.filterStatus(this.filterByKeyword(HelperFunctions.copy(this.charts), this.filters.value.keyword),
302
        this.filters.value.status),
303
      this.filters.value.chartType
304
    );
305
    this.displayCharts.forEach(section => {
306
      section.indicators.forEach(indicator => {
307
        indicator.indicatorPaths.forEach(indicatorPath => {
308
          let url = this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath);
309
          if (!this.safeUrls.get('url')) {
310
            indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath);
311
            this.safeUrls.set(url, indicatorPath.safeResourceUrl);
312
          }
313
        });
314
      })
315
    });
316
    this.buildSections();
317
  }
318
  
319
  filterNumbers() {
320
    this.displayNumbers = this.filterStatus(
321
      this.filterByKeyword(HelperFunctions.copy(this.numbers), this.filters.value.keyword),
322
      this.filters.value.status);
323
    this.buildSections();
324
    this.setNumberIndicators();
325
  }
326
  
327
  onChartTypeChange(value) {
328
    this.displayCharts = this.filterChartType(HelperFunctions.copy(this.charts), value);
329
  }
330
  
331
  
332
  onStatusChange(value) {
333
    this.displayCharts = this.filterStatus(HelperFunctions.copy(this.charts), value);
334
    this.displayNumbers = this.filterStatus(HelperFunctions.copy(this.numbers), value);
335
  }
336
  
337
  onKeywordChange(value) {
338
    this.displayCharts = this.filterByKeyword(HelperFunctions.copy(this.charts), value);
339
    this.displayNumbers = this.filterByKeyword(HelperFunctions.copy(this.numbers), value);
340
  }
341
  
342
  private filterChartType(sections: Section[], value): Section[] {
343
    if (value !== 'all') {
344
      sections.forEach(section =>
345
        section.indicators = section.indicators.filter(indicator =>
346
          indicator.indicatorPaths.filter(indicatorPath => indicatorPath.type === value).length > 0));
347
    }
348
    return sections;
349
  }
350
  
351
  
352
  private filterStatus(sections: Section[], value): Section[] {
353
    if (value !== 'all') {
354
      sections.forEach(section =>
355
        section.indicators = section.indicators.filter(indicator => indicator.visibility === value));
356
    }
357
    return sections;
358
  }
359
  
360
  private filterByKeyword(sections: Section[], value): Section[] {
361
    if (value !== null && value !== '') {
362
      sections.forEach(section =>
363
        section.indicators = section.indicators.filter(indicator => (indicator.name && indicator.name.toLowerCase().includes(value.toLowerCase()))
364
          || (indicator.description && indicator.description.toLowerCase().includes(value.toLowerCase()))
365
          || (indicator.additionalDescription && indicator.additionalDescription.toLowerCase().includes(value.toLowerCase()))
366
          || indicator.indicatorPaths.filter(indicatorPath => (indicatorPath.parameters && indicatorPath.parameters.title &&
367
            indicatorPath.parameters.title.includes(value.toLowerCase()))).length > 0));
368
    }
369
    return sections;
370
  }
371
  
372
  get charts(): Section[] {
373
    if (this.stakeholder.topics[this.topicIndex] &&
374
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] &&
375
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) {
376
      return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts;
377
    } else {
378
      return [];
379
    }
380
  }
381
  
382
  set charts(sections: Section[]) {
383
    this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts = sections;
384
  }
385
  
386
  get numbers(): Section[] {
387
    if (this.stakeholder.topics[this.topicIndex] &&
388
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] &&
389
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) {
390
      return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers;
391
    } else {
392
      return [];
393
    }
394
  }
395
  
396
  set numbers(sections: Section[]) {
397
    this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers = sections;
398
  }
399
  
400
  get open(): boolean {
401
    return this.layoutService.open;
402
  }
403
  
404
  get canReorder(): boolean {
405
    return this.filters.value.chartType === 'all' &&
406
      this.filters.value.status === 'all' && this.filters.value.keyword === '' && !this.editing;
407
  }
408
  
409
  get canEdit() {
410
    return this.stakeholder &&
411
      this.stakeholder.topics[this.topicIndex] &&
412
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] &&
413
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex];
414
  }
415
  
416
  public get numberIndicatorPaths(): FormArray {
417
    return this.numberIndicatorFb.get('indicatorPaths') as FormArray;
418
  }
419
  
420
  public get chartIndicatorPaths(): FormArray {
421
    return this.chartIndicatorFb.get('indicatorPaths') as FormArray;
422
  }
423
  
424
  public getNumberClassBySize(size: IndicatorSize) {
425
    if (size === 'small') {
426
      return 'uk-width-1-4@xl uk-width-1-3@l uk-width-1-2@m uk-width-1-1';
427
    } else if (size === 'medium') {
428
      return 'uk-width-1-3@l uk-width-1-2@m uk-width-1-1';
429
    } else {
430
      return 'uk-width-1-2@l uk-width-1-1@m uk-width-1-1';
431
    }
432
  }
433
  
434
  public getChartClassBySize(size: IndicatorSize) {
435
    if (size === 'small') {
436
      return 'uk-width-1-3@xl uk-width-1-2@m uk-width-1-1';
437
    } else if (size === 'medium') {
438
      return 'uk-width-1-2@l uk-width-1-1';
439
    } else {
440
      return 'uk-width-1-1';
441
    }
442
  }
443
  
444
  public addJsonPath(index: number) {
445
    if (index == 0 && this.getJsonPath(index).getRawValue()[index].indexOf(",") != -1) {
446
      //if in the first path there are more than one paths comma separated, split them and autogenerate the forms
447
      let paths = this.getJsonPath(index).getRawValue()[index].split(",");
448
      for (let i = 0; i < paths.length; i++) {
449
        if (i != 0) {
450
          this.getJsonPath(index).push(this.fb.control('', Validators.required));
451
        }
452
      }
453
      this.getJsonPath(index).setValue(paths)
454
    } else {
455
      this.getJsonPath(index).push(this.fb.control('', Validators.required));
456
    }
457
  }
458
  
459
  public removeJsonPath(i: number, j: number) {
460
    if (this.getJsonPath(i).enabled) {
461
      this.getJsonPath(i).removeAt(j);
462
    }
463
  }
464
  
465
  public validateJsonPath(index: number, dirty: boolean = false) {
466
    let indicatorPath: FormGroup = <FormGroup>this.numberIndicatorPaths.at(index);
467
    if (this.indicator.defaultId === null) {
468
      this.getJsonPath(index).disable();
469
    }
470
    indicatorPath.get('result').setErrors({validating: true});
471
    this.subscriptions.push(this.statisticsService.getNumbers(null, indicatorPath.get('url').value).subscribe(response => {
472
      let result = JSON.parse(JSON.stringify(response));
473
      this.getJsonPath(index).controls.forEach(jsonPath => {
474
        if (result) {
475
          result = result[jsonPath.value];
476
        }
477
      });
478
      setTimeout(() => {
479
        if (this.indicator.defaultId === null) {
480
          this.getJsonPath(index).enable();
481
          if (dirty) {
482
            this.getJsonPath(index).markAsDirty();
483
          }
484
        }
485
        indicatorPath.get('result').setErrors(null);
486
        if (typeof result === 'string' || typeof result === 'number') {
487
          result = Number(result);
488
          if (result !== Number.NaN) {
489
            indicatorPath.get('result').setValue(result);
490
          } else {
491
            indicatorPath.get('result').setValue(0);
492
          }
493
        } else {
494
          indicatorPath.get('result').setValue(0);
495
        }
496
      }, 500);
497
    }, error => {
498
      setTimeout(() => {
499
        if (this.indicator.defaultId === null) {
500
          this.getJsonPath(index).enable();
501
          if (dirty) {
502
            this.getJsonPath(index).markAsDirty();
503
          }
504
        }
505
        indicatorPath.get('result').setErrors(null);
506
        indicatorPath.get('result').setValue(0);
507
      }, 500);
508
    }));
509
  }
510
  
511
  public getJsonPath(index: number): FormArray {
512
    return this.numberIndicatorPaths.at(index).get('jsonPath') as FormArray;
513
  }
514
  
515
  public getCurrentJsonPath(index: number): string[] {
516
    return this.section.indicators[this.index].indicatorPaths[index].jsonPath;
517
  }
518
  
519
  public getParameters(index: number): FormArray {
520
    return this.chartIndicatorPaths.at(index).get('parameters') as FormArray;
521
  }
522
  
523
  public getParameter(index: number, key: string): FormControl {
524
    return this.getParameters(index).controls.filter(control => control.value.key === key)[0] as FormControl;
525
  }
526
  
527
  private getSecureUrlByStakeHolder(indicatorPath: IndicatorPath) {
528
    return this.sanitizer.bypassSecurityTrustResourceUrl(
529
      this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)));
530
  }
531
  
532
  private getUrlByStakeHolder(indicatorPath: IndicatorPath) {
533
    return this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath));
534
  }
535
  
536
  public addNumberIndicatorPath(url: string = '', parameters: FormArray = new FormArray([]), source: string = 'stats-tool', jsonPath: FormArray = new FormArray([])) {
537
    if (jsonPath.length === 0) {
538
      jsonPath.push(this.fb.control('', Validators.required));
539
    }
540
    this.numberIndicatorPaths.push(this.fb.group({
541
        url: this.fb.control(url, [Validators.required, StringUtils.urlValidator()]),
542
        jsonPath: jsonPath,
543
        result: this.fb.control(0, Validators.required),
544
        // parameters: parameters,
545
        source: this.fb.control(source, Validators.required)
546
      }
547
    ));
548
    let index = this.numberIndicatorPaths.length - 1;
549
    if (this.numberIndicatorPaths.at(index).get('url').valid) {
550
      this.validateJsonPath(index);
551
      this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value);
552
    }
553
    if (this.indicator.defaultId === null) {
554
      this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => {
555
          this.numberIndicatorPaths.at(index).get('result').setValue(null);
556
          if (this.numberIndicatorPaths.at(index).get('url').valid) {
557
            let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.statisticsService.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.statisticsService.numberSources.get(this.statisticsService.getNumberSource(value)));
558
            if ((indicatorPath.chartObject && Object.keys(indicatorPath.parameters).indexOf("index_id") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_name") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_shortName") == -1)
559
              || (!indicatorPath.chartObject && indicatorPath.url.indexOf("index_id") == -1 && indicatorPath.url.indexOf("index_name") == -1 && (indicatorPath.url).indexOf("index_shortName") == -1)) {
560
              // default profile
561
              if (this.stakeholder.defaultId == null) {
562
                this.urlParameterizedMessage = "This indicator couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly."
563
              } else {
564
                this.urlParameterizedMessage = "This indicator couldn't be generated properly. Please make sure chart data is for the current stakeholder."
565
              }
566
            } else {
567
              this.urlParameterizedMessage = null;
568
            }
569
            this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value);
570
            if (this.indicator.indicatorPaths[index]) {
571
              this.indicator.indicatorPaths[index] = indicatorPath;
572
            } else {
573
              this.indicator.indicatorPaths.push(indicatorPath);
574
            }
575
            if (indicatorPath.source) {
576
              this.numberIndicatorPaths.at(index).get('source').setValue(indicatorPath.source);
577
            }
578
            if (indicatorPath.jsonPath.length > 1 && this.getJsonPath(index).length == 1) {
579
              let paths = indicatorPath.jsonPath;
580
              for (let i = 0; i < paths.length; i++) {
581
                if (i == this.getJsonPath(index).length) {
582
                  this.getJsonPath(index).push(this.fb.control('', Validators.required));
583
                }
584
              }
585
              this.getJsonPath(index).setValue(paths)
586
            }
587
          } else {
588
            this.urlParameterizedMessage = null;
589
          }
590
        })
591
      );
592
      
593
      this.subscriptions.push(this.numberIndicatorPaths.at(index).get('jsonPath').valueChanges.subscribe(value => {
594
          if (this.indicator.indicatorPaths[index]) {
595
            this.indicator.indicatorPaths[index].jsonPath = value;
596
          }
597
          this.numberIndicatorPaths.at(index).get('result').setValue(null);
598
        })
599
      );
600
      this.subscriptions.push(this.numberIndicatorPaths.at(index).get('source').valueChanges.subscribe(value => {
601
          if (this.indicator.indicatorPaths[index]) {
602
            this.indicator.indicatorPaths[index].source = value;
603
          }
604
        })
605
      );
606
    } else {
607
      this.numberIndicatorPaths.at(index).get('url').disable();
608
      this.numberIndicatorPaths.at(index).get('jsonPath').disable();
609
      this.numberIndicatorPaths.at(index).get('source').disable();
610
    }
611
  }
612
  
613
  public addChartIndicatorPath(value: string = '', parameters: FormArray = new FormArray([]), disableUrl: boolean = false, type: string = null) {
614
    this.chartIndicatorPaths.push(this.fb.group({
615
        url: this.fb.control(value, [Validators.required, StringUtils.urlValidator()]),
616
        parameters: parameters,
617
        type: this.fb.control(type)
618
      }
619
    ));
620
    let index = this.chartIndicatorPaths.length - 1;
621
    if (disableUrl) {
622
      this.chartIndicatorPaths.at(index).get('url').disable();
623
    } else {
624
      this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value);
625
      this.urlSubscriptions.push(this.chartIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => {
626
        if (this.chartIndicatorPaths.at(index).get('url').valid) {
627
          let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(value), value, this.chartIndicatorPaths.at(index).get('type').value, this.stakeholder);
628
          if (indicatorPath.chartObject && Object.keys(indicatorPath.parameters).indexOf("index_id") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_name") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_shortName") == -1) {
629
            // default profile
630
            if (this.stakeholder.defaultId == null) {
631
              this.urlParameterizedMessage = "This chart couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly."
632
            } else {
633
              this.urlParameterizedMessage = "This chart couldn't be generated properly. Please make sure chart data is for the current stakeholder."
634
            }
635
          } else {
636
            this.urlParameterizedMessage = null;
637
          }
638
          this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value);
639
          (this.chartIndicatorPaths.at(index) as FormGroup).get('type').setValue(indicatorPath.type);
640
          let parameters = this.getParametersAsFormArray(indicatorPath);
641
          (this.chartIndicatorPaths.at(index) as FormGroup).setControl('parameters', parameters);
642
          if (!this.indicator.indicatorPaths[index]) {
643
            this.indicator.indicatorPaths[index] = indicatorPath;
644
            this.indicator.indicatorPaths[index].safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath);
645
          } else {
646
            indicatorPath.safeResourceUrl = this.indicator.indicatorPaths[index].safeResourceUrl;
647
            this.indicator.indicatorPaths[index] = indicatorPath;
648
          }
649
        } else {
650
          this.urlParameterizedMessage = null;
651
        }
652
      }));
653
    }
654
  }
655
  
656
  private getJsonPathAsFormArray(indicatorPath: IndicatorPath): FormArray {
657
    let jsonPath = this.fb.array([]);
658
    if (indicatorPath.jsonPath) {
659
      indicatorPath.jsonPath.forEach(path => {
660
        jsonPath.push(this.fb.control(path, Validators.required));
661
      });
662
    }
663
    return jsonPath;
664
  }
665
  
666
  private getParametersAsFormArray(indicatorPath: IndicatorPath): FormArray {
667
    let parameters = this.fb.array([]);
668
    if (indicatorPath.parameters) {
669
      Object.keys(indicatorPath.parameters).forEach(key => {
670
        if (this.indicatorUtils.ignoredParameters.indexOf(key) === -1) {
671
          if (this.indicatorUtils.parametersValidators.has(key)) {
672
            parameters.push(this.fb.group({
673
              key: this.fb.control(key),
674
              value: this.fb.control(indicatorPath.parameters[key], this.indicatorUtils.parametersValidators.get(key))
675
            }));
676
          } else {
677
            parameters.push(this.fb.group({
678
              key: this.fb.control(key),
679
              value: this.fb.control(indicatorPath.parameters[key])
680
            }));
681
          }
682
        }
683
      });
684
    }
685
    return parameters;
686
  }
687
  
688
  public editNumberIndicatorOpen(section: Section, id = null) {
689
    this.urlParameterizedMessage = null;
690
    this.section = section;
691
    this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1;
692
    if (this.index !== -1) {
693
      this.indicator = HelperFunctions.copy(this.section.indicators[this.index]);
694
      this.numberIndicatorFb = this.fb.group({
695
        _id: this.fb.control(this.indicator._id),
696
        name: this.fb.control(this.indicator.name, Validators.required),
697
        description: this.fb.control(this.indicator.description),
698
        creationDate: this.fb.control(this.indicator.creationDate),
699
        additionalDescription: this.fb.control(this.indicator.additionalDescription),
700
        visibility: this.fb.control(this.indicator.visibility),
701
        indicatorPaths: this.fb.array([], Validators.required),
702
        type: this.fb.control(this.indicator.type),
703
        width: this.fb.control(this.indicator.width),
704
        height: this.fb.control(this.indicator.height),
705
        defaultId: this.fb.control(this.indicator.defaultId)
706
      });
707
      this.indicator.indicatorPaths.forEach(indicatorPath => {
708
        this.addNumberIndicatorPath(this.statisticsService.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath));
709
      });
710
    } else {
711
      this.indicator = new Indicator('', '', '', 'number', 'small', 'small', "PUBLIC", []);
712
      this.numberIndicatorFb = this.fb.group({
713
        _id: this.fb.control(this.indicator._id),
714
        name: this.fb.control(this.indicator.name, Validators.required),
715
        description: this.fb.control(this.indicator.description),
716
        additionalDescription: this.fb.control(this.indicator.additionalDescription),
717
        visibility: this.fb.control(this.indicator.visibility),
718
        indicatorPaths: this.fb.array([], Validators.required),
719
        type: this.fb.control(this.indicator.type),
720
        width: this.fb.control(this.indicator.width),
721
        height: this.fb.control(this.indicator.height),
722
        defaultId: this.fb.control(this.indicator.defaultId)
723
      });
724
      this.addNumberIndicatorPath();
725
    }
726
    if (this.indicator.defaultId) {
727
      setTimeout(() => {
728
        this.numberIndicatorFb.get('description').disable();
729
      }, 0);
730
    }
731
    this.editNumberModal.cancelButtonText = 'Cancel';
732
    this.editNumberModal.okButtonLeft = false;
733
    this.editNumberModal.alertMessage = false;
734
    if (this.index === -1) {
735
      this.editNumberModal.alertTitle = 'Create a new number indicator';
736
      this.editNumberModal.okButtonText = 'Save';
737
    } else {
738
      this.editNumberModal.alertTitle = 'Edit number indicator\'s information';
739
      this.editNumberModal.okButtonText = 'Save Changes';
740
    }
741
    this.editNumberModal.open();
742
  }
743
  
744
  public editChartIndicatorOpen(section: Section, id = null) {
745
    this.urlParameterizedMessage = null;
746
    this.urlSubscriptions.forEach(value => {
747
      if (value instanceof Subscriber) {
748
        value.unsubscribe();
749
      }
750
    });
751
    this.section = section;
752
    this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1;
753
    if (this.index !== -1) {
754
      this.indicator = HelperFunctions.copy(this.section.indicators[this.index]);
755
      this.chartIndicatorFb = this.fb.group({
756
        _id: this.fb.control(this.indicator._id),
757
        name: this.fb.control(this.indicator.name),
758
        creationDate: this.fb.control(this.indicator.creationDate),
759
        description: this.fb.control(this.indicator.description),
760
        additionalDescription: this.fb.control(this.indicator.additionalDescription),
761
        visibility: this.fb.control(this.indicator.visibility),
762
        indicatorPaths: this.fb.array([]),
763
        width: this.fb.control(this.indicator.width),
764
        height: this.fb.control(this.indicator.height),
765
        defaultId: this.fb.control(this.indicator.defaultId)
766
      });
767
      this.indicator.indicatorPaths.forEach(indicatorPath => {
768
        this.addChartIndicatorPath(this.getUrlByStakeHolder(indicatorPath),
769
          this.getParametersAsFormArray(indicatorPath), this.indicator.defaultId !== null, indicatorPath.type);
770
        indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath);
771
      });
772
    } else {
773
      this.indicator = new Indicator('', '', '', 'chart', 'medium', 'medium', "PUBLIC", []);
774
      this.chartIndicatorFb = this.fb.group({
775
        _id: this.fb.control(this.indicator._id),
776
        name: this.fb.control(this.indicator.name),
777
        description: this.fb.control(this.indicator.description),
778
        additionalDescription: this.fb.control(this.indicator.additionalDescription),
779
        visibility: this.fb.control(this.indicator.visibility),
780
        indicatorPaths: this.fb.array([]),
781
        width: this.fb.control(this.indicator.width, Validators.required),
782
        height: this.fb.control(this.indicator.height, Validators.required),
783
        defaultId: this.fb.control(this.indicator.defaultId)
784
      });
785
      this.addChartIndicatorPath();
786
    }
787
    if (this.indicator.defaultId) {
788
      setTimeout(() => {
789
        this.chartIndicatorFb.get('description').disable();
790
      }, 0);
791
    }
792
    this.editChartModal.cancelButtonText = 'Cancel';
793
    this.editChartModal.okButtonLeft = false;
794
    this.editChartModal.alertMessage = false;
795
    if (this.index === -1) {
796
      this.editChartModal.alertTitle = 'Create a new chart indicator';
797
      this.editChartModal.okButtonText = 'Save';
798
    } else {
799
      this.editChartModal.alertTitle = 'Edit chart indicator\'s information';
800
      this.editChartModal.okButtonText = 'Save Changes';
801
    }
802
    this.editChartModal.open();
803
  }
804
  
805
  saveIndicator() {
806
    this.editing = true;
807
    if (this.indicator.type === 'chart') {
808
      this.chartIndicatorFb.get('description').enable();
809
      this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type, true);
810
      this.section = this.charts.find(section => section._id === this.section._id);
811
    } else {
812
      this.numberIndicatorFb.get('description').enable();
813
      this.indicator = this.indicatorUtils.generateIndicatorByForm(this.numberIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type, false);
814
      this.section = this.numbers.find(section => section._id === this.section._id);
815
    }
816
    let path = [
817
      this.stakeholder._id,
818
      this.stakeholder.topics[this.topicIndex]._id,
819
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
820
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id,
821
      this.section._id
822
    ];
823
    this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.indicator, path).subscribe(indicator => {
824
      if (this.index !== -1) {
825
        this.section.indicators[this.index] = indicator;
826
      } else {
827
        this.section.indicators.push(indicator);
828
      }
829
      if (this.indicator.type === "chart") {
830
        this.filterCharts();
831
        this.chartIndicatorFb = null;
832
      } else {
833
        this.filterNumbers();
834
        this.numberIndicatorFb = null;
835
      }
836
      UIkit.notification('Indicator has been <b>successfully saved</b>', {
837
        status: 'success',
838
        timeout: 6000,
839
        pos: 'bottom-right'
840
      });
841
      this.editing = false;
842
    }, error => {
843
      this.chartIndicatorFb = null;
844
      UIkit.notification(error.error.message, {
845
        status: 'danger',
846
        timeout: 6000,
847
        pos: 'bottom-right'
848
      });
849
      this.editing = false;
850
    }));
851
  }
852
  
853
  reorderIndicators(sectionId: string, type: IndicatorType, reorder: Reorder) {
854
    this.editing = true;
855
    let path = [
856
      this.stakeholder._id,
857
      this.stakeholder.topics[this.topicIndex]._id,
858
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
859
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id,
860
      sectionId
861
    ];
862
    this.subscriptions.push(this.stakeholderService.reorderIndicators(this.properties.monitorServiceAPIURL, path, reorder, type).subscribe(indicators => {
863
      if (type === 'chart') {
864
        this.charts.find(section => section._id === sectionId).indicators = indicators;
865
        this.filterCharts();
866
      } else {
867
        this.numbers.find(section => section._id === sectionId).indicators = indicators;
868
        this.filterNumbers();
869
      }
870
      this.editing = false;
871
    }));
872
  }
873
  
874
  hasDifference(index: number): boolean {
875
    let hasDifference = false;
876
    this.chartIndicatorPaths.at(index).value.parameters.forEach((parameter) => {
877
      if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) {
878
        hasDifference = true;
879
        return;
880
      }
881
    });
882
    return hasDifference || this.indicator.indicatorPaths[index].safeResourceUrl.toString() !==
883
      this.getSecureUrlByStakeHolder(this.indicator.indicatorPaths[index]).toString();
884
  }
885
  
886
  public get isAdministrator(): boolean {
887
    return Session.isPortalAdministrator(this.user);
888
  }
889
  
890
  public get isCurator(): boolean {
891
    return this.isAdministrator || Session.isMonitorCurator(this.user);
892
  }
893
  
894
  refreshIndicator() {
895
    this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, 'chart', true);
896
    this.indicator.indicatorPaths.forEach(indicatorPath => {
897
      indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath);
898
    });
899
  }
900
  
901
  deleteIndicatorOpen(section: Section, indicatorId: string, type: string, childrenAction: string = null) {
902
    this.indicatorChildrenActionOnDelete = null;
903
    if (childrenAction == "delete") {
904
      this.indicatorChildrenActionOnDelete = childrenAction;
905
    } else if (childrenAction == "disconnect") {
906
      this.indicatorChildrenActionOnDelete = childrenAction;
907
    }
908
    
909
    this.section = section;
910
    if (type === 'chart') {
911
      this.index = this.charts.find(value => value._id == section._id).indicators.findIndex(value => value._id == indicatorId);
912
    } else {
913
      this.index = this.numbers.find(value => value._id == section._id).indicators.findIndex(value => value._id == indicatorId);
914
    }
915
    this.indicator = section.indicators.find(value => value._id == indicatorId);
916
    this.deleteModal.alertTitle = 'Delete indicator';
917
    this.deleteModal.cancelButtonText = 'No';
918
    this.deleteModal.okButtonText = 'Yes';
919
    this.deleteModal.open();
920
  }
921
  
922
  deleteIndicator() {
923
    this.editing = true;
924
    let path = [
925
      this.stakeholder._id,
926
      this.stakeholder.topics[this.topicIndex]._id,
927
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
928
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id,
929
      this.section._id,
930
      this.indicator._id
931
    ];
932
    this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.indicatorChildrenActionOnDelete).subscribe(() => {
933
      if (this.indicator.type === 'chart') {
934
        this.charts.find(section => section._id === this.section._id).indicators.splice(this.index, 1);
935
        this.filterCharts();
936
      } else {
937
        this.numbers.find(section => section._id === this.section._id).indicators.splice(this.index, 1);
938
        this.filterNumbers();
939
      }
940
      UIkit.notification('Indicator has been <b>successfully deleted</b>', {
941
        status: 'success',
942
        timeout: 6000,
943
        pos: 'bottom-right'
944
      });
945
      this.editing = false;
946
    }, error => {
947
      UIkit.notification(error.error.message, {
948
        status: 'danger',
949
        timeout: 6000,
950
        pos: 'bottom-right'
951
      });
952
      this.editing = false;
953
    }));
954
  }
955
  
956
  changeIndicatorStatus(sectionId: string, indicator: Indicator, visibility: Visibility) {
957
    this.editing = true;
958
    let path = [
959
      this.stakeholder._id,
960
      this.stakeholder.topics[this.topicIndex]._id,
961
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
962
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id,
963
      sectionId,
964
      indicator._id
965
    ];
966
    this.subscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(visibility => {
967
      indicator.visibility = visibility;
968
      UIkit.notification('Indicator has been <b>successfully changed</b> to ' + indicator.visibility.toLowerCase(), {
969
        status: 'success',
970
        timeout: 6000,
971
        pos: 'bottom-right'
972
      });
973
      this.editing = false;
974
    }, error => {
975
      UIkit.notification('An error has been occurred. Try again later', {
976
        status: 'danger',
977
        timeout: 6000,
978
        pos: 'bottom-right'
979
      });
980
      this.editing = false;
981
    }));
982
  }
983
  
984
  saveSection(section: Section, index: number, type: IndicatorType = "chart") {
985
    this.editing = true;
986
    let path = [
987
      this.stakeholder._id,
988
      this.stakeholder.topics[this.topicIndex]._id,
989
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
990
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id
991
    ];
992
    this.subscriptions.push(this.stakeholderService.saveSection(this.properties.monitorServiceAPIURL, section, path, index).subscribe(section => {
993
      if (type === 'chart') {
994
        this.charts[index] = section;
995
        this.filterCharts();
996
      } else {
997
        this.numbers[index] = section;
998
        this.filterNumbers();
999
      }
1000
      this.initReorder();
1001
      UIkit.notification('Section has been <b>successfully saved</b>', {
1002
        status: 'success',
1003
        timeout: 6000,
1004
        pos: 'bottom-right'
1005
      });
1006
      this.editing = false;
1007
    }, error => {
1008
      UIkit.notification(error.error.message, {
1009
        status: 'danger',
1010
        timeout: 6000,
1011
        pos: 'bottom-right'
1012
      });
1013
      this.editing = false;
1014
    }));
1015
  }
1016
  
1017
  createSection(index = -1, type: IndicatorType = 'chart') {
1018
    this.editing = true;
1019
    this.section = new Section(type, null, null, this.stakeholder.alias);
1020
    let path = [
1021
      this.stakeholder._id,
1022
      this.stakeholder.topics[this.topicIndex]._id,
1023
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
1024
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id
1025
    ];
1026
    this.subscriptions.push(this.stakeholderService.saveSection(this.properties.monitorServiceAPIURL, this.section, path, index).subscribe(section => {
1027
      if (type === 'chart') {
1028
        if (index !== -1) {
1029
          this.charts.splice(index, 0, section);
1030
        } else {
1031
          this.charts.push(section);
1032
        }
1033
        this.filterCharts();
1034
      } else {
1035
        if (index !== -1) {
1036
          this.numbers.splice(index, 0, section);
1037
        } else {
1038
          this.numbers.push(section);
1039
        }
1040
        this.filterNumbers();
1041
      }
1042
      this.initReorder();
1043
      UIkit.notification('Section has been <b>successfully created</b>', {
1044
        status: 'success',
1045
        timeout: 6000,
1046
        pos: 'bottom-right'
1047
      });
1048
      this.editing = false;
1049
    }, error => {
1050
      UIkit.notification(error.error.message, {
1051
        status: 'danger',
1052
        timeout: 6000,
1053
        pos: 'bottom-right'
1054
      });
1055
      this.editing = false;
1056
    }));
1057
  }
1058
  
1059
  // deleteNumberSectionOpen(section: Section, index: number) {
1060
  //   this.section = section;
1061
  //   this.index = index;
1062
  //   this.deleteNumberSectionModal.alertTitle = 'Delete Section';
1063
  //   this.deleteNumberSectionModal.cancelButtonText = 'No';
1064
  //   this.deleteNumberSectionModal.okButtonText = 'Yes';
1065
  //   this.deleteNumberSectionModal.open();
1066
  // }
1067
  //
1068
  // deleteChartSectionOpen(section: Section, index: number) {
1069
  //   this.section = section;
1070
  //   this.index = index;
1071
  //   this.deleteChartSectionModal.alertTitle = 'Delete Section';
1072
  //   this.deleteChartSectionModal.cancelButtonText = 'No';
1073
  //   this.deleteChartSectionModal.okButtonText = 'Yes';
1074
  //   this.deleteChartSectionModal.open();
1075
  // }
1076
  
1077
  deleteSectionOpen(section: Section, index: number, type: IndicatorType, childrenAction: string = null) {
1078
    if (!this.editing && !section.defaultId) {
1079
      this.sectionTypeToDelete = type;
1080
      this.sectionChildrenActionOnDelete = null;
1081
      if (childrenAction == "delete") {
1082
        this.sectionChildrenActionOnDelete = childrenAction;
1083
      } else if (childrenAction == "disconnect") {
1084
        this.sectionChildrenActionOnDelete = childrenAction;
1085
      }
1086
      
1087
      this.section = section;
1088
      this.index = index;
1089
      this.deleteSectionModal.alertTitle = 'Delete Section';
1090
      this.deleteSectionModal.cancelButtonText = 'No';
1091
      this.deleteSectionModal.okButtonText = 'Yes';
1092
      this.deleteSectionModal.open();
1093
    }
1094
  }
1095
  
1096
  deleteSection() {
1097
    this.editing = true;
1098
    let path = [
1099
      this.stakeholder._id,
1100
      this.stakeholder.topics[this.topicIndex]._id,
1101
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
1102
      this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id,
1103
      this.section._id
1104
    ];
1105
    this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.sectionChildrenActionOnDelete).subscribe(() => {
1106
      if (this.sectionTypeToDelete === "chart") {
1107
        this.charts.splice(this.index, 1);
1108
        this.filterCharts();
1109
      } else {
1110
        this.numbers.splice(this.index, 1);
1111
        this.filterNumbers();
1112
      }
1113
      this.initReorder();
1114
      UIkit.notification('Section has been <b>successfully deleted</b>', {
1115
        status: 'success',
1116
        timeout: 6000,
1117
        pos: 'bottom-right'
1118
      });
1119
      this.editing = false;
1120
    }, error => {
1121
      UIkit.notification(error.error.message, {
1122
        status: 'danger',
1123
        timeout: 6000,
1124
        pos: 'bottom-right'
1125
      });
1126
      this.editing = false;
1127
    }));
1128
  }
1129
  private checkForSchemaEnhancements(url:string){
1130
    //new schema
1131
    this.showCheckForSchemaEnhancements = this.isAdministrator && url && !this.properties.useOldStatisticsSchema && this.indicatorUtils.checkForSchemaEnhancements(url);
1132
  }
1133

    
1134
}
(3-3/7)