From 9f8b4bb9f7226b74613d80a9d3a641243e5d7d7c Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Wed, 9 Sep 2020 17:52:42 +0300 Subject: [PATCH] Add License info step for the DMP Editor --- dmp-frontend/src/app/ui/dmp/dmp.module.ts | 4 +- .../ui/dmp/editor/dmp-editor.component.html | 4 + .../app/ui/dmp/editor/dmp-editor.component.ts | 4 +- .../license-info/license-info.component.html | 113 +++++++++++++++++ .../license-info/license-info.component.scss | 105 ++++++++++++++++ .../license-info/license-info.component.ts | 115 ++++++++++++++++++ dmp-frontend/src/assets/i18n/en.json | 7 ++ 7 files changed, 349 insertions(+), 3 deletions(-) create mode 100644 dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.html create mode 100644 dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.scss create mode 100644 dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.ts diff --git a/dmp-frontend/src/app/ui/dmp/dmp.module.ts b/dmp-frontend/src/app/ui/dmp/dmp.module.ts index c4b629388..187982142 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.module.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.module.ts @@ -42,6 +42,7 @@ import { DatasetInfoComponent } from './editor/dataset-info/dataset-info.compone import { DatasetEditorDetailsModule } from './editor/dataset-editor-details/dataset-editor-details.module'; import { DatasetEditorDetailsComponent } from './editor/dataset-editor-details/dataset-editor-details.component'; import { DatasetDescriptionFormModule } from '../misc/dataset-description-form/dataset-description-form.module'; +import { LicenseInfoComponent } from './editor/license-info/license-info.component'; @NgModule({ imports: [ @@ -88,7 +89,8 @@ import { DatasetDescriptionFormModule } from '../misc/dataset-description-form/d StartNewDmpDialogComponent, MainInfoComponent, FundingInfoComponent, - DatasetInfoComponent + DatasetInfoComponent, + LicenseInfoComponent ], entryComponents: [ DmpInvitationDialogComponent, diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html index da99abc8d..28eceacdc 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html @@ -81,6 +81,8 @@
  • {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}}
  • +
  • {{'DMP-EDITOR.STEPPER.LICENSE-INFO' | translate}} (6)
  • +
  • {{'DMP-EDITOR.STEPPER.DATASET' | translate}}
    @@ -126,6 +128,8 @@ + +
    diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts index 0c4dd3c51..9d6b4b81d 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts @@ -92,8 +92,8 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC selectedTab = 0; step: number = 0; - stepsBeforeDatasets: number = 3; - maxStep: number = 3; + stepsBeforeDatasets: number = 4; + maxStep: number = 4; constructor( private dmpProfileService: DmpProfileService, diff --git a/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.html b/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.html new file mode 100644 index 000000000..c7c672404 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.html @@ -0,0 +1,113 @@ +
    +
    + {{'DMP-EDITOR.LICENSE-INFO.INTRO' | translate}} +
    +
    + +
    +
    +
    4.1 {{'DMP-EDITOR.FIELDS.LANGUAGE' | translate}}
    +
    {{'DMP-EDITOR.LICENSE-INFO.HINT' | translate}}
    +
    + + + + {{ lang.name }} + + + + {{formGroup.get('extraProperties').get('language').getError('backendError').message}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
    +
    +
    + +
    +
    +
    4.2 {{'DMP-EDITOR.FIELDS.LICENSE' | translate}}
    +
    {{'DMP-EDITOR.LICENSE-INFO.HINT' | translate}}
    +
    + + + + + {{formGroup.get('extraProperties').get('license').getError('backendError').message}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
    +
    +
    + +
    +
    +
    4.3 {{'DMP-EDITOR.FIELDS.VISIBILITY' | translate}}
    +
    {{'DMP-EDITOR.LICENSE-INFO.HINT' | translate}}
    +
    + + + + {{vis.name | translate}} + + + + {{formGroup.get('extraProperties').get('visible').getError('backendError').message}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
    +
    +
    + +
    +
    +
    4.4 {{'DMP-EDITOR.FIELDS.PUBLICATION' | translate}}
    +
    {{'DMP-EDITOR.LICENSE-INFO.HINT' | translate}}
    +
    + + + + + + {{formGroup.get('extraProperties').get('publicDate').getError('backendError').message}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
    +
    +
    +
    +
    +
    4.5 {{'DMP-EDITOR.FIELDS.CONTACT' | translate}}
    +
    {{'DMP-EDITOR.LICENSE-INFO.HINT' | translate}}
    +
    + + + + {{vis.name | translate}} + + + + {{formGroup.get('extraProperties').get('contact').getError('backendError').message}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
    +
    +
    +
    +
    +
    4.6 {{'DMP-EDITOR.FIELDS.COST' | translate}}
    +
    {{'DMP-EDITOR.LICENSE-INFO.HINT' | translate}}
    +
    + + +
    +
    +
    +
    +
    diff --git a/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.scss b/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.scss new file mode 100644 index 000000000..51514d57e --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.scss @@ -0,0 +1,105 @@ +.main-info { + // position: relative; + // left: 362px; + // width: calc(100% - 366px); + + .intro { + text-align: left; + font-weight: 400; + letter-spacing: 0px; + color: #212121; + opacity: 1; + margin: 3rem 0rem 3rem 0rem; + } + + .heading { + text-align: left; + font-weight: 700; + font-size: 18px; + letter-spacing: 0px; + color: #212121; + opacity: 0.81; + margin-top: 1.625rem; + margin-bottom: 0.625rem; + } + + .hint { + text-align: left; + font-weight: 400; + font-size: 16px; + letter-spacing: 0px; + color: #212121; + opacity: 0.81; + margin-bottom: 2.125rem; + } + + .title-form, + .description-form { + text-align: left; + font-weight: 400; + font-size: 16px; + letter-spacing: 0.15px; + color: #7d7d7d; + opacity: 1; + margin-bottom: 1rem; + } + + // textarea::placeholder { + // font-style: oblique; + // } + + .input-btn { + border: none; + color: #aaaaaa; + background-color: #ffffff00; + cursor: pointer; + } + + .input-btn :hover { + color: #00b29f !important; + } +} + +::ng-deep .title-form .mat-form-field-appearance-outline .mat-form-field-outline { + background: #fafafa !important; +} + +::ng-deep .description-form .mat-form-field-appearance-outline .mat-form-field-outline { + background: #fafafa !important; +} + +::ng-deep .organizations-form .mat-form-field-appearance-outline .mat-form-field-outline { + background: #fafafa !important; +} + +::ng-deep .author-form .mat-form-field-appearance-outline .mat-form-field-outline { + background: #fafafa !important; +} + +::ng-deep .title-form .mat-form-field-appearance-outline .mat-form-field-infix { + font-size: 1rem; + padding: 0.6em 0 1em 0 !important; +} + +::ng-deep .description-form .mat-form-field-appearance-outline .mat-form-field-infix { + font-size: 1rem; + padding: 0.6em 0 1em 0 !important; +} + +::ng-deep .organizations-form .mat-form-field-appearance-outline .mat-form-field-infix { + font-size: 1rem; + padding: 0.6em 0 1em 0 !important; +} + +::ng-deep .author-form .mat-form-field-appearance-outline .mat-form-field-infix { + font-size: 1rem; + padding: 0.6em 0 1em 0 !important; +} + +.cost-placeholder { + text-decoration: underline; +} + +.cost-add { + margin-top: 1em; +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.ts b/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.ts new file mode 100644 index 000000000..60f2fa2d7 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/license-info/license-info.component.ts @@ -0,0 +1,115 @@ +import { BaseComponent } from '@common/base/base.component'; +import { OnInit, Component, Input, Output, EventEmitter } from '@angular/core'; +import { FormGroup, FormControl, FormArray } from '@angular/forms'; +import { map, takeUntil } from 'rxjs/operators'; +import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item'; +import { Observable } from 'rxjs'; +import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; +import { isNullOrUndefined } from 'util'; +import { MatDialog } from '@angular/material'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; +import { LanguageInfo } from '@app/core/model/language-info'; +import { LanguageInfoService } from '@app/core/services/culture/language-info-service'; +import { RequestItem } from '@app/core/query/request-item'; +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; + name: string; +} + +@Component({ + selector: 'license-info', + templateUrl: './license-info.component.html', + styleUrls: ['./license-info.component.scss'] +}) +export class LicenseInfoComponent extends BaseComponent implements OnInit { + + @Input() formGroup: FormGroup = null; + // @Input() datasetFormGroup: FormGroup; + @Input() isNewVersion: boolean; + @Input() isNewDataset: boolean; + @Input() isUserOwner: boolean; + @Input() isClone: boolean; + @Output() onFormChanged: EventEmitter = new EventEmitter(); + + visibles: Visible[] = [ + { value: true, name: 'DMP-EDITOR.VISIBILITY.PUBLIC' }, + { value: false, name: 'DMP-EDITOR.VISIBILITY.RESTRICTED' } + ] + + public formControl = new FormControl(); + + licenseAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { + filterFn: this.licenseSearch.bind(this), + initialItems: (excludedItems: any[]) => this.licenseSearch('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['name'], + titleFn: (item) => item['name'] + }; + + constructor( + private externalSourcesService: ExternalSourcesService, + private dialog: MatDialog, + private languageInfoService: LanguageInfoService + ) { + super(); + } + + ngOnInit() { + // if (this.formGroup.get('definition')) { this.selectedDmpProfileDefinition = this.formGroup.get('definition').value; } + // this.registerFormEventsForDmpProfile(); + + if (this.isNewVersion) { + this.formGroup.get('label').disable(); + } + + if (!this.isUserOwner && !this.isClone) { + this.formGroup.disable(); + } + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('publicDate').value)) { + this.formGroup.get('extraProperties').get('publicDate').patchValue(new Date()); + } + + this.formGroup.valueChanges.pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.onFormChanged.emit(); + }); + } + + getLanguageInfos(): LanguageInfo[] { + return this.languageInfoService.getLanguageInfoValues(); + } + + licenseSearch(query: string): Observable { + const request = new RequestItem(); + request.criteria = new LicenseCriteria(); + request.criteria.like = query; + request.criteria.type = ''; + return this.externalSourcesService.searchLicense(request); + } + + 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); + let costeditModel: CostEditorModel = new CostEditorModel(); + costeditModel = costeditModel.fromModel(result); + (this.formGroup.get('extraProperties').get('costs')).push(costeditModel.buildForm(null, true)); + } + }); + } +} diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 835adea18..cbe090e2d 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -794,6 +794,7 @@ "VISIBILITY": "Visibility", "PUBLICATION": "Publication Date", "CONTACT": "Contact", + "COST": "Costs", "DATASETS": "Datasets" }, "ACTIONS": { @@ -837,6 +838,7 @@ "FUNDING-INFO": "Funding info", "DATASET-SELECTION": "Dataset selection", "DATASET-INFO": "Dataset info", + "LICENSE-INFO": "License info", "DATASET": "Dataset", "PREVIOUS": "Previous", "NEXT": "Next" @@ -855,6 +857,11 @@ "SECOND-INTRO": "Datasets are documented following pre-defined templates which set the content of dataset descriptions. In Argos, a DMP can contain as many dataset descriptions as the datasets it documents.", "FIND": "Couldn't find a suitable one?" }, + "LICENSE-INFO": { + "INTRO": "Each DMP can contain specific license informatation over how much open and available it is, that way you can determine who can see your dataset and for how long that data will be private", + "HINT": "A brief description of what license the DMP is using, it’s type and when it will open.", + "TYPING": "Type more letters of the name so its more possible to find the correct one." + }, "CHANGES": "unsaved changes", "CLONE-DIALOG": { "CLONE": "Clone",