import {Component, Input, OnDestroy, ViewChild} from "@angular/core"; import {Stakeholder} from "../../../monitor/entities/stakeholder"; import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms"; import {StakeholderUtils} from "../../utils/indicator-utils"; import {Option} from "../../../sharedComponents/input/input.component"; import {Subscription} from "rxjs"; import {EnvProperties} from "../../../utils/properties/env-properties"; import {properties} from "src/environments/environment"; import {StakeholderService} from "../../../monitor/services/stakeholder.service"; import {UtilitiesService} from "../../../services/utilities.service"; import {Role, Session, User} from "../../../login/utils/helper.class"; import {UserManagementService} from "../../../services/user-management.service"; import {StringUtils} from "../../../utils/string-utils.class"; import {NotifyFormComponent} from "../../../notifications/notify-form/notify-form.component"; import {NotificationUtils} from "../../../notifications/notification-utils"; import {Notification} from "../../../notifications/notifications"; import {NotificationHandler} from "../../../utils/notification-handler"; import {StatsProfilesService} from "../../utils/services/stats-profiles.service"; @Component({ selector: 'edit-stakeholder', template: `
OR
{{uploadError}}
`, styleUrls: ['edit-stakeholder.component.less'] }) export class EditStakeholderComponent implements OnDestroy { @Input() public disableAlias: boolean = false; public stakeholderFb: UntypedFormGroup; public secure: boolean = false; public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); public defaultStakeholdersOptions: Option[]; public defaultStakeholders: Stakeholder[]; public alias: string[]; public stakeholder: Stakeholder; public isDefault: boolean; public isNew: boolean; public loading: boolean = false; public types: Option[]; public statsProfiles: string[]; public properties: EnvProperties = properties; private subscriptions: any[] = []; /** * Photo upload * */ public file: File; public photo: string | ArrayBuffer; public uploadError: string; public deleteCurrentPhoto: boolean = false; private maxsize: number = 200 * 1024; user: User; @ViewChild('notify', {static: true}) notify: NotifyFormComponent; private notification: Notification; constructor(private fb: UntypedFormBuilder, private stakeholderService: StakeholderService, private statsProfileService: StatsProfilesService, private utilsService: UtilitiesService, private userManagementService: UserManagementService,) { } ngOnDestroy() { this.reset(); } public init(stakeholder: Stakeholder, alias: string[], defaultStakeholders: Stakeholder[], isDefault: boolean, isNew: boolean) { this.reset(); this.deleteCurrentPhoto = false; this.stakeholder = stakeholder; this.alias = alias; this.defaultStakeholders = defaultStakeholders; this.isDefault = isDefault; this.isNew = isNew; this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { this.user = user; if (this.isCurator) { this.subscriptions.push(this.statsProfileService.getStatsProfiles().subscribe(statsProfiles => { this.statsProfiles = statsProfiles; }, error => { this.statsProfiles = []; })); } else { this.statsProfiles = []; } this.types = this.stakeholderUtils.getTypesByUserRoles(this.user, this.stakeholder.alias); this.stakeholderFb = this.fb.group({ _id: this.fb.control(this.stakeholder._id), defaultId: this.fb.control(this.stakeholder.defaultId), name: this.fb.control(this.stakeholder.name, Validators.required), description: this.fb.control(this.stakeholder.description), index_name: this.fb.control(this.stakeholder.index_name, Validators.required), index_id: this.fb.control(this.stakeholder.index_id, Validators.required), index_shortName: this.fb.control(this.stakeholder.index_shortName, Validators.required), statsProfile: this.fb.control(this.stakeholder.statsProfile, Validators.required), locale: this.fb.control(this.stakeholder.locale, Validators.required), projectUpdateDate: this.fb.control(this.stakeholder.projectUpdateDate), creationDate: this.fb.control(this.stakeholder.creationDate), alias: this.fb.control(this.stakeholder.alias, [ Validators.required, this.stakeholderUtils.aliasValidatorString( this.alias.filter(alias => alias !== this.stakeholder.alias) )] ), isDefault: this.fb.control((this.isDefault)), visibility: this.fb.control(this.stakeholder.visibility, Validators.required), type: this.fb.control(this.stakeholder.type, Validators.required), topics: this.fb.control(this.stakeholder.topics), isUpload: this.fb.control(this.stakeholder.isUpload), logoUrl: this.fb.control(this.stakeholder.logoUrl), }); if (this.stakeholder.isUpload) { this.stakeholderFb.get('logoUrl').clearValidators(); this.stakeholderFb.get('logoUrl').updateValueAndValidity(); } else { this.stakeholderFb.get('logoUrl').setValidators([StringUtils.urlValidator()]); this.stakeholderFb.get('logoUrl').updateValueAndValidity(); } this.subscriptions.push(this.stakeholderFb.get('isUpload').valueChanges.subscribe(value => { if (value == true) { this.stakeholderFb.get('logoUrl').clearValidators(); this.stakeholderFb.updateValueAndValidity(); } else { this.stakeholderFb.get('logoUrl').setValidators([StringUtils.urlValidator()]); this.stakeholderFb.updateValueAndValidity(); } })); this.secure = (!this.stakeholderFb.get('logoUrl').value || this.stakeholderFb.get('logoUrl').value.includes('https://')); this.subscriptions.push(this.stakeholderFb.get('logoUrl').valueChanges.subscribe(value => { this.secure = (!value || value.includes('https://')); })); this.initPhoto(); this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => { this.onTypeChange(value, defaultStakeholders); })); this.stakeholderFb.setControl('defaultId', this.fb.control(stakeholder.defaultId, (this.isDefault && !this.isNew)?[]:Validators.required)); if (!this.isNew) { this.notification = NotificationUtils.editStakeholder(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); this.notify.reset(this.notification.message); if (this.isAdmin) { if (this.disableAlias) { setTimeout(() => { this.stakeholderFb.get('alias').disable(); }, 0); } } else { if (!this.isCurator) { setTimeout(() => { this.stakeholderFb.get('statsProfile').disable(); }, 0); } setTimeout(() => { this.stakeholderFb.get('alias').disable(); this.stakeholderFb.get('index_id').disable(); this.stakeholderFb.get('index_name').disable(); this.stakeholderFb.get('index_shortName').disable(); }, 0); } setTimeout(() => { this.stakeholderFb.get('type').disable(); }, 0); } else { this.notification = NotificationUtils.createStakeholder(this.user.firstname + ' ' + this.user.lastname); this.notify.reset(this.notification.message); setTimeout(() => { this.stakeholderFb.get('type').enable(); }, 0); } })); } public get isAdmin() { return Session.isPortalAdministrator(this.user); } public get isCurator() { return this.stakeholder && (this.isAdmin || Session.isCurator(this.stakeholder.type, this.user)); } public get disabled(): boolean { return (this.stakeholderFb && this.stakeholderFb.invalid) || (this.stakeholderFb && this.stakeholderFb.pristine && !this.isNew && !this.file) || (this.uploadError && this.uploadError.length > 0); } public get dirty(): boolean { return this.stakeholderFb && this.stakeholderFb.dirty; } public get canChooseTemplate(): boolean { return this.isNew && this.stakeholderFb.get('type').valid && !!this.defaultStakeholdersOptions; } reset() { this.uploadError = null; this.stakeholderFb = null; this.subscriptions.forEach(subscription => { if (subscription instanceof Subscription) { subscription.unsubscribe(); } }); } onTypeChange(value, defaultStakeholders: Stakeholder[]) { this.stakeholderFb.setControl('defaultId', this.fb.control(this.stakeholder.defaultId, (this.isDefault && !this.isNew)?[]:Validators.required)); this.defaultStakeholdersOptions = [{ label: 'New blank profile', value: '-1' }]; defaultStakeholders.filter(stakeholder => stakeholder.type === value).forEach(stakeholder => { this.defaultStakeholdersOptions.push({ label: 'Use ' + stakeholder.name + ' profile', value: stakeholder._id }) }); } public save(callback: Function, errorCallback: Function = null) { this.loading = true; if (this.file) { this.subscriptions.push(this.utilsService.uploadPhoto(this.properties.utilsService + "/upload/" + encodeURIComponent(this.stakeholderFb.getRawValue().type) + "/" + encodeURIComponent(this.stakeholderFb.getRawValue().alias), this.file).subscribe(res => { this.deletePhoto(); this.stakeholderFb.get('logoUrl').setValue(res.filename); this.removePhoto(); this.saveStakeholder(callback, errorCallback); }, error => { this.uploadError = "An error has been occurred during upload your image. Try again later"; this.saveStakeholder(callback, errorCallback); })); } else if (this.deleteCurrentPhoto) { this.deletePhoto(); this.saveStakeholder(callback, errorCallback); } else { this.saveStakeholder(callback, errorCallback); } } public saveStakeholder(callback: Function, errorCallback: Function = null) { if (this.isNew) { let defaultStakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.getRawValue().defaultId); this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.getRawValue(), (defaultStakeholder ? defaultStakeholder.topics : []), this.stakeholderFb.getRawValue().isDefault)); this.removePhoto(); if(this.stakeholderFb.getRawValue().isDefault) { this.stakeholderFb.get('defaultId').setValue(null); } this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL, this.stakeholderFb.getRawValue()).subscribe(stakeholder => { this.notification.entity = stakeholder._id; this.notification.stakeholder = stakeholder.alias; this.notification.stakeholderType = stakeholder.type; this.notification.groups = [Role.curator(stakeholder.type)]; this.notify.sendNotification(this.notification); NotificationHandler.rise(stakeholder.name + ' has been successfully created'); callback(stakeholder); this.loading = false; }, error => { NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); if (errorCallback) { errorCallback(error) } this.loading = false; })); } else { this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.getRawValue()).subscribe(stakeholder => { this.notification.entity = stakeholder._id; this.notification.stakeholder = stakeholder.alias; this.notification.stakeholderType = stakeholder.type; this.notification.groups = [Role.curator(stakeholder.type), Role.manager(stakeholder.type, stakeholder.alias)]; this.notify.sendNotification(this.notification); NotificationHandler.rise(stakeholder.name + ' has been successfully saved'); callback(stakeholder); this.loading = false; }, error => { NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); if (errorCallback) { errorCallback(error) } this.loading = false; })); } } fileChangeEvent(event) { if (event.target.files && event.target.files[0]) { this.file = event.target.files[0]; if (this.file.type !== 'image/png' && this.file.type !== 'image/jpeg') { this.uploadError = 'You must choose a file with type: image/png or image/jpeg!'; this.stakeholderFb.get('isUpload').setValue(false); this.stakeholderFb.get('isUpload').markAsDirty(); this.removePhoto(); } else if (this.file.size > this.maxsize) { this.uploadError = 'File exceeds size\'s limit! Maximum resolution is 256x256 pixels.'; this.stakeholderFb.get('isUpload').setValue(false); this.stakeholderFb.get('isUpload').markAsDirty(); this.removePhoto(); } else { this.uploadError = null; const reader = new FileReader(); reader.readAsDataURL(this.file); reader.onload = () => { this.photo = reader.result; this.stakeholderFb.get('isUpload').setValue(true); this.stakeholderFb.get('isUpload').markAsDirty(); }; } } } initPhoto() { if (this.stakeholderFb.getRawValue().isUpload) { this.photo = this.properties.utilsService + "/download/" + this.stakeholderFb.get('logoUrl').value; } } removePhoto() { if (this.file) { if (typeof document != 'undefined') { (document.getElementById("photo")).value = ""; } this.initPhoto(); this.file = null; } } remove() { this.stakeholderFb.get('isUpload').setValue(false); this.stakeholderFb.get('isUpload').markAsDirty(); this.removePhoto(); this.stakeholderFb.get('logoUrl').setValue(null); if (this.stakeholder.isUpload) { this.deleteCurrentPhoto = true; } } public deletePhoto() { if (this.stakeholder.logoUrl && this.stakeholder.isUpload) { this.subscriptions.push(this.utilsService.deletePhoto(this.properties.utilsService + '/delete/' + encodeURIComponent(this.stakeholder.type) + "/" + encodeURIComponent(this.stakeholder.alias) + "/" + this.stakeholder.logoUrl).subscribe()); } } }