Project

General

Profile

1
import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
2
import {ActivatedRoute, Router} from '@angular/router';
3
import {Title} from '@angular/platform-browser';
4
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
5
import {Category, Stakeholder, SubCategory, Topic} from "../utils/entities/stakeholder";
6
import {StakeholderService} from "../services/stakeholder.service";
7
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
8
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
9
import {Subscriber} from "rxjs";
10
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
11
import {IndicatorUtils} from "../utils/indicator-utils";
12

    
13
declare var UIkit;
14

    
15
@Component({
16
  selector: 'topic',
17
  templateUrl: './topic.component.html',
18
})
19
export class TopicComponent implements OnInit, OnDestroy {
20
  public subscriptions: any[] = [];
21
  public properties: EnvProperties;
22
  public indicatorUtils: IndicatorUtils = new IndicatorUtils();
23
  public loading: boolean = true;
24
  public stakeholder: Stakeholder;
25
  /**
26
   * Current topic
27
   **/
28
  public topicIndex: number = 0;
29
  public topicFb: FormGroup;
30

    
31
  /**
32
   * categoryIndex: Current category to be edited, selectedCategoryIndex: selected on menu(opened)
33
   */
34
  public categoryIndex: number = 0;
35
  public selectedCategoryIndex: number = 0;
36
  public categoryFb: FormGroup;
37
  /**
38
   * Current Subcategory to be edited
39
   */
40
  public subCategoryIndex: number = 0;
41
  public subcategoryFb: FormGroup;
42
  /**
43
   * Current drop element and index of topic, category or subcategory to be deleted.
44
   */
45
  public element: any;
46
  public index: number;
47
  /**
48
   * Check form validity
49
   */
50
  public toggle: boolean = false;
51

    
52
  @ViewChild('deleteTopicModal') deleteTopicModal: AlertModal;
53
  @ViewChild('deleteCategoryModal') deleteCategoryModal: AlertModal;
54
  @ViewChild('deleteSubcategoryModal') deleteSubcategoryModal: AlertModal;
55

    
56
  constructor(
57
    private route: ActivatedRoute,
58
    private router: Router,
59
    private title: Title,
60
    private fb: FormBuilder,
61
    private stakeholderService: StakeholderService) {
62
  }
63

    
64
  public ngOnInit() {
65
    this.route.data
66
      .subscribe((data: { envSpecific: EnvProperties }) => {
67
        this.properties = data.envSpecific;
68
        this.route.params.subscribe( params => {
69
          this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
70
            if (stakeholder) {
71
              this.stakeholder = HelperFunctions.copy(stakeholder);
72
              this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']);
73
              if(this.topicIndex === -1) {
74
                this.navigateToError();
75
              } else {
76
                this.title.setTitle(stakeholder.index_shortName + ' | ' + this.stakeholder.topics[this.topicIndex].name);
77
                this.toggle = true;
78
              }
79
            }
80
          }));
81
        });
82
      });
83
  }
84

    
85
  public ngOnDestroy() {
86
    this.subscriptions.forEach( value => {
87
      if(value instanceof Subscriber) {
88
        value.unsubscribe();
89
      }
90
    });
91
  }
92

    
93
  public hide(element) {
94
    UIkit.drop(element).hide();
95
  }
96

    
97
  public show(element) {
98
    UIkit.drop(element).show();
99
  }
100

    
101
  private buildTopic(topic: Topic) {
102
    this.topicFb = this.fb.group({
103
      _id: this.fb.control(topic._id),
104
      name: this.fb.control(topic.name, Validators.required),
105
      description: this.fb.control(topic.description),
106
      alias: this.fb.control(topic.alias),
107
      isActive: this.fb.control(topic.isActive),
108
      isPublic: this.fb.control(topic.isPublic),
109
      isDefault: this.fb.control(topic.isDefault),
110
      categories: this.fb.control(topic.categories)
111
    });
112
  }
113

    
114
  public editTopicOpen(element) {
115
    if(element.className.indexOf('uk-open') !== -1) {
116
      this.hide(element);
117
    } else {
118
      this.buildTopic(this.stakeholder.topics[this.topicIndex]);
119
      this.show(element);
120
    }
121
  }
122

    
123
  public saveTopic(element) {
124
    if(!this.topicFb.invalid) {
125
      if(!this.topicFb.value.alias) {
126
        this.topicFb.value.alias = this.topicFb.value.name.toLowerCase().trim();
127
      }
128
      let path = [this.stakeholder._id];
129
      let callback = (topic: Topic): void => {
130
          this.stakeholder.topics[this.topicIndex] = topic;
131
          this.stakeholderService.setStakeholder(this.stakeholder);
132
      };
133
      this.save('Topic has been successfully saved', element, path, this.topicFb.value, callback,true);
134
    }
135
  }
136

    
137
  public deleteTopicOpen(name: string, element) {
138
    this.deleteOpen(name,'topic', this.deleteTopicModal, element, this.topicIndex);
139
  }
140

    
141
  public deleteTopic() {
142
    let path: string[] = [
143
      this.stakeholder._id,
144
      this.stakeholder.topics[this.topicIndex]._id
145
    ];
146
    let callback = (): void => {
147
      this.stakeholder.topics.splice(this.topicIndex, 1);
148
      this.stakeholderService.setStakeholder(this.stakeholder);
149
    };
150
    this.delete('Topic has been successfully be deleted', path, callback, true);
151
  }
152

    
153
  public toggleCategory(index: number) {
154
   if(this.selectedCategoryIndex !== index) {
155
      this.selectedCategoryIndex = index;
156
      this.toggle = true;
157
    } else {
158
      this.toggle = !this.toggle;
159
    }
160
  }
161

    
162
  private buildCategory(category: Category) {
163
    this.categoryFb = this.fb.group({
164
      _id: this.fb.control(category._id),
165
      name: this.fb.control(category.name, Validators.required),
166
      alias: this.fb.control(category.alias),
167
      isActive: this.fb.control(category.isActive),
168
      isPublic: this.fb.control(category.isPublic),
169
      isDefault: this.fb.control(category.isDefault),
170
      subCategories: this.fb.control(category.subCategories)
171
    });
172
  }
173

    
174
  public editCategoryOpen(element, index:number = -1) {
175
    if(element.className.indexOf('uk-open') !== -1) {
176
      this.hide(element);
177
    } else {
178
      if(index === -1) {
179
        this.buildCategory(new Category(null, null, null, true, true));
180
      } else {
181
        this.buildCategory(this.stakeholder.topics[this.topicIndex].categories[index]);
182
      }
183
      this.show(element);
184
    }
185
  }
186

    
187
  public saveCategory(element, index = -1) {
188
    if(!this.categoryFb.invalid) {
189
      if(!this.categoryFb.value.alias) {
190
        this.categoryFb.value.alias = this.categoryFb.value.name.toLowerCase();
191
      }
192
      let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id];
193
      let callback = (category: Category): void => {
194
        if(index === -1) {
195
          this.stakeholder.topics[this.topicIndex].categories.push(category);
196
        } else {
197
          this.stakeholder.topics[this.topicIndex].categories[index] = HelperFunctions.copy(category);
198
        }
199
        this.stakeholderService.setStakeholder(this.stakeholder);
200
      };
201
      if(index === -1) {
202
        this.save('Category has been successfully created', element, path, this.categoryFb.value, callback);
203
      } else {
204
        this.save('Category has been successfully saved', element, path, this.categoryFb.value, callback);
205
      }
206
    }
207
  }
208

    
209
  public deleteCategoryOpen(name: string, element, index) {
210
    this.deleteOpen(name,'category', this.deleteCategoryModal, element, index);
211
  }
212

    
213
  public deleteCategory() {
214
    let path: string[] = [
215
      this.stakeholder._id,
216
      this.stakeholder.topics[this.topicIndex]._id,
217
      this.stakeholder.topics[this.topicIndex].categories[this.index]._id
218
    ];
219
    let callback = (): void => {
220
      this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1);
221
      this.stakeholderService.setStakeholder(this.stakeholder);
222
    };
223
    this.delete('Category has been successfully be deleted', path, callback);
224
  }
225

    
226
  private buildSubcategory(subCategory: SubCategory) {
227
    this.subcategoryFb = this.fb.group({
228
      _id: this.fb.control(subCategory._id),
229
      name: this.fb.control(subCategory.name, Validators.required),
230
      alias: this.fb.control(subCategory.alias),
231
      isActive: this.fb.control(subCategory.isActive),
232
      isPublic: this.fb.control(subCategory.isPublic),
233
      isDefault: this.fb.control(subCategory.isDefault),
234
      charts: this.fb.control(subCategory.charts),
235
      numbers: this.fb.control(subCategory.numbers)
236
    });
237
  }
238

    
239
  public editSubCategoryOpen(element, index:number = -1) {
240
    if(element.className.indexOf('uk-open') !== -1) {
241
      this.hide(element);
242
    } else {
243
      if(index === -1) {
244
        this.buildSubcategory(new SubCategory(null, null, null, true, true));
245
      } else {
246
        this.buildSubcategory(this.stakeholder.topics[this.topicIndex].
247
          categories[this.selectedCategoryIndex].subCategories[index]);
248
      }
249
      this.show(element);
250
    }
251
  }
252

    
253
  public saveSubCategory(element, index = -1) {
254
    if(!this.subcategoryFb.invalid) {
255
      if(!this.subcategoryFb.value.alias) {
256
        this.subcategoryFb.value.alias = this.subcategoryFb.value.name.toLowerCase();
257
      }
258
      let path: string[] = [
259
        this.stakeholder._id,
260
        this.stakeholder.topics[this.topicIndex]._id,
261
        this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex]._id,
262
      ];
263
      let callback = (subCategory: SubCategory): void => {
264
        if(index === -1) {
265
          this.stakeholder.topics[this.topicIndex].
266
            categories[this.selectedCategoryIndex].subCategories.push(subCategory);
267
        } else {
268
          this.stakeholder.topics[this.topicIndex].
269
            categories[this.selectedCategoryIndex].subCategories[index] = subCategory;
270
        }
271
        this.stakeholderService.setStakeholder(this.stakeholder);
272
      };
273
      if(index === -1) {
274
        this.save('Subcategory has been successfully created', element, path, this.subcategoryFb.value, callback);
275
      } else {
276
        this.save('Subcategory has been successfully saved', element, path, this.subcategoryFb.value, callback);
277
      }
278
      this.hide(element);
279
    }
280
  }
281

    
282
  public deleteSubcategoryOpen(name: string, element, index) {
283
    this.deleteOpen(name,'subcategory', this.deleteSubcategoryModal, element, index);
284
  }
285

    
286
  public deleteSubcategory() {
287
    let path: string[] = [
288
      this.stakeholder._id,
289
      this.stakeholder.topics[this.topicIndex]._id,
290
      this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex]._id,
291
      this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[this.index]._id
292
    ];
293
    let callback = (): void => {
294
      this.stakeholder.topics[this.topicIndex].
295
        categories[this.selectedCategoryIndex].subCategories.splice(this.index, 1);
296
      this.stakeholderService.setStakeholder(this.stakeholder);
297
    };
298
    this.delete('Subcategory has been successfully be deleted', path, callback);
299
  }
300

    
301
  private navigateToError() {
302
    this.router.navigate(['/error'], {queryParams: {'page': this.router.url}});
303
  }
304

    
305
  private deleteOpen(name: string, type: string, modal: AlertModal, element, index) {
306
    this.element = element;
307
    this.index = index;
308
    modal.alertTitle = 'Delete ' + name;
309
    modal.cancelButtonText = 'No';
310
    modal.okButtonText = 'Yes';
311
    modal.message = 'This ' + type + ' will permanently be deleted. Are you sure you want to proceed?';
312
    modal.open();
313
  }
314

    
315
  private save(message: string, element, path: string[], saveElement: any, callback: Function, redirect = false) {
316
    this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => {
317
      callback(saveElement);
318
      UIkit.notification(message, {
319
        status: 'success',
320
        timeout: 3000,
321
        pos: 'top-left'
322
      });
323
      if(redirect) {
324
        this.router.navigate(['../' + saveElement.alias], {
325
          relativeTo: this.route
326
        });
327
      }
328
      this.hide(element);
329
    }, error => {
330
      UIkit.notification(error.error.message, {
331
        status: 'danger',
332
        timeout: 3000,
333
        pos: 'top-left'
334
      });
335
      this.hide(element);
336
    });
337
  }
338

    
339
  private delete(message: string, path: string[], callback: Function, redirect = false) {
340
    this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path).subscribe(() => {
341
      callback();
342
      UIkit.notification(message, {
343
        status: 'success',
344
        timeout: 3000,
345
        pos: 'top-left'
346
      });
347
      if(redirect) {
348
        this.back();
349
      }
350
      this.hide(this.element);
351
    }, error => {
352
      UIkit.notification(error.error.message, {
353
        status: 'danger',
354
        timeout: 3000,
355
        pos: 'top-left'
356
      });
357
      this.hide(this.element);
358
    });
359
  }
360

    
361
  back() {
362
    this.router.navigate(['../'], {
363
      relativeTo: this.route
364
    });
365
  }
366

    
367
  chooseSubcategory(categoryIndex: number, subcategoryIndex: number) {
368
    this.categoryIndex = categoryIndex;
369
    this.subCategoryIndex = subcategoryIndex;
370
  }
371
}
(5-5/6)