import { BaseErrorModel } from '../../models/error/BaseErrorModel'; import { SnackBarNotificationComponent } from '../../shared/components/notificaiton/snack-bar-notification.component'; import { DatasetProfileCriteria } from '../../models/criteria/dataset-profile/DatasetProfileCriteria'; import { DataManagementPlanModel } from '../../models/data-managemnt-plans/DataManagementPlanModel'; import { JsonSerializer } from '../../utilities/JsonSerializer'; import { DataManagementPlanCriteria } from '../../models/criteria/data-management-plan/DataManagementPlanCriteria'; import { RequestItem } from '../../models/criteria/RequestItem'; import { DatasetService } from '../../services/dataset/dataset.service'; import { ExternalSourcesItemModel } from '../../models/external-sources/ExternalSourcesItemModel'; import { DatasetProfileModel } from '../../models/datasetprofile/DatasetProfileModel'; import { DatasetProfileDefinitionModel } from '../../models/DatasetProfileDefinitionModel'; import { DatasetWizardModel } from '../../models/datasets/DatasetWizardModel'; import { DataManagementPlanService } from '../../services/data-management-plan/data-management-plan.service'; import { ExternalSourcesService } from '../../services/external-sources/external-sources.service'; import { DatasetWizardService } from '../../services/dataset-wizard/dataset-wizard.service'; import { TranslateService } from '@ngx-translate/core'; import { ActivatedRoute, Router, Params } from '@angular/router'; import { Component, ViewChild, OnInit, AfterViewInit, ViewEncapsulation, TemplateRef, ChangeDetectionStrategy } from "@angular/core"; import { FormGroup, Validators, FormBuilder, FormArray } from "@angular/forms"; import * as FileSaver from 'file-saver'; import { MatPaginator, MatSort, MatSnackBar, MatStepper, MatDialog } from "@angular/material"; import { ExternalDatasetCriteria } from '../../models/criteria/external-dataset/ExternalDatasetCriteria'; import { ExternalDatasetModel } from '../../models/external-dataset/ExternalDatasetModel'; import { RegistryCriteria } from '../../models/criteria/registry/RegistryCriteria'; import { RegisterModel } from '../../models/registers/RegisterModel'; import { DataRepositoryCriteria } from '../../models/criteria/data-repository/DataRepositoryCriteria'; import { ServicesCriteria } from '../../models/criteria/services/ServicesCriteria'; import { ServiceModel } from '../../models/services/ServiceModel'; import { DataRepositoryModel } from '../../models/dataRepositories/DataRepositoryModel'; import { ExternalSourcesConfigurationService } from '../../services/external-sources/external-sources-configuration.service'; import { ExternalSourcesConfiguration } from '../../models/external-sources/ExternalSourcesConfiguration'; import { IBreadCrumbComponent } from '../../shared/components/breadcrumb/definition/IBreadCrumbComponent'; import { Observable } from 'rxjs/Observable'; import { BreadcrumbItem } from '../../shared/components/breadcrumb/definition/breadcrumb-item'; import { TagsCriteria } from '../../models/criteria/tags/TagsCriteria'; import { TagModel } from '../../models/tags/TagModel'; import { AutoCompleteConfiguration } from '../../shared/components/auto-complete/AutoCompleteConfiguration'; import { SingleAutoCompleteConfiguration } from '../../shared/components/autocompletes/single/single-auto-complete-configuration'; import { DataManagementPlanListingModel } from '../../models/data-managemnt-plans/DataManagementPlanListingModel'; import { DataRepositoryReferencedModelHelperComponent } from '../dataset-referenced-models-helper/datarepository/datarepository-referenced-model-helper.component'; import { RegistryReferencedModelHelperComponent } from '../dataset-referenced-models-helper/registry/registry-referenced-model-helper.component'; import { ExternalDatasetReferencedModelHelperComponent } from '../dataset-referenced-models-helper/externalDataset/externaldataset-referenced-model-helper.component'; import { ServicesReferencedModelHelperComponent } from '../dataset-referenced-models-helper/services/services-referenced-model-helper.component'; @Component({ selector: 'app-dataset-wizard-component', templateUrl: 'dataset-wizard.component.html', styleUrls: ['./dataset-wizard.component.scss'], encapsulation: ViewEncapsulation.None, }) export class DatasetWizardComponent implements OnInit, IBreadCrumbComponent { breadCrumbs: Observable; viewOnly = false; @ViewChild('stepper') stepper: MatStepper; //autocomplete Display Functions; externalDatasetDisplayFunc = (item) => item ? item.label : null; registriesDisplayFunc = (item) => item ? item.label : null; dataRepositoryDisplayFunc = (item) => item ? item.name : null; servicesDisplayFunc = (item) => item ? item.label : null; tagsDisplayFunc = (item) => item ? item.name : null; //autocomplete Display Functions; externalDatasetDisplaySubtitleFunc = (item) => item ? item.tag : null; registriesDisplaySubtitleFunc = (item) => item ? item.tag : null; dataRepositoryDisplaySubtitleFunc = (item) => item ? item.tag : null; servicesDisplaySubtitleFunc = (item) => item ? item.tag : null; tagsDisplaySubtitleFunc = (item) => item ? item.tag : null; //autocomplete Configurations; externalDatasetAutoCompleteConfiguration: AutoCompleteConfiguration; registriesAutoCompleteConfiguration: AutoCompleteConfiguration; dataRepositoriesAutoCompleteConfiguration: AutoCompleteConfiguration; servicesAutoCompleteConfiguration: AutoCompleteConfiguration; tagsAutoCompleteConfiguration: AutoCompleteConfiguration; dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration; externalSourcesConfiguration: ExternalSourcesConfiguration; datasetWizardModel: DatasetWizardModel; isNew = true; formGroup: FormGroup; datasetProfileDefinitionModel: DatasetProfileDefinitionModel; availableProfiles: DatasetProfileModel[] = []; itemId: string constructor( private datasetWizardService: DatasetWizardService, private formBuilder: FormBuilder, private datasetService: DatasetService, private route: ActivatedRoute, public snackBar: MatSnackBar, public router: Router, public language: TranslateService, public externalSourcesService: ExternalSourcesService, public dataManagementPlanService: DataManagementPlanService, public dialog: MatDialog, public externalSourcesConfigurationService: ExternalSourcesConfigurationService ) { } isLinear = false; firstStepFormGroup: FormGroup; secondFormGroup: FormGroup; ngOnInit() { this.route .data .subscribe(v => this.viewOnly = v["public"]); let dmpRequestItem: RequestItem = new RequestItem(); dmpRequestItem.criteria = new DataManagementPlanCriteria(); let externalDatasetRequestItem: RequestItem = new RequestItem(); externalDatasetRequestItem.criteria = new ExternalDatasetCriteria(); this.externalDatasetAutoCompleteConfiguration = new AutoCompleteConfiguration(this.externalSourcesService.searchDatasetSExternalDatasetservice.bind(this.externalSourcesService), externalDatasetRequestItem) let registriesRequestItem: RequestItem = new RequestItem(); registriesRequestItem.criteria = new RegistryCriteria(); this.registriesAutoCompleteConfiguration = new AutoCompleteConfiguration(this.externalSourcesService.searchDatasetRegistry.bind(this.externalSourcesService), registriesRequestItem) let dataRepositoriesRequestItem: RequestItem = new RequestItem(); dataRepositoriesRequestItem.criteria = new DataRepositoryCriteria(); this.dataRepositoriesAutoCompleteConfiguration = new AutoCompleteConfiguration(this.externalSourcesService.searchDatasetRepository.bind(this.externalSourcesService), dataRepositoriesRequestItem) let servicesRequestItem: RequestItem = new RequestItem(); servicesRequestItem.criteria = new ServicesCriteria(); this.servicesAutoCompleteConfiguration = new AutoCompleteConfiguration(this.externalSourcesService.searchDatasetService.bind(this.externalSourcesService), servicesRequestItem) let tagsRequestItem: RequestItem = new RequestItem(); tagsRequestItem.criteria = new TagsCriteria(); this.tagsAutoCompleteConfiguration = new AutoCompleteConfiguration(this.externalSourcesService.searchDatasetTags.bind(this.externalSourcesService), tagsRequestItem) this.externalSourcesConfigurationService.getExternalSourcesConfiguration().subscribe(result => { this.externalSourcesConfiguration = result; this.externalSourcesConfiguration.dataRepositories.push({ key: '', label: "All" }) this.externalSourcesConfiguration.externalDatasets.push({ key: '', label: "All" }) this.externalSourcesConfiguration.registries.push({ key: '', label: "All" }) this.externalSourcesConfiguration.services.push({ key: '', label: "All" }) this.externalSourcesConfiguration.tags.push({ key: '', label: "All" }) }) this.dmpAutoCompleteConfiguration = { filterFn: this.searchDmp.bind(this), items: this.searchDmp(''), displayFn: (item) => item["label"], titleFn: (item) => item["label"], //mapFn: (item) => new JsonSerializer().fromJSONArray(item, ProjectReference).map(item => item.toDropdownList()), loadDataOnStart: true }; this.route.params.subscribe((params: Params) => { this.itemId = params['id']; const dmpId = params['dmpId']; if (this.itemId != null) { this.isNew = false; this.datasetWizardService.getSingle(this.itemId).map(data => data as DatasetWizardModel) .subscribe(data => { this.datasetWizardModel = JsonSerializer.fromJSONObject(data, DatasetWizardModel); this.breadCrumbs = Observable.of([ { parentComponentName: null, label: "Datasets", url: "/datasets", notFoundResolver: [ { parentComponentName: null, label: this.datasetWizardModel.dmp.project.label, url: "/projects/edit/" + this.datasetWizardModel.dmp.project.id }, { parentComponentName: null, label: this.datasetWizardModel.dmp.label, url: "/dmps/edit/" + this.datasetWizardModel.dmp.id, }, ] }]) this.formGroup = this.datasetWizardModel.buildForm(); if (this.datasetWizardModel.status == 1) { this.formGroup.disable() this.viewOnly = true; } if (this.viewOnly) this.formGroup.disable(); this.loadDatasetProfiles(); }); } else if (dmpId != null) { this.isNew = true; this.dataManagementPlanService.getSingle(dmpId).map(data => data as DataManagementPlanModel) .subscribe(data => { this.datasetWizardModel = new DatasetWizardModel(); setTimeout(() => { this.datasetWizardModel.dmp = data; this.formGroup = this.datasetWizardModel.buildForm(); if (this.datasetWizardModel.status == 1) { this.formGroup.disable() this.viewOnly = true; } this.loadDatasetProfiles(); this.breadCrumbs = Observable.of([ { parentComponentName: null, label: "Datasets", url: "/datasets", notFoundResolver: [ { parentComponentName: null, label: this.datasetWizardModel.dmp.project.label, url: "/projects/edit/" + this.datasetWizardModel.dmp.project.id }, { parentComponentName: null, label: this.datasetWizardModel.dmp.label, url: "/dmps/edit/" + this.datasetWizardModel.dmp.id, }] }]) }); }); } else { this.datasetWizardModel = new DatasetWizardModel(); this.formGroup = this.datasetWizardModel.buildForm() if (this.datasetWizardModel.status == 1) { this.formGroup.disable() this.viewOnly = true; } if (this.viewOnly) this.formGroup.disable(); this.formGroup.get('dmp').valueChanges.subscribe(x => { this.loadDatasetProfiles(); }) } }); } ngAfterViewInit() { this.route.params.subscribe((params: Params) => { let itemId = params['id']; if (itemId != null) this.stepper.selectedIndex = 2; }) } searchDmp(query: string): Observable { let dmpRequestItem: RequestItem = new RequestItem(); dmpRequestItem.criteria = new DataManagementPlanCriteria(); dmpRequestItem.criteria.like = query; return this.dataManagementPlanService.get(dmpRequestItem); } loadDatasetProfiles() { let 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).subscribe(items => { this.availableProfiles = JsonSerializer.fromJSONArray(items, DatasetProfileModel); }); } public cancel(): void { //this.router.navigate(['/dataManagementPlans']); } getDefinition() { if (this.isNew) { this.datasetWizardService.getDefinition(this.formGroup.get("profile").get("id").value).subscribe(item => { this.datasetWizardModel.datasetProfileDefinition = JsonSerializer.fromJSONObject(item, DatasetProfileDefinitionModel); this.datasetProfileDefinitionModel = this.datasetWizardModel.datasetProfileDefinition; this.formGroup.addControl("datasetProfileDefinition", this.datasetProfileDefinitionModel.buildForm()) }) } } formSubmit(): void { if (!this.isFormValid()) { return; } this.onSubmit(); } public isFormValid() { return this.formGroup.valid; } onSubmit(): void { this.datasetWizardService.createDataset(this.formGroup.value).subscribe( complete => { this.datasetWizardService.getSingle(complete.id).subscribe( result => { this.datasetWizardModel = JsonSerializer.fromJSONObject(result, DatasetWizardModel); } ) this.onCallbackSuccess() }, error => this.onCallbackError(error) ); } submit() { this.datasetWizardService.createDataset(this.formGroup.value).subscribe(data => { this.router.navigateByUrl("/datasets/dmp/" + this.formGroup.get("dmp").value.id); }); } save() { if (!this.isFormValid()) { return; } this.formGroup.get("status").setValue("0"); this.submit(); } saveFinalize() { if (!this.isFormValid()) { return; } this.formGroup.get("status").setValue("1"); this.submit(); } onCallbackSuccess(): void { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language }, duration: 3000, }) } onCallbackError(error: any) { this.setErrorModel(error.error); } public setErrorModel(errorModel: BaseErrorModel) { Object.keys(errorModel).forEach(item => { (this.datasetWizardModel.errorModel)[item] = (errorModel)[item]; }) } downloadPDF(): void { this.datasetWizardService.downloadPDF(this.itemId).subscribe(response => { const blob = new Blob([response.body], { type: 'application/pdf' }) const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename) }) } downloadXML(): void { this.datasetWizardService.downloadXML(this.itemId).subscribe(response => { const blob = new Blob([response.body], { type: 'application/xml' }) const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename) }) } getFilenameFromContentDispositionHeader(header: string): string { const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g); const matches = header.match(regex); let filename: string; for (let i = 0; i < matches.length; i++) { const match = matches[i]; if (match.includes('filename="')) { filename = match.substring(10, match.length - 1); break; } else if (match.includes('filename=')) { filename = match.substring(9); break; } } return filename; } public redirectToProject() { this.router.navigate(["projects/edit/" + this.datasetWizardModel.dmp.project.id]) } public redirectToDmp() { this.router.navigate(["dmps/edit/" + this.datasetWizardModel.dmp.id]) } externalDatasetsOnItemChange(event) { let externalDatasetModel = new ExternalDatasetModel(event.id, event.abbreviation, event.label, event.reference); (this.formGroup.get("externalDatasets")).push(externalDatasetModel.buildForm()); } registriesOnItemChange(event) { let registryModel = new RegisterModel(event.abbreviation, event.definition, event.id, event.label, event.reference, event.uri); (this.formGroup.get("registries")).push(registryModel.buildForm()); } servicesOnItemChange(event) { let serviceModel = new ServiceModel(event.abbreviation, event.definition, event.id, event.label, event.reference, event.uri); (this.formGroup.get("services")).push(serviceModel.buildForm()); } tagsOnItemChange(event) { let serviceModel = new TagModel(event.id, event.name); (this.formGroup.get("tags")).push(serviceModel.buildForm()); } dataRepositoriesOnItemChange(event) { let dataRepositoryModel = new DataRepositoryModel(event.id, event.name, event.abbreviation, event.uri, event.pid); (this.formGroup.get("dataRepositories")).push(dataRepositoryModel.buildForm()); } addDataRepository() { let dialogRef = this.dialog.open(DataRepositoryReferencedModelHelperComponent, { height: '255px', width: '700px', data: { } }); dialogRef.afterClosed().subscribe(result => { if (!result) return let dataRepositoryModel = new DataRepositoryModel(result.id, result.label, result.pid, result.uri, result.reference); (this.formGroup.get("dataRepositories")).push(dataRepositoryModel.buildForm()); }); } addRegistry() { let dialogRef = this.dialog.open(RegistryReferencedModelHelperComponent, { height: '255px', width: '700px', data: { } }); dialogRef.afterClosed().subscribe(result => { if (!result) return let registryModel = new RegisterModel(result.abbreviation, result.definition, result.id, result.label, result.reference, result.uri); (this.formGroup.get("registries")).push(registryModel.buildForm()); }); } addExternalDataset() { let dialogRef = this.dialog.open(ExternalDatasetReferencedModelHelperComponent, { height: '255px', width: '700px', data: { } }); dialogRef.afterClosed().subscribe(result => { if (!result) return let externalDatasetModel = new ExternalDatasetModel(result.id, result.abbreviation, result.label, result.reference); (this.formGroup.get("externalDatasets")).push(externalDatasetModel.buildForm()); }); } addService() { let dialogRef = this.dialog.open(ServicesReferencedModelHelperComponent, { height: '255px', width: '700px', data: { } }); dialogRef.afterClosed().subscribe(result => { if (!result) return let serviceModel = new ServiceModel(result.id, result.abbreviation, result.definition, result.uri, result.label, result.reference); (this.formGroup.get("services")).push(serviceModel.buildForm()); }); } }