import {Component, Input, OnDestroy, ViewChild} from "@angular/core"; import {Stakeholder} from "../../openaireLibrary/monitor/entities/stakeholder"; import {FormBuilder, FormGroup, Validators} from "@angular/forms"; import {StakeholderUtils} from "../../utils/indicator-utils"; import {Option} from "../../openaireLibrary/sharedComponents/input/input.component"; import {Subscriber, Subscription} from "rxjs"; import {EnvProperties} from "../../openaireLibrary/utils/properties/env-properties"; import {properties} from "../../../environments/environment"; import {StakeholderService} from "../../openaireLibrary/monitor/services/stakeholder.service"; import {UtilitiesService} from "../../openaireLibrary/services/utilities.service"; import {Role, Session, User} from "../../openaireLibrary/login/utils/helper.class"; import {UserManagementService} from "../../openaireLibrary/services/user-management.service"; import {StringUtils} from "../../openaireLibrary/utils/string-utils.class"; import {NotifyFormComponent} from "../../openaireLibrary/notifications/notify-form/notify-form.component"; import {NotificationUtils} from "../../openaireLibrary/notifications/notification-utils"; import {Notification} from "../../openaireLibrary/notifications/notifications"; declare var UIkit; @Component({ selector: 'edit-stakeholder', template: `
OR
{{uploadError}}
`, styleUrls: ['edit-stakeholder.component.css'] }) export class EditStakeholderComponent implements OnDestroy { @Input() public maxHeight = 'none'; @Input() public paddingLarge: boolean = false; @Input() public disableAlias: boolean = false; public stakeholderFb: FormGroup; 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 types: Option[]; 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: FormBuilder, private stakeholderService: StakeholderService, 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; 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), 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(); if (!isDefault) { this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => { this.onTypeChange(value, defaultStakeholders); })); this.stakeholderFb.setControl('defaultId', this.fb.control(stakeholder.defaultId, Validators.required)); } if (!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 { 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 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 canChooseType(): boolean { return !this.stakeholderFb.get('isDefault').value && 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, 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) { if (this.file) { this.stakeholderFb.get('alias').enable(); this.subscriptions.push(this.utilsService.uploadPhoto(this.properties.utilsService + "/upload/" + encodeURIComponent(this.stakeholder.type) + "/" + encodeURIComponent(this.stakeholderFb.value.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) { if (!this.stakeholderFb.value.isDefault) { let stakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.value.defaultId); this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.value, (stakeholder ? stakeholder.topics : []))); } this.removePhoto(); this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL, this.stakeholderFb.value).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); UIkit.notification(stakeholder.name + ' has been successfully created', { status: 'success', timeout: 6000, pos: 'bottom-right' }); callback(stakeholder); }, error => { UIkit.notification('An error has occurred. Please try again later', { status: 'danger', timeout: 6000, pos: 'bottom-right' }); if (errorCallback) { errorCallback(error) } })); } else { this.stakeholderFb.get('alias').enable(); this.stakeholderFb.get('type').enable(); this.stakeholderFb.get('index_id').enable(); this.stakeholderFb.get('index_name').enable(); this.stakeholderFb.get('index_shortName').enable(); this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.value).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); UIkit.notification(stakeholder.name + ' has been successfully saved', { status: 'success', timeout: 6000, pos: 'bottom-right' }); callback(stakeholder); }, error => { UIkit.notification('An error has occurred. Please try again later', { status: 'danger', timeout: 6000, pos: 'bottom-right' }); })); } } 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.value.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()); } } }