Merge branch 'ui-redesign' of gitlab.eudat.eu:dmp/OpenAIRE-EUDAT-DMP-service-pilot into ui-redesign

This commit is contained in:
gpapavgeri 2020-07-17 17:50:26 +03:00
commit 578093a53c
22 changed files with 1470 additions and 26 deletions

View File

@ -47,7 +47,7 @@
<div *ngFor="let item of listingItems; let i = index">
<app-dataset-listing-item-component [isPublic]="isPublic" [dataset]="item" [showDivider]="i != (listingItems.length - 1)"></app-dataset-listing-item-component>
</div>
<div *ngIf="listingItems && listingItems.length > 0 && this.startIndex < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center">
<div *ngIf="listingItems && listingItems.length > 0 && listingItems.length >= startIndex + pageSize" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>

View File

@ -36,6 +36,9 @@ import { AddCostComponent } from './editor/cost-editor/add-cost/add-cost.compone
import { CostListingComponent } from './editor/cost-editor/cost-listing/cost-listing.component';
import { DmpCriteriaDialogComponent } from './listing/criteria/dmp-criteria-dialog.component';
import { StartNewDmpDialogComponent } from './start-new-dmp-dialogue/start-new-dmp-dialog.component';
import { MainInfoComponent } from './editor/main-info/main-info.component';
import { FundingInfoComponent } from './editor/funding-info/funding-info.component';
import { DatasetInfoComponent } from './editor/dataset-info/dataset-info.component';
@NgModule({
@ -79,7 +82,10 @@ import { StartNewDmpDialogComponent } from './start-new-dmp-dialogue/start-new-d
AddOrganizationComponent,
AddCostComponent,
CostListingComponent,
StartNewDmpDialogComponent
StartNewDmpDialogComponent,
MainInfoComponent,
FundingInfoComponent,
DatasetInfoComponent
],
entryComponents: [
DmpInvitationDialogComponent,

View File

@ -1,6 +1,6 @@
<form *ngIf="formGroup" [formGroup]="formGroup">
<h1 mat-dialog-title>{{'ADDORGANIZATION-EDITOR.TITLE' | translate}}</h1>
<div mat-dialog-content class="row">
<div mat-dialog-content class="row pb-2">
<mat-form-field class="col-12">
<input matInput formControlName="name" placeholder="{{'ADDORGANIZATION-EDITOR.NAME' | translate}}" required>
<mat-error *ngIf="formGroup.get('name').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>

View File

@ -1,6 +1,6 @@
<form *ngIf="formGroup" [formGroup]="formGroup">
<h1 mat-dialog-title>{{'ADDRESEARCHERS-EDITOR.TITLE' | translate}}</h1>
<div mat-dialog-content class="row">
<div mat-dialog-content class="row pb-2">
<mat-form-field class="col-12">
<input matInput formControlName="firstName" placeholder="{{'ADDRESEARCHERS-EDITOR.FIRST_NAME' | translate}}" required>
<mat-error *ngIf="formGroup.get('firstName').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>

View File

@ -0,0 +1,34 @@
<div class="main-info" [formGroup]="formGroup">
<div class="col-12 intro">
<p>{{'DMP-EDITOR.DATASET-INFO.INTRO' | translate}}</p>
<p>{{'DMP-EDITOR.DATASET-INFO.SECOND-INTRO' | translate}}</p>
</div>
<div class="col-12 card">
<div class="row">
<div class="col-12">
<div class="heading">3 {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}}*</div>
<div class="hint">
<div class="pb-1">{{'DMP-EDITOR.MAIN-INFO.HINT' | translate}}</div>
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
</div>
<div class="profile-form">
<mat-form-field appearance="outline">
<app-multiple-auto-complete required='true' [formControl]="formGroup.get('profiles')" placeholder="{{'DMP-EDITOR.FIELDS.DATASET-TEMPLATES' | translate}}" [configuration]="profilesAutoCompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="formGroup.get('profiles').hasError('backendError')">
{{formGroup.get('profiles').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('profiles').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<button matSuffix class="input-btn" [disabled]="formGroup.get('profiles').disabled" (click)="availableProfiles($event)">
<mat-icon class="icon-btn">view_list</mat-icon>
</button>
</mat-form-field>
</div>
<div class="col pb-3 d-flex">
<span class="not-found">{{'DMP-EDITOR.DATASET-INFO.FIND' | translate}}</span>
<span class="insert" (click)="addDataset(dmp.id)">{{'DMP-EDITOR.ACTIONS.CREATE-DATASET' | translate}}</span>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,85 @@
.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;
}
.insert {
text-decoration: underline;
color: #00b29f;
cursor: pointer;
font-size: 1rem;
font-weight: 400;
}
.not-found {
cursor: pointer;
font-size: 1rem;
font-weight: 400;
padding: 0rem 0.5rem 0rem 0rem;
}
}
::ng-deep .profile-form .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
::ng-deep .profile-form .mat-form-field-appearance-outline .mat-form-field-infix {
font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}

View File

@ -0,0 +1,123 @@
import { BaseComponent } from '@common/base/base.component';
import { OnInit, Component, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { map, takeUntil } from 'rxjs/operators';
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 { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile';
import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service';
import { AvailableProfilesComponent } from '../available-profiles/available-profiles.component';
import { DmpEditorModel } from '../dmp-editor.model';
import { Router } from '@angular/router';
@Component({
selector: 'dataset-info',
templateUrl: './dataset-info.component.html',
styleUrls: ['./dataset-info.component.scss']
})
export class DatasetInfoComponent extends BaseComponent implements OnInit {
@Input() formGroup: FormGroup = null;
@Input() isUserOwner: boolean;
@Input() dmp: DmpEditorModel;
@Input() isPublic: boolean;
@Input() isFinalized: boolean;
@Input() isNewVersion: boolean;
@Input() isClone: boolean;
@Output() onFormChanged: EventEmitter<any> = new EventEmitter();
profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
filterFn: this.filterProfiles.bind(this),
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
displayFn: (item) => item['label'],
titleFn: (item) => item['label'],
subtitleFn: (item) => item['description']
};
selectedDmpProfileDefinition: DmpProfileDefinition;
constructor(
private language: TranslateService,
private configurationService: ConfigurationService,
private externalSourcesService: ExternalSourcesService,
private dialog: MatDialog,
private _service: DmpService,
private dmpProfileService: DmpProfileService,
private router: Router
) {
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();
});
}
// Researchers
filterProfiles(value: string): Observable<DatasetProfileModel[]> {
const request = new DataTableRequest<DatasetProfileCriteria>(null, null, { fields: ['+label'] });
const criteria = new DatasetProfileCriteria();
criteria.like = value;
request.criteria = criteria;
return this._service.searchDMPProfiles(request);
}
registerFormEventsForDmpProfile(definitionProperties?: DmpProfileDefinition): void {
this.formGroup.get('profile').valueChanges
.pipe(
takeUntil(this._destroyed))
.subscribe(Option => {
if (Option instanceof Object) {
this.selectedDmpProfileDefinition = null;
this.dmpProfileService.getSingle(Option.id)
.pipe(takeUntil(this._destroyed))
.subscribe(result => {
this.selectedDmpProfileDefinition = result.definition;
});
} else {
this.selectedDmpProfileDefinition = null;
}
this.selectedDmpProfileDefinition = definitionProperties;
})
}
availableProfiles(event: MouseEvent) {
event.stopPropagation();
const dialogRef = this.dialog.open(AvailableProfilesComponent, {
data: {
profiles: this.formGroup.get('profiles')
}
});
return false;
}
addDataset(id: String) {
this.router.navigate(['/datasets/new/' + id]);
}
}

View File

@ -1,4 +1,68 @@
<div class="main-content">
<div *ngIf="dmp" class="container-fluid">
<form *ngIf="formGroup" [formGroup]="formGroup" (ngSubmit)="formSubmit()">
<div class="fixed-editor-header">
<div class="card editor-header">
<div class="col">
<div class="row">
<div class="col-auto">
<div class="title">{{'DMP-EDITOR.TITLE.EDIT-DMP' | translate}}</div>
<div class="subtitle">{{ formGroup.get('label').value }} <span *ngIf="isDirty()" class="changes">({{'DMP-EDITOR.CHANGES' | translate}})</span></div>
</div>
<div class="ml-auto d-flex flex-row">
<button *ngIf="isDirty()" type="button" class="discard-btn mr-3" (click)="discardChanges()">
{{'DMP-EDITOR.ACTIONS.DISCARD' | translate}}
</button>
<div *ngIf="isNew" mat-raised-button type="button" (click)="addDataset()" class="save-btn">
<div>{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}</div>
</div>
<div *ngIf="!isNew && formGroup.enabled && !lockStatus">
<button *ngIf="!isFinalized" mat-raised-button type="submit" class="save-btn">
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}
</button>
</div>
<!-- <div *ngIf="!isNew && formGroup.enabled && !lockStatus">
<div *ngIf="!isFinalized" mat-raised-button type="submit" mat-raised-button type="button" (click)="addDataset()" class="save-btn">
<div>{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}</div>
</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
<div class="row editor-content">
<div class="col-auto stepper">
<div class="stepper-title">{{'DMP-EDITOR.STEPPER.USER-GUIDE' | translate}}</div>
<div class="stepper-options">
<ol class="stepper-list">
<li (click)="changeStep(0)" [ngClass]="{'active': this.step === 0}">{{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (4)</li>
<li (click)="changeStep(1)" [ngClass]="{'active': this.step === 1}">{{'DMP-EDITOR.STEPPER.FUNDING-INFO' | translate}} (3)</li>
<li (click)="changeStep(2)" [ngClass]="{'active': this.step === 2}">{{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}}</li>
</ol>
</div>
<div class="stepper-actions">
<div mat-raised-button type="button" class="col-auto previous stepper-btn mr-2 ml-auto" [ngClass]="{'previous-disabled': this.step === 0}" (click)="previousStep()">
<span class="material-icons">chevron_left</span>
<div>{{'DMP-EDITOR.STEPPER.PREVIOUS' | translate}}</div>
</div>
<div mat-raised-button type="button" class="col-auto next stepper-btn ml-auto" [ngClass]="{'next-disabled': this.step === this.maxStep}" (click)="nextStep()">
<span class="material-icons">chevron_right</span>
<div>{{'DMP-EDITOR.STEPPER.NEXT' | translate}}</div>
</div>
</div>
</div>
<div class="col-auto form">
<main-info [hidden]="this.step !== 0" [formGroup]="formGroup" [isUserOwner]="isUserOwner" (onFormChanged)="formChanged()"></main-info>
<funding-info [hidden]="this.step !== 1" [formGroup]="formGroup" [grantformGroup]="formGroup.get('grant')" [projectFormGroup]="formGroup.get('project')" [funderFormGroup]="formGroup.get('funder')" [isFinalized]="isFinalized || lockStatus" [isNew]="isNew" [isUserOwner]="isUserOwner" (onFormChanged)="formChanged()"></funding-info>
<dataset-info [hidden]="this.step !== 2" [formGroup]="formGroup" [dmp]="dmp" [isPublic]="isPublic" [isFinalized]="isFinalized || lockStatus" [isUserOwner]="isUserOwner" (onFormChanged)="formChanged()"></dataset-info>
</div>
</div>
</form>
</div>
</div>
<!-- <div class="main-content">
<div class="container-fluid">
<div *ngIf="dmp" class="card">
<div class="card-header card-header-plain d-flex">
@ -87,12 +151,6 @@
<mat-tab *ngIf="isNew" disabled>
<ng-template mat-tab-label></ng-template>
</mat-tab>
<!-- <mat-tab>
<ng-template mat-tab-label>
<mat-icon class="mr-2">settings</mat-icon>
{{ 'DMP-LISTING.ACTIONS.SETTINGS' | translate }}
</ng-template>
</mat-tab> -->
</mat-tab-group>
<div class="d-flex justify-content-end pt-2 pb-4 pl-2">
@ -129,4 +187,4 @@
</form>
</div>
</div>
</div>
</div> -->

View File

@ -8,6 +8,14 @@
}
}
form {
height: calc(100vh - 124px);
}
.main-content {
height: 100vh !important;
}
.menu-item {
width: 248px;
}
@ -29,6 +37,175 @@
padding-right: 6px;
}
.fixed-editor-header {
// position: fixed;
// width: calc(100% - 310px);
z-index: 3;
background-color: whitesmoke;
}
.editor-header {
height: 64px;
background: var(--unnamed-color-129d99) 0% 0% no-repeat padding-box;
background: #129d99 0% 0% no-repeat padding-box;
box-shadow: 0px 3px 6px #00000029;
padding: 0.6rem;
margin: 30px 0px 0px 0px;
border-radius: 4px;
opacity: 1;
}
.editor-content {
.form {
// position: relative;
// left: 362px;
// width: calc(100% - 366px);
position: relative;
left: 362px;
width: calc(100% - 366px);
overflow-y: auto;
height: calc(100vh - 172px);
}
}
.title {
text-align: left;
font-weight: 400;
font-size: 14px;
color: #ffffff;
opacity: 0.75;
}
.subtitle {
text-align: left;
color: #ffffff;
font-weight: 700;
font-size: 16px;
opacity: 1;
}
.discard-btn {
background: transparent;
border: 1px solid #ffffff;
color: white;
border-radius: 30px;
opacity: 1;
width: 110px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.save-btn {
background: #ffffff 0% 0% no-repeat padding-box;
border-radius: 30px;
opacity: 1;
width: 110px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
font-weight: 700;
color: #129d99;
cursor: pointer;
}
.changes {
font-weight: 400;
color: #ffffff;
}
.stepper {
position: fixed;
// height: 100%;
display: flex;
flex-direction: column;
height: calc(100vh - 205px);
}
.stepper-title {
text-align: left;
font-weight: 300;
font-size: 20px;
letter-spacing: 0px;
color: #212121;
opacity: 0.6;
margin: 2.875rem 0rem 2.875rem 0rem;
padding-left: 1rem;
}
.stepper-list li {
text-align: left;
font-weight: 400;
letter-spacing: 0px;
color: #212121;
padding: 0.3rem 0.1rem;
opacity: 0.6;
cursor: pointer;
}
.stepper-list .active {
color: #212121;
font-weight: 700;
opacity: 1;
}
.stepper-options {
// flex-grow: 1;
}
.stepper-actions {
display: flex;
padding-left: 1rem;
margin-top: auto;
// margin-top: 5rem;
// flex-grow: 8;
}
.stepper-btn {
border-radius: 30px;
opacity: 1;
width: 154px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
}
.previous {
color: #212121;
background: #f5f5f5 0% 0% no-repeat padding-box;
box-shadow: 0px 3px 6px #1e202029;
border: 2px solid #212121;
font-weight: 500;
cursor: pointer;
}
.next {
background: #129d99 0% 0% no-repeat padding-box;
color: white;
box-shadow: 0px 3px 6px #1e202029;
font-weight: 400;
cursor: pointer;
}
.previous-disabled {
border: 1px solid #b5b5b5;
color: #b5b5b5;
cursor: auto !important;
}
.next-disabled {
background: #cbcbcb 0% 0% no-repeat padding-box;
box-shadow: 0px 3px 6px #1e202029;
color: white;
cursor: auto !important;
}
::ng-deep .mat-tab-labels {
justify-content: space-between;
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Params, Router } from '@angular/router';
@ -61,8 +61,10 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
isFinalized = false;
dmp: DmpEditorModel;
formGroup: FormGroup = null;
selectedTab = 0;
formGroupRawValue: any;
hasChanges = false;
selectedTab = 0;
createNewVersion;
associatedUsers: Array<UserModel>;
people: Array<UserInfoListingModel>;
@ -72,6 +74,8 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
isUserOwner: boolean = true;
lock: LockModel;
lockStatus: Boolean;
step: number = 0;
maxStep: number = 2;
constructor(
private dmpProfileService: DmpProfileService,
@ -138,6 +142,7 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
this.dmp.extraProperties = new ExtraPropertiesFormModel();
this.dmp.fromModel(data);
this.formGroup = this.dmp.buildForm();
this.formGroupRawValue = this.formGroup.getRawValue();
this.setIsUserOwner();
if (!this.isUserOwner) {
this.isFinalized = true;
@ -195,6 +200,7 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
this.dmp.extraProperties = new ExtraPropertiesFormModel();
this.dmp.fromModel(data);
this.formGroup = this.dmp.buildForm();
this.formGroupRawValue = this.formGroup.getRawValue();
//this.registerFormEventsForDmpProfile(this.dmp.definition);
this.formGroup.disable();
// if (!this.isAuthenticated) {
@ -231,6 +237,7 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
this.dmp.extraProperties.visible = false;
this.dmp.extraProperties.contact = this.authService.current().id;
this.formGroup = this.dmp.buildForm();
this.formGroupRawValue = this.formGroup.getRawValue();
this.registerFormEventsForNewItem();
if (this.isAuthenticated) {
this.language.get('NAV-BAR.MY-DMPS').pipe(takeUntil(this._destroyed)).subscribe(x => {
@ -259,6 +266,10 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
});
}
public formChanged() {
this.hasChanges = true;
}
isAuthenticated() {
return this.authService.current() != null;
}
@ -576,6 +587,27 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => this.lock.id = Guid.parse(result));
}
public changeStep(index: number) {
this.step = index;
}
public nextStep() {
this.step = this.step < this.maxStep ? this.step + 1 : this.step;
}
public previousStep() {
this.step = this.step !== 0 ? this.step - 1 : this.step;
}
public isDirty(): boolean {
return this.formGroup.dirty && this.hasChanges;
}
public discardChanges() {
this.formGroup.patchValue(this.formGroupRawValue);
this.hasChanges = false;
}
// advancedClicked() {
// const dialogRef = this.dialog.open(ExportMethodDialogComponent, {
// maxWidth: '500px',

View File

@ -0,0 +1,143 @@
<div class="funding-info">
<form *ngIf="grantformGroup" [formGroup]="grantformGroup">
<div class="col-12 intro">
{{'DMP-EDITOR.FUNDING-INFO.INTRO' | translate}}
</div>
<div class="col-12 card">
<!-- Funder Field -->
<div class="row">
<div class="col-12">
<div class="heading">2.1 {{'DMP-EDITOR.FIELDS.FUNDING-ORGANIZATIONS' | translate}}*</div>
<div class="hint">
<div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div>
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
</div>
<div class="funder-form">
<div *ngIf="!isCreateNewFunder">
<mat-form-field appearance="outline">
<app-single-auto-complete required='true' [formControl]="funderFormGroup.get('existFunder')" placeholder="{{'DMP-EDITOR.FIELDS.FUNDER' | translate}}" [configuration]="funderAutoCompleteConfiguration">
</app-single-auto-complete>
</mat-form-field>
</div>
<!-- Create New Funder -->
<div *ngIf="isCreateNewFunder">
<mat-form-field appearance="outline">
<input matInput placeholder="{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.FIRST-STEP.FIELDS.FUNDER-LABEL' | translate}}" type="text" name="label" [formControl]="funderFormGroup.get('label')" required>
<mat-error *ngIf="funderFormGroup.get('label').hasError('backendError')">
{{funderFormGroup.get('label').getError('backendError').message}}</mat-error>
<mat-error *ngIf="funderFormGroup.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
<!-- Toggle Between Add Funder or Use Existing -->
<div class="col d-flex">
<div class="row" *ngIf="showToggleButton()">
<div *ngIf="isCreateNewFunder" (click)="createFunder()">
<span class="insert">{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.ACTIONS.EXIST-FUNDER' | translate}}</span>
</div>
<div *ngIf="!isCreateNewFunder" (click)="createFunder()">
<span [ngClass]="isNewVersion?'disabled-toggle':'not-found'">{{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}}</span>
<span [ngClass]="isNewVersion?'disabled-toggle':'insert'">{{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}}</span>
</div>
</div>
</div>
</div>
</div>
<!-- Grant field -->
<div class="row">
<div class="col-12">
<div class="heading">2.2 {{'DMP-EDITOR.FIELDS.GRANTS' | translate}}*</div>
<div class="hint">
<div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div>
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
</div>
<div class="grant-form">
<div *ngIf="!isCreateNew">
<mat-form-field appearance="outline">
<app-single-auto-complete required='true' [formControl]="grantformGroup.get('existGrant')" placeholder="{{'DMP-EDITOR.FIELDS.GRANT' | translate}}" [configuration]="grantAutoCompleteConfiguration">
</app-single-auto-complete>
</mat-form-field>
</div>
<!-- Create New Grant -->
<div *ngIf="isCreateNew">
<mat-form-field appearance="outline">
<input matInput placeholder="{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.FIRST-STEP.FIELDS.GRANT-LABEL' | translate}}" type="text" name="label" [formControl]="grantformGroup.get('label')" required>
<mat-error *ngIf="grantformGroup.get('label').hasError('backendError')">
{{grantformGroup.get('label').getError('backendError').message}}</mat-error>
<mat-error *ngIf="grantformGroup.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field appearance="outline">
<textarea matInput class="description-area" placeholder="{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.FIRST-STEP.FIELDS.DESCRIPTION' | translate}}" [formControl]="grantformGroup.get('description')" [required]="true"></textarea>
<mat-error *ngIf="grantformGroup.get('description').hasError('backendError')">
{{projectFormGroup.get('description').getError('backendError').message}}</mat-error>
<mat-error *ngIf="grantformGroup.get('description').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<!-- Toggle Between Add Grant or Use Existing -->
<div class="col d-flex">
<div class="row" *ngIf="showToggleButton()">
<div *ngIf="isCreateNew" (click)="createGrant()">
<span class="insert">{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.ACTIONS.EXIST-GRANT' | translate}}</span>
</div>
<div *ngIf="!isCreateNew" (click)="createGrant()">
<span [ngClass]="isNewVersion || isGrantDisabled()?'disabled-toggle':'not-found'">{{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}}</span>
<span [ngClass]="isNewVersion || isGrantDisabled()?'disabled-toggle':'insert'">{{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Project field-->
<div class="row">
<div class="col-12">
<div class="heading">2.3 {{'DMP-EDITOR.FIELDS.PROJECT' | translate}}</div>
<div class="hint">
<div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div>
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
</div>
<div class="project-form">
<div *ngIf="!isCreateNewProject">
<mat-form-field appearance="outline">
<app-single-auto-complete [formControl]="projectFormGroup.get('existProject')" placeholder="{{'DMP-EDITOR.FIELDS.PROJECT' | translate}}" [configuration]="projectAutoCompleteConfiguration">
</app-single-auto-complete>
</mat-form-field>
</div>
<!-- Create New Project -->
<div *ngIf="isCreateNewProject">
<mat-form-field appearance="outline">
<input matInput placeholder="{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.FIRST-STEP.FIELDS.PROJECT-LABEL' | translate}}" type="text" name="label" [formControl]="projectFormGroup.get('label')" required>
<mat-error *ngIf="projectFormGroup.get('label').hasError('backendError')">
{{projectFormGroup.get('label').getError('backendError').message}}</mat-error>
<mat-error *ngIf="projectFormGroup.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field appearance="outline">
<textarea matInput class="description-area" placeholder="{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.FIRST-STEP.FIELDS.DESCRIPTION' | translate}}" [formControl]="projectFormGroup.get('description')" [required]="true"></textarea>
<mat-error *ngIf="projectFormGroup.get('description').hasError('backendError')">
{{projectFormGroup.get('description').getError('backendError').message}}</mat-error>
<mat-error *ngIf="projectFormGroup.get('description').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<!-- Toggle Between Add Project or Use Existing -->
<div class="col pb-3 d-flex">
<div class="row" *ngIf="showToggleButton()">
<div *ngIf="isCreateNewProject" (click)="createProject()">
<span class="insert">{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.ACTIONS.EXIST-PROJECT' | translate}}</span>
</div>
<div *ngIf="!isCreateNewProject" (click)="createProject()">
<span [ngClass]="isNewVersion?'disabled-toggle':'not-found'">{{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}}</span>
<span [ngClass]="isNewVersion?'disabled-toggle':'insert'">{{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>

View File

@ -0,0 +1,112 @@
.funding-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;
}
.insert {
text-decoration: underline;
color: #00b29f;
cursor: pointer;
font-size: 1rem;
font-weight: 400;
}
.not-found {
cursor: pointer;
font-size: 1rem;
font-weight: 400;
padding: 0rem 0.5rem 0rem 0rem;
}
.disabled-toggle {
font-size: 1rem;
font-weight: 400;
padding: 0rem 0.5rem 0rem 0rem;
color: #e0e0e0 !important;
text-decoration: none;
}
}
::ng-deep .funder-form .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
::ng-deep .grant-form .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
::ng-deep .project-form .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
::ng-deep .funder-form .mat-form-field-appearance-outline .mat-form-field-infix {
font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}
::ng-deep .grant-form .mat-form-field-appearance-outline .mat-form-field-infix {
font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}
::ng-deep .project-form .mat-form-field-appearance-outline .mat-form-field-infix {
font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}

View File

@ -0,0 +1,250 @@
import { BaseComponent } from '@common/base/base.component';
import { OnInit, Component, Input, EventEmitter, Output } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { GrantTabModel } from '../grant-tab/grant-tab-model';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { FunderService } from '@app/core/services/funder/funder.service';
import { ProjectService } from '@app/core/services/project/project.service';
import { GrantService } from '@app/core/services/grant/grant.service';
import { RequestItem } from '@app/core/query/request-item';
import { GrantCriteria } from '@app/core/query/grant/grant-criteria';
import { ProjectCriteria } from '@app/core/query/project/project-criteria';
import { FunderCriteria } from '@app/core/query/funder/funder-criteria';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'funding-info',
templateUrl: './funding-info.component.html',
styleUrls: ['./funding-info.component.scss']
})
export class FundingInfoComponent extends BaseComponent implements OnInit {
// @Input() formGroup: FormGroup = null;
@Input() isUserOwner: boolean;
@Input() isNew: boolean;
@Input() isFinalized: boolean;
@Input() isClone: boolean = false;
@Input() isNewVersion: boolean;
@Input() formGroup: FormGroup;
@Input() grantformGroup: FormGroup;
@Input() projectFormGroup: FormGroup;
@Input() funderFormGroup: FormGroup = null;
@Output() onFormChanged: EventEmitter<any> = new EventEmitter();
isCreateNew = false;
isCreateNewProject = false;
isCreateNewFunder = false;
grant: GrantTabModel;
grantAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
projectAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
funderAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
constructor(
private grantService: GrantService,
private projectService: ProjectService,
private funderService: FunderService,
private language: TranslateService
) {
super();
}
getGrantIdText(item) {
if (item.reference != null && typeof item.reference == 'string') {
const parts = (item.reference as String).split('::');
return parts.length > 1 ? ' (' + parts[parts.length - 1] + ')' : '';
}
return '';
}
ngOnInit() {
const grantRequestItem: RequestItem<GrantCriteria> = new RequestItem();
grantRequestItem.criteria = new GrantCriteria();
this.funderAutoCompleteConfiguration = {
filterFn: this.searchFunder.bind(this),
initialItems: () => this.searchFunder(''),
displayFn: (item) => item['label'],
titleFn: (item) => item['label'],
subtitleFn: (item) => item['source'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['source'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'))
}
this.grantAutoCompleteConfiguration = {
filterFn: this.searchGrant.bind(this),
initialItems: () => this.searchGrant(''),
displayFn: (item) => item['label'] + this.getGrantIdText(item),
titleFn: (item) => item['label'] + this.getGrantIdText(item),
subtitleFn: (item) => item['source'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['source'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'))
};
this.projectAutoCompleteConfiguration = {
filterFn: this.searchProject.bind(this),
initialItems: () => this.searchProject(''),
displayFn: (item) => item['label'],
titleFn: (item) => item['label'],
subtitleFn: (item) => item['source'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['source'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'))
}
this.isCreateNew = (this.grantformGroup.get('label').value != null && this.grantformGroup.get('label').value.length > 0);
this.isCreateNewProject = (this.projectFormGroup.get('label').value != null && this.projectFormGroup.get('label').value.length > 0);
this.isCreateNewFunder = (this.funderFormGroup.get('label').value != null && this.funderFormGroup.get('label').value.length > 0);
this.setGrantValidators();
this.setProjectValidators();
this.setFunderValidators();
this.registerFormListeners();
if (this.isNew && !this.isClone) {
this.grantformGroup.reset();
this.grantformGroup.disable();
}
this.formGroup.valueChanges.pipe(takeUntil(this._destroyed))
.subscribe(x => {
this.onFormChanged.emit();
});
}
searchGrant(query: any) {
const grantRequestItem: RequestItem<GrantCriteria> = new RequestItem();
grantRequestItem.criteria = new GrantCriteria();
grantRequestItem.criteria.like = query;
if (this.funderFormGroup.get('existFunder').value) {
grantRequestItem.criteria.funderReference = this.funderFormGroup.controls['existFunder'].value.reference;
}
return this.grantService.getWithExternal(grantRequestItem);
}
searchProject(query: string) {
const projectRequestItem: RequestItem<ProjectCriteria> = new RequestItem();
projectRequestItem.criteria = new ProjectCriteria();
projectRequestItem.criteria.like = query;
return this.projectService.getWithExternal(projectRequestItem);
}
searchFunder(query: string) {
const funderRequestItem: RequestItem<FunderCriteria> = new RequestItem();
funderRequestItem.criteria = new FunderCriteria();
funderRequestItem.criteria.like = query;
return this.funderService.getWithExternal(funderRequestItem)
}
createGrant() {
if (this.isNewVersion) { return };
if (this.isGrantDisabled()) return;
this.isCreateNew = !this.isCreateNew;
this.setGrantValidators();
}
createProject() {
if (this.isNewVersion) { return };
this.isCreateNewProject = !this.isCreateNewProject;
this.setProjectValidators();
}
createFunder() {
if (this.isNewVersion) { return };
this.isCreateNewFunder = !this.isCreateNewFunder;
this.setFunderValidators();
}
setGrantValidators() {
if (this.isCreateNew) {
this.grantformGroup.get('existGrant').disable();
this.grantformGroup.get('label').enable();
this.grantformGroup.get('description').enable();
} else if (this.isClone && !this.isNewVersion) {
this.grantformGroup.get('existGrant').enable();
this.grantformGroup.get('label').disable();
this.grantformGroup.get('label').reset();
this.grantformGroup.get('description').disable();
this.grantformGroup.get('description').reset();
} else if (this.isFinalized || this.isNewVersion || !this.isUserOwner) {
this.grantformGroup.get('existGrant').disable();
this.grantformGroup.get('label').disable();
this.grantformGroup.get('description').disable();
} else {
this.grantformGroup.get('existGrant').enable();
this.grantformGroup.get('label').disable();
this.grantformGroup.get('label').reset();
this.grantformGroup.get('description').disable();
this.grantformGroup.get('description').reset();
}
}
setProjectValidators() {
if (this.isCreateNewProject) {
this.projectFormGroup.get('existProject').disable();
this.projectFormGroup.get('label').enable();
this.projectFormGroup.get('description').enable();
} else if (this.isClone && !this.isNewVersion) {
this.projectFormGroup.get('existProject').enable();
this.projectFormGroup.get('label').disable()
this.projectFormGroup.get('label').reset();
this.projectFormGroup.get('description').disable();
this.projectFormGroup.get('description').reset();
} else if (this.isFinalized || this.isNewVersion || !this.isUserOwner) {
this.projectFormGroup.get('existProject').disable();
this.projectFormGroup.get('label').disable();
this.projectFormGroup.get('description').disable();
} else {
this.projectFormGroup.get('existProject').enable();
this.projectFormGroup.get('label').disable();
this.projectFormGroup.get('label').reset();
this.projectFormGroup.get('description').disable();
this.projectFormGroup.get('description').reset();
}
}
setFunderValidators() {
if (this.isCreateNewFunder) {
this.funderFormGroup.get('existFunder').disable();
this.funderFormGroup.get('label').enable();
} else if (this.isClone && !this.isNewVersion) {
if (this.funderFormGroup.get('existFunder')) {
this.funderFormGroup.get('existFunder').enable();
this.funderFormGroup.get('label').disable();
this.funderFormGroup.get('label').reset();
} else {
this.funderFormGroup.get('label').enable();
}
} else if (this.isFinalized || this.isNewVersion || !this.isUserOwner) {
this.funderFormGroup.get('existFunder').disable();
this.funderFormGroup.get('label').disable();
} else {
this.funderFormGroup.enable();
this.funderFormGroup.get('label').disable();
this.funderFormGroup.get('label').reset();
}
}
registerFormListeners() {
this.funderFormGroup.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => {
this.funderValueChanged(x);
})
}
funderValueChanged(funder: any) {
if ((funder.label !== "" && funder.label != null && funder.label !== undefined)
|| (funder.existFunder !== null && funder.existFunder !== undefined && funder.existFunder.id !== undefined)) {
this.grantformGroup.reset();
this.grantformGroup.enable();
this.setGrantValidators();
} else {
this.grantformGroup.reset();
this.grantformGroup.disable();
if (this.isCreateNew) this.isCreateNew = !this.isCreateNew;
}
}
isGrantDisabled() {
return this.grantformGroup.disabled;
}
showToggleButton() {
return (!this.isFinalized && this.isUserOwner) || this.isClone;
}
}

View File

@ -177,7 +177,6 @@ export class GeneralTabComponent extends BaseComponent implements OnInit {
}
filterProfiles(value: string): Observable<DatasetProfileModel[]> {
const request = new DataTableRequest<DatasetProfileCriteria>(null, null, { fields: ['+label'] });
const criteria = new DatasetProfileCriteria();
criteria.like = value;

View File

@ -0,0 +1,80 @@
<div class="main-info" [formGroup]="formGroup">
<div class="col-12 intro">
{{'DMP-EDITOR.MAIN-INFO.INTRO' | translate}}
</div>
<div class="col-12 card">
<!-- Title Field -->
<div class="row">
<div class="col-12">
<div class="heading">1.1 {{'DMP-EDITOR.FIELDS.NAME' | translate}}*</div>
<div class="hint">{{'DMP-EDITOR.MAIN-INFO.HINT' | translate}}</div>
<div class="title-form">
<mat-form-field appearance="outline">
<input matInput placeholder="{{'DMP-EDITOR.FIELDS.NAME' | translate}}" type="text" name="label" formControlName="label" required>
<mat-error *ngIf="formGroup.get('label').hasError('backendError')">
{{formGroup.get('label').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
</div>
<!-- Description field -->
<div class="row">
<div class="col-12">
<div class="heading">1.2 {{'DMP-EDITOR.FIELDS.DESCRIPTION' | translate}}</div>
<div class="hint">{{'DMP-EDITOR.MAIN-INFO.HINT' | translate}}</div>
<div class="description-form">
<mat-form-field appearance="outline">
<textarea rows="3" matInput class="description-area" placeholder="{{'DMP-EDITOR.PLACEHOLDER.DESCRIPTION' | translate}}" formControlName="description"></textarea>
</mat-form-field>
</div>
</div>
</div>
<!-- Authors field-->
<div class="row">
<div class="col-12">
<div class="heading">1.3 {{'DMP-EDITOR.FIELDS.AUTHORS' | translate}}</div>
<div class="hint">
<div class="pb-1">{{'DMP-EDITOR.MAIN-INFO.HINT' | translate}}</div>
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
</div>
<div class="author-form">
<mat-form-field appearance="outline">
<app-multiple-auto-complete [formControl]="formGroup.get('researchers')" placeholder="{{'DMP-EDITOR.PLACEHOLDER.AUTHORS' | translate}}" [configuration]="researchersAutoCompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="formGroup.get('researchers').hasError('backendError')">
{{formGroup.get('researchers').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('researchers').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<button matSuffix class="input-btn" [disabled]="formGroup.get('researchers').disabled" type="button" (click)="addResearcher($event)">
<mat-icon class="icon-btn">add_circle</mat-icon>
</button>
</mat-form-field>
</div>
</div>
</div>
<!-- Organizations Field -->
<div class="row">
<div class="col-12">
<div class="heading">1.4 {{'DMP-EDITOR.FIELDS.ORGANISATIONS' | translate}}</div>
<div class="hint">
<div class="pb-1">{{'DMP-EDITOR.FIELDS.ORGANISATIONS-HINT' | translate}}</div>
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
</div>
<div class="organizations-form">
<mat-form-field appearance="outline">
<app-multiple-auto-complete [formControl]="formGroup.get('organisations')" placeholder="{{'DMP-EDITOR.PLACEHOLDER.ORGANIZATION' | translate}}" [configuration]="organisationsAutoCompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="formGroup.get('organisations').hasError('backendError')">
{{formGroup.get('organisations').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('organisations').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<button *ngIf="showOrganizationCreator()" matSuffix class="input-btn" [disabled]="canAddOrganizations()" type="button" (click)="addOrganization($event)">
<mat-icon class="icon-btn">add_circle</mat-icon>
</button>
</mat-form-field>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,97 @@
.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;
}

View File

@ -0,0 +1,139 @@
import { BaseComponent } from '@common/base/base.component';
import { OnInit, Component, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
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 { AddOrganizationComponent } from '../add-organization/add-organization.component';
import { AddResearcherComponent } from '../add-researcher/add-researcher.component';
@Component({
selector: 'main-info',
templateUrl: './main-info.component.html',
styleUrls: ['./main-info.component.scss']
})
export class MainInfoComponent extends BaseComponent implements OnInit {
@Input() formGroup: FormGroup = null;
@Input() isNewVersion: boolean;
@Input() isUserOwner: boolean;
@Input() isClone: boolean;
@Output() onFormChanged: EventEmitter<any> = new EventEmitter();
organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
filterFn: this.filterOrganisations.bind(this),
initialItems: (excludedItems: any[]) => this.filterOrganisations('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
displayFn: (item) => item['name'],
titleFn: (item) => item['name'],
subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'))
};
researchersAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
filterFn: this.filterResearchers.bind(this),
initialItems: (excludedItems: any[]) => this.filterResearchers('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
displayFn: (item) => item['name'],
titleFn: (item) => item['name'],
subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'))
};
constructor(
private language: TranslateService,
private configurationService: ConfigurationService,
private externalSourcesService: ExternalSourcesService,
private dialog: MatDialog
) {
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();
});
}
// Researchers
filterResearchers(value: string): Observable<ExternalSourceItemModel[]> {
return this.externalSourcesService.searchDMPResearchers({ criteria: { name: value, like: null } });
}
addResearcher(event: MouseEvent) {
event.stopPropagation();
const dialogRef = this.dialog.open(AddResearcherComponent, {
data: this.formGroup.get('researchers')
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
const fullName = result.firstName + " " + result.lastName;
const newItem = {
label: null,
name: fullName,
id: null,
status: 0,
key: "Internal",
};
const researchersArray = this.formGroup.get('researchers').value || [];
researchersArray.push(newItem);
this.formGroup.get('researchers').setValue(researchersArray);
}
});
}
// Organizations
showOrganizationCreator(): boolean {
return this.configurationService.allowOrganizationCreator;
}
filterOrganisations(value: string): Observable<ExternalSourceItemModel[]> {
return this.externalSourcesService.searchDMPOrganizations(value);
}
canAddOrganizations(): boolean {
if (!isNullOrUndefined(this.formGroup.get('organizations'))) {
return this.formGroup.get('organiztions').disabled;
} else {
return false;
}
}
addOrganization(event: MouseEvent) {
event.stopPropagation();
const dialogRef = this.dialog.open(AddOrganizationComponent, {
data: this.formGroup.get('organisations')
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
const fullName = result.name;
const newItem = {
label: null,
name: fullName,
id: null,
status: 0,
key: "Internal",
};
const organizationsArray = this.formGroup.get('organisations').value || [];
organizationsArray.push(newItem);
this.formGroup.get('organisations').setValue(organizationsArray);
}
});
}
}

View File

@ -42,7 +42,7 @@ export class DmpInvitationDialogComponent extends BaseComponent implements OnIni
public router: Router,
public dialogRef: MatDialogRef<DmpInvitationDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any
) {
) {
super();
this.roleNames = Object.keys(this.roles).filter(key => key.length > 1);
}
@ -60,7 +60,6 @@ export class DmpInvitationDialogComponent extends BaseComponent implements OnIni
titleFn: (item) => typeof(item) === 'string' ? item : item.name,
valueAssign: (item) => {
const result = typeof(item) === 'string' ? item : item.email;
console.log(result);
return result;
}
};
@ -124,5 +123,5 @@ export class DmpInvitationDialogComponent extends BaseComponent implements OnIni
// this.filteredUsersAsync = false;
// });
}
}
}

View File

@ -128,7 +128,7 @@
"LANGUAGE-EDITOR": "Language Editor",
"GUIDE-EDITOR": "User Guide Editor",
"LANGUAGE": "Language",
"SIGN-IN":"Sign in to account"
"SIGN-IN": "Sign in to account"
},
"FILE-TYPES": {
"PDF": "PDF",
@ -749,6 +749,7 @@
"TITLE": {
"NEW": "New Data Management Plan",
"EDIT": "Edit",
"EDIT-DMP": "Editing DMP",
"SUBTITLE": "DOI"
},
"FIELDS": {
@ -758,13 +759,16 @@
"ORGANISATIONS": "Organizations",
"ORGANISATIONS-HINT": "Add here the names of the organizations contributing to the creation and revision of the DMPs",
"RESEARCHERS": "Researchers",
"AUTHORS": "Authors",
"TEMPLATES": "Templates",
"TEMPLATE": "DMP Template",
"DATASET-TEMPLATES": "Related Dataset Description Templates",
"PROFILE": "DMP Template",
"PROJECT": "Project",
"GRANT": "Grant",
"GRANTS": "Grants",
"FUNDER": "Funder",
"FUNDING-ORGANIZATIONS": "Funding organizations",
"STATUS": "DMP Status",
"EXTERNAL-SOURCE-HINT": "List of values provided by external source(s)",
"COLLABORATORS": "Collaborators",
@ -781,9 +785,17 @@
"SAVE": "Save",
"CANCEL": "Cancel",
"DELETE": "Delete",
"DISCARD": "Discard",
"FINALISE": "Finalize",
"LOCK": "DMP is locked by another user",
"PERMISSION": "You have no permission to edit this DMP"
"PERMISSION": "You have no permission to edit this DMP",
"INSERT-MANUALLY": "Insert it manually",
"CREATE-DATASET": "Create new one"
},
"PLACEHOLDER": {
"DESCRIPTION": "Fill with description",
"ORGANIZATION": "Select organization",
"AUTHORS": "Select authors"
},
"SNACK-BAR": {
"UNSUCCESSFUL-DOI": "Unsuccessful DOI creation",
@ -798,7 +810,31 @@
"VISIBILITY": {
"PUBLIC": "Public",
"RESTRICTED": "Restricted"
}
},
"STEPPER": {
"USER-GUIDE": "Guide steps",
"MAIN-INFO": "Main info",
"FUNDING-INFO": "Funding info",
"DATASET-SELECTION": "Dataset selection",
"DATASET-INFO": "Dataset info",
"PREVIOUS": "Previous",
"NEXT": "Next"
},
"MAIN-INFO": {
"INTRO": "A DMP in Argos consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research datasets, namely dataset descriptions, that highlight the steps followed and the means used across data management activities.",
"HINT": "A brief description of what the DMP is about, its scope and objectives.",
"TYPING": "Type more letters of the name so its more possible to find the correct one."
},
"FUNDING-INFO": {
"INTRO": "A Data Management Plan (DMP) consist of your Data Management Plans closer to where they are generated, analysed and stored. argos is an open, extensible, collaborative tool supporting Open and FAIR Data Management Plans.",
"FIND": "Couldn't find the correct one?"
},
"DATASET-INFO": {
"INTRO": "A DMP in Argos consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research datasets, namely dataset descriptions, that highlight the steps followed and the means used across data management activities.",
"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?"
},
"CHANGES": "unsaved changes"
},
"DMP-PROFILE-LISTING": {
"TITLE": "DMP Templates",
@ -911,6 +947,9 @@
"DELETE": "Delete",
"UPDATE": "Update"
},
"PLACEHOLDER": {
"DESCRIPTION": "Fill with description"
},
"VERSION-DIALOG": {
"ABOUT": "Versioning is automated.",
"QUESTION": "It seems your Dataset Description Template is outdated. Do you want to update it to the latest version?"

View File

@ -745,6 +745,7 @@
"TITLE": {
"NEW": "Nuevo Plan de Gestión de Datos",
"EDIT": "Editar",
"EDIT-DMP": "Editing DMP",
"SUBTITLE": "DOI"
},
"FIELDS": {
@ -754,13 +755,16 @@
"ORGANISATIONS": "Organizaciones",
"ORGANISATIONS-HINT": "Añadir aquí los nombre de las organizaciones participantes en la creación y revisión de los PGDs",
"RESEARCHERS": "Investigadores",
"AUTHORS": "Authors",
"TEMPLATES": "Plantillas",
"TEMPLATE": "Plantilla del PGD",
"DATASET-TEMPLATES": "Related Dataset Description Templates",
"PROFILE": "Plantilla del PGD",
"PROJECT": "Proyecto",
"GRANT": "Subvención",
"GRANTS": "Grants",
"FUNDER": "Financiador",
"FUNDING-ORGANIZATIONS": "Funding organizations",
"STATUS": "Estado del PGD",
"EXTERNAL-SOURCE-HINT": "Lista de valores proporcioador por fuente(s) externa(s)",
"COLLABORATORS": "Collaborators",
@ -775,10 +779,18 @@
"SAVE-CHANGES": "Guardar cambios",
"SAVE": "Grabar",
"CANCEL": "Cancelar",
"DISCARD": "Discard",
"DELETE": "Borrar",
"FINALISE": "Finalizar",
"LOCK": "DMP is locked by another user",
"PERMISSION": "You have no permission to edit this DMP"
"PERMISSION": "You have no permission to edit this DMP",
"INSERT-MANUALLY": "Insert it manually",
"CREATE-DATASET": "Create new one"
},
"PLACEHOLDER": {
"DESCRIPTION": "Fill with description",
"ORGANIZATION": "Select organization",
"AUTHORS": "Select authors"
},
"SNACK-BAR": {
"UNSUCCESSFUL-DOI": "Fallo en la creación del DOI",
@ -793,7 +805,31 @@
"VISIBILITY": {
"PUBLIC": "Public",
"RESTRICTED": "Restricted"
}
},
"STEPPER": {
"USER-GUIDE": "Guide steps",
"MAIN-INFO": "Main info",
"FUNDING-INFO": "Funding info",
"DATASET-SELECTION": "Dataset selection",
"DATASET-INFO": "Dataset info",
"PREVIOUS": "Previous",
"NEXT": "Next"
},
"MAIN-INFO": {
"INTRO": "A DMP in Argos consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research datasets, namely dataset descriptions, that highlight the steps followed and the means used across data management activities.",
"HINT": "A brief description of what the DMP is about, its scope and objectives.",
"TYPING": "Type more letters of the name so its more possible to find the correct one."
},
"FUNDING-INFO": {
"INTRO": "A Data Management Plan (DMP) consist of your Data Management Plans closer to where they are generated, analysed and stored. argos is an open, extensible, collaborative tool supporting Open and FAIR Data Management Plans.",
"FIND": "Couldn't find the correct one?"
},
"DATASET-INFO": {
"INTRO": "A DMP in Argos consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research datasets, namely dataset descriptions, that highlight the steps followed and the means used across data management activities.",
"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?"
},
"CHANGES": "unsaved changes"
},
"DMP-PROFILE-LISTING": {
"TITLE": "Plantilla del PGD",

View File

@ -746,6 +746,7 @@
"TITLE": {
"NEW": "Νέα Σχέδιο Διαχείρισης Δεδομένων",
"EDIT": "Επεξεργασία",
"EDIT-DMP": "Editing DMP",
"SUBTITLE": "Μονοσήμαντο Αναγνωριστικό Ψηφιακού Αντικειμένου (DOI)"
},
"FIELDS": {
@ -755,13 +756,16 @@
"ORGANISATIONS": "Οργανισμοί",
"ORGANISATIONS-HINT": "Προσθήκη ονομάτων των οργανισμών που συνεισφέρουν στη δημιουργία και αναθεώρηση των Σχεδίων Διαχείρισης Δεδομένων",
"RESEARCHERS": "Ερευνητές",
"AUTHORS": "Authors",
"TEMPLATES": "Templates",
"TEMPLATE": "Template Σχεδίου Διαχείρισης Δεδομένων",
"DATASET-TEMPLATES": "Σχετικά Templates Περιγραφής Συνόλου Δεδομένων",
"PROFILE": "Template Σχεδίου Διαχείρισης Δεδομένων",
"PROJECT": "Έργο",
"GRANT": "Επιχορήγηση",
"GRANTS": "Grants",
"FUNDER": "Χορηγός",
"FUNDING-ORGANIZATIONS": "Funding organizations",
"STATUS": "Κατάσταση Σχεδίου Διαχείρισης Δεδομένων",
"EXTERNAL-SOURCE-HINT": "Κατάλογος των τιμών που παρέχονται από εξωτερικές πηγές",
"COLLABORATORS": "Συνεργάτες",
@ -777,9 +781,17 @@
"SAVE": "Αποθήκευση",
"CANCEL": "Ακύρωση",
"DELETE": "Διαγραφή",
"DISCARD": "Discard",
"FINALISE": "Οριστικοποίηση",
"LOCK": "Κλειδωμένο Σχέδιο Διαχείρισης Δεδομένων",
"PERMISSION": "Δεν έχετε άδεια να επεξεργαστείτε αυτό το Σχέδιο Διαχείρισης Δεδομένων"
"PERMISSION": "Δεν έχετε άδεια να επεξεργαστείτε αυτό το Σχέδιο Διαχείρισης Δεδομένων",
"INSERT-MANUALLY": "Insert it manually",
"CREATE-DATASET": "Create new one"
},
"PLACEHOLDER": {
"DESCRIPTION": "Fill with description",
"ORGANIZATION": "Select organization",
"AUTHORS": "Select authors"
},
"SNACK-BAR": {
"UNSUCCESSFUL-DOI": "Αποτυχία δημιουργίας Μονοσήμαντων Αναγνωριστικών Ψηφιακών Αντικειμένων (DOI)",
@ -794,7 +806,31 @@
"VISIBILITY": {
"PUBLIC": "Public",
"RESTRICTED": "Restricted"
}
},
"STEPPER": {
"USER-GUIDE": "Guide steps",
"MAIN-INFO": "Main info",
"FUNDING-INFO": "Funding info",
"DATASET-SELECTION": "Dataset selection",
"DATASET-INFO": "Dataset info",
"PREVIOUS": "Previous",
"NEXT": "Next"
},
"MAIN-INFO": {
"INTRO": "A DMP in Argos consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research datasets, namely dataset descriptions, that highlight the steps followed and the means used across data management activities.",
"HINT": "A brief description of what the DMP is about, its scope and objectives.",
"TYPING": "Type more letters of the name so its more possible to find the correct one."
},
"FUNDING-INFO": {
"INTRO": "A Data Management Plan (DMP) consist of your Data Management Plans closer to where they are generated, analysed and stored. argos is an open, extensible, collaborative tool supporting Open and FAIR Data Management Plans.",
"FIND": "Couldn't find the correct one?"
},
"DATASET-INFO": {
"INTRO": "A DMP in Argos consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research datasets, namely dataset descriptions, that highlight the steps followed and the means used across data management activities.",
"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?"
},
"CHANGES": "unsaved changes"
},
"DMP-PROFILE-LISTING": {
"TITLE": "Templates Σχεδίων Διαχείρισης Δεδομένων",

View File

@ -2,7 +2,6 @@ function toggleClass(ids, option) {
ids.forEach(id => {
var element = document.getElementById(id);
var className = element.getAttribute("class").replace(/ .*/, '');
console.log(className);
if (id === option) {
element.classList.replace(className, "selected");
} else {