Project

General

Profile

1
import {Component, Input, OnDestroy} from "@angular/core";
2
import {Stakeholder} from "../../openaireLibrary/monitor/entities/stakeholder";
3
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
4
import {StakeholderUtils} from "../../utils/indicator-utils";
5
import {Option} from "../../openaireLibrary/dashboard/sharedComponents/input/input.component";
6
import {Subscription} from "rxjs";
7
import {EnvProperties} from "../../openaireLibrary/utils/properties/env-properties";
8
import {properties} from "../../../environments/environment";
9
import {StakeholderService} from "../../openaireLibrary/monitor/services/stakeholder.service";
10
import {UtilitiesService} from "../../openaireLibrary/services/utilities.service";
11
import {Session, User} from "../../openaireLibrary/login/utils/helper.class";
12
import {UserManagementService} from "../../openaireLibrary/services/user-management.service";
13

    
14
declare var UIkit;
15

    
16
@Component({
17
  selector: 'edit-stakeholder',
18
  template: `
19
    <div *ngIf="stakeholderFb && user" [ngStyle]="{'max-height': maxHeight}"
20
         [class.uk-padding-small]="!paddingLarge" [class.uk-padding-large]="paddingLarge"
21
         class="uk-overflow-auto"
22
         [formGroup]="stakeholderFb">
23
      <div class="uk-grid" uk-grid uk-height-match=".uk-form-hint">
24
        <div dashboard-input class="uk-width-1-2@m" [formInput]="stakeholderFb.get('name')" label="Name"
25
             placeholder="Write a name..."
26
             hint="Set a name for your profile."></div>
27
        <div dashboard-input class="uk-width-1-2@m" [formInput]="stakeholderFb.get('alias')"
28
             hint="Set an URL alias for your profile."
29
             label="URL Alias" placeholder="Write an alias..."></div>
30
        <div dashboard-input class="uk-width-1-3@m" [formInput]="stakeholderFb.get('index_id')"
31
             label="Index ID" placeholder="Write index ID.">
32
        </div>
33
        <div dashboard-input class="uk-width-1-3@m" [formInput]="stakeholderFb.get('index_name')"
34
             label="Index Name" placeholder="Write index name.">
35
        </div>
36
        <div dashboard-input class="uk-width-1-3@m" [formInput]="stakeholderFb.get('index_shortName')"
37
             label="Index Short Name" placeholder="Write index short name.">
38
        </div>
39
        <div dashboard-input class="uk-width-1-1" [type]="'textarea'" placeholder="Write a description..."
40
             hint="Write a description for your profile"
41
             [rows]="4" [formInput]="stakeholderFb.get('description')" label="Description"></div>
42
        <input #file id="photo" type="file" class="uk-hidden" (change)="fileChangeEvent($event)"/>
43
        <div dashboard-input class="uk-width-1-1" [hideControl]="stakeholderFb.get('isUpload').value"
44
             hint="Upload or link the logo of your profile" [placeholder]="'Write link to the logo'"
45
             [formInput]="stakeholderFb.get('logoUrl')" label="Logo">
46
          <div *ngIf="!stakeholderFb.get('isUpload').value" class="uk-width-2-5@l uk-width-1-1">
47
            <div class="uk-grid uk-flex uk-flex-middle" uk-grid>
48
              <div class="uk-width-3-4@l uk-width-1-1 uk-flex uk-flex-center">
49
                <button class="uk-button uk-button-secondary uk-flex uk-flex-middle uk-flex-wrap"
50
                        (click)="file.click()">
51
                  <icon name="cloud_upload" [flex]="true"></icon>
52
                  <span class="uk-margin-small-left">Upload a file</span>
53
                </button>
54
              </div>
55
              <div class="uk-text-center uk-text-bold uk-width-expand">
56
                OR
57
              </div>
58
            </div>
59
          </div>
60
          <div *ngIf="stakeholderFb.get('isUpload').value" class="uk-width-1-1 uk-flex uk-flex-middle">
61
            <div class="uk-card uk-card-default uk-text-center uk-border-circle">
62
              <img class="uk-position-center" [src]="photo">
63
            </div>
64
            <div class="uk-margin-left">
65
              <button (click)="remove()" class="uk-button-secondary outlined uk-icon-button">
66
                <icon name="remove"></icon>
67
              </button>
68
            </div>
69
            <div class="uk-margin-small-left">
70
              <button class="uk-button-secondary uk-icon-button" (click)="file.click()">
71
                <icon name="edit"></icon>
72
              </button>
73
            </div>
74
          </div>
75
        </div>
76
        <div *ngIf="uploadError" class="uk-text-danger uk-width-1-1">{{uploadError}}</div>
77
        <div dashboard-input class="uk-width-1-3@m" [formInput]="stakeholderFb.get('visibility')"
78
             [placeholder]="'Select a status'"
79
             label="Status" hint="Select the visibility status of your profile"
80
             [options]="stakeholderUtils.statuses" type="select">
81
        </div>
82
        <div dashboard-input class="uk-width-1-3@m" [formInput]="stakeholderFb.get('type')"
83
             [placeholder]="'Select a type'" hint="Select the type of your profile"
84
             label="Type" [options]="types" type="select">
85
        </div>
86
        <ng-container
87
            *ngIf="!stakeholderFb.get('isDefault').value && isNew && stakeholderFb.get('type').valid && defaultStakeholdersOptions">
88
          <div [placeholder]="'Select a template'"
89
               hint="Select a template for your profile"
90
               dashboard-input class="uk-width-1-3@m" [formInput]="stakeholderFb.get('defaultId')"
91
               label="Template" [options]="defaultStakeholdersOptions" type="select"></div>
92
        </ng-container>
93
      </div>
94
    </div>`,
95
  styleUrls: ['edit-stakeholder.component.css']
96
})
97
export class EditStakeholderComponent implements OnDestroy {
98
  @Input()
99
  public maxHeight = 'none';
100
  @Input()
101
  public paddingLarge: boolean = false;
102
  @Input()
103
  public disableAlias: boolean = false;
104
  public stakeholderFb: FormGroup;
105
  public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
106
  public defaultStakeholdersOptions: Option[];
107
  public defaultStakeholders: Stakeholder[];
108
  public stakeholders: Stakeholder[];
109
  public stakeholder: Stakeholder;
110
  public isDefault: boolean;
111
  public isNew: boolean;
112
  public types: Option[];
113
  public properties: EnvProperties = properties;
114
  private subscriptions: any[] = [];
115
  /**
116
   * Photo upload
117
   * */
118
  public file: File;
119
  public photo: string | ArrayBuffer;
120
  public uploadError: string;
121
  public deleteCurrentPhoto: boolean = false;
122
  private maxsize: number = 200 * 1024;
123
  user: User;
124
  
125
  constructor(private fb: FormBuilder,
126
              private stakeholderService: StakeholderService,
127
              private utilsService: UtilitiesService, private userManagementService: UserManagementService,) {
128
  }
129
  
130
  ngOnDestroy() {
131
    this.reset();
132
  }
133
  
134
  public init(stakeholder: Stakeholder, stakeholders: Stakeholder[], defaultStakeholders: Stakeholder[], isDefault: boolean, isNew: boolean) {
135
    this.reset();
136
    this.deleteCurrentPhoto = false;
137
    this.stakeholder = stakeholder;
138
    this.stakeholders = stakeholders;
139
    this.defaultStakeholders = defaultStakeholders;
140
    this.isDefault = isDefault;
141
    this.isNew = isNew;
142
    this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
143
        this.user = user;
144
        this.types = this.stakeholderUtils.getTypesByUserRoles(this.user, this.stakeholder.alias);
145
        this.stakeholderFb = this.fb.group({
146
          _id: this.fb.control(this.stakeholder._id),
147
          defaultId: this.fb.control(this.stakeholder.defaultId),
148
          name: this.fb.control(this.stakeholder.name, Validators.required),
149
          description: this.fb.control(this.stakeholder.description),
150
          index_name: this.fb.control(this.stakeholder.index_name, Validators.required),
151
          index_id: this.fb.control(this.stakeholder.index_id, Validators.required),
152
          index_shortName: this.fb.control(this.stakeholder.index_shortName, Validators.required),
153
          creationDate: this.fb.control(this.stakeholder.creationDate),
154
          alias: this.fb.control(this.stakeholder.alias,
155
            [
156
              Validators.required,
157
              this.stakeholderUtils.aliasValidator(
158
                (this.isDefault) ?
159
                  this.defaultStakeholders.filter(stakeholder => stakeholder.alias !== this.stakeholder.alias) :
160
                  this.stakeholders.filter(stakeholder => stakeholder.alias !== this.stakeholder.alias)
161
              )]
162
          ),
163
          isDefault: this.fb.control((this.isDefault)),
164
          visibility: this.fb.control(this.stakeholder.visibility, Validators.required),
165
          type: this.fb.control(this.stakeholder.type, Validators.required),
166
          topics: this.fb.control(this.stakeholder.topics),
167
          managers: this.fb.control(this.stakeholder.managers),
168
          isUpload: this.fb.control(this.stakeholder.isUpload),
169
          logoUrl: this.fb.control(this.stakeholder.logoUrl),
170
        });
171
        this.initPhoto();
172
        if (!isDefault) {
173
          this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => {
174
            this.onTypeChange(value, defaultStakeholders);
175
          }));
176
          this.stakeholderFb.setControl('defaultId', this.fb.control(stakeholder.defaultId, Validators.required));
177
        }
178
        if (!isNew) {
179
          if (this.isAdmin) {
180
            if (this.disableAlias) {
181
              setTimeout(() => {
182
                this.stakeholderFb.get('alias').disable();
183
              }, 0);
184
            }
185
          } else {
186
            setTimeout(() => {
187
              this.stakeholderFb.get('alias').disable();
188
              this.stakeholderFb.get('index_id').disable();
189
              this.stakeholderFb.get('index_name').disable();
190
              this.stakeholderFb.get('index_shortName').disable();
191
            }, 0);
192
          }
193
          setTimeout(() => {
194
            this.stakeholderFb.get('type').disable();
195
          }, 0);
196
        } else {
197
          setTimeout(() => {
198
            this.stakeholderFb.get('type').enable();
199
          }, 0);
200
        }
201
      }
202
    ));
203
  }
204
  
205
  public get isAdmin() {
206
    return Session.isPortalAdministrator(this.user);
207
  }
208
  
209
  public get disabled(): boolean {
210
    return (this.stakeholderFb && this.stakeholderFb.invalid) ||
211
      (this.stakeholderFb && this.stakeholderFb.pristine && !this.isNew && !this.file) ||
212
      (this.uploadError && this.uploadError.length > 0);
213
  }
214
  
215
  public get dirty(): boolean {
216
    return this.stakeholderFb && this.stakeholderFb.dirty;
217
  }
218
  
219
  reset() {
220
    this.uploadError = null;
221
    this.stakeholderFb = null;
222
    this.subscriptions.forEach(subscription => {
223
      if (subscription instanceof Subscription) {
224
        subscription.unsubscribe();
225
      }
226
    });
227
  }
228
  
229
  onTypeChange(value, defaultStakeholders: Stakeholder[]) {
230
    this.stakeholderFb.setControl('defaultId', this.fb.control(this.stakeholder.defaultId, Validators.required));
231
    this.defaultStakeholdersOptions = [{
232
      label: 'New blank profile',
233
      value: '-1'
234
    }];
235
    defaultStakeholders.filter(stakeholder => stakeholder.type === value).forEach(stakeholder => {
236
      this.defaultStakeholdersOptions.push({
237
        label: 'Use ' + stakeholder.name + ' profile',
238
        value: stakeholder._id
239
      })
240
    });
241
  }
242
  
243
  public save(callback: Function, errorCallback: Function = null) {
244
    if (this.file) {
245
      this.utilsService.uploadPhoto(this.properties.utilsService + "/upload/stakeholder/" + encodeURIComponent(this.stakeholderFb.value.alias), this.file).subscribe(res => {
246
        this.deletePhoto();
247
        this.removePhoto();
248
        this.stakeholderFb.get('logoUrl').setValue(res.filename);
249
        this.saveStakeholder(callback, errorCallback);
250
      }, error => {
251
        this.uploadError = "An error has been occurred during upload your image. Try again later";
252
        this.saveStakeholder(callback, errorCallback);
253
      });
254
    } else if (this.deleteCurrentPhoto) {
255
      this.deletePhoto();
256
      this.saveStakeholder(callback, errorCallback);
257
    } else {
258
      this.saveStakeholder(callback, errorCallback);
259
    }
260
  }
261
  
262
  public saveStakeholder(callback: Function, errorCallback: Function = null) {
263
    if (this.isNew) {
264
      if (!this.stakeholderFb.value.isDefault) {
265
        let stakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.value.defaultId);
266
        this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.value,
267
          (stakeholder ? stakeholder.topics : [])));
268
      }
269
      this.removePhoto();
270
      this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL,
271
        this.stakeholderFb.value).subscribe(stakeholder => {
272
        UIkit.notification(stakeholder.name + '\'s has been successfully created', {
273
          status: 'success',
274
          timeout: 3000,
275
          pos: 'top-left'
276
        });
277
        callback(stakeholder);
278
      }, error => {
279
        UIkit.notification('An error has occurred. Please try again later', {
280
          status: 'danger',
281
          timeout: 3000,
282
          pos: 'top-left'
283
        });
284
        if (errorCallback) {
285
          errorCallback(error)
286
        }
287
      });
288
    } else {
289
      this.stakeholderFb.get('type').enable();
290
      this.stakeholderFb.get('alias').enable();
291
      this.stakeholderFb.get('index_id').enable();
292
      this.stakeholderFb.get('index_name').enable();
293
      this.stakeholderFb.get('index_shortName').enable();
294
      this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.value).subscribe(stakeholder => {
295
        UIkit.notification(stakeholder.name + '\'s has been successfully saved', {
296
          status: 'success',
297
          timeout: 3000,
298
          pos: 'top-left'
299
        });
300
        callback(stakeholder);
301
      }, error => {
302
        UIkit.notification('An error has occurred. Please try again later', {
303
          status: 'danger',
304
          timeout: 3000,
305
          pos: 'top-left'
306
        });
307
      });
308
    }
309
  }
310
  
311
  fileChangeEvent(event) {
312
    if (event.target.files && event.target.files[0]) {
313
      this.file = event.target.files[0];
314
      if (this.file.type !== 'image/png' && this.file.type !== 'image/jpeg') {
315
        this.uploadError = 'You must choose a file with type: image/png or image/jpeg!';
316
        this.stakeholderFb.get('isUpload').setValue(false);
317
        this.stakeholderFb.get('isUpload').markAsDirty();
318
        this.removePhoto();
319
      } else if (this.file.size > this.maxsize) {
320
        this.uploadError = 'File exceeds size\'s limit! Maximum resolution is 256x256 pixels.';
321
        this.stakeholderFb.get('isUpload').setValue(false);
322
        this.stakeholderFb.get('isUpload').markAsDirty();
323
        this.removePhoto();
324
      } else {
325
        this.uploadError = null;
326
        const reader = new FileReader();
327
        reader.readAsDataURL(this.file);
328
        reader.onload = () => {
329
          this.photo = reader.result;
330
          this.stakeholderFb.get('isUpload').setValue(true);
331
          this.stakeholderFb.get('isUpload').markAsDirty();
332
        };
333
      }
334
    }
335
  }
336
  
337
  initPhoto() {
338
    if (this.stakeholderFb.value.isUpload) {
339
      this.photo = this.properties.utilsService + "/download/" + this.stakeholderFb.get('logoUrl').value;
340
    }
341
  }
342
  
343
  removePhoto() {
344
    if (this.file) {
345
      if (typeof document != 'undefined') {
346
        (<HTMLInputElement>document.getElementById("photo")).value = "";
347
      }
348
      this.initPhoto();
349
      this.file = null;
350
    }
351
  }
352
  
353
  remove() {
354
    this.stakeholderFb.get('isUpload').setValue(false);
355
    this.stakeholderFb.get('isUpload').markAsDirty();
356
    this.removePhoto();
357
    this.stakeholderFb.setControl('logoUrl', this.fb.control(null));
358
    if (this.stakeholder.isUpload) {
359
      this.deleteCurrentPhoto = true;
360
    }
361
  }
362
  
363
  public deletePhoto() {
364
    if (this.stakeholder.logoUrl) {
365
      this.utilsService.deletePhoto(this.properties.utilsService + '/delete/stakeholder/' + this.stakeholder.logoUrl).subscribe();
366
    }
367
  }
368
}
(2-2/3)