argos/dmp-frontend/src/app/ui/dmp/editor/dataset-editor-details/dataset-editor-details.comp...

271 lines
10 KiB
TypeScript

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;
@Output() formChanged: EventEmitter<any> = 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.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);
});
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(profiledId: string) {
if (profiledId && profiledId.length > 0) {
this.formGroup.removeControl('datasetProfileDefinition');
this.getDefinition();
}
}
onChanges(): void {
this.formGroup.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(val => {
this.formChanged.emit(val);
});
}
getDefinition() {
// if (this.formGroup.invalid) { setTimeout(() => this.stepper.selectedIndex = 0); return; }
this.datasetWizardService.getDefinition(this.formGroup.get('profile').value)
.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<DatasetProfileCriteria> = 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) {
(<FormArray>this.formGroup.get('tags')).removeAt(((<FormArray>this.formGroup.get('tags')).value as any[]).indexOf(tag));
}
addTag(ev: MatChipInputEvent) {
if (ev.value !== '' && isNullOrUndefined(((<FormArray>this.formGroup.get('tags')).value as ExternalTagEditorModel[]).find(tag => tag.name === ev.value))) {
(<FormArray>this.formGroup.get('tags')).push(new ExternalTagEditorModel('', ev.value).buildForm());
}
ev.input.value = '';
}
}