Modified clone dmp

This commit is contained in:
apapachristou 2020-09-03 12:52:35 +03:00
parent fc7f8d4278
commit b908df98d7
22 changed files with 912 additions and 64 deletions

View File

@ -86,8 +86,8 @@ export class DmpService {
return this.http.post<DmpModel>(this.actionUrl + 'new/' + id, dataManagementPlanModel, { headers: this.headers });
}
clone(dataManagementPlanModel: DmpModel, id: String): Observable<DmpModel> {
return this.http.post<DmpModel>(this.actionUrl + 'clone/' + id, dataManagementPlanModel, { headers: this.headers });
clone(dataManagementPlanModel: DmpModel, id: String): Observable<String> {
return this.http.post<String>(this.actionUrl + 'clone/' + id, dataManagementPlanModel, { headers: this.headers });
}
delete(id: String): Observable<DmpModel> {

View File

@ -60,7 +60,7 @@
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DMP-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isDraftDmp(activity)" [routerLink]="['/new/dataset/' + activity.id]" target="_blank"><span class="material-icons icon-align">add</span>{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isUserOwner(activity)" (click)="openShareDialog(activity.id, activity.title)"><span class="material-icons icon-align pr-2">group_add</span>{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" [routerLink]="['/plans/clone/' + activity.id]" target="_blank"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="cloneClicked(activity)"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto pointer" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div>

View File

@ -14,7 +14,7 @@ import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog
import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { takeUntil } from 'rxjs/operators';
import { takeUntil, map } from 'rxjs/operators';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DatasetService } from '@app/core/services/dataset/dataset.service';
@ -27,12 +27,19 @@ import { RecentDmpModel } from '@app/core/model/recent-activity/recent-dmp-activ
import { RecentDatasetModel } from '@app/core/model/recent-activity/recent-dataset-activity.model';
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
import { FormControl, FormBuilder } from '@angular/forms';
import { FormControl, FormBuilder, FormGroup } from '@angular/forms';
import { DatasetCopyDialogueComponent } from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { Location } from '@angular/common';
import { LockService } from '@app/core/services/lock/lock.service';
import { DatasetUrlListing } from '@app/core/model/dataset/dataset-url-listing';
import { DmpEditorModel } from '@app/ui/dmp/editor/dmp-editor.model';
import { GrantTabModel } from '@app/ui/dmp/editor/grant-tab/grant-tab-model';
import { ProjectFormModel } from '@app/ui/dmp/editor/grant-tab/project-form-model';
import { FunderFormModel } from '@app/ui/dmp/editor/grant-tab/funder-form-model';
import { ExtraPropertiesFormModel } from '@app/ui/dmp/editor/general-tab/extra-properties-form.model';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { CloneDialogComponent } from '@app/ui/dmp/clone/clone-dialog/clone-dialog.component';
@Component({
selector: 'app-recent-edited-activity',
@ -45,12 +52,14 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
allRecentActivities: RecentActivityModel[];
recentActivityTypeEnum = RecentActivityType;
dmpModel: DmpEditorModel;
isDraft: boolean;
totalCount: number;
startIndex: number = 0;
dmpOffset: number = 0;
datasetOffset: number = 0;
pageSize: number = 5;
dmpFormGroup: FormGroup;
public formGroup = new FormBuilder().group({
like: new FormControl(),
order: new FormControl()
@ -187,6 +196,46 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
});
}
cloneClicked(dmp: RecentActivityModel) {
this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmpModel = new DmpEditorModel();
this.dmpModel.grant = new GrantTabModel();
this.dmpModel.project = new ProjectFormModel();
this.dmpModel.funder = new FunderFormModel();
this.dmpModel.extraProperties = new ExtraPropertiesFormModel();
this.dmpModel.fromModel(data);
this.dmpModel.status = DmpStatus.Draft;
this.dmpFormGroup = this.dmpModel.buildForm();
this.dmpFormGroup.get('label').setValue(dmp.title + " New");
this.openCloneDialog();
});
}
openCloneDialog() {
const dialogRef = this.dialog.open(CloneDialogComponent, {
maxWidth: '700px',
data: {
formGroup: this.dmpFormGroup,
datasets: this.dmpFormGroup.get('datasets').value,
confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CLONE'),
cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCloneCallbackSuccess(complete),
error => this.onCloneCallbackError(error)
);
}
});
}
openDeleteDmpDialog(dmp: DmpListingModel) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '300px',
@ -257,6 +306,15 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
}
onCloneCallbackSuccess(cloneId: String): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/plans/edit/', cloneId]);
}
onCloneCallbackError(error: any) {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-CLONE'), SnackBarNotificationLevel.Error);
}
redirect(id: string, type: RecentActivityType) {
switch (type) {
case RecentActivityType.Grant: {

View File

@ -54,7 +54,7 @@
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DMP-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isDraftDmp(activity)" [routerLink]="['/new/dataset/' + activity.id]" target="_blank"><span class="material-icons icon-align">add</span>{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isUserOwner(activity)" (click)="openShareDialog(activity.id, activity.label)"><span class="material-icons icon-align pr-2">group_add</span>{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" [routerLink]="['/plans/clone/' + activity.id]" target="_blank"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="cloneClicked(activity)"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto pointer" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div>

View File

@ -14,17 +14,24 @@ import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog
import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { takeUntil } from 'rxjs/operators';
import { takeUntil, map } from 'rxjs/operators';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DatasetService } from '@app/core/services/dataset/dataset.service';
import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing';
import { Role } from '@app/core/common/enum/role';
import { FormBuilder, FormControl } from '@angular/forms';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { Location } from '@angular/common';
import { LockService } from '@app/core/services/lock/lock.service';
import { ExploreDmpCriteriaModel } from '@app/core/query/explore-dmp/explore-dmp-criteria';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { CloneDialogComponent } from '@app/ui/dmp/clone/clone-dialog/clone-dialog.component';
import { DmpEditorModel } from '@app/ui/dmp/editor/dmp-editor.model';
import { GrantTabModel } from '@app/ui/dmp/editor/grant-tab/grant-tab-model';
import { ExtraPropertiesFormModel } from '@app/ui/dmp/editor/general-tab/extra-properties-form.model';
import { FunderFormModel } from '@app/ui/dmp/editor/grant-tab/funder-form-model';
import { ProjectFormModel } from '@app/ui/dmp/editor/grant-tab/project-form-model';
@Component({
selector: 'app-recent-edited-dmp-activity',
@ -37,12 +44,14 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O
dmpActivities: DmpListingModel[];
datasetActivities: DatasetListingModel[];
dmpModel: DmpEditorModel;
recentActivityTypeEnum = RecentActivityType;
isDraft: boolean;
totalCount: number;
startIndex: number = 0;
pageSize: number = 5;
dmpFormGroup: FormGroup;
public formGroup = new FormBuilder().group({
like: new FormControl(),
order: new FormControl()
@ -158,8 +167,43 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O
}
cloneClicked(dmp: DmpListingModel) {
let url = this.router.createUrlTree(['/plans/clone/', dmp.id]);
window.open(url.toString(), '_blank');
this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmpModel = new DmpEditorModel();
this.dmpModel.grant = new GrantTabModel();
this.dmpModel.project = new ProjectFormModel();
this.dmpModel.funder = new FunderFormModel();
this.dmpModel.extraProperties = new ExtraPropertiesFormModel();
this.dmpModel.fromModel(data);
this.dmpModel.status = DmpStatus.Draft;
this.dmpFormGroup = this.dmpModel.buildForm();
this.dmpFormGroup.get('label').setValue(dmp.label + " New");
this.openCloneDialog();
});
}
openCloneDialog() {
const dialogRef = this.dialog.open(CloneDialogComponent, {
maxWidth: '700px',
data: {
formGroup: this.dmpFormGroup,
datasets: this.dmpFormGroup.get('datasets').value,
confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CLONE'),
cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCloneCallbackSuccess(complete),
error => this.onCloneCallbackError(error)
);
}
});
}
deleteClicked(id: string) {
@ -243,6 +287,15 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
}
onCloneCallbackSuccess(cloneId: String): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/plans/edit/', cloneId]);
}
onCloneCallbackError(error: any) {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-CLONE'), SnackBarNotificationLevel.Error);
}
redirect(id: string) {
if (this.isAuthenticated()) {
this.router.navigate(['../plans/overview/' + id]);

View File

@ -266,7 +266,7 @@ export class DatasetExternalReferencesEditorComponent extends BaseComponent impl
isInternal(element: any): boolean {
if (element.get('source') == null) {
console.log(element);
// console.log(element);
}
return element.get('source').value === 'Internal';
}

View File

@ -1,4 +1,110 @@
<div class="main-content">
<div class="container-fluid">
<form *ngIf="formGroup" [formGroup]="formGroup" (ngSubmit)="formSubmit()">
<!-- DMP Header -->
<div [hidden]="this.step >= stepsBeforeDatasets" class="fixed-editor-header">
<div class="card editor-header">
<div class="col">
<div class="row">
<div class="col-auto info">
<div class="title">{{'DMP-EDITOR.TITLE.CLONE-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" mat-raised-button class="discard-btn mr-3" (click)="discardChanges()">
{{'DMP-EDITOR.ACTIONS.DISCARD' | translate}}
</button>
<div *ngIf="formGroup.enabled">
<button *ngIf="!isFinalized" mat-raised-button type="submit" (click)="formSubmit()" [disabled]="!isFormValid()" class="save-btn">
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Dataset Header -->
<div *ngFor="let dataset of datasets.controls; let i = index" [hidden]="(this.step !== i + stepsBeforeDatasets)" class="fixed-editor-header">
<div class="card dataset-editor-header">
<div class="col">
<div class="row">
<div class="col info">
<!-- <div class="dataset-title">{{'DMP-EDITOR.TITLE.EDIT-DATASET' | translate}}</div> -->
<div class="dataset-title">{{'DATASET-LISTING.SELECT-DATASETS-TO-CLONE' | translate}}</div>
<div class="dataset-subtitle">{{ dataset.value.label }} <span *ngIf="isDirty()" class="dataset-changes">({{'DMP-EDITOR.CHANGES' | translate}})</span></div>
<div class="d-flex flex-direction-row pt-2">
<div class="col-auto dataset-part-of">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
<div class="col-auto dmp-label ml-3">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
</div>
<div class="col-auto dmp-title">{{ formGroup.get('label').value }}</div>
<div class="col d-flex align-items-center">
<a [routerLink]="['/overview/' + formGroup.get('id').value]" target="_blank" class="pointer"><span class="material-icons">open_in_new</span></a>
</div>
</div>
</div>
<div class="row">
<div class="col-auto d-flex align-items-center p-0">
<button *ngIf="isDirty()" type="button" mat-raised-button class="dataset-discard-btn" (click)="discardChanges()">
{{'DMP-EDITOR.ACTIONS.DISCARD' | translate}}
</button>
</div>
<div class="col-auto d-flex align-items-center">
<button mat-raised-button class="dataset-save-btn" type="submit" (click)="formSubmit()" [disabled]="!isFormValid()">{{ 'DATASET-WIZARD.ACTIONS.SAVE' | translate }}</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row editor-content">
<div class="col-auto" [ngClass]="{'dmp-stepper': this.step < stepsBeforeDatasets, 'dataset-stepper': this.step >= stepsBeforeDatasets}">
<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>
<li *ngFor="let dataset of datasets.controls; let i = index" #selectedItems (click)="changeStep(i + stepsBeforeDatasets, dataset)" [ngClass]="{'active-dataset': this.step === i + stepsBeforeDatasets}">
<div class="dataset-tag">{{'DMP-EDITOR.STEPPER.DATASET' | translate}}</div>
<span class="d-flex">
<div *ngIf="dataset.value.status === 1" class="finalized-label" ><mat-icon class="status-icon check-icon">check</mat-icon>{{'TYPES.DATASET-STATUS.FINALISED' | translate}}</div>
<!-- <mat-checkbox class="col-auto pl-0 pt-1" checked="true" [value]="dataset.value.id" color="accent" (change)="selectionChanged($event, dataset)">
Include in clone
</mat-checkbox> -->
</span>
<ul class="dataset-list">
<li [ngClass]="{'active': this.step === i + stepsBeforeDatasets}">{{ dataset.get('label').value }} (8)</li>
</ul>
</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 stepper-btn ml-auto" [ngClass]="{ 'next-disabled': this.step === this.maxStep, 'next': this.step < stepsBeforeDatasets, 'dataset-next': this.step >= stepsBeforeDatasets }" (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" [isNewVersion]="isNewVersion" [isClone]="isClone" (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" [isNewVersion]="isNewVersion" [isClone]="isClone" [isNew]="isNew" [isUserOwner]="isUserOwner" (onFormChanged)="formChanged()"></funding-info>
<dataset-info [hidden]="this.step !== 2" [formGroup]="formGroup" [dmp]="dmp" [isPublic]="isPublic" [isFinalized]="isFinalized" [isUserOwner]="isUserOwner" (onFormChanged)="formChanged()"></dataset-info>
<div *ngFor="let dataset of datasets.controls; let i = index" [hidden]="this.step !== i + stepsBeforeDatasets">
<dataset-editor-details [formGroup]="dataset" [dmpId]="formGroup.get('id').value" (formChanged)="formChanged($event)"></dataset-editor-details>
</div>
</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">
@ -56,4 +162,4 @@
</form>
</div>
</div>
</div>
</div> -->

View File

@ -1,42 +1,421 @@
.menu-item {
width: 248px;
form {
height: calc(100vh - 124px);
}
.more-horiz {
font-size: 28px;
color: #aaaaaa;
a {
color: #000000;
}
.clone-dmp {
height: 3.5em;
}
.clone-mode {
// line-height: 2em;
text-transform: uppercase;
color: #089dbb;
font-weight: 400;
align-self: center;
}
.clone-mode-text {
color: black;
align-self: center;
}
.more-icon :hover {
a:hover {
color: #00b29f;
}
::ng-deep .mat-tab-labels {
justify-content: space-between;
.main-content {
height: 100vh !important;
}
::ng-deep .mat-tab-label-content {
text-transform: uppercase;
.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;
.info {
flex: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.dataset-editor-header {
height: 113px;
background: var(--unnamed-color-129d99) 0% 0% no-repeat padding-box;
background: #f7dd72 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;
.info {
flex: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.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 - 218px);
}
}
.title {
text-align: left;
font-weight: 400;
font-size: 14px;
color: #ffffff;
opacity: 0.75;
}
.dataset-title {
text-align: left;
letter-spacing: 0px;
color: #212121;
opacity: 0.9;
font-size: 14px;
font-weight: 400;
}
.subtitle {
text-align: left;
color: #ffffff;
font-weight: 700;
font-size: 16px;
opacity: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dataset-subtitle {
text-align: left;
letter-spacing: 0px;
color: #212121;
font-weight: 700;
font-size: 16px;
opacity: 0.9;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.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;
}
.dataset-discard-btn {
border: 1px solid #212121;
border-radius: 30px;
opacity: 1;
background-color: transparent;
font-weight: 700;
width: 110px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.dataset-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;
cursor: pointer;
}
.dataset-part-of {
display: flex;
flex-direction: row;
text-align: left;
font-weight: 400;
font-family: "Roboto", sans-serif;
font-size: 0.875rem;
align-items: center;
letter-spacing: 0px;
color: #3d3d3d;
padding: 0;
}
.changes {
font-weight: 400;
color: #ffffff;
}
.dataset-changes {
font-weight: 400;
color: #000000;
}
.dataset-stepper {
position: fixed;
// height: 100%;
display: flex;
flex-direction: column;
height: calc(100vh - 240px);
overflow-y: auto;
}
.dmp-stepper {
position: fixed;
// height: 100%;
display: flex;
flex-direction: column;
height: calc(100vh - 190px);
overflow-y: auto;
}
.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;
max-width: 290px;
}
.stepper-list .active {
color: #212121;
font-weight: 700;
opacity: 1;
}
.stepper-list .active-dataset {
color: #212121;
font-weight: 700;
opacity: 1;
.dataset-tag {
width: 73px;
height: 27px;
background-color: #f7dd72;
color: #5d5d5d;
border-radius: 4px;
font-weight: 400;
font-size: 14px;
justify-content: center;
display: flex;
align-items: center;
}
}
.stepper-options {
// flex-grow: 1;
}
.stepper-actions {
display: flex;
padding-left: 1rem;
margin-top: auto;
margin-bottom: 0.5rem;
// 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;
}
.dataset-next {
background: #f7dd72 0% 0% no-repeat padding-box;
color: #212121;
box-shadow: 0px 3px 6px #1e202029;
font-weight: 700;
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;
}
.dataset-list {
list-style-type: none;
padding-left: 0px;
}
.dmp-label {
width: 67px;
height: 37px;
background: #129d99 0% 0% no-repeat padding-box;
color: white;
border-radius: 4px;
opacity: 1;
display: flex;
align-items: center;
justify-content: center;
}
.dmp-title {
text-align: left;
font-weight: 500;
font-family: "Roboto", sans-serif;
font-size: 1rem;
opacity: 0.81;
padding-top: 0.75rem;
padding-bottom: 0.55rem;
color: #212121;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.status-icon {
font-size: 1.2em;
color: #a7a7a7;
vertical-align: text-top;
}
.cursor-default {
cursor: default;
}
.finalized-label {
display: flex;
align-items: center;
padding-right: 1rem;
font-weight: 400;
font-size: 0.875rem;
}
// ::ng-deep .mat-tab-labels {
// justify-content: space-between;
// }
// ::ng-deep .mat-tab-label-content {
// text-transform: uppercase;
// }
::ng-deep .mat-ink-bar {
background-color: #00b29f !important;
// background-color: #0070c0 !important;
}
/////// Old version style
// .menu-item {
// width: 248px;
// }
// .more-horiz {
// font-size: 28px;
// color: #aaaaaa;
// }
// .clone-dmp {
// height: 3.5em;
// }
// .clone-mode {
// // line-height: 2em;
// text-transform: uppercase;
// color: #089dbb;
// font-weight: 400;
// align-self: center;
// }
// .clone-mode-text {
// color: black;
// align-self: center;
// }
// .more-icon :hover {
// color: #00b29f;
// }
// ::ng-deep .mat-tab-labels {
// justify-content: space-between;
// }
// ::ng-deep .mat-tab-label-content {
// text-transform: uppercase;
// }
// ::ng-deep .mat-ink-bar {
// background-color: #00b29f !important;
// }

View File

@ -1,7 +1,7 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormGroup, FormControl, FormBuilder, FormArray } from '@angular/forms';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { DmpService } from '@app/core/services/dmp/dmp.service';
@ -18,6 +18,14 @@ import { Observable, of as observableOf } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model';
import { Principal } from '@app/core/model/auth/principal';
import { AuthService } from '@app/core/services/auth/auth.service';
import { Role } from '@app/core/common/enum/role';
import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria';
import { DatasetService } from '@app/core/services/dataset/dataset.service';
import { DmpEditorModel } from '../editor/dmp-editor.model';
@Component({
@ -28,23 +36,35 @@ import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties
export class DmpCloneComponent extends BaseComponent implements OnInit {
breadCrumbs: Observable<BreadcrumbItem[]>;
dmp: DmpWizardEditorModel;
// dmp: DmpWizardEditorModel;
dmp: DmpEditorModel;
formGroup: FormGroup;
itemId: string;
datasetId: string = null;
isFinalized: false;
isPublic: false;
selectedTab = 0;
parentDmpLabel: string;
isNewVersion: boolean = false;
isClone: boolean = true;
isNew: boolean = false;
isUserOwner: boolean = true;
// datasets: DatasetListingModel[] = [];
datasets = new FormArray([]);
removeIndexes = [];
selectedTab = 0;
step: number = 0;
stepsBeforeDatasets: number = 3;
maxStep: number = 3;
constructor(
private route: ActivatedRoute,
private router: Router,
private language: TranslateService,
private dmpService: DmpService,
private uiNotificationService: UiNotificationService
private authentication: AuthService,
private uiNotificationService: UiNotificationService,
private datasetService: DatasetService
) {
super();
}
@ -57,7 +77,7 @@ export class DmpCloneComponent extends BaseComponent implements OnInit {
this.dmpService.getSingle(this.itemId).pipe(map(data => data as DmpModel))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmp = new DmpWizardEditorModel();
this.dmp = new DmpEditorModel();
this.dmp.grant = new GrantTabModel();
this.dmp.project = new ProjectFormModel();
this.dmp.funder = new FunderFormModel();
@ -66,6 +86,8 @@ export class DmpCloneComponent extends BaseComponent implements OnInit {
this.dmp.status = DmpStatus.Draft;
this.formGroup = this.dmp.buildForm();
this.datasets = this.formGroup.get('datasets') as FormArray;
this.parentDmpLabel = this.formGroup.get('label').value;
if (this.route.routeConfig.path.startsWith('new_version/')) {
this.formGroup.get('version').setValue(this.formGroup.get('version').value + 1);
@ -77,12 +99,29 @@ export class DmpCloneComponent extends BaseComponent implements OnInit {
this.isNewVersion = false;
}
// const request: DataTableRequest<DatasetCriteria> = new DataTableRequest<DatasetCriteria>(null, null, null);
// request.criteria = new DatasetCriteria();
// request.criteria.dmpIds = [this.formGroup.get('id').value];
// request.criteria.allVersions = true;
// this.datasetService.getPaged(request)
// .pipe(takeUntil(this._destroyed))
// .subscribe(items => {
// this.datasets = items.data;
// this.formGroup.addControl('datasets', new FormBuilder().array(new Array<FormControl>()));
// this.datasets.forEach(element => {
// console.log(element);
// (<FormArray>this.formGroup.get('datasets')).push(new FormBuilder().group({ id: element.value }));
// });
// });
const breadCrumbs = [];
breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DMPS'), url: "/plans" });
breadCrumbs.push({ parentComponentName: 'DmpListingComponent', label: this.dmp.label, url: '/plans/clone/' + this.dmp.id });
this.breadCrumbs = observableOf(breadCrumbs);
});
});
}
public cancel(id: String): void {
@ -108,6 +147,7 @@ export class DmpCloneComponent extends BaseComponent implements OnInit {
);
}
else {
this.removeDatasetsFromClone();
this.dmpService.clone(this.formGroup.getRawValue(), this.itemId)
.pipe(takeUntil(this._destroyed))
.subscribe(
@ -136,4 +176,59 @@ export class DmpCloneComponent extends BaseComponent implements OnInit {
});
}
isDirty() {
}
discardChanges() {
}
public changeStep(index: number, dataset?: DatasetListingModel) {
this.step = index;
if (dataset) { this.datasetId = dataset.id };
}
public nextStep() {
this.step = this.step < this.maxStep ? this.step + 1 : this.step;
if (this.step >= this.stepsBeforeDatasets) {
this.datasetId = this.datasets[this.step - this.stepsBeforeDatasets].id;
}
}
public previousStep() {
this.step = this.step !== 0 ? this.step - 1 : this.step;
if (this.step >= this.stepsBeforeDatasets) {
this.datasetId = this.datasets[this.step - this.stepsBeforeDatasets].id;
}
}
setIsUserOwner() {
if (this.dmp) {
const principal: Principal = this.authentication.current();
this.isUserOwner = principal.id === this.dmp.users.find(x => x.role === Role.Owner).id;
}
}
formChanged() {
}
selectionChanged(event, dataset) {
var datasetIndex = this.formGroup.get('datasets').value.map(function (item) { return item.id; }).indexOf(dataset.value.id);
if (!event.checked) {
if (this.removeIndexes.indexOf(datasetIndex) === -1) { this.removeIndexes.push(datasetIndex); }
} else {
var index = this.removeIndexes.indexOf(datasetIndex);
this.removeIndexes.splice(index, 1)
}
}
removeDatasetsFromClone() {
this.removeIndexes.forEach(index => {
this.formGroup.get('datasets')['controls'].splice(index, 1);
this.formGroup.get('datasets').value.splice(index, 1)
})
}
}

View File

@ -90,6 +90,7 @@ export class DatasetEditorDetailsComponent extends BaseComponent implements OnIn
}
ngOnInit() {
if (this.formGroup.get('status').value === 1) {
this.formGroup.disable();
}
@ -174,7 +175,7 @@ export class DatasetEditorDetailsComponent extends BaseComponent implements OnIn
public restartTour(label: string): void {
this.setDashboardTourDmp(label);
console.log(this.dashboardTourDmp.steps[0].selector);
// console.log(this.dashboardTourDmp.steps[0].selector);
this.guidedTourService.startTour(this.dashboardTourDmp);
}

View File

@ -47,6 +47,7 @@ import { DmpListingModel } from '@app/core/model/dmp/dmp-listing';
import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria';
import { DatasetDescriptionFormEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model';
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
import { CloneDialogComponent } from '../clone/clone-dialog/clone-dialog.component';
@Component({
selector: 'app-dmp-editor-component',
@ -587,9 +588,37 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
this.router.navigate(['/plans/new_version/' + id, { dmpLabel: label }]);
}
clone(id: String) {
this.router.navigate(['/plans/clone/' + id]);
}
// OLD CLONE VERSION
// clone(id: String) {
// this.router.navigate(['/plans/clone/' + id]);
// }
// NEW CLONE VERSION
// clone(dmp: DmpListingModel) {
// this.openCloneDialog();
// }
// openCloneDialog() {
// const dialogRef = this.dialog.open(CloneDialogComponent, {
// maxWidth: '700px',
// data: {
// formGroup: this.formGroup,
// datasets: this.formGroup.get('datasets').value,
// confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CLONE'),
// cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
// }
// });
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
// if (result) {
// this.dmpService.clone(this.formGroup.getRawValue(), this.formGroup.get('id').value)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// complete => this.onCloneCallbackSuccess(complete),
// error => this.onCloneCallbackError(error)
// );
// }
// });
// }
viewVersions(rowId: String, rowLabel: String) {
this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });

View File

@ -31,7 +31,7 @@
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DMP-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isDraftDmp(dmp)" [routerLink]="['/new/dataset/' + dmp.id]" target="_blank"><span class="material-icons icon-align">add</span>{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isUserOwner(dmp)" (click)="openShareDialog(dmp.id, dmp.label)"><span class="material-icons icon-align pr-2">group_add</span>{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" [routerLink]="['/plans/clone/' + dmp.id]" target="_blank"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="cloneClicked(dmp)"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto pointer" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div>

View File

@ -10,7 +10,7 @@ import { TranslateService } from '@ngx-translate/core';
import { DmpStatus } from '../../../../core/common/enum/dmp-status';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { takeUntil } from 'rxjs/operators';
import { takeUntil, map } from 'rxjs/operators';
import { BaseComponent } from '@common/base/base.component';
import * as FileSaver from 'file-saver';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
@ -18,6 +18,14 @@ import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/serv
import { Role } from '@app/core/common/enum/role';
import { LockService } from '@app/core/services/lock/lock.service';
import { Location } from '@angular/common';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { FormGroup } from '@angular/forms';
import { DmpEditorModel } from '../../editor/dmp-editor.model';
import { CloneDialogComponent } from '../../clone/clone-dialog/clone-dialog.component';
import { ProjectFormModel } from '../../editor/grant-tab/project-form-model';
import { FunderFormModel } from '../../editor/grant-tab/funder-form-model';
import { ExtraPropertiesFormModel } from '../../editor/general-tab/extra-properties-form.model';
import { GrantTabModel } from '../../editor/grant-tab/grant-tab-model';
@Component({
selector: 'app-dmp-listing-item-component',
@ -34,6 +42,8 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
isDraft: boolean;
isFinalized: boolean;
isPublished: boolean;
dmpModel: DmpEditorModel;
dmpFormGroup: FormGroup;
constructor(
private router: Router,
@ -145,7 +155,43 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
}
cloneClicked(dmp: DmpListingModel) {
this.router.navigate(['/plans/clone/' + dmp.id]);
this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmpModel = new DmpEditorModel();
this.dmpModel.grant = new GrantTabModel();
this.dmpModel.project = new ProjectFormModel();
this.dmpModel.funder = new FunderFormModel();
this.dmpModel.extraProperties = new ExtraPropertiesFormModel();
this.dmpModel.fromModel(data);
this.dmpModel.status = DmpStatus.Draft;
this.dmpFormGroup = this.dmpModel.buildForm();
this.dmpFormGroup.get('label').setValue(dmp.label + " New");
this.openCloneDialog();
});
}
openCloneDialog() {
const dialogRef = this.dialog.open(CloneDialogComponent, {
maxWidth: '700px',
data: {
formGroup: this.dmpFormGroup,
datasets: this.dmpFormGroup.get('datasets').value,
confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CLONE'),
cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCloneCallbackSuccess(complete),
error => this.onCloneCallbackError(error)
);
}
});
}
newVersion(id: String, label: String) {
@ -283,6 +329,15 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
this.router.navigate(['/plans']);
}
onCloneCallbackSuccess(cloneId: String): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/plans/edit/', cloneId]);
}
onCloneCallbackError(error: any) {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-CLONE'), SnackBarNotificationLevel.Error);
}
isUserOwner(activity: DmpListingModel): boolean {
const principal: Principal = this.authentication.current();
if (principal) return principal.id === activity.users.find(x => x.role === Role.Owner).id;

View File

@ -19,7 +19,7 @@ import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { Observable, of as observableOf, interval } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { takeUntil, map } from 'rxjs/operators';
import { Role } from "@app/core/common/enum/role";
import { DmpInvitationDialogComponent } from '../invitation/dmp-invitation-dialog.component';
import { MultipleChoiceDialogModule } from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.module';
@ -30,12 +30,19 @@ import { Oauth2DialogService } from '@app/ui/misc/oauth2-dialog/service/oauth2-d
import { isNullOrUndefined } from 'util';
import { UserService } from '@app/core/services/user/user.service';
import { Location } from '@angular/common';
import { FormGroup } from '@angular/forms';
import { FormGroup, FormArray, FormControl } from '@angular/forms';
import { LockService } from '@app/core/services/lock/lock.service';
import { ReturnStatement, ConditionalExpr } from '@angular/compiler';
import { LockModel } from '@app/core/model/lock/lock.model';
import { Guid } from '@common/types/guid';
import { VersionListingModel } from '@app/core/model/version/version-listing.model';
import { CloneDialogComponent } from '../clone/clone-dialog/clone-dialog.component';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { DmpEditorModel } from '../editor/dmp-editor.model';
import { FunderFormModel } from '../editor/grant-tab/funder-form-model';
import { ProjectFormModel } from '../editor/grant-tab/project-form-model';
import { GrantTabModel } from '../editor/grant-tab/grant-tab-model';
import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model';
@Component({
selector: 'app-dmp-overview',
@ -45,6 +52,7 @@ import { VersionListingModel } from '@app/core/model/version/version-listing.mod
export class DmpOverviewComponent extends BaseComponent implements OnInit {
dmp: DmpOverviewModel;
dmpModel: DmpEditorModel;
isNew = true;
isFinalized = false;
isPublicView = true;
@ -61,7 +69,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
@ViewChild('doi', { static: false })
doi: ElementRef;
@Input() formGroup: FormGroup;
formGroup: FormGroup;
constructor(
private route: ActivatedRoute,
@ -167,8 +175,52 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
}
cloneClicked(dmp: DmpOverviewModel) {
let url = this.router.createUrlTree(['/plans/clone/', dmp.id]);
window.open(url.toString(), '_blank');
this.dmpService.getSingle(this.dmp.id).pipe(map(data => data as DmpModel))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmpModel = new DmpEditorModel();
this.dmpModel.grant = new GrantTabModel();
this.dmpModel.project = new ProjectFormModel();
this.dmpModel.funder = new FunderFormModel();
this.dmpModel.extraProperties = new ExtraPropertiesFormModel();
this.dmpModel.fromModel(data);
this.dmpModel.status = DmpStatus.Draft;
this.formGroup = this.dmpModel.buildForm();
this.formGroup.get('label').setValue(this.dmp.label + " New");
this.openCloneDialog();
});
}
openCloneDialog() {
const dialogRef = this.dialog.open(CloneDialogComponent, {
maxWidth: '700px',
data: {
formGroup: this.formGroup,
datasets: this.dmp.datasets,
confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CLONE'),
cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.dmpService.clone(this.formGroup.getRawValue(), this.dmp.id)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCallbackSuccess(complete),
error => this.onCallbackError(error)
);
}
});
}
onCallbackSuccess(cloneId: String): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/plans/edit/', cloneId]);
}
onCallbackError(error: any) {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-CLONE'), SnackBarNotificationLevel.Error);
}
grantClicked(grantId: String) {

View File

@ -8,6 +8,7 @@ import { DmpOverviewComponent } from '@app/ui/dmp/overview/dmp-overview.componen
import { CommonFormsModule } from '@common/forms/common-forms.module';
import { CommonUiModule } from '@common/ui/common-ui.module';
import { RouterModule } from '@angular/router';
import { CloneDialogModule } from '../clone/clone-dialog/clone-dialog.module';
@NgModule({
imports: [
@ -15,10 +16,11 @@ import { RouterModule } from '@angular/router';
CommonFormsModule,
UrlListingModule,
ConfirmationDialogModule,
CloneDialogModule,
ExportMethodDialogModule,
FormattingModule,
AutoCompleteModule,
RouterModule
RouterModule
],
declarations: [
DmpOverviewComponent

View File

@ -16,6 +16,7 @@ import { ValidationErrorModel } from '@common/forms/validation/error-model/valid
import { ValidationContext } from '@common/forms/validation/validation-context';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model';
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';
export class DmpWizardEditorModel {
public id: string;
@ -34,6 +35,7 @@ export class DmpWizardEditorModel {
public researchers: ResearcherModel[] = [];
public profiles: DmpProfile[] = [];
public associatedUsers: UserModel[] = [];
public users: UserInfoListingModel[] = [];
public definition: DmpProfileDefinition;
public dynamicFields: Array<DmpDynamicFieldEditorModel> = [];
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
@ -55,6 +57,7 @@ export class DmpWizardEditorModel {
this.researchers = item.researchers;
this.profiles = item.profiles;
this.associatedUsers = item.associatedUsers;
this.users = item.users;
if (item.definition) { this.definition = item.definition; }
if (item.dynamicFields) { item.dynamicFields.map(x => this.dynamicFields.push(new DmpDynamicFieldEditorModel().fromModel(x))); }
this.creator = item.creator;
@ -81,6 +84,7 @@ export class DmpWizardEditorModel {
researchers: [{ value: this.researchers, disabled: disabled }, context.getValidation('researchers').validators],
profiles: [{ value: this.profiles, disabled: disabled }, context.getValidation('profiles').validators],
associatedUsers: [{ value: this.associatedUsers, disabled: disabled }, context.getValidation('associatedUsers').validators],
users: [{ value: this.users, disabled: disabled }, context.getValidation('users').validators],
extraProperties: this.extraProperties.buildForm(),
});
@ -108,6 +112,7 @@ export class DmpWizardEditorModel {
baseContext.validation.push({ key: 'researchers', validators: [BackendErrorValidator(this.validationErrorModel, 'researchers')] });
baseContext.validation.push({ key: 'profiles', validators: [Validators.required, ValidJsonValidator, BackendErrorValidator(this.validationErrorModel, 'profiles')] });
baseContext.validation.push({ key: 'associatedUsers', validators: [BackendErrorValidator(this.validationErrorModel, 'associatedUsers')] });
baseContext.validation.push({ key: 'users', validators: [BackendErrorValidator(this.validationErrorModel, 'users')] });
return baseContext;
}

View File

@ -29,7 +29,6 @@
[isChild]="true" [showDelete]="true"></app-form-composite-field>
</div>
</div>
{{compositeFieldFormGroup.get('multiplicity').value | json}}
<div *ngIf="(compositeFieldFormGroup.get('multiplicity').value.max - 1) > (compositeFieldFormGroup.get('multiplicityItems').length)"
class="col-12 addOneFieldButton">
<button mat-icon-button color="primary" (click)="addMultipleField(i)" [disabled]="compositeFieldFormGroup.disabled" matTooltip="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-ADD-ONE-FIELD' | translate}}">

View File

@ -693,6 +693,7 @@
"SUBTITLE": "DOI",
"ADD-DATASET": "Adding dataset to ",
"EDIT-DATASET": "Editing Dataset",
"CLONE-DMP": "Clone",
"CREATE-DATASET": "Creating Dataset Description"
},
"FIELDS": {
@ -712,7 +713,8 @@
"FUNDER": "Fördergeber",
"STATUS": "DMP Status",
"EXTERNAL-SOURCE-HINT": "Liste der Werte, die von externer(n) Quelle(n) stammen",
"COLLABORATORS": "Mitwirkende"
"COLLABORATORS": "Mitwirkende",
"DATASETS": "Datasets"
},
"ACTIONS": {
"GO-TO-GRANT": "Gehe zu DMP Förderung",

View File

@ -762,6 +762,7 @@
"EDIT-DMP": "Editing DMP",
"ADD-DATASET": "Adding dataset to ",
"EDIT-DATASET": "Editing Dataset",
"CLONE-DMP": "Clone",
"CREATE-DATASET": "Creating Dataset Description",
"SUBTITLE": "DOI"
},
@ -790,7 +791,8 @@
"LICENSE": "License",
"VISIBILITY": "Visibility",
"PUBLICATION": "Publication Date",
"CONTACT": "Contact"
"CONTACT": "Contact",
"DATASETS": "Datasets"
},
"ACTIONS": {
"GO-TO-GRANT": "Go To DMP Grant",
@ -850,7 +852,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?"
},
"CHANGES": "unsaved changes"
"CHANGES": "unsaved changes",
"CLONE-DIALOG": {
"CLONE": "Clone",
"CANCEL": "Cancel"
}
},
"DMP-PROFILE-LISTING": {
"TITLE": "DMP Templates",

View File

@ -762,6 +762,7 @@
"EDIT-DMP": "Editando PGD",
"ADD-DATASET": "Adding dataset to ",
"EDIT-DATASET": "Editing Dataset",
"CLONE-DMP": "Clone",
"CREATE-DATASET": "Creating Dataset Description",
"SUBTITLE": "DOI"
},
@ -790,7 +791,8 @@
"LICENSE": "Licencia",
"VISIBILITY": "Visibilidad",
"PUBLICATION": "Fecha de publicación",
"CONTACT": "Contacto"
"CONTACT": "Contacto",
"DATASETS": "Datasets"
},
"ACTIONS": {
"GO-TO-GRANT": "Ir a las subvención del PGD",

View File

@ -757,6 +757,7 @@
"EDIT-DMP": "Editing DMP",
"ADD-DATASET": "Adding dataset to ",
"EDIT-DATASET": "Editing Dataset",
"CLONE-DMP": "Clone",
"SUBTITLE": "Μονοσήμαντο Αναγνωριστικό Ψηφιακού Αντικειμένου (DOI)"
},
"FIELDS": {
@ -783,7 +784,8 @@
"LANGUAGE": "Language",
"LICENSE": "License",
"VISIBILITY": "Visibility",
"PUBLICATION": "Publication Date"
"PUBLICATION": "Publication Date",
"DATASETS": "Datasets"
},
"ACTIONS": {
"GO-TO-GRANT": "Μεταβείτε στην Επιχορήγηση Σχεδίου Διαχείρισης Δεδομένων",

View File

@ -750,6 +750,7 @@
"EDIT": "Düzenle",
"EDIT-DMP": " VYP'yi düzenleme",
"ADD-DATASET": "Adding dataset to ",
"CLONE-DMP": "Clone",
"SUBTITLE": "DOI"
},
"FIELDS": {
@ -776,7 +777,8 @@
"LICENSE": "Lisans",
"VISIBILITY": "Görünürlük",
"PUBLICATION": "Yayın Tarihi",
"CONTACT": "İletişim"
"CONTACT": "İletişim",
"DATASETS": "Datasets"
},
"ACTIONS": {
"GO-TO-GRANT": "VYP Hibesine Git",