import { BaseComponent } from '@common/base/base.component'; import { OnInit, Component, Input, Output, EventEmitter } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; import { MatDialog, MatSnackBar, MatChipInputEvent } from '@angular/material'; import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; import { ActivatedRoute, Router } from '@angular/router'; import { DmpService } from '@app/core/services/dmp/dmp.service'; import { ExternalSourcesConfigurationService } from '@app/core/services/external-sources/external-sources-configuration.service'; import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service'; import { FormService } from '@common/forms/form-service'; import { LockService } from '@app/core/services/lock/lock.service'; import { AuthService } from '@app/core/services/auth/auth.service'; import { DatasetStatus } from '@app/core/common/enum/dataset-status'; import { FormGroup, FormControl, FormArray } from '@angular/forms'; import { DatasetDescriptionFormEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model'; import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; import { LockModel } from '@app/core/model/lock/lock.model'; import { takeUntil, map, catchError } from 'rxjs/operators'; import { RequestItem } from '@app/core/query/request-item'; import { isNullOrUndefined } from 'util'; import { interval, Observable, of as observableOf } from 'rxjs'; import { Guid } from '@common/types/guid'; import { Location } from '@angular/common'; import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; import { DmpListingModel } from '@app/core/model/dmp/dmp-listing'; import { DatasetWizardEditorModel, ExternalTagEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model'; import { ENTER, COMMA } from '@angular/cdk/keycodes'; import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants'; import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'; @Component({ selector: 'dataset-editor-details', templateUrl: './dataset-editor-details.component.html', styleUrls: ['./dataset-editor-details.component.scss'] }) export class DatasetEditorDetailsComponent extends BaseComponent implements OnInit { viewOnly = false; editMode = false; // publicMode = false; // DatasetStatus = DatasetStatus; // dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration; datasetWizardModel: DatasetWizardEditorModel; // isNew = true; // isCopy = false; // formGroup: FormGroup = null; datasetProfileDefinitionModel: DatasetDescriptionFormEditorModel; availableProfiles: DatasetProfileModel[] = []; // itemId: string; // publicId: string; // profileUpdateId: string; // downloadDocumentId: string; // isLinear = false; lock: LockModel; lockStatus: Boolean; dmpText: string; @Input() formGroup: FormGroup; @Input() dmpId: string; @Input() datasetId: string; @Input() isNewDataset: boolean; @Output() formChanged: EventEmitter = new EventEmitter(); readonly separatorKeysCodes: number[] = [ENTER, COMMA]; constructor( private datasetWizardService: DatasetWizardService, private route: ActivatedRoute, public snackBar: MatSnackBar, public router: Router, private language: TranslateService, private configurationService: ConfigurationService, private externalSourcesService: ExternalSourcesService, private dialog: MatDialog, public dmpService: DmpService, public externalSourcesConfigurationService: ExternalSourcesConfigurationService, private uiNotificationService: UiNotificationService, private formService: FormService, private lockService: LockService, private location: Location, private authService: AuthService, private guidedTourService: GuidedTourService ) { super(); } ngOnInit() { if (this.formGroup.get('status').value === 1) { this.formGroup.disable(); } this.datasetWizardModel = new DatasetWizardEditorModel(); this.registerFormListeners(); if (this.datasetId) { this.datasetWizardService.getSingle(this.datasetId) .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.lockService.checkLockStatus(data.id).pipe(takeUntil(this._destroyed)).subscribe(lockStatus => { this.lockStatus = lockStatus; this.datasetWizardModel = new DatasetWizardEditorModel().fromModel(data); this.needsUpdate(); this.formGroup = this.datasetWizardModel.buildForm(); this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft; if (this.datasetWizardModel.status === DatasetStatus.Finalized || lockStatus) { this.formGroup.disable(); this.viewOnly = true; } if (!lockStatus && !isNullOrUndefined(this.authService.current())) { this.lock = new LockModel(data.id, this.authService.current()); this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => { this.lock.id = Guid.parse(result); interval(this.configurationService.lockInterval).pipe(takeUntil(this._destroyed)).subscribe(() => this.pumpLock()); }); } // if (this.viewOnly) { this.formGroup.disable(); } // For future use, to make Dataset edit like DMP. this.loadDatasetProfiles(); this.registerFormListeners(); // this.availableProfiles = this.datasetWizardModel.dmp.profiles; this.onChanges(); this.formChanged.emit(this.formGroup); }) }, error => { switch (error.status) { case 403: this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-WIZARD.MESSAGES.DATASET-NOT-ALLOWED'), SnackBarNotificationLevel.Error); break; case 404: this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-WIZARD.MESSAGES.DATASET-NOT-FOUND'), SnackBarNotificationLevel.Error); break; default: this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.ERRORS.HTTP-REQUEST-ERROR'), SnackBarNotificationLevel.Error); } this.router.navigate(['/datasets/']); return observableOf(null); }); } } public dashboardTourDmp: GuidedTour = { tourId: 'only-dmp-tour', useOrb: true, steps: [ { title: this.dmpText, content: 'Step 1', orientation: Orientation.Bottom, highlightPadding: 3, isStepUnique: true, customTopOffset: 8 } ] }; getDmpText(): string { return this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' + this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' + this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' + this.language.instant('DMP-LISTING.GET-IDEA'); } setDashboardTourDmp(label: string): void { this.dashboardTourDmp.steps[0].title = this.getDmpText(); this.dashboardTourDmp.steps[0].selector = '.dmp-tour-' + label; } public restartTour(label: string): void { this.setDashboardTourDmp(label); console.log(this.dashboardTourDmp.steps[0].selector); this.guidedTourService.startTour(this.dashboardTourDmp); } registerFormListeners() { this.formGroup.get('dmp').valueChanges .pipe(takeUntil(this._destroyed)) .subscribe(x => { this.dmpValueChanged(x); }); if (this.isNewDataset) { this.formGroup.get('profile').valueChanges .pipe(takeUntil(this._destroyed)) .subscribe(x => { this.datasetProfileValueChanged(x); }); } } dmpValueChanged(dmp: DmpListingModel) { if (dmp) { this.formGroup.get('profile').enable(); this.loadDatasetProfiles(); } else { this.availableProfiles = []; this.formGroup.get('profile').reset(); this.formGroup.get('profile').disable(); this.formGroup.removeControl('datasetProfileDefinition'); } } datasetProfileValueChanged(profileId: string) { if (profileId && profileId.length > 0) { this.formGroup.removeControl('datasetProfileDefinition'); this.getDefinition(profileId); } } onChanges(): void { this.formGroup.valueChanges .pipe(takeUntil(this._destroyed)) .subscribe(val => { this.formChanged.emit(val); }); } getDefinition(profileId: string) { // if (this.formGroup.invalid) { setTimeout(() => this.stepper.selectedIndex = 0); return; } this.datasetWizardService.getDefinition(profileId) .pipe(takeUntil(this._destroyed)) .subscribe(item => { this.datasetWizardModel.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item); this.datasetProfileDefinitionModel = this.datasetWizardModel.datasetProfileDefinition; this.formGroup.addControl('datasetProfileDefinition', this.datasetProfileDefinitionModel.buildForm()); }); } loadDatasetProfiles() { const datasetProfileRequestItem: RequestItem = new RequestItem(); datasetProfileRequestItem.criteria = new DatasetProfileCriteria(); datasetProfileRequestItem.criteria.id = this.formGroup.get('dmp').value.id; if (datasetProfileRequestItem.criteria.id) { this.datasetWizardService.getAvailableProfiles(datasetProfileRequestItem) .pipe(takeUntil(this._destroyed)) .subscribe(items => { this.availableProfiles = items; }); } } needsUpdate() { if (this.datasetWizardModel.isProfileLatestVersion || (this.datasetWizardModel.status === DatasetStatus.Finalized) || (this.datasetWizardModel.isProfileLatestVersion == undefined && this.datasetWizardModel.status == undefined)) { return false; } else { return true; } } private pumpLock() { this.lock.touchedAt = new Date(); this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => { if (!isNullOrUndefined(result)) { this.lock.id = Guid.parse(result); } else { this.location.back(); } }); } removeTag(tag: any) { (this.formGroup.get('tags')).removeAt(((this.formGroup.get('tags')).value as any[]).indexOf(tag)); } addTag(ev: MatChipInputEvent) { if (ev.value !== '' && isNullOrUndefined(((this.formGroup.get('tags')).value as ExternalTagEditorModel[]).find(tag => tag.name === ev.value))) { (this.formGroup.get('tags')).push(new ExternalTagEditorModel('', ev.value).buildForm()); } ev.input.value = ''; } }