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'; import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; import { AvailableProfilesComponent } from '../available-profiles/available-profiles.component'; @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 = null; @Input() formGroup: FormGroup; @Input() dmpId: string; @Input() datasetId: string; @Input() availableProfiles: DatasetProfileModel[]; @Output() formChanged: EventEmitter = new EventEmitter(); readonly separatorKeysCodes: number[] = [ENTER, COMMA]; profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; 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.profilesAutoCompleteConfiguration = { filterFn: this.filterProfiles.bind(this), initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), displayFn: (item) => item['label'], titleFn: (item) => item['label'], subtitleFn: (item) => item['description'], popupItemActionIcon: 'visibility' }; } 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); 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 => { // if (!isNullOrUndefined(x)) { // this.datasetProfileValueChanged(x.id); // } // }); // } } 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); }); } onFormChanged(event) { // this.formChanged.emit(event); } 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.dmpId; 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 = ''; } getProfileId(): string { if (!isNullOrUndefined(this.formGroup.get('profile').value)) { return this.formGroup.get('profile').value.id; } else { return undefined; } } hasProfileId(): boolean { return !isNullOrUndefined(this.getProfileId()); } filterProfiles(value: string): Observable { const request = new DataTableRequest(null, null, { fields: ['+label'] }); const criteria = new DatasetProfileCriteria(); criteria.like = value; request.criteria = criteria; return this.dmpService.searchDMPProfiles(request); } allAvailableProfiles(event: MouseEvent) { event.stopPropagation(); const dialogRef = this.dialog.open(AvailableProfilesComponent, { data: { profiles: this.formGroup.get('profiles') } }); return false; } public compareWith(object1: any, object2: any) { return object1 && object2 && object1.id === object2.id; } }