From a7a8e3db3537ca99c1c3fe1559a13dfaab5271ca Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Wed, 1 Jul 2020 14:26:58 +0300 Subject: [PATCH 01/15] Add contact field and "add cost" dialog --- dmp-frontend/src/app/core/model/dmp/cost.ts | 9 +++ dmp-frontend/src/app/ui/dmp/dmp.module.ts | 9 ++- .../add-cost/add-cost.component.html | 28 +++++++++ .../add-cost/add-cost.component.ts | 60 +++++++++++++++++++ .../cost-editor/add-cost/add-cost.model.ts | 44 ++++++++++++++ .../extra-properties-form.model.ts | 14 ++++- .../general-tab/general-tab.component.html | 29 +++++++-- .../general-tab/general-tab.component.ts | 22 +++++++ dmp-frontend/src/assets/i18n/en.json | 15 ++++- 9 files changed, 222 insertions(+), 8 deletions(-) create mode 100644 dmp-frontend/src/app/core/model/dmp/cost.ts create mode 100644 dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.html create mode 100644 dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.ts create mode 100644 dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.model.ts diff --git a/dmp-frontend/src/app/core/model/dmp/cost.ts b/dmp-frontend/src/app/core/model/dmp/cost.ts new file mode 100644 index 000000000..ab432f02b --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/cost.ts @@ -0,0 +1,9 @@ +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { ValidationContext } from '@common/forms/validation/validation-context'; + +export interface CostModel { + code: string; + description: string; + title: string; + value: number; +} diff --git a/dmp-frontend/src/app/ui/dmp/dmp.module.ts b/dmp-frontend/src/app/ui/dmp/dmp.module.ts index d331894da..67a9a3f76 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.module.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.module.ts @@ -32,6 +32,8 @@ import { FormValidationErrorsDialogModule } from '@common/forms/form-validation- import { CommonUiModule } from '@common/ui/common-ui.module'; import { MultipleChoiceDialogModule } from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.module'; import { AddOrganizationComponent } from './editor/add-organization/add-organization.component'; +import { AddCostComponent } from './editor/cost-editor/add-cost/add-cost.component'; +import { CostListingComponent } from './editor/cost-editor/cost-listing/cost-listing.component'; @NgModule({ imports: [ @@ -69,7 +71,9 @@ import { AddOrganizationComponent } from './editor/add-organization/add-organiza GrantTabComponent, DatasetsTabComponent, DmpCloneComponent, - AddOrganizationComponent + AddOrganizationComponent, + AddCostComponent, + CostListingComponent ], entryComponents: [ DmpInvitationDialogComponent, @@ -77,7 +81,8 @@ import { AddOrganizationComponent } from './editor/add-organization/add-organiza AvailableProfilesComponent, DmpFinalizeDialogComponent, DmpUploadDialogue, - AddOrganizationComponent + AddOrganizationComponent, + AddCostComponent ] }) export class DmpModule { } diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.html b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.html new file mode 100644 index 000000000..fca4f3c07 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.html @@ -0,0 +1,28 @@ +
+

{{'ADDEDITCOST-EDITOR.ADD-TITLE' | translate}}

+
+ + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+
+
+
+
+
diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.ts b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.ts new file mode 100644 index 000000000..e6f8d57e7 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.ts @@ -0,0 +1,60 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { ExternalResearcherService } from '@app/core/services/external-sources/researcher/external-researcher.service'; +import { BaseComponent } from '@common/base/base.component'; +import { takeUntil } from 'rxjs/operators'; +import { CostEditorModel } from './add-cost.model'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; +import { Observable } from 'rxjs'; +import { LocalFetchModel } from '@app/core/model/local-fetch/local-fetch.model'; +import { CurrencyService } from '@app/core/services/currency/currency.service'; + +@Component({ + selector: 'app-add-cost-component', + templateUrl: 'add-cost.component.html', +}) +export class AddCostComponent extends BaseComponent implements OnInit { + + public formGroup: FormGroup; + + currencyAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { + filterFn: this.searchCurrency.bind(this), + initialItems: () => this.searchCurrency(''), + displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + valueAssign: (item) => typeof (item) == 'string' ? JSON.parse(item)['value'] : item.value + }; + + constructor( + private externalResearcherService: ExternalResearcherService, + public dialogRef: MatDialogRef, + private currencyService: CurrencyService, + @Inject(MAT_DIALOG_DATA) public data: any + ) { super(); } + + ngOnInit(): void { + const cost = new CostEditorModel(); + this.formGroup = cost.buildForm(); + } + + send(value: any) { + this.externalResearcherService.createResearcher(this.formGroup.value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + null, null, () => this.dialogRef.close() + ); + } + + addCost() { + this.dialogRef.close(this.formGroup.value); + } + + isFormValid() { + return this.formGroup.valid; + } + + searchCurrency(like: string): Observable { + return this.currencyService.get(like); + } +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.model.ts b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.model.ts new file mode 100644 index 000000000..252e4950d --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.model.ts @@ -0,0 +1,44 @@ +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ResearcherModel } from '@app/core/model/researcher/researcher'; +import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { ValidationContext } from '@common/forms/validation/validation-context'; +import { OrganizationModel } from '@app/core/model/organisation/organization'; +import { CostModel } from '@app/core/model/dmp/cost'; + +export class CostEditorModel implements CostModel{ + public code: string; + public description: string; + public title: string; + public value: number; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: CostModel): CostEditorModel { + this.code = item.code; + this.description = item.description; + this.title = item.title; + this.value = item.value; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + code: [{ value: this.code, disabled: disabled }, context.getValidation('code').validators], + description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], + title: [{ value: this.title, disabled: disabled }, context.getValidation('title').validators], + value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators] + }); + + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'code', validators: [] }); + baseContext.validation.push({ key: 'description', validators: [] }); + baseContext.validation.push({ key: 'title', validators: [BackendErrorValidator(this.validationErrorModel, 'title')] }); + baseContext.validation.push({ key: 'value', validators: [] }); + return baseContext; + } +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts b/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts index 89d32c5ce..5d4d4d0a9 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts @@ -1,18 +1,26 @@ import { ValidationContext } from '@common/forms/validation/validation-context'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; +import { CostModel } from '@app/core/model/dmp/cost'; +import { isNullOrUndefined } from 'util'; export class ExtraPropertiesFormModel { public language: string; public license: string; public visible: boolean; public publicDate: Date; + public contact: string; + public costs: CostModel[] = []; fromModel(item: any): ExtraPropertiesFormModel { this.language = item.language; this.license = item.license; this.visible = item.visible; this.publicDate = item.publicDate; + this.contact = item.contact; + if (!isNullOrUndefined(item.costs)) { + this.costs = item.costs; + } return this; } @@ -23,7 +31,9 @@ export class ExtraPropertiesFormModel { language: [{ value: this.language, disabled: disabled }, context.getValidation('language').validators], license: [{ value: this.license, disabled: disabled }, context.getValidation('license').validators], visible: [{ value: this.visible, disabled: disabled }, context.getValidation('visible').validators], - publicDate: [{ value: this.publicDate, disabled: disabled }, context.getValidation('publicDate').validators] + publicDate: [{ value: this.publicDate, disabled: disabled }, context.getValidation('publicDate').validators], + contact: [{ value: this.contact, disabled: disabled }, context.getValidation('contact').validators], + costs: [{ value: this.costs, disabled: disabled }, context.getValidation('costs').validators] }); return formGroup; } @@ -34,6 +44,8 @@ export class ExtraPropertiesFormModel { baseContext.validation.push({ key: 'license', validators: [] }); baseContext.validation.push({ key: 'visible', validators: [] }); baseContext.validation.push({ key: 'publicDate', validators: [] }); + baseContext.validation.push({ key: 'contact', validators: [] }); + baseContext.validation.push({ key: 'costs', validators: [] }); return baseContext; } diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html index ce433d868..5e18a75dd 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html @@ -88,7 +88,7 @@ - {{formGroup.get('extraProperties').get('language').getError('backendError').message}} + {{formGroup.get('extraProperties').get('license').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -117,13 +117,34 @@ - - {{formGroup.get('extraProperties').get('visible').getError('backendError').message}} - + + {{formGroup.get('extraProperties').get('publicDate').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} +
+ + + + + {{vis.name | translate}} + + + + {{formGroup.get('extraProperties').get('contact').getError('backendError').message}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + +
+
+ +
diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts index 0dee0573f..54387fa92 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts @@ -26,6 +26,7 @@ import { ConfigurationService } from '@app/core/services/configuration/configura import { LanguageInfoService } from '@app/core/services/culture/language-info-service'; import { LanguageInfo } from '@app/core/model/language-info'; import { LicenseCriteria } from '@app/core/query/license/license-criteria'; +import { AddCostComponent } from '../cost-editor/add-cost/add-cost.component'; interface Visible { value: boolean; @@ -253,4 +254,25 @@ export class GeneralTabComponent extends BaseComponent implements OnInit { getLanguageInfos(): LanguageInfo[] { return this.languageInfoService.getLanguageInfoValues(); } + + getAssociates(): any[] { + let associates: any[] = []; + //associates = (this.formGroup.get('researchers').value as any[]); + associates = associates.concat(this.formGroup.get('associatedUsers').value); + return associates; + } + + addCost(event: MouseEvent) { + event.stopPropagation(); + const dialogRef = this.dialog.open(AddCostComponent, { + data: this.formGroup.get('extraProperties').get('costs') + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + const costsArray = this.formGroup.get('extraProperties').get('costs').value || []; + costsArray.push(result); + this.formGroup.get('extraProperties').get('costs').setValue(costsArray); + } + }); + } } diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 9c5ff334a..31a07273d 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -711,7 +711,8 @@ "LANGUAGE": "Language", "LICENSE": "License", "VISIBILITY": "Visibility", - "PUBLICATION": "Publication Date" + "PUBLICATION": "Publication Date", + "CONTACT": "Contact" }, "ACTIONS": { "GO-TO-GRANT": "Go To DMP Grant", @@ -986,6 +987,18 @@ "CANCEL": "Cancel" } }, + "ADDEDITCOST-EDITOR": { + "ADD-TITLE": "Add a Cost", + "EDIT-TITLE": "Edit the Cost", + "CODE": "Code", + "DESCRIPTION": "Description", + "TITLE": "Title", + "VALUE": "Value", + "ACTIONS": { + "SAVE": "Save", + "CANCEL": "Cancel" + } + }, "DMP-WIZARD": { "FIRST-STEP": { "DMP": "DMP Editor", From bfb9eaf87c1a330ced54296166ac1ab868683feb Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Wed, 1 Jul 2020 18:33:16 +0300 Subject: [PATCH 02/15] Add costs listing (wip) --- .../cost-listing/cost-listing.component.html | 32 ++++++++++++ .../cost-listing/cost-listing.component.scss | 10 ++++ .../cost-listing/cost-listing.component.ts | 51 +++++++++++++++++++ .../general-tab/general-tab.component.html | 10 ++-- .../general-tab/general-tab.component.scss | 4 ++ 5 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.html create mode 100644 dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.scss create mode 100644 dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.ts diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.html b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.html new file mode 100644 index 000000000..1fb26780b --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.html @@ -0,0 +1,32 @@ + + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+ + + + + +
diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.scss b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.scss new file mode 100644 index 000000000..52f45cc20 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.scss @@ -0,0 +1,10 @@ +.listing-container { + height: fit-content; + width: fit-content; + background-color: whitesmoke; +} + + +.cost-element { + margin-bottom: 1em; +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.ts b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.ts new file mode 100644 index 000000000..1272e51c6 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.ts @@ -0,0 +1,51 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { BaseComponent } from '@common/base/base.component'; +import { FormArray } from '@angular/forms'; +import { takeUntil } from 'rxjs/operators'; +import { CostModel } from '@app/core/model/dmp/cost'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; +import { CurrencyService } from '@app/core/services/currency/currency.service'; +import { Observable } from 'rxjs'; +import { LocalFetchModel } from '@app/core/model/local-fetch/local-fetch.model'; + +@Component({ + selector: 'app-cost-listing', + templateUrl: './cost-listing.component.html', + styleUrls: ['./cost-listing.component.scss'] +}) +export class CostListingComponent extends BaseComponent implements OnInit { + + @Input() form: FormArray; + + costs: CostModel[] = []; + + currencyAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { + filterFn: this.searchCurrency.bind(this), + initialItems: () => this.searchCurrency(''), + displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + valueAssign: (item) => this.getValue(item) + }; + + constructor( + private currencyService: CurrencyService, + ) { + super(); + } + + ngOnInit() { + this.form.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(value => { + this.costs = value; + }); + } + + searchCurrency(like: string): Observable { + return this.currencyService.get(like); +} + + getValue(item: any): any { + console.log(item); + return item; + } + +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html index 5e18a75dd..2d85e7ccc 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html @@ -140,10 +140,12 @@
-
- +
+ Costs + +
diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.scss b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.scss index 05d8ae793..595aabb5c 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.scss +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.scss @@ -37,3 +37,7 @@ ::ng-deep .mat-form-field-appearance-legacy .mat-form-field-wrapper { padding-bottom: 1.25em; } + +.cost-placeholder { + text-decoration: underline; +} From 747ad60fb1ff2639849e13d770d697cf54d1d906 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Thu, 2 Jul 2020 10:16:11 +0300 Subject: [PATCH 03/15] Update cost listing --- .../general-tab/extra-properties-form.model.ts | 17 ++++++++++++++--- .../editor/general-tab/general-tab.component.ts | 7 +++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts b/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts index 5d4d4d0a9..8124cc5d5 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts @@ -3,6 +3,7 @@ import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; import { CostModel } from '@app/core/model/dmp/cost'; import { isNullOrUndefined } from 'util'; +import { CostEditorModel } from '../cost-editor/add-cost/add-cost.model'; export class ExtraPropertiesFormModel { public language: string; @@ -10,7 +11,7 @@ export class ExtraPropertiesFormModel { public visible: boolean; public publicDate: Date; public contact: string; - public costs: CostModel[] = []; + public costs: CostEditorModel[] = []; fromModel(item: any): ExtraPropertiesFormModel { this.language = item.language; @@ -26,15 +27,25 @@ export class ExtraPropertiesFormModel { buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { if (context == null) { context = this.createValidationContext(); } - + const formBuilder = new FormBuilder(); const formGroup = new FormBuilder().group({ language: [{ value: this.language, disabled: disabled }, context.getValidation('language').validators], license: [{ value: this.license, disabled: disabled }, context.getValidation('license').validators], visible: [{ value: this.visible, disabled: disabled }, context.getValidation('visible').validators], publicDate: [{ value: this.publicDate, disabled: disabled }, context.getValidation('publicDate').validators], contact: [{ value: this.contact, disabled: disabled }, context.getValidation('contact').validators], - costs: [{ value: this.costs, disabled: disabled }, context.getValidation('costs').validators] + // costs: [{ value: this.costs, disabled: disabled }, context.getValidation('costs').validators] }); + + const costArray = new Array(); + //if (this.externalDatasets && this.externalDatasets.length > 0) { + this.costs.forEach(item => { + costArray.push(item.buildForm(context.getValidation('externalDatasets').descendantValidations, disabled)); + }); + // } else { + // //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled)); + // } + formGroup.addControl('costs', formBuilder.array(costArray)); return formGroup; } diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts index 54387fa92..f699dad91 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; -import { FormGroup } from '@angular/forms'; +import { FormGroup, FormArray } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; @@ -27,6 +27,7 @@ import { LanguageInfoService } from '@app/core/services/culture/language-info-se import { LanguageInfo } from '@app/core/model/language-info'; import { LicenseCriteria } from '@app/core/query/license/license-criteria'; import { AddCostComponent } from '../cost-editor/add-cost/add-cost.component'; +import { CostEditorModel } from '../cost-editor/add-cost/add-cost.model'; interface Visible { value: boolean; @@ -271,7 +272,9 @@ export class GeneralTabComponent extends BaseComponent implements OnInit { if (result) { const costsArray = this.formGroup.get('extraProperties').get('costs').value || []; costsArray.push(result); - this.formGroup.get('extraProperties').get('costs').setValue(costsArray); + let costeditModel: CostEditorModel = new CostEditorModel(); + costeditModel = costeditModel.fromModel(result); + (this.formGroup.get('extraProperties').get('costs')).push(costeditModel.buildForm(null, true)); } }); } From 62118179ffd2380a72369a3659f97328836a97b6 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Thu, 2 Jul 2020 17:06:47 +0300 Subject: [PATCH 04/15] Update the cost listing (near finalization) and fix some issues while loading costs from the backend --- .../add-cost/add-cost.component.ts | 2 +- .../cost-listing/cost-listing.component.html | 16 ++++++++-- .../cost-listing/cost-listing.component.ts | 30 +++++++++++++------ .../extra-properties-form.model.ts | 6 ++-- .../general-tab/general-tab.component.html | 2 +- .../general-tab/general-tab.component.scss | 4 +++ 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.ts b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.ts index e6f8d57e7..7a4da0f75 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/add-cost/add-cost.component.ts @@ -23,7 +23,7 @@ export class AddCostComponent extends BaseComponent implements OnInit { initialItems: () => this.searchCurrency(''), displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, - valueAssign: (item) => typeof (item) == 'string' ? JSON.parse(item)['value'] : item.value + valueAssign: (item) => JSON.stringify(item) }; constructor( diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.html b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.html index 1fb26780b..8ed92f09d 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.html @@ -9,20 +9,30 @@
- +
- +
- +
+
+
+
+
+
+
+
+
+
+
diff --git a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.ts b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.ts index 1272e51c6..16bbc9a89 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/cost-editor/cost-listing/cost-listing.component.ts @@ -1,12 +1,13 @@ import { Component, OnInit, Input } from '@angular/core'; import { BaseComponent } from '@common/base/base.component'; -import { FormArray } from '@angular/forms'; +import { FormArray, FormControl } from '@angular/forms'; import { takeUntil } from 'rxjs/operators'; import { CostModel } from '@app/core/model/dmp/cost'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { CurrencyService } from '@app/core/services/currency/currency.service'; import { Observable } from 'rxjs'; import { LocalFetchModel } from '@app/core/model/local-fetch/local-fetch.model'; +import { CostEditorModel } from '../add-cost/add-cost.model'; @Component({ selector: 'app-cost-listing', @@ -17,14 +18,14 @@ export class CostListingComponent extends BaseComponent implements OnInit { @Input() form: FormArray; - costs: CostModel[] = []; + private cost: CostEditorModel[] = []; currencyAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { filterFn: this.searchCurrency.bind(this), initialItems: () => this.searchCurrency(''), displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, - valueAssign: (item) => this.getValue(item) + valueAssign: (item) => JSON.stringify(item) }; constructor( @@ -34,18 +35,29 @@ export class CostListingComponent extends BaseComponent implements OnInit { } ngOnInit() { - this.form.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(value => { - this.costs = value; - }); } searchCurrency(like: string): Observable { return this.currencyService.get(like); } - getValue(item: any): any { - console.log(item); - return item; +switchEditMode(event: number) { + const control = this.form.at(event); + if (control.disabled) { + this.cost[event] = control.value; + control.enable(); + } else { + control.disable(); } +} + +removeCost(event: number) { + this.form.removeAt(event); +} + +revertEdits(event: number) { + this.form.at(event).setValue(this.cost[event]); + this.form.at(event).disable(); +} } diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts b/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts index 8124cc5d5..8ef442501 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts @@ -20,7 +20,9 @@ export class ExtraPropertiesFormModel { this.publicDate = item.publicDate; this.contact = item.contact; if (!isNullOrUndefined(item.costs)) { - this.costs = item.costs; + (item.costs).forEach(element => { + this.costs.push(new CostEditorModel().fromModel(element)); + }); } return this; } @@ -40,7 +42,7 @@ export class ExtraPropertiesFormModel { const costArray = new Array(); //if (this.externalDatasets && this.externalDatasets.length > 0) { this.costs.forEach(item => { - costArray.push(item.buildForm(context.getValidation('externalDatasets').descendantValidations, disabled)); + costArray.push(item.buildForm(context.getValidation('costs').descendantValidations, disabled)); }); // } else { // //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled)); diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html index 2d85e7ccc..78852a3a6 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html @@ -143,7 +143,7 @@
Costs -
diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.scss b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.scss index 595aabb5c..322c63d34 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.scss +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.scss @@ -41,3 +41,7 @@ .cost-placeholder { text-decoration: underline; } + +.cost-add { + margin-top: 1em; +} From 094cff06b171186b2b1a7ff2b891231fe59559e2 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Thu, 2 Jul 2020 17:08:38 +0300 Subject: [PATCH 05/15] Properly remove associate Collaborators from a DMP --- .../managers/DataManagementPlanManager.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 9583b2862..8d272f67d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -368,6 +368,14 @@ public class DataManagementPlanManager { apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().createOrUpdate(newDmp.getGrant()); newDmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); + if (dataManagementPlan.getUsers() != null && !dataManagementPlan.getUsers().isEmpty()) { + clearUsers(newDmp); + for (UserInfoListingModel userListing : dataManagementPlan.getUsers()) { + UserInfo tempUser = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(userListing.getId()); + assignUser(dmp, tempUser, UserDMP.UserDMPRoles.fromInteger(userListing.getRole())); + } + } + // Dataset manipulation for when the DMP is set to be finalized. if (dataManagementPlan.getStatus() == DMP.DMPStatus.FINALISED.getValue()) { if (dataManagementPlan.getDatasetsToBeFinalized() != null && !dataManagementPlan.getDatasetsToBeFinalized().isEmpty()) { @@ -1445,13 +1453,22 @@ public class DataManagementPlanManager { * */ private void assignUser(DMP dmp, UserInfo userInfo) { + this.assignUser(dmp, userInfo, UserDMP.UserDMPRoles.OWNER); + } + + private void assignUser(DMP dmp, UserInfo userInfo, UserDMP.UserDMPRoles role) { UserDMP userDMP = new UserDMP(); userDMP.setDmp(dmp); userDMP.setUser(userInfo); - userDMP.setRole(UserDMP.UserDMPRoles.OWNER.getValue()); + userDMP.setRole(role.getValue()); databaseRepository.getUserDmpDao().createOrUpdate(userDMP); } + private void clearUsers(DMP dmp) { + List userDMPs = apiContext.getOperationsContext().getDatabaseRepository().getUserDmpDao().asQueryable().where(((builder, root) -> builder.equal(root.get("dmp").get("id"), dmp.getId()))).toList(); + userDMPs.forEach(userDMP -> apiContext.getOperationsContext().getDatabaseRepository().getUserDmpDao().delete(userDMP)); + } + private void assignGrandUserIfInternal(DMP dmp, UserInfo user) { if (dmp.getGrant().getCreationUser() == null && (dmp.getGrant().getReference() != null && dmp.getGrant().getReference().startsWith("dmp:"))) { dmp.getGrant().setCreationUser(user); From 7127f6dbd6773ce5b3c8ca4bc3fb631b57482388 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Thu, 2 Jul 2020 18:35:16 +0300 Subject: [PATCH 06/15] Minor fix over cost listing --- .../ui/dmp/editor/general-tab/extra-properties-form.model.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts b/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts index 8ef442501..c2dc45d91 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/extra-properties-form.model.ts @@ -42,7 +42,7 @@ export class ExtraPropertiesFormModel { const costArray = new Array(); //if (this.externalDatasets && this.externalDatasets.length > 0) { this.costs.forEach(item => { - costArray.push(item.buildForm(context.getValidation('costs').descendantValidations, disabled)); + costArray.push(item.buildForm(context.getValidation('costs').descendantValidations, true)); }); // } else { // //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled)); From 6d491b5930f487a6a4d2ce03f57ea365ea8fafed Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Thu, 2 Jul 2020 18:36:18 +0300 Subject: [PATCH 07/15] Rda mapper will now be able to use the new DMP fields --- .../eudat/models/rda/mapper/DmpRDAMapper.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java index a64649c86..bda50f6ba 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java @@ -3,6 +3,7 @@ package eu.eudat.models.rda.mapper; import eu.eudat.data.entities.*; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.utilities.helpers.StreamDistinctBy; +import eu.eudat.models.rda.Cost; import eu.eudat.models.rda.Dmp; import eu.eudat.models.rda.DmpId; import net.minidev.json.JSONObject; @@ -43,16 +44,34 @@ public class DmpRDAMapper { Map extraProperties = new org.json.JSONObject(dmp.getExtraProperties()).toMap(); if (!extraProperties.isEmpty()) { - rda.setLanguage(LanguageRDAMapper.mapLanguageIsoToRDAIso(extraProperties.get("language").toString())); + if (extraProperties.get("language") != null) { + rda.setLanguage(LanguageRDAMapper.mapLanguageIsoToRDAIso(extraProperties.get("language").toString())); + } + if (extraProperties.get("costs") != null) { + rda.setCost(new ArrayList<>()); + ((List) extraProperties.get("costs")).forEach(costl -> { + Cost cost = new Cost(); + Map code = new org.json.JSONObject((String) ((Map) costl).get("code")).toMap(); + cost.setCurrencyCode(Cost.CurrencyCode.fromValue((String) code.get("value"))); + cost.setDescription((String) ((Map) costl).get("description")); + cost.setTitle((String) ((Map) costl).get("title")); + cost.setValue(((Integer) ((Map) costl).get("value")).doubleValue()); + rda.getCost().add(cost); + }); + } + if (extraProperties.get("contact") != null) { + UserInfo contact = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(UUID.fromString((String)extraProperties.get("contact"))); + rda.setContact(ContactRDAMapper.toRDA(contact)); + } } - UserInfo creator; + /*UserInfo creator; if (dmp.getCreator() != null) { creator = dmp.getCreator(); } else { creator = dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).map(UserDMP::getUser).findFirst().orElse(new UserInfo()); } - rda.setContact(ContactRDAMapper.toRDA(creator)); + rda.setContact(ContactRDAMapper.toRDA(creator));*/ rda.setContributor(new ArrayList<>()); if (dmp.getResearchers() != null && !dmp.getResearchers().isEmpty()) { rda.getContributor().addAll(dmp.getResearchers().stream().map(ContributorRDAMapper::toRDA).collect(Collectors.toList())); From d10615d13ad25de147a79c09c14b0f69e56c7131 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Mon, 6 Jul 2020 11:58:59 +0300 Subject: [PATCH 08/15] Replace dmp and grant form String to DataManagementOverviewMaodel and GrantOverviewModel on DatasetOverviewModel --- .../data/dataset/DatasetOverviewModel.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dataset/DatasetOverviewModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dataset/DatasetOverviewModel.java index 1fe23c6a8..2ef2aeba1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dataset/DatasetOverviewModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dataset/DatasetOverviewModel.java @@ -3,6 +3,8 @@ package eu.eudat.models.data.dataset; import eu.eudat.data.entities.Dataset; import eu.eudat.models.DataModel; import eu.eudat.models.data.datasetprofile.DatasetProfileOverviewModel; +import eu.eudat.models.data.grant.GrantOverviewModel; +import eu.eudat.models.data.listingmodels.DataManagementPlanOverviewModel; import eu.eudat.models.data.listingmodels.UserInfoListingModel; import java.util.Date; @@ -17,8 +19,8 @@ public class DatasetOverviewModel implements DataModel users; - private String dmp; - private String grant; + private DataManagementPlanOverviewModel dmp; + private GrantOverviewModel grant; private String description; private Boolean isPublic; private Date modified; @@ -59,19 +61,19 @@ public class DatasetOverviewModel implements DataModel new UserInfoListingModel().fromDataModel(x)).collect(Collectors.toList()); - this.dmp = entity.getDmp().getLabel(); - this.grant = entity.getDmp().getGrant().getLabel(); + this.dmp = new DataManagementPlanOverviewModel().fromDataModel(entity.getDmp()); + this.grant = new GrantOverviewModel().fromDataModel(entity.getDmp().getGrant()); this.description = entity.getDescription(); this.isPublic = entity.getDmp().isPublic(); this.modified = entity.getModified(); From 75be44ee6090de2331a5ce408f1519422307a8f3 Mon Sep 17 00:00:00 2001 From: gpapavgeri Date: Mon, 6 Jul 2020 13:21:11 +0300 Subject: [PATCH 09/15] dataset-overview_update v3 --- .../core/services/dataset/dataset.service.ts | 28 ++- .../overview/dataset-overview.component.html | 68 +++---- .../overview/dataset-overview.component.scss | 7 +- .../overview/dataset-overview.component.ts | 179 +++++++++++++++++- .../dmp/overview/dmp-overview.component.html | 6 +- .../dmp/overview/dmp-overview.component.scss | 2 +- .../ui/dmp/overview/dmp-overview.component.ts | 12 +- dmp-frontend/src/assets/i18n/en.json | 3 +- dmp-frontend/src/assets/i18n/es.json | 3 +- dmp-frontend/src/assets/i18n/gr.json | 3 +- 10 files changed, 252 insertions(+), 59 deletions(-) diff --git a/dmp-frontend/src/app/core/services/dataset/dataset.service.ts b/dmp-frontend/src/app/core/services/dataset/dataset.service.ts index d21df6676..e7306d139 100644 --- a/dmp-frontend/src/app/core/services/dataset/dataset.service.ts +++ b/dmp-frontend/src/app/core/services/dataset/dataset.service.ts @@ -11,7 +11,7 @@ import { BaseHttpService } from '../http/base-http.service'; import { DatasetProfileCriteria } from '../../query/dataset-profile/dataset-profile-criteria'; import { ConfigurationService } from '../configuration/configuration.service'; import { DatasetOverviewModel } from '@app/core/model/dataset/dataset-overview'; -import { HttpHeaders } from '@angular/common/http'; +import { HttpHeaders, HttpResponse, HttpClient } from '@angular/common/http'; import { DatasetModel } from '@app/core/model/dataset/dataset'; @Injectable() @@ -22,7 +22,8 @@ export class DatasetService { constructor( private http: BaseHttpService, - private configurationSevice: ConfigurationService) { + private configurationSevice: ConfigurationService, + private httpClient: HttpClient) { this.actionUrl = configurationSevice.server + 'datasets/'; } @@ -69,4 +70,27 @@ export class DatasetService { delete(id: String): Observable { return this.http.delete(this.actionUrl + 'delete/' + id, { headers: this.headers }); // + 'delete/' } + + publish(id: String): Observable { + return this.http.get(this.actionUrl + 'makepublic/' + id, { headers: this.headers }); + } + + public downloadXML(id: string): Observable> { + let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml') + return this.httpClient.get(this.actionUrl + id, { responseType: 'blob', observe: 'response', headers: headerXml }); //+ "/getXml/" + } + + public downloadDocx(id: string): Observable> { + let headerDoc: HttpHeaders = this.headers.set('Content-Type', 'application/msword') + return this.httpClient.get(this.actionUrl + id, { responseType: 'blob', observe: 'response', headers: headerDoc }); + } + + public downloadPDF(id: string): Observable> { + let headerPdf: HttpHeaders = this.headers.set('Content-Type', 'application/pdf') + return this.httpClient.get(this.actionUrl + 'getPDF/' + id, { responseType: 'blob', observe: 'response', headers: headerPdf }); + } + + public downloadJson(id: string): Observable> { + return this.httpClient.get(this.actionUrl + 'rda/' + id, { responseType: 'blob', observe: 'response' }); + } } diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html index ea6fa3f22..dcd35cc47 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html @@ -9,7 +9,7 @@
-

{{ dataset.label }}

+

{{ dataset.label }}

@@ -41,34 +41,38 @@ (click)="viewVersions(dmp.groupId, dmp.label)"> {{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}} --> -
{{'GENERAL.STATUSES.EDIT' | translate}} : +
{{'GENERAL.STATUSES.EDIT' | translate}} : {{dataset.modified | date:"longDate"}}
- +
+ create + {{'TYPES.DATASET-STATUS.DRAFT' | translate}} +
+
-
{{ 'DATASET-LISTING.TOOLTIP.DMP-FOR' | translate }}: {{ dataset.datasetTemplate.label }}
@@ -85,7 +90,7 @@
{{'DMP-OVERVIEW.GRANT' | translate}}
-
Grant label
+
Grant label
{{'DMP-OVERVIEW.RESEARCHERS' | translate}}
@@ -127,8 +132,8 @@
-->
- - +
- - +
diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss index cc76c8022..979463146 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss @@ -20,7 +20,7 @@ font-size: 1.2em; } -.mat-mini-fab:hover { +.actions-btn:hover { background-color: #129D99; color: #FFFFFF; } @@ -150,13 +150,12 @@ color: #008887; padding-right: 0.5em; align-self: center; - } .header { opacity: 0.6; margin-top: 1em; - margin-bottom: 0.25em; + margin-bottom: 0.5em; } .dataset-label, .header { @@ -262,7 +261,7 @@ // ********CENTER ELEMENTS******** -.mat-mini-fab, .mat-mini-fab-icon, +.mat-mini-fab, .mat-mini-fab-icon, .actions-btn, .status-icon, .dataset-logo, .frame-btn, .finalize-btn { display: flex; justify-content: center; diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts index e7cbd4742..6df5ec3b3 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts @@ -19,6 +19,12 @@ import { Location } from '@angular/common'; import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; import { DatasetStatus } from '@app/core/common/enum/dataset-status'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import * as FileSaver from 'file-saver'; +import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation.component'; +import { DatasetWizardEditorModel } from '../dataset-wizard/dataset-wizard-editor.model'; +import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; +import { FormControl } from '@angular/forms'; +import { DatasetCopyDialogueComponent } from '../dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component'; @Component({ @@ -29,6 +35,7 @@ import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog export class DatasetOverviewComponent extends BaseComponent implements OnInit { dataset: DatasetOverviewModel; + datasetWizardModel: DatasetWizardEditorModel; isNew = true; isFinalized = false; isPublicView = true; @@ -50,7 +57,8 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { private configurationService: ConfigurationService, private oauth2DialogService: Oauth2DialogService, private userService: UserService, - private location: Location + private location: Location, + private datasetWizardService: DatasetWizardService ) { super(); } @@ -69,6 +77,10 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.dataset = data; + this.datasetWizardService.getSingle(this.dataset.id).pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.datasetWizardModel = new DatasetWizardEditorModel().fromModel(data); + }); // this.checkLockStatus(this.dataset.id); this.setIsUserOwner(); const breadCrumbs = []; @@ -92,6 +104,10 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.dataset = data; + this.datasetWizardService.getSingle(this.dataset.id).pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.datasetWizardModel = new DatasetWizardEditorModel().fromModel(data); + }); // this.checkLockStatus(this.dataset.id); this.setIsUserOwner(); const breadCrumbs = []; @@ -130,7 +146,12 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { if (principal) this.isUserOwner = principal.id === this.dataset.users.find(x => x.role === Role.Owner).id; } } - + + isUserAuthor(userId: string): boolean { + const principal: Principal = this.authentication.current(); + return userId === principal.id; + } + isUserDatasetRelated() { const principal: Principal = this.authentication.current(); let isRelated: boolean = false; @@ -143,6 +164,17 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { } return isRelated; } + + roleDisplay(value: UserInfoListingModel) { + if (value.role === Role.Owner) { + return this.translate.instant('DMP-LISTING.OWNER'); + } else if (value.role === Role.Member) { + return this.translate.instant('DMP-LISTING.MEMBER'); + } else { + return this.translate.instant('DMP-LISTING.OWNER'); + } + } + roleDisplayFromList(value: UserInfoListingModel[]) { const principal: Principal = this.authentication.current(); @@ -162,21 +194,37 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { return this.translate.instant('DMP-LISTING.OWNER'); } } + + openShareDialog(rowId: any, rowName: any) { + const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { + // height: '250px', + // width: '700px', + restoreFocus: false, + data: { + dmpId: rowId, + dmpName: rowName + } + }); + } public isAuthenticated(): boolean { return !(!this.authentication.current()); } - cloneClicked(dataset: DatasetOverviewModel) { - this.router.navigate(['/datasets/clone/' + dataset.id]); - } - isDraftDataset(dataset: DatasetOverviewModel) { return dataset.status == DatasetStatus.Draft; } + + isFinalizedDataset(dataset: DatasetOverviewModel) { + return dataset.status == DatasetStatus.Finalized; + } editClicked(dataset: DatasetOverviewModel) { - this.router.navigate(['/datasets/edit/' + dataset.id]); + if (dataset.public) { + this.router.navigate(['/datasets/publicEdit/' + dataset.id]); + } else { + this.router.navigate(['/datasets/edit/' + dataset.id]); + } } deleteClicked() { @@ -200,6 +248,10 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { } }); } + + dmpClicked(dmpId: String) { + this.router.navigate(['/plans/overview/' + dmpId]); + } onCallbackSuccess(): void { this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); @@ -213,9 +265,116 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { public getOrcidPath(): string { return this.configurationService.orcidPath; } + + downloadPDF(id: string) { + this.datasetService.downloadPDF(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/pdf' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + }); + } + + downloadDocx(id: string) { + this.datasetService.downloadDocx(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/msword' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + }); + } + + downloadXml(id: string) { + this.datasetService.downloadXML(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/xml' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + }); + } + + downloadJson(id: string) { + this.datasetService.downloadJson(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/json' }); + 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; + } + + showPublishButton(dataset: DatasetOverviewModel) { + return this.isFinalizedDataset(dataset) && !dataset.public && this.hasPublishButton; + } + + publish(datasetId: String) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '500px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.PUBLISH-ITEM'), + privacyPolicyNames: this.language.instant('GENERAL.CONFIRMATION-DIALOG.PRIVACY-POLICY-NAMES'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: false + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.datasetService.publish(datasetId) + .pipe(takeUntil(this._destroyed)) + .subscribe(() => { this.hasPublishButton = false }); + } + }); + } + + openDmpSearchDialogue() { + const formControl = new FormControl(); + const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, { + width: '500px', + restoreFocus: false, + data: { + formControl: formControl, + datasetId: this.dataset.id, + datasetProfileId: this.datasetWizardModel.profile, + datasetProfileExist: false, + confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), + cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result && result.datasetProfileExist) { + const newDmpId = result.formControl.value.id + this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); + } + }); + } - // showPublishButton(dataset: DatasetOverviewModel) { - // return this.isFinalizedDmp(dmp) && !dmp.isPublic && this.hasPublishButton; - // } } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index cd5c4e1f2..5ee16de2b 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -46,7 +46,11 @@
check - {{'DATASET-LISTING.COLUMNS.FINALIZED' | translate}} + {{'TYPES.DMP.FINALISED' | translate}} +
+
+ create + {{'TYPES.DMP.DRAFT' | translate}}
diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss index 9ceae05d1..97e0fc96d 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss @@ -161,7 +161,7 @@ .header { opacity: 0.6; margin-top: 1em; - margin-bottom: 0.25em; + margin-bottom: 0.5em; } .dmp-label, .header { diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index 1d233f5fc..14f877006 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -183,12 +183,12 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } datasetClicked(datasetId: String) { - if (this.isPublicView) { - this.router.navigate(['/datasets/publicEdit/' + datasetId]); - } else { - this.router.navigate(['/datasets/edit/' + datasetId]); - console.log('inhere') - } + // if (this.isPublicView) { + // this.router.navigate(['/datasets/publicEdit/' + datasetId]); + // } else { + // this.router.navigate(['/datasets/edit/' + datasetId]); + // } + this.router.navigate(['/datasets/overview/' + datasetId]); } datasetsClicked(dmpId: String) { diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 11ed9caaf..452088bf1 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -106,6 +106,7 @@ "LOGIN": "Login", "DMP-OVERVIEW": "DMP Overview", "DMP-EDIT": "Edit DMP", + "DATASET-OVERVIEW": "Dataset Overview", "DATASET-EDIT": "Dataset View/Edit", "DMP-NEW-VERSION": "DMP New Version", "DMP-CLONE": "Clone DMP", @@ -567,7 +568,7 @@ } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Dataset description Authors", + "DATASET-AUTHORS": "Dataset description authors", "ERROR": { "DELETED-DATASET": "The requested dataset is deleted", "FORBIDEN-DATASET": "You are not allowed to access this dataset" diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index dc4e1e6e4..02fa89ccd 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -105,6 +105,7 @@ "LOGIN": "Iniciar sesión", "DMP-OVERVIEW": "Resumen del PGD", "DMP-EDIT": "Editar el PGD", + "DATASET-OVERVIEW": "Resumen del Dataset", "DATASET-EDIT": "Ver/Editar el Dataset", "DMP-NEW-VERSION": "Nueva versiónd del PGD", "DMP-CLONE": "Clonar el PGD", @@ -565,7 +566,7 @@ } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Descripciones del Dataset Autores", + "DATASET-AUTHORS": "Descripciones del dataset autores", "ERROR": { "DELETED-DATASET": "El Dataset solicitado está borrado", "FORBIDEN-DATASET": "No tiene permiso para acceder a esto Dataset" diff --git a/dmp-frontend/src/assets/i18n/gr.json b/dmp-frontend/src/assets/i18n/gr.json index 75dc1c0e2..4f696bf13 100644 --- a/dmp-frontend/src/assets/i18n/gr.json +++ b/dmp-frontend/src/assets/i18n/gr.json @@ -105,6 +105,7 @@ "LOGIN": "Σύνδεση", "DMP-OVERVIEW": "Επισκόπηση Σχεδίου Διαχείρισης Δεδομένων", "DMP-EDIT": "Επεξεργασία Σχεδίου Διαχείρισης Δεδομένων", + "DATASET-OVERVIEW": "Επισκόπηση Συνόλου Δεδομένων", "DATASET-EDIT": "Προβολή / Επεξεργασία Συνόλου Δεδομένων", "DMP-NEW-VERSION": "Νέα έκδοση Σχεδίου Διαχείρισης Δεδομένων", "DMP-CLONE": "Κλωνοποίηση Σχεδίου Διαχείρισης Δεδομένων", @@ -566,7 +567,7 @@ } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Συγγραφείς Περιγραφής Δεδομένων", + "DATASET-AUTHORS": "Συγγραφείς περιγραφής δεδομένων", "ERROR": { "DELETED-DATASET": "H επιλεγμένη Περιγραφή Δεδομένων θα διαγραφεί", "FORBIDEN-DATASET": "Δεν επιτρέπεται η πρόσβαση σε αυτή την Περιγραφή Δεδομένων" From 84bb291cd698d5947097ae3b912ccd3361652950 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Mon, 6 Jul 2020 14:11:14 +0300 Subject: [PATCH 10/15] Make DMP total count to use distinct in order to avoid counting duplicate entries --- .../java/eu/eudat/logic/managers/DataManagementPlanManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 8d272f67d..6d62ddb4e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -189,7 +189,7 @@ public class DataManagementPlanManager { .whenComplete((resultList, throwable) -> dataTable.setData(resultList)); } - CompletableFuture countFuture = authItems.countAsync().whenComplete((count, throwable) -> dataTable.setTotalCount(count)); + CompletableFuture countFuture = authItems.distinct().countAsync().whenComplete((count, throwable) -> dataTable.setTotalCount(count)); CompletableFuture.allOf(itemsFuture, countFuture).join(); return dataTable; } From f432caa58465b1b2215588410f11107373020f81 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Mon, 6 Jul 2020 14:18:42 +0300 Subject: [PATCH 11/15] When getting user statistics on the dashboard make sure the DMP count to be distinct --- .../src/main/java/eu/eudat/logic/managers/DashBoardManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java index 2796406fb..709b4265d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java @@ -137,7 +137,7 @@ public class DashBoardManager { List roles = new LinkedList<>(); List finalDmps = dmps; - CompletableFuture dmpFuture = dataManagementPlanRepository.getAuthenticated(dmps != null ? dataManagementPlanRepository.asQueryable().where((builder, root) -> root.get("id").in(finalDmps.stream().map(Dmp::getId).collect(Collectors.toList()))) : dataManagementPlanRepository.getWithCriteria(dataManagementPlanCriteria), principal.getId(), roles).countAsync() + CompletableFuture dmpFuture = dataManagementPlanRepository.getAuthenticated(dmps != null ? dataManagementPlanRepository.asQueryable().where((builder, root) -> root.get("id").in(finalDmps.stream().map(Dmp::getId).collect(Collectors.toList()))) : dataManagementPlanRepository.getWithCriteria(dataManagementPlanCriteria), principal.getId(), roles).distinct().countAsync() .whenComplete((dmpsStats, throwable) -> statistics.setTotalDataManagementPlanCount(dmpsStats)); List finalDatasets = datasets; CompletableFuture datasetFuture = datasetRepository.getAuthenticated(datasets != null ? datasetRepository.asQueryable().where((builder, root) -> root.get("id").in(finalDatasets.stream().map(x -> UUID.fromString(x.getId())).collect(Collectors.toList()))) : datasetRepository.getWithCriteria(datasetCriteria), user, roles).countAsync() From 029c246a4bb1fc3d54e9d92d246ddc8ed3a373ab Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Mon, 6 Jul 2020 18:23:37 +0300 Subject: [PATCH 12/15] Fixed minor issue --- dmp-frontend/src/app/ui/dmp/dmp.module.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmp-frontend/src/app/ui/dmp/dmp.module.ts b/dmp-frontend/src/app/ui/dmp/dmp.module.ts index 7a503afd3..dee306705 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.module.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.module.ts @@ -73,7 +73,7 @@ import { DmpCriteriaDialogComponent } from './listing/criteria/dmp-criteria-dial DatasetsTabComponent, DmpCloneComponent, AddOrganizationComponent, - DmpCriteriaDialogComponent + DmpCriteriaDialogComponent, AddOrganizationComponent, AddCostComponent, CostListingComponent @@ -85,7 +85,7 @@ import { DmpCriteriaDialogComponent } from './listing/criteria/dmp-criteria-dial DmpFinalizeDialogComponent, DmpUploadDialogue, AddOrganizationComponent, - DmpCriteriaDialogComponent + DmpCriteriaDialogComponent, AddOrganizationComponent, AddCostComponent ] From 7c3f06d9f4af003d3d9c7c27ca14e5e23118f8e6 Mon Sep 17 00:00:00 2001 From: gpapavgeri Date: Mon, 6 Jul 2020 18:42:54 +0300 Subject: [PATCH 13/15] dataset-overview_update v4 --- .../core/model/dataset/dataset-overview.ts | 3 +- .../app/core/model/researcher/researcher.ts | 2 +- .../overview/dataset-overview.component.html | 90 +--- .../overview/dataset-overview.component.scss | 3 +- .../overview/dataset-overview.component.ts | 411 +++++++++--------- .../dmp/overview/dmp-overview.component.html | 28 +- .../ui/dmp/overview/dmp-overview.component.ts | 19 - 7 files changed, 226 insertions(+), 330 deletions(-) diff --git a/dmp-frontend/src/app/core/model/dataset/dataset-overview.ts b/dmp-frontend/src/app/core/model/dataset/dataset-overview.ts index 34bbe936c..3080a1548 100644 --- a/dmp-frontend/src/app/core/model/dataset/dataset-overview.ts +++ b/dmp-frontend/src/app/core/model/dataset/dataset-overview.ts @@ -1,5 +1,6 @@ import { DatasetProfileModel } from "./dataset-profile"; import { GrantOverviewModel } from '../grant/grant-overview'; +import { DmpOverviewModel } from '../dmp/dmp-overview'; export interface DatasetOverviewModel { id: string; @@ -8,7 +9,7 @@ export interface DatasetOverviewModel { datasetTemplate: DatasetProfileModel; users: any[]; - dmp: String; + dmp: DmpOverviewModel; grant: GrantOverviewModel; description: String; public: boolean; diff --git a/dmp-frontend/src/app/core/model/researcher/researcher.ts b/dmp-frontend/src/app/core/model/researcher/researcher.ts index 6c5bf6a98..9d23a8403 100644 --- a/dmp-frontend/src/app/core/model/researcher/researcher.ts +++ b/dmp-frontend/src/app/core/model/researcher/researcher.ts @@ -1,5 +1,5 @@ export interface ResearcherModel { - id: String; + id: string; name: String; reference: String; lastName: String; diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html index dcd35cc47..a85436ba8 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html @@ -8,8 +8,8 @@
- -

{{ dataset.label }}

+ +

{{ dataset.label }}

@@ -27,20 +27,10 @@ {{'DMP-OVERVIEW.PRIVATE' | translate}}
- - +
+ lock_outline + {{'DMP-OVERVIEW.LOCKED' | translate}} +
{{'GENERAL.STATUSES.EDIT' | translate}} : {{dataset.modified | date:"longDate"}}
@@ -49,10 +39,6 @@ check {{'TYPES.DATASET-STATUS.FINALISED' | translate}}
-
- create - {{'TYPES.DATASET-STATUS.DRAFT' | translate}} -
@@ -71,17 +57,10 @@ matTooltipPosition="above"> delete -
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
-
{{'DMP-OVERVIEW.GRANT' | translate}}
-
Grant label
- +
{{ dataset.grant.label }}
{{'DMP-OVERVIEW.RESEARCHERS' | translate}}
- +
{{'DATASET-LISTING.COLUMNS.DESCRIPTION' | translate}}
@@ -109,28 +87,6 @@
-
-
- -
- -

{{ 'DMP-LISTING.ACTIONS.MAKE-PUBLIC' | translate }}

-
-
-
-
- lock_outline - {{'DMP-OVERVIEW.LOCKED' | translate}} -
-
- lock_open - {{'DMP-OVERVIEW.UNLOCKED' | translate}} -
+
+ lock_outline + {{'DMP-OVERVIEW.LOCKED' | translate}}
-
- create - {{'TYPES.DMP.DRAFT' | translate}} -
@@ -60,22 +50,16 @@ matTooltip="{{'DMP-LISTING.ACTIONS.CLONE' | translate}}" matTooltipPosition="above"> content_copy - - -
{{'DMP-OVERVIEW.GRANT' | translate}}
{{ dmp.grant.label }}
@@ -145,7 +129,7 @@
-
+
- + +
@@ -60,7 +62,7 @@
-
About
+
FAQs
FAQs
@@ -108,7 +110,7 @@
-

ARGOS is comprised of two main functionalities: DMP templates and Dataset Descriptions. +

ARGOS is comprised of two main functionalities: DMP templates and Dataset Descriptions. Additional entities are Projects that link to funders and grants information.
ARGOS can be used for:

A. viewing/ consulting publicly released DMPs and @@ -131,7 +133,7 @@ Examples may refer to embedding DMP and DMP tools in specific curricula or even utilization of the tool for researchers and students familiarization with the concept and process, as part of library instructions’ sessions. -

+
@@ -206,4 +208,4 @@ - \ No newline at end of file + diff --git a/dmp-frontend/src/assets/splash/about/how-it-works.html b/dmp-frontend/src/assets/splash/about/how-it-works.html index 9bfe06404..7446523a2 100644 --- a/dmp-frontend/src/assets/splash/about/how-it-works.html +++ b/dmp-frontend/src/assets/splash/about/how-it-works.html @@ -59,7 +59,7 @@
-
About
+
How it works
How it works
From ace12c3140e7d2ed0e6b3d6baec6dfc7445a62e9 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Tue, 7 Jul 2020 12:22:45 +0300 Subject: [PATCH 15/15] Add updateusers end point for DMP --- .../src/main/java/eu/eudat/controllers/DMPs.java | 14 ++++++++++++++ .../logic/managers/DataManagementPlanManager.java | 12 ++++++++++++ .../src/app/core/services/dmp/dmp.service.ts | 5 +++++ 3 files changed, 31 insertions(+) diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java index 371a61386..135cac60b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java @@ -28,6 +28,7 @@ import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.listingmodels.DataManagementPlanListingModel; import eu.eudat.models.data.listingmodels.DataManagementPlanOverviewModel; +import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.query.DMPQuery; import eu.eudat.types.ApiMessageCode; @@ -277,6 +278,19 @@ public class DMPs extends BaseController { } } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"/updateusers/{id}"}) + public ResponseEntity> updateUsers(@PathVariable String id, @RequestBody List users, Principal principal) { + try { + this.dataManagementPlanManager.updateUsers(UUID.fromString(id), users, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Successfully Updated Colaborators for Data Datamanagement Plan.")); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to update the users of Data Management Plan.")); + } + } + /* * DOI Generation * */ diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 6d62ddb4e..495811aaa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -867,6 +867,18 @@ public class DataManagementPlanManager { this.updateIndex(dmp); } + public void updateUsers(UUID id, List users, Principal principal) throws Exception { + DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(id); + if (!isUserOwnerOfDmp(dmp, principal)) + throw new Exception("User does not have the privilege to do this action."); + clearUsers(dmp); + for (UserInfoListingModel userListing : users) { + UserInfo tempUser = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(userListing.getId()); + assignUser(dmp, tempUser, UserDMP.UserDMPRoles.fromInteger(userListing.getRole())); + } + + } + /* * Export Data * */ diff --git a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts index 9819c90e3..e97f1ec25 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts @@ -19,6 +19,7 @@ import { ExploreDmpCriteriaModel } from '../../query/explore-dmp/explore-dmp-cri import { RequestItem } from '../../query/request-item'; import { BaseHttpService } from '../http/base-http.service'; import { ConfigurationService } from '../configuration/configuration.service'; +import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; @Injectable() export class DmpService { @@ -96,6 +97,10 @@ export class DmpService { return this.http.post(this.actionUrl + 'unfinalize/' + id, { headers: this.headers }); } + updateUsers(id: string, users: UserInfoListingModel[]): Observable { + return this.http.post(`${this.actionUrl}updateusers/${id}`, users, {headers: this.headers}); + } + getDoi(id: string): Observable { return this.http.post(this.actionUrl + 'createZenodoDoi/' + id, { headers: this.headers }); }