Merge branch 'dmp-refactoring' of code-repo.d4science.org:MaDgiK-CITE/argos into dmp-refactoring

# Conflicts:
#	dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts
This commit is contained in:
Efstratios Giannopoulos 2024-03-14 11:26:21 +02:00
commit dadda72a09
33 changed files with 475 additions and 532 deletions

View File

@ -116,7 +116,7 @@ public class DashboardServiceImpl implements DashboardService {
referenceTypeStatistics.setCount(this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).typeIds(typeId).authorize(EnumSet.of(Public))
.dmpReferenceSubQuery(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active)
.dmpSubQuery(dmpQuery)).count());
referenceTypeStatistics.setReferenceType(this.builderFactory.builder(PublicReferenceTypeBuilder.class).build(new BaseFieldSet().ensure(PublicReferenceType._name), this.queryFactory.query(ReferenceTypeQuery.class).ids(typeId).first()));
referenceTypeStatistics.setReferenceType(this.builderFactory.builder(PublicReferenceTypeBuilder.class).build(new BaseFieldSet().ensure(PublicReferenceType._id), this.queryFactory.query(ReferenceTypeQuery.class).ids(typeId).first()));
statistics.getReferenceTypeStatistics().add(referenceTypeStatistics);
}
}
@ -135,11 +135,15 @@ public class DashboardServiceImpl implements DashboardService {
DashboardStatisticsCacheService.DashboardStatisticsCacheValue cacheValue = this.dashboardStatisticsCacheService.lookup(this.dashboardStatisticsCacheService.buildKey(this.userScope.getUserId().toString().toLowerCase(Locale.ROOT)));
if (cacheValue == null || cacheValue.getDashboardStatistics() == null) {
DmpQuery dmpQuery = this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).versionStatuses(DmpVersionStatus.Current);
DmpUserQuery dmpUserLookup = this.queryFactory.query(DmpUserQuery.class);
dmpUserLookup.userIds(this.userScope.getUserId());
dmpUserLookup.isActives(IsActive.Active);
DmpQuery dmpQuery = this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).dmpUserSubQuery(dmpUserLookup).versionStatuses(DmpVersionStatus.Current);
DashboardStatistics statistics = new DashboardStatistics();
statistics.setDmpCount(dmpQuery.authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).count());
statistics.setDescriptionCount(this.queryFactory.query(DescriptionQuery.class).isActive(IsActive.Active).dmpSubQuery(dmpQuery).statuses(DescriptionStatus.Finalized).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).count());
statistics.setDescriptionCount(this.queryFactory.query(DescriptionQuery.class).isActive(IsActive.Active).dmpSubQuery(dmpQuery).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).count());
statistics.setReferenceTypeStatistics(new ArrayList<>());
if (!this.conventionService.isListNullOrEmpty(this.config.getReferenceTypeCounters())){
@ -148,7 +152,7 @@ public class DashboardServiceImpl implements DashboardService {
referenceTypeStatistics.setCount(this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).typeIds(typeId).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission)
.dmpReferenceSubQuery(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active)
.dmpSubQuery(dmpQuery)).count());
referenceTypeStatistics.setReferenceType(this.builderFactory.builder(PublicReferenceTypeBuilder.class).build(new BaseFieldSet().ensure(PublicReferenceType._code), this.queryFactory.query(ReferenceTypeQuery.class).ids(typeId).first()));
referenceTypeStatistics.setReferenceType(this.builderFactory.builder(PublicReferenceTypeBuilder.class).build(new BaseFieldSet().ensure(PublicReferenceType._id), this.queryFactory.query(ReferenceTypeQuery.class).ids(typeId).first()));
statistics.getReferenceTypeStatistics().add(referenceTypeStatistics);
}
}

View File

@ -1,6 +1,6 @@
deposit:
sources:
- url: http://localhost:8082
- url: http://dev04.local.cite.gr:55330/zenodo
repositoryId: zenodo
pdfTransformerId: docx-file-transformer
rdaTransformerId: rda-file-transformer

View File

@ -1,13 +1,13 @@
transformer:
sources:
- url: http://localhost:8084
- url: http://dev04.local.cite.gr:55330/file/docx
transformerId: docx-file-transformer
codes: [ docx, pdf ]
issuer-url: ${IDP_ISSUER_URI_TOKEN:}
client-id: ${IDP_APIKEY_CLIENT_ID:}
client-secret: ${IDP_APIKEY_CLIENT_SECRET:}
scope: ${IDP_APIKEY_SCOPE:}
- url: http://localhost:8086
- url: http://dev04.local.cite.gr:55330/file/rdajson
transformerId: rda-file-transformer
codes: [ json ]
issuer-url: ${IDP_ISSUER_URI_TOKEN:}

View File

@ -2,5 +2,4 @@ export enum RecentActivityOrder {
UpdatedAt = 0,
Label = 1,
Status = 2,
Published = 3
}

View File

@ -1,6 +1,12 @@
import { PublicReferenceType } from "../dmp/dmp";
export interface DashboardStatistics {
dmpCount: number;
descriptionCount: number;
organizationCount: number;
grantCount: number;
referenceTypeStatistics: DashboardReferenceTypeStatistics[];
}
export interface DashboardReferenceTypeStatistics {
count: number;
referenceType: PublicReferenceType
}

View File

@ -186,16 +186,9 @@ export interface PublicReference {
export interface PublicReferenceType {
id: Guid;
name: string;
code: string;
}
export interface PublicReference {
id: Guid;
label: string;
type: PublicUser;
role: DmpUserRole;
}
export interface PublicDmpUser {
id: Guid;
dmp: PublicDmp;

View File

@ -8,7 +8,7 @@ import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/sing
import { QueryResult } from '@common/model/query-result';
import { FilterService } from '@common/modules/text-filter/filter-service';
import { Guid } from '@common/types/guid';
import { Observable, throwError } from 'rxjs';
import { Observable, of, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { ConfigurationService } from '../configuration/configuration.service';
@ -16,6 +16,7 @@ import { BaseHttpV2Service } from '../http/base-http-v2.service';
import { FileFormat } from '@app/core/model/file/file-format.model';
import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { DescriptionValidationResult } from '@app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component';
@Injectable()
export class DescriptionService {
@ -90,6 +91,10 @@ export class DescriptionService {
catchError((error: any) => throwError(error)));
}
public validate(descriptionIds: Guid[]): Observable<DescriptionValidationResult[]> {
return of(new Array<DescriptionValidationResult>());
}
// public downloadPDF(id: string): Observable<HttpResponse<Blob>> {
// return this.httpClient.get(`${this.apiBase}/${id}/export/Pdf`, { responseType: 'blob', observe: 'response', headers: this.headers });
// }

View File

@ -137,4 +137,8 @@ export class ReferenceTypeService {
public getGrantReferenceType(): any {
return '5b9c284f-f041-4995-96cc-fad7ad13289c';
}
public getOrganizationReferenceType(): any {
return '7eeffb98-58fb-4921-82ec-e27f32f8e738';
}
}

View File

@ -28,9 +28,9 @@
<mat-card-title *ngIf="isNew">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.NEW' | translate}}</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="row mt-4">
<div class="col-6">
<mat-form-field class="col-md-12">
<div class="d-flex flex-wrap mt-4">
<div class="col-md-12">
<mat-form-field class="w-100">
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.NOTIFICATION-TYPE' | translate}}</mat-label>
<mat-select [formControl]="formGroup.get('notificationType')" name="notificationType" required>
<mat-option *ngFor="let type of notificationTypeEnum" [value]="type">
@ -80,16 +80,18 @@
</div>
<!-- Subject -->
<div class="row">
<div class="d-flex flex-wrap">
<h3 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-SECTION' | translate}}</h3>
<mat-form-field class="col-md-12">
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-TEXT' | translate}}</mat-label>
<input matInput [formControl]="formGroup.get('value').get('subjectText')">
<mat-error *ngIf="formGroup.get('value').get('subjectText').hasError('backendError')">{{formGroup.get('value').get('subjectText').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('value').get('subjectText').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<div class="col-4">
<mat-form-field class="col-md-12">
<div class="col-md-6">
<mat-form-field class="w-100">
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-TEXT' | translate}}</mat-label>
<input matInput [formControl]="formGroup.get('value').get('subjectText')">
<mat-error *ngIf="formGroup.get('value').get('subjectText').hasError('backendError')">{{formGroup.get('value').get('subjectText').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('value').get('subjectText').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="w-100">
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-KEY' | translate}}</mat-label>
<input matInput [formControl]="formGroup.get('value').get('subjectKey')">
<mat-error *ngIf="formGroup.get('value').get('subjectKey').hasError('backendError')">{{formGroup.get('value').get('subjectKey').getError('backendError').message}}</mat-error>
@ -113,8 +115,8 @@
<!-- Body -->
<div>
<h3 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-SECTION' | translate}}</h3>
<div class="col-4">
<mat-form-field class="col-md-12">
<div class="col-md-6">
<mat-form-field class="w-100">
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-KEY' | translate}}</mat-label>
<input matInput [formControl]="formGroup.get('value').get('bodyKey')">
<mat-error *ngIf="formGroup.get('value').get('bodyKey').hasError('backendError')">{{formGroup.get('value').get('bodyKey').getError('backendError').message}}</mat-error>
@ -123,7 +125,7 @@
</div>
<div class="col-12">
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-TEXT' | translate}}</mat-label>
<editor class="w-100" [init]="{
<editor class="w-100 mt-2" [init]="{
base_url: '/tinymce',
suffix: '.min',
height: 800,
@ -149,7 +151,7 @@
<h4 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-FIELD-OPTIONS' | translate}}
<mat-checkbox [checked]="bodyFieldOptionsEnabled" (change)="bodyFieldOptionsSelectionChanged($event)"></mat-checkbox>
</h4>
<div *ngIf="bodyFieldOptionsEnabled == true">
<ng-container *ngIf="bodyFieldOptionsEnabled == true">
<app-notification-template-field-options-component
[form]="formGroup.get('value').get('bodyFieldOptions')"
[validationErrorModel]="editorModel.validationErrorModel"
@ -157,7 +159,7 @@
[bodyMandatoryFields]="subjectMandatoryFields"
[formatting]="bodyFormatting">
</app-notification-template-field-options-component>
</div>
</ng-container>
<!--Extra Options -->
<div class="row">
<h3 class="col-md-12">{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.EXTRA-OPTIONS' | translate}}</h3>

View File

@ -85,7 +85,8 @@
</div>
<!-- Type reply in thread -->
<div *ngIf="this.canEdit && !this.isDeleted" class="col-12">
<!-- <div *ngIf="this.canEdit && !this.isDeleted" class="col-12"> -->
<div class="col-12">
<div class="row new-reply mr-0">
<mat-form-field class="col pt-2 pb-2 pr-0">
<textarea matInput matTextareaAutosize matAutosizeMinRows="1" [formControl]="this.threadReplyTextsFG[thread.id.toString()].get('replyText')" placeholder="{{'ANNOTATION-DIALOG.THREADS.REPLY' | translate}}"></textarea>

View File

@ -64,7 +64,7 @@
<div class="counter-zero">0</div>
<a [routerLink]="['/plans']" class="link">{{'DASHBOARD.DMPS' | translate}}</a>
<div class="counter-zero">0</div>
<a [routerLink]="['/datasets']" class="link">{{'DASHBOARD.DESCRIPTIONS' | translate}}</a>
<a [routerLink]="['/descriptions']" class="link">{{'DASHBOARD.DESCRIPTIONS' | translate}}</a>
<div class="counter-zero">0</div>
<a class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a>
<div class="counter-zero">0</div>
@ -78,12 +78,12 @@
<a [routerLink]="['/plans']" class="link">{{'DASHBOARD.DMPS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatistics?.descriptionCount != 0, 'counter-zero': dashboardStatistics?.descriptionCount == 0}">
{{dashboardStatistics?.descriptionCount}}</div>
<a [routerLink]="['/datasets']" class="link">{{'DASHBOARD.DESCRIPTIONS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatistics?.grantCount != 0, 'counter-zero': dashboardStatistics?.grantCount == 0}">
{{dashboardStatistics?.grantCount}}</div>
<a [routerLink]="['/descriptions']" class="link">{{'DASHBOARD.DESCRIPTIONS' | translate}}</a>
<div [ngClass]="{'counter': grantCount != 0, 'counter-zero': grantCount == 0}">
{{grantCount}}</div>
<a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatistics?.organizationCount != 0, 'counter-zero': dashboardStatistics?.organizationCount == 0}">
{{dashboardStatistics?.organizationCount}}</div>
<div [ngClass]="{'counter': organizationCount != 0, 'counter-zero': organizationCount == 0}">
{{organizationCount}}</div>
<a href="#" class="link-disabled">{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}</a>
</div>
</div>
@ -151,12 +151,12 @@
<a [routerLink]="['/plans']" class="link">{{'DASHBOARD.PUBLIC-DMPS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatistics?.descriptionCount != 0, 'counter-zero': dashboardStatistics?.descriptionCount == 0}">
{{dashboardStatistics?.descriptionCount}}</div>
<a [routerLink]="['/datasets']" class="link">{{'DASHBOARD.PUBLIC-DATASETS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatistics?.grantCount != 0, 'counter-zero': dashboardStatistics?.grantCount == 0}">
{{dashboardStatistics?.grantCount}}</div>
<a [routerLink]="['/descriptions']" class="link">{{'DASHBOARD.PUBLIC-DESCRIPTIONS' | translate}}</a>
<div [ngClass]="{'counter': grantCount != 0, 'counter-zero': grantCount == 0}">
{{grantCount}}</div>
<a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatistics?.organizationCount != 0, 'counter-zero': dashboardStatistics?.organizationCount == 0}">
{{dashboardStatistics?.organizationCount}}</div>
<div [ngClass]="{'counter': organizationCount != 0, 'counter-zero': organizationCount == 0}">
{{organizationCount}}</div>
<a href="#" class="link-disabled">{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}</a>
</div>
</div>

View File

@ -12,6 +12,7 @@ import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators';
import { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
@Component({
@ -22,6 +23,8 @@ import { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/st
export class DashboardComponent extends BaseComponent implements OnInit {
public dashboardStatistics: DashboardStatistics;
public grantCount = 0;
public organizationCount = 0;
currentType: string = "recent";
constructor(
@ -32,7 +35,8 @@ export class DashboardComponent extends BaseComponent implements OnInit {
private dialog: MatDialog,
private language: TranslateService,
private guidedTourService: GuidedTourService,
private matomoService: MatomoService
private matomoService: MatomoService,
public referenceTypeService: ReferenceTypeService
) {
super();
}
@ -55,12 +59,16 @@ export class DashboardComponent extends BaseComponent implements OnInit {
.pipe(takeUntil(this._destroyed))
.subscribe(results => {
this.dashboardStatistics = results;
this.grantCount = this.dashboardStatistics.referenceTypeStatistics.filter(x => x.referenceType.id == this.referenceTypeService.getGrantReferenceType())?.find(Boolean).count;
this.organizationCount = this.dashboardStatistics.referenceTypeStatistics.filter(x => x.referenceType.id == this.referenceTypeService.getOrganizationReferenceType())?.find(Boolean).count;
});
} else {
this.dashboardService.getMyDashboardStatistics()
.pipe(takeUntil(this._destroyed))
.subscribe(results => {
this.dashboardStatistics = results;
this.grantCount = this.dashboardStatistics.referenceTypeStatistics.filter(x => x.referenceType.id == this.referenceTypeService.getGrantReferenceType())?.find(Boolean).count;
this.organizationCount = this.dashboardStatistics.referenceTypeStatistics.filter(x => x.referenceType.id == this.referenceTypeService.getOrganizationReferenceType())?.find(Boolean).count;
if (this.dashboardStatistics && this.dashboardStatistics.dmpCount === 0) {
this.openDashboardTour();
@ -108,8 +116,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
if (this.dashboardStatistics) {
return this.dashboardStatistics.dmpCount !== 0
|| this.dashboardStatistics.descriptionCount !== 0
|| this.dashboardStatistics.grantCount !== 0
|| this.dashboardStatistics.organizationCount !== 0;
|| this.dashboardStatistics.referenceTypeStatistics.length !== 0
} else {
return false;
}

View File

@ -101,11 +101,10 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
}
updateUrl() {
// let parameters = "?type=dmps" +
let parameters = "" +
(this.page != 1 ? "&page=" + this.page : "") +
//TODO refactor
(((this.formGroup.get("order").value != this.order.UpdatedAt && !this.publicMode) || (this.formGroup.get("order").value != this.order.Published && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
// (((this.formGroup.get("order").value != this.order.UpdatedAt && !this.publicMode) || (this.formGroup.get("order").value != this.order.Published && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}

View File

@ -5,6 +5,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
@ -121,25 +122,25 @@ export class RecentEditedDescriptionActivityComponent extends BaseComponent impl
this.lookup.project = {
fields: [
[nameof<Description>(x => x.id)].join('.'),
[nameof<Description>(x => x.label)].join('.'),
[nameof<Description>(x => x.status)].join('.'),
[nameof<Description>(x => x.updatedAt)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.updatedAt)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
]
};

View File

@ -55,7 +55,7 @@
</button>
</div>
<div class="col-auto d-flex align-items-center">
<button [disabled]="saving" *ngIf="!lockStatus && !viewOnly" mat-raised-button class="description-save-btn mr-2" type="button">
<button [disabled]="saving" *ngIf="!lockStatus && !viewOnly && hasReversableStatus() == false" mat-raised-button class="description-save-btn mr-2" type="button">
<span class="d-flex flex-row row">
<span (click)="!saving?formSubmit():null" class="col">{{ 'DESCRIPTION-EDITOR.ACTIONS.SAVE' | translate }}</span>
<mat-divider [vertical]="true"></mat-divider>
@ -73,7 +73,7 @@
<button [disabled]="saving" mat-menu-item (click)="save()" type="button">{{ 'DESCRIPTION-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
</mat-menu>
<button [disabled]="saving" *ngIf="!lockStatus && !viewOnly" mat-raised-button class="description-save-btn mr-2" type="button" (click)="saveFinalize()">{{ 'DESCRIPTION-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
<button [disabled]="saving" *ngIf="!lockStatus && !viewOnly && hasReversableStatus() == false" mat-raised-button class="description-save-btn mr-2" type="button" (click)="finalize()">{{ 'DESCRIPTION-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
<button [disabled]="saving" *ngIf="lockStatus" mat-raised-button disabled class="description-save-btn cursor-default" type="button">{{ 'DMP-OVERVIEW.LOCKED' | translate}}</button>
<button [disabled]="saving" *ngIf="hasReversableStatus() && !lockStatus" mat-raised-button class="description-save-btn mr-2" (click)="reverse()" type="button">{{ 'DESCRIPTION-EDITOR.ACTIONS.REVERSE' | translate }}</button>
</div>

View File

@ -6,7 +6,7 @@ import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { Description, DescriptionPersist } from '@app/core/model/description/description';
import { Description, DescriptionPersist, DescriptionStatusPersist } from '@app/core/model/description/description';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { DescriptionService } from '@app/core/services/description/description.service';
@ -39,6 +39,7 @@ import { PrefillDescriptionDialogComponent } from './prefill-description/prefill
import { ToCEntry } from './table-of-contents/models/toc-entry';
import { ToCEntryType } from './table-of-contents/models/toc-entry-type.enum';
import { TableOfContentsComponent } from './table-of-contents/table-of-contents.component';
import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
@Component({
selector: 'app-description-editor-component',
@ -272,6 +273,11 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
}
})
}
if(this.route.snapshot.url[1] && this.route.snapshot.url[1].path == 'finalize' && !this.lockStatus && !this.viewOnly) {
setTimeout(() => {
this.finalize();
}, 0);
}
// if (this.itemId != null && this.newDmpId == null) {
// this.isNew = false;
@ -639,10 +645,11 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
}
formSubmit(): void {
this.formService.removeAllBackEndErrors(this.formGroup);
this.formService.touchAllFormFields(this.formGroup);
// if (!this.isFormValid()) {
// return;
// }
if (!this.isFormValid()) {
return;
}
this.persistEntity();
}
@ -971,10 +978,59 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
}
finalize() {
// if (this.checkValidity()) {
// this.formGroup.get('status').setValue(DescriptionStatus.Finalized);
// this.formSubmit();
// }
this.formService.removeAllBackEndErrors(this.formGroup);
this.formService.touchAllFormFields(this.formGroup);
if (!this.isFormValid()) {
this.dialog.open(FormValidationErrorsDialogComponent, {
data: {
errorMessages: [this.language.instant('DESCRIPTION-EDITOR.MESSAGES.MISSING-FIELDS')]
}
})
this.formService.touchAllFormFields(this.formGroup);
return;
}
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.FINALIZE-ITEM'),
confirmButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.AFFIRMATIVE'),
cancelButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.NEGATIVE'),
isDeleteConfirmation: false
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.formGroup.get('status').setValue(DescriptionStatus.Finalized);
this.persistEntity();
}});
}
reverse() {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
restoreFocus: false,
data: {
message: this.language.instant('DESCRIPTION-EDITOR.ACTIONS.UNDO-FINALIZATION-QUESTION'),
confirmButton: this.language.instant('DESCRIPTION-EDITOR.ACTIONS.CONFIRM'),
cancelButton: this.language.instant('DESCRIPTION-EDITOR.ACTIONS.REJECT'),
isDeleteConfirmation: false
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
const dmpUserRemovePersist: DescriptionStatusPersist = {
id: this.formGroup.get('id').value,
status: DescriptionStatus.Draft,
hash: this.formGroup.get('hash').value
};
this.descriptionService.persistStatus(dmpUserRemovePersist, DescriptionEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.prepareForm(data);
this.onCallbackSuccess()
}, (error: any) => {
this.onCallbackError(error)
});
}});
}
}

View File

@ -18,7 +18,7 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti
status: DescriptionStatus;
description: string;
properties: DescriptionPropertyDefinitionEditorModel = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel);
tags: string[];
tags: string[] = [];
references: DescriptionReferenceEditorModel[];
permissions: string[];
@ -470,11 +470,11 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist {
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'textValue', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}textValue`)] });
baseValidationArray.push({ key: 'textListValue', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}textListValue`)] });
baseValidationArray.push({ key: 'dateValue', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}dateValue`)] });
baseValidationArray.push({ key: 'references', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}references`)] });
baseValidationArray.push({ key: 'reference', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}references`)] });
baseValidationArray.push({ key: 'textValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}textValue`)] });
baseValidationArray.push({ key: 'textListValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}textListValue`)] });
baseValidationArray.push({ key: 'dateValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}dateValue`)] });
baseValidationArray.push({ key: 'references', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}references`)] });
baseValidationArray.push({ key: 'reference', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}references`)] });
baseValidationArray.push({ key: 'externalIdentifier', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}externalIdentifier`)] });
baseContext.validation = baseValidationArray;
return baseContext;
@ -551,8 +551,8 @@ export class DescriptionExternalIdentifierEditorModel implements DescriptionExte
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'identifier', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}identifier`)] });
baseValidationArray.push({ key: 'type', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}type`)] });
baseValidationArray.push({ key: 'identifier', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}identifier`)] });
baseValidationArray.push({ key: 'type', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}type`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}

View File

@ -121,6 +121,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
return [
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.id)].join('.'),
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.label)].join('.'),
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.status)].join('.'),
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.isActive)].join('.'),
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),

View File

@ -27,6 +27,23 @@ const routes: Routes = [
}
}
},
{
path: ':id/finalize',
canActivate: [AuthGuard],
component: DescriptionEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DescriptionEditorResolver
},
data: {
...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.EDIT-DESCRIPTION'
}),
authContext: {
permissions: [AppPermission.EditDescription]
}
}
},
{
path: ':dmpId/:dmpSectionId',
canActivate: [AuthGuard],

View File

@ -395,7 +395,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
takeUntil(this._destroyed)
)
.subscribe(_ => {
this.router.navigate(['descriptions', 'edit', description.id, 'finalize']);
this.router.navigate(['descriptions/edit/' + description.id + '/finalize']);
})
}
@ -409,7 +409,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
data: {
message: this.language.instant('DESCRIPTION-OVERVIEW.UNDO-FINALIZATION-DIALOG.TITLE'),
confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.UNDO-FINALIZATION-DIALOG.CONFIRM'),
cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.UNDO-FINALIZATION-DIALOG.CANCEL'),
cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.UNDO-FINALIZATION-DIALOG.NEGATIVE'),
isDeleteConfirmation: false
}
});
@ -438,6 +438,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
nameof<Description>(x => x.description),
nameof<Description>(x => x.status),
nameof<Description>(x => x.updatedAt),
nameof<Description>(x => x.hash),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
@ -447,6 +448,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.name)].join('.'),

View File

@ -0,0 +1,82 @@
<div class="row d-flex flex-row">
<div mat-dialog-title class="col-auto">{{ 'DMP-FINALISE-DIALOG.TITLE' | translate }}</div>
<div class="col-auto close-btn ml-auto" (click)="close()">
<mat-icon>close</mat-icon>
</div>
</div>
<div mat-dialog-content class="pt-2 pb-2">
<div class="container">
<mat-accordion [multi]="true">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'DMP-FINALISE-DIALOG.DMP' | translate }}
</mat-panel-title>
<mat-panel-description class="dmp-title">
{{ dmp.label }}
</mat-panel-description>
</mat-expansion-panel-header>
{{ dmp.description }}
</mat-expansion-panel>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'DMP-FINALISE-DIALOG.DESCRPIPTIONS' | translate }}
</mat-panel-title>
<mat-panel-description></mat-panel-description>
</mat-expansion-panel-header>
<div *ngIf="dmp.descriptions.length > 0">
<div *ngFor="let description of dmp.descriptions" class="row pl-3 descriptions">
<mat-icon *ngIf="description.status == descriptionStatusEnum.Draft" class="col-1 draft-bookmark">bookmark</mat-icon>
<mat-icon *ngIf="description.status == descriptionStatusEnum.Finalized" class="col-1 finalized-bookmark">bookmark</mat-icon>
<h4 *ngIf="description.status == descriptionStatusEnum.Draft" class="col-11 ml-auto mt-1 mb-4">
<span>{{ 'TYPES.DATASET-STATUS.DRAFT' | translate }}
<ng-container *ngIf="!isDescriptionValid(description.id)">
({{'DMP-FINALISE-DIALOG.INVALID' | translate}})
</ng-container>
:</span>
{{ description.label }}
<i *ngIf="isDescriptionValid(description.id)" class="fa fa-spinner fa-spin" ></i>
</h4>
<h4 *ngIf="description.status == descriptionStatusEnum.Finalized" class="col-11 ml-auto mt-1 mb-4">{{ description.label }}</h4>
</div>
</div>
<div *ngIf="dmp.descriptions.length === 0" class="emptyList">{{ 'DMP-FINALISE-DIALOG.EMPTY' | translate }} </div>
</mat-expansion-panel>
</mat-accordion>
<div *ngIf="validDraftDescriptions.length > 0" class="pt-4 pb-2">
<h4 class="pl-2">{{'DMP-FINALISE-DIALOG.FINALISE-TITLE' | translate}}</h4>
<mat-selection-list [(ngModel)]="descriptionsToBeFinalized">
<div class="styleBorder" *ngFor="let description of validDraftDescriptions">
<mat-list-option [value]='description.id' [disabled]="!isDescriptionValid(description.id)">
<span class="text-truncate" [matTooltip]="description.label">{{ description.label }}</span>
</mat-list-option>
</div>
</mat-selection-list>
</div>
<mat-error *ngIf="getFinalizedDescriptions().length === 0 && descriptionsToBeFinalized.length === 0">
{{'DMP-FINALISE-DIALOG.VALIDATION.AT-LEAST-ONE-DESCRPIPTION-FINALISED' | translate}}
</mat-error>
</div>
</div>
<div *ngIf="getFinalizedDescriptions().length != 0">
<div class="row pt-2 pb-2 pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.IMPACT' | translate }}
</div>
<div *ngIf="dmp.accessType == dmpAccessTypeEnum.Public" class="row pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.PUBLIC-DMP-MESSAGE' | translate }}
</div>
<div *ngIf="dmp.accessType == dmpAccessTypeEnum.Restricted" class="row pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.RESTRICTED-DMP-MESSAGE' | translate }}
</div>
</div>
<div mat-dialog-actions class="d-flex justify-content-end mb-1">
<div class="col-auto">
<button mat-raised-button cdkFocusInitial (click)="close()" class="cancel-btn">{{ 'DMP-FINALISE-DIALOG.ACTIONS.CANCEL' | translate }}</button>
</div>
<div class="col-auto">
<button mat-raised-button [disabled]="getFinalizedDescriptions().length === 0 && descriptionsToBeFinalized.length === 0" class="submit-btn" (click)="onSubmit()">{{ 'DMP-FINALISE-DIALOG.ACTIONS.SUBMIT' | translate }}</button>
</div>
</div>

View File

@ -25,7 +25,7 @@
}
}
.dataset-card {
.description-card {
display: flex;
flex-direction: column;
min-width: 0;
@ -65,7 +65,7 @@
cursor: pointer;
}
.datasets span {
.descriptions span {
color: var(--primary-color-3);
}

View File

@ -0,0 +1,78 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
import { Dmp } from '@app/core/model/dmp/dmp';
import { DescriptionService } from '@app/core/services/description/description.service';
import { BaseComponent } from '@common/base/base.component';
import { Guid } from '@common/types/guid';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-dmp-finalize-dialog-component',
templateUrl: 'dmp-finalize-dialog.component.html',
styleUrls: ['./dmp-finalize-dialog.component.scss']
})
export class DmpFinalizeDialogComponent extends BaseComponent implements OnInit {
dmp: Dmp;
dmpAccessTypeEnum = DmpAccessType;
descriptionStatusEnum = DescriptionStatus;
descriptionValidationOutputEnum = DescriptionValidationOutput;
validationResults: DescriptionValidationResult[] = [];
descriptionsToBeFinalized: Guid[] = [];
constructor(
public router: Router,
public dialogRef: MatDialogRef<DmpFinalizeDialogComponent>,
public descriptionService: DescriptionService,
@Inject(MAT_DIALOG_DATA) public data: any
) {
super();
this.dmp = data.dmp;
}
ngOnInit(): void {
this.validateDescriptions(this.dmp);
}
isDescriptionValid(descriptionId: Guid): boolean {
return this.validationResults.find(x => x.descriptionId == descriptionId)?.result === DescriptionValidationOutput.Valid;
}
onSubmit() {
this.dialogRef.close(this.descriptionsToBeFinalized);
}
getFinalizedDescriptions() {
return this.dmp.descriptions.filter(x => x.status === DescriptionStatus.Finalized);
}
close() {
this.dialogRef.close(null);
}
validateDescriptions(dmp: Dmp) {
if (!dmp.descriptions.some(x => x.status == DescriptionStatus.Draft)) return;
this.descriptionService.validate(dmp.descriptions.filter(x => x.status == DescriptionStatus.Draft).map(x => x.id)).pipe(takeUntil(this._destroyed),
).subscribe(result => {
this.validationResults = result;
});
}
get validDraftDescriptions() {
return this.dmp.descriptions.filter(x => this.validationResults.some(y => y.descriptionId == x.id && y.result == DescriptionValidationOutput.Valid));
}
}
export interface DescriptionValidationResult {
descriptionId: Guid;
result: DescriptionValidationOutput;
}
export enum DescriptionValidationOutput {
Valid = 1,
Invalid = 2
}

View File

@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
import { RichTextEditorModule } from "@app/library/rich-text-editor/rich-text-editor.module";
import { CommonUiModule } from '@common/ui/common-ui.module';
import { DmpFinalizeDialogComponent } from './dmp-finalize-dialog.component';
@NgModule({
imports: [CommonUiModule, FormsModule, ReactiveFormsModule, AutoCompleteModule, RichTextEditorModule],
declarations: [DmpFinalizeDialogComponent],
exports: [DmpFinalizeDialogComponent]
})
export class DmpFinalizeDialogModule {
constructor() { }
}

View File

@ -1,188 +0,0 @@
<div class="row d-flex flex-row">
<div mat-dialog-title class="col-auto">{{ data.message }}</div>
<div class="col-auto close-btn ml-auto" (click)="close()">
<mat-icon>close</mat-icon>
</div>
</div>
<div mat-dialog-content class="pt-2 pb-2">
<div class="container">
<mat-accordion [multi]="true">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'DMP-FINALISE-DIALOG.DMP' | translate }}
</mat-panel-title>
<mat-panel-description class="dmp-title">
{{ inputModel.dmpLabel }}
</mat-panel-description>
</mat-expansion-panel-header>
{{ inputModel.dmpDescription }}
</mat-expansion-panel>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'DMP-FINALISE-DIALOG.DATASETS' | translate }}
</mat-panel-title>
<mat-panel-description></mat-panel-description>
</mat-expansion-panel-header>
<div *ngIf="inputModel.datasets.length > 0">
<div *ngFor="let dataset of inputModel.datasets" class="row pl-3 datasets">
<mat-icon *ngIf="dataset.status == 0" class="col-1 draft-bookmark">bookmark</mat-icon>
<mat-icon *ngIf="dataset.status != 0" class="col-1 finalized-bookmark">bookmark</mat-icon>
<h4 *ngIf="dataset.status == 0" class="col-11 ml-auto mt-1 mb-4">
<span>{{ 'TYPES.DATASET-STATUS.DRAFT' | translate }}
<ng-container *ngIf="datasetLookupStatus[dataset.id] && (datasetLookupStatus[dataset.id] === datasetLookupStatusEnum.INVALID)">
({{'DMP-FINALISE-DIALOG.INVALID' | translate}})
</ng-container>
:</span>
{{ dataset.label }}
<i *ngIf="(datasetLookupStatus[dataset.id] != datasetLookupStatusEnum.INVALID) && (datasetLookupStatus[dataset.id] != datasetLookupStatusEnum.VALID) " class="fa fa-spinner fa-spin" ></i>
</h4>
<h4 *ngIf="dataset.status != 0" class="col-11 ml-auto mt-1 mb-4">{{ dataset.label }}</h4>
</div>
</div>
<div *ngIf="inputModel.datasets.length === 0" class="emptyList">{{ 'DMP-FINALISE-DIALOG.EMPTY' | translate }} </div>
</mat-expansion-panel>
</mat-accordion>
<div *ngIf="validDrafts.length > 0" class="pt-4 pb-2">
<h4 class="pl-2">{{'DMP-FINALISE-DIALOG.FINALISE-TITLE' | translate}}</h4>
<mat-selection-list #datasetsDraftSelectionList [(ngModel)]="outputModel.datasetsToBeFinalized">
<div class="styleBorder" *ngFor="let dataset of validDrafts">
<mat-list-option [value]='dataset.id' [disabled]="!datasetLookupStatus[dataset.id] || (datasetLookupStatus[dataset.id] != datasetLookupStatusEnum.VALID)">
<span class="text-truncate" [matTooltip]="dataset.label">{{ dataset.label }}</span>
</mat-list-option>
</div>
</mat-selection-list>
</div>
<mat-error *ngIf="getFinalizedDatasets().length === 0 && outputModel.datasetsToBeFinalized.length === 0">
{{'DMP-FINALISE-DIALOG.VALIDATION.AT-LEAST-ONE-DATASET-FINALISED' | translate}}
</mat-error>
</div>
</div>
<div *ngIf="getFinalizedDatasets().length != 0">
<div class="row pt-2 pb-2 pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.IMPACT' | translate }}
</div>
<div *ngIf="inputModel.accessRights" class="row pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION-PUBLISH' | translate }}
</div>
<div *ngIf="!inputModel.accessRights" class="row pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION-RESTRICT-ACCESS' | translate }}
</div>
</div>
<div mat-dialog-actions class="d-flex justify-content-end mb-1">
<div class="col-auto">
<button mat-raised-button cdkFocusInitial (click)="close()" class="cancel-btn">{{ data.cancelButton }}</button>
</div>
<div class="col-auto">
<button mat-raised-button [disabled]="getFinalizedDatasets().length === 0 && outputModel.datasetsToBeFinalized.length === 0" class="submit-btn" (click)="onSubmit()">{{ data.confirmButton }}</button>
</div>
</div>
<!-- <form *ngIf="formGroup" (ngSubmit)="onSubmit()">
<div class="row d-flex flex-row">
<div mat-dialog-title class="col-auto">{{ data.message }}</div>
<div class="col-auto close-btn ml-auto" (click)="close()">
<mat-icon>close</mat-icon>
</div>
</div>
<div mat-dialog-content *ngIf="datasetsFinalized && datasetsDraft" class="pt-2 pb-2">
<mat-accordion [multi]="true">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'DMP-FINALISE-DIALOG.DMP' | translate }}
</mat-panel-title>
<mat-panel-description class="dmp-title">
{{ formGroup.get('label').value }}
</mat-panel-description>
</mat-expansion-panel-header>
{{ formGroup.get('description').value }}
</mat-expansion-panel>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'DMP-FINALISE-DIALOG.DATASETS' | translate }}
</mat-panel-title>
<mat-panel-description></mat-panel-description>
</mat-expansion-panel-header>
<div *ngIf="allDatasets.length > 0">
<div *ngFor="let dataset of allDatasets" class="row pl-3 datasets">
<mat-icon *ngIf="isDraft(dataset)" class="col-1 draft-bookmark">bookmark</mat-icon>
<mat-icon *ngIf="!isDraft(dataset)" class="col-1 finalized-bookmark">bookmark</mat-icon>
<h4 *ngIf="isDraft(dataset)" class="col-11 ml-auto mt-1 mb-4">
<span>{{ 'TYPES.DATASET-STATUS.DRAFT' | translate }}:</span>
{{ dataset.label }}</h4>
<h4 *ngIf="!isDraft(dataset)" class="col-11 ml-auto mt-1 mb-4">{{ dataset.label }}</h4>
</div>
</div>
<div *ngIf="allDatasets.length === 0" class="emptyList">{{ 'DMP-FINALISE-DIALOG.EMPTY' | translate }} </div>
</mat-expansion-panel>
</mat-accordion>
<div *ngIf="datasetsDraft.length > 0" class="pt-4 pb-2">
<h4 class="pl-2">{{'DMP-FINALISE-DIALOG.FINALISE-TITLE' | translate}}</h4>
<mat-selection-list #datasetsDraftSelectionList [ngModel]="outputModel.datasetToBeFinalized">
<div class="styleBorder" *ngFor="let dataset of datasetsDraft">
<mat-list-option [value]='dataset.id'>
{{ dataset.label }}
</mat-list-option>
</div>
</mat-selection-list>
</div>
<mat-error *ngIf="datasetsFinalized.length == 0">{{'DMP-FINALISE-DIALOG.VALIDATION.AT-LEAST-ONE-DATASET-FINALISED'
| translate}}</mat-error>
</div>
<div mat-dialog-content *ngIf="isWizard" class="pt-2 pb-2">
<mat-accordion [multi]="true">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'DMP-FINALISE-DIALOG.DMP' | translate }}
</mat-panel-title>
<mat-panel-description class="dmp-title">
{{ formGroup.get('dmp')?.get('label')?.value }}
</mat-panel-description>
</mat-expansion-panel-header>
{{ formGroup.get('dmp')?.get('description')?.value }}
</mat-expansion-panel>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'DMP-FINALISE-DIALOG.DATASETS' | translate }}
</mat-panel-title>
<mat-panel-description></mat-panel-description>
</mat-expansion-panel-header>
<div *ngIf="allDatasetLabels.length > 0">
<div *ngFor="let label of allDatasetLabels" class="row pl-3 datasets">
<mat-icon class="col-1 finalized-bookmark">bookmark</mat-icon>
<h4 class="col-11 ml-auto mt-1 mb-4">{{ label }}</h4>
</div>
</div>
<div *ngIf="allDatasetLabels.length === 0" class="emptyList"> {{ 'DMP-FINALISE-DIALOG.EMPTY' | translate }}
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
<div *ngIf="datasetsFinalized && datasetsFinalized.length != 0">
<div class="row pt-2 pb-2 pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.IMPACT' | translate }}
</div>
<div class="row pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION' | translate }}
</div>
</div>
<div mat-dialog-actions class="d-flex justify-content-end">
<div class="col-auto">
<button mat-raised-button class="confirm" (click)="onSubmit()">{{ data.confirmButton }}</button>
</div>
<div class="col-auto">
<button mat-raised-button cdkFocusInitial (click)="close()" class="cancel">{{ data.cancelButton }}</button>
</div>
</div>
</form> -->

View File

@ -1,113 +0,0 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { BaseComponent } from '@common/base/base.component';
import { Observable, of } from 'rxjs';
import { catchError, map, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-dmp-finalize-dialog-component',
templateUrl: 'dmp-finalize-dialog.component.html',
styleUrls: ['./dmp-finalize-dialog.component.scss']
})
export class DmpFinalizeDialogComponent extends BaseComponent implements OnInit {
inputModel: DmpFinalizeDialogInput;
outputModel: DmpFinalizeDialogOutput;
protected datasetLookupStatus:DatasetStatusLookup[] = [];
protected datasetLookupStatusEnum = DatasetStatusLookup;
constructor(
public router: Router,
public dialogRef: MatDialogRef<DmpFinalizeDialogComponent>,
public datasetService: DatasetService,
@Inject(MAT_DIALOG_DATA) public data: any
) {
super();
this.inputModel = data['dialogInputModel'];
this.outputModel = { datasetsToBeFinalized: [] };
}
ngOnInit(): void {
this.inputModel.datasets.forEach(ds=>{
this.validateDataset(ds.id).subscribe(_=>{
console.log('response', _);
});
})
const drafts = this.getDraftDatasets();
drafts.forEach(draft=>{
this.datasetLookupStatus[draft.id] == DatasetStatusLookup.PENDING_VALIDATION;
this.validateDataset(draft.id)
.subscribe(isValid=>{
if(isValid){
this.datasetLookupStatus[draft.id] = DatasetStatusLookup.VALID;
}else{
this.datasetLookupStatus[draft.id] = DatasetStatusLookup.INVALID;
}
})
});
}
onSubmit() {
this.dialogRef.close(this.outputModel);
}
getFinalizedDatasets() {
return this.inputModel.datasets.filter(x => x.status === DatasetStatus.Finalized);
}
getDraftDatasets() {
return this.inputModel.datasets.filter(x => x.status === DatasetStatus.Draft);
}
close() {
this.dialogRef.close({ cancelled: true } as DmpFinalizeDialogOutput);
}
validateDataset(datasetId: string) : Observable<boolean>{
return this.datasetService
.validateDataset(datasetId)
.pipe(
takeUntil(this._destroyed),
map(_=>{
return true
}),
catchError(error=>{
return of(false);
})
);
}
get validDrafts(){
return this.getDraftDatasets().filter(x=> this.datasetLookupStatus[x.id] && (this.datasetLookupStatus[x.id] == DatasetStatusLookup.VALID));
}
}
export interface DmpFinalizeDialogInput {
dmpLabel: string;
dmpDescription: string;
datasets: DmpFinalizeDialogDataset[];
accessRights: boolean;
}
export interface DmpFinalizeDialogDataset {
label: string;
id?: string;
status: DatasetStatus;
}
export interface DmpFinalizeDialogOutput {
cancelled?: boolean;
datasetsToBeFinalized?: string[];
}
enum DatasetStatusLookup{
VALID = "VALID",
INVALID = "INVALID",
PENDING_VALIDATION = "PENDING"
}

View File

@ -44,6 +44,7 @@ import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-vers
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { DmpFinalizeDialogComponent } from '../dmp-finalize-dialog/dmp-finalize-dialog.component';
@Component({
selector: 'app-dmp-overview',
@ -115,9 +116,9 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmp = data;
this.dmp.dmpUsers = data.dmpUsers.filter(x=> x.isActive === IsActive.Active);
if(this.dmp.descriptions) this.dmp.descriptions = data.descriptions.filter(x=> x.isActive === IsActive.Active);
this.selectedBlueprint= data.blueprint;
this.dmp.dmpUsers = data.dmpUsers.filter(x => x.isActive === IsActive.Active);
if (this.dmp.descriptions) this.dmp.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active);
this.selectedBlueprint = data.blueprint;
this.researchers = this.referenceService.getReferencesForTypes(this.dmp?.dmpReferences, [this.referenceTypeService.getResearcherReferenceType()]);
if (!this.hasDoi()) {
this.selectedModel = this.dmp.entityDois[0];
@ -166,14 +167,14 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
});
}
});
if(this.isAuthenticated()){
if (this.isAuthenticated()) {
this.depositRepositoriesService.getAvailableRepos()
.pipe(takeUntil(this._destroyed))
.subscribe(
repos => {
this.depositRepos = repos;
},
error => this.depositRepos = []);
.pipe(takeUntil(this._destroyed))
.subscribe(
repos => {
this.depositRepos = repos;
},
error => this.depositRepos = []);
}
}
@ -493,69 +494,27 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
}
finalize() {
//TODO: add this
// const extraProperties = new ExtraPropertiesFormModel();
// this.dmpService.getSingle(this.dmp.id).pipe(map(data => data as Dmp))
// .pipe(takeUntil(this._destroyed))
// .subscribe(data => {
const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, {
maxWidth: '500px',
restoreFocus: false,
autoFocus: false,
data: {
dmp: this.dmp
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((descriptionsToBeFinalized: Guid[]) => {
if (descriptionsToBeFinalized && descriptionsToBeFinalized.length > 0) {
// if (!isNullOrUndefined(data.extraProperties)) {
// extraProperties.fromModel(data.extraProperties);
// }
// const dialogInputModel: DmpFinalizeDialogInput = {
// dmpLabel: this.dmp.label,
// dmpDescription: this.dmp.description,
// descriptions: this.dmp.descriptions.map(x => {
// return { label: x.label, id: x.id, status: x.status }
// }),
// accessRights: extraProperties.visible
// }
// this.dmpService.finalize(descriptionsToBeFinalized, this.dmp.id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// complete => {
// const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, {
// maxWidth: '500px',
// restoreFocus: false,
// autoFocus: false,
// data: {
// dialogInputModel: dialogInputModel,
// message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.FINALIZE-ITEM'),
// confirmButton: this.language.instant('DMP-FINALISE-DIALOG.SUBMIT'),
// cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
// }
// });
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: DmpFinalizeDialogOutput) => {
// if (result && !result.cancelled) {
// this.checkIfAnyProfileIsUsedLessThanMin(data).subscribe(checked => {
// if (!checked) {
// var descriptionsToBeFinalized: DescriptionsToBeFinalized = {
// uuids: result.descriptionsToBeFinalized
// };
// this.dmpService.finalize(descriptionsToBeFinalized, this.dmp.id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// complete => {
// if (extraProperties.visible) {
// //this.publish(this.dmp.id);
// this.dmpService.publish(this.dmp.id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(() => {
// //this.hasPublishButton = false;
// this.dmp.status = DmpStatus.Finalized;
// this.onUpdateCallbackSuccess();
// });
// }
// else {
// this.dmp.status = DmpStatus.Finalized;
// this.onUpdateCallbackSuccess();
// }
// },
// error => this.onUpdateCallbackError(error)
// );
// }
// })
// }
// });
// });
// },
// error => this.onUpdateCallbackError(error)
// );
}
});
}

View File

@ -7,6 +7,7 @@ import { CommonFormsModule } from '@common/forms/common-forms.module';
import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module';
import { CommonUiModule } from '@common/ui/common-ui.module';
import { NgDialogAnimationService } from 'ng-dialog-animation';
import { DmpFinalizeDialogModule } from '../dmp-finalize-dialog/dmp-finalize-dialog.module';
import { DmpOverviewRoutingModule } from './dmp-overview.routing';
@NgModule({
@ -16,7 +17,8 @@ import { DmpOverviewRoutingModule } from './dmp-overview.routing';
ConfirmationDialogModule,
FormattingModule,
AutoCompleteModule,
DmpOverviewRoutingModule
DmpOverviewRoutingModule,
DmpFinalizeDialogModule
],
declarations: [
DmpOverviewComponent,

View File

@ -1,15 +1,15 @@
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { Component, Input, OnInit } from '@angular/core';
import { FormArray, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { FormArray } from '@angular/forms';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { DmpUserType } from '@app/core/common/enum/dmp-user-type';
import { DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { UserService } from '@app/core/services/user/user.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { BaseComponent } from '@common/base/base.component';
import { DmpEditorModel, DmpUserEditorModel } from '../dmp-editor-blueprint/dmp-editor.model';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { DmpUserType } from '@app/core/common/enum/dmp-user-type';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { UserService } from '@app/core/services/user/user.service';
import { DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DmpEditorModel, DmpUserEditorModel } from '../dmp-editor-blueprint/dmp-editor.model';
@Component({
selector: 'app-user-field-component',
@ -42,7 +42,7 @@ export class UserFieldComponent extends BaseComponent implements OnInit {
addUser(): void {
const userArray = this.form.get('users') as FormArray;
const dmpUser: DmpUserEditorModel = new DmpUserEditorModel(this.validationErrorModel);
userArray.push(dmpUser.buildForm({rootPath: "users[" + userArray.length + "]."}));
userArray.push(dmpUser.buildForm({ rootPath: "users[" + userArray.length + "]." }));
}
removeUser(userIndex: number): void {

View File

@ -41,6 +41,8 @@ export class TagsComponent extends BaseComponent implements OnInit {
}
add(event: MatChipInputEvent): void {
if(this.form.disabled == true) return;
const value = (event.value || '').trim();
// Add our tag
@ -51,10 +53,12 @@ export class TagsComponent extends BaseComponent implements OnInit {
// Clear the input value
event.chipInput!.clear();
this.form.setValue(null);
this.form.setValue(this.tags);
}
remove(tag: string): void {
if(this.form.disabled == true) return;
const index = this.tags.indexOf(tag);
if (index >= 0) {
@ -65,6 +69,6 @@ export class TagsComponent extends BaseComponent implements OnInit {
selected(event: MatAutocompleteSelectedEvent): void {
this.tags.push(event.option.viewValue);
this.tagInput.nativeElement.value = '';
this.form.setValue(null);
this.form.setValue(this.tags);
}
}

View File

@ -60,7 +60,6 @@
"CONFIRMATION-DIALOG": {
"DELETE-ITEM": "Delete this item?",
"DELETE-USER": "Remove this collaborator?",
"FINALIZE-ITEM": "Finalize this item?",
"UNFINALIZE-ITEM": "Undo Finalization?",
"PUBLISH-ITEM": "Publish this item?",
"ADD-DATASET": "Do you want to continue by adding a Dataset to your DMP? You can always add more Datasets using \"Add Dataset (Wizard)\" menu.",
@ -269,7 +268,7 @@
"NEW-LANGUAGE": "New",
"EDIT-LANGUAGE": "Edit",
"NOTIFICATION-TEMPLATES": "Notification Templates",
"INAPP-NOTIFICATIONS":"Notifications",
"INAPP-NOTIFICATIONS": "Notifications",
"NOTIFICATIONS": "Notifications",
"PREFILLING-SOURCES": "Prefilling Sources",
"NEW-PREFILLING-SOURCE": "New",
@ -376,10 +375,10 @@
"LANGUAGES": "Languages",
"MAINTENANCE": "Maintenance",
"NOTIFICATION-TEMPLATES": "Notification Templates",
"NOTIFICATIONS":"Notifications",
"PREFILLING-SOURCES":"Prefilling Sources"
"NOTIFICATIONS": "Notifications",
"PREFILLING-SOURCES": "Prefilling Sources"
},
"DESCRIPTION-TEMPLATE-PREVIEW" : {
"DESCRIPTION-TEMPLATE-PREVIEW": {
"TEMPLATE": "Template"
},
"ANNOTATION-DIALOG": {
@ -387,7 +386,7 @@
"THREADS": {
"NEW-THREAD": "New comment",
"FROM-USER": "From",
"SEND": "Send comment",
"SEND": "Send comment",
"PROTECTION": {
"TITLE": "Visibility"
}
@ -520,7 +519,7 @@
},
"FIELD": {
"FIELDS": {
"FIELD-LABEL":"Label",
"FIELD-LABEL": "Label",
"REFERENCE-TYPE": "Reference Type",
"REFERENCE-TYPE-TITLE": "Reference Type",
"MULTIPLE-SELECT": "Multiple Select",
@ -1023,6 +1022,7 @@
"CANCEL": "Cancel"
},
"UNDO-FINALIZATION-DIALOG": {
"TITLE": "Undo Finalization?",
"CONFIRM": "Yes",
"NEGATIVE": "No"
},
@ -1103,7 +1103,14 @@
"SAVE-AND-ADD-NEW": "Save & Add New",
"SAVE-AND-CLOSE": "Save & Close",
"FINALIZE": "Finalize",
"DISCARD": "Discard"
"DISCARD": "Discard",
"REVERSE": "Undo Finalization",
"UNDO-FINALIZATION-QUESTION": "Undo finalization?",
"CONFIRM": "Yes",
"REJECT": "No"
},
"MESSAGES":{
"MISSING-FIELDS": "There are some required fields left unfilled. Please check the DMP and make sure that all required questions are answered and URLs are provided with valid input. (Missing fields are marked in red color)"
}
},
"DESCRIPTION-COPY-DIALOG": {
@ -1111,18 +1118,18 @@
"PLACEHOLDER": "Search DMP"
},
"PREFILL-DESCRIPTION-DIALOG": {
"TITLE": "Initialize your Dataset",
"OR": "OR",
"HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.",
"DESCRIPTION-TEMPLATE": "Description Template",
"PREFILLING-SOURCE": "Prefilling Source",
"SEARCH-HEADER": "Prefilled object",
"SEARCH": "Start typing to search for an entity to use for prefilling",
"ACTIONS": {
"NEXT": "Next",
"PREFILL": "Prefill",
"MANUALLY": "Manually"
}
"TITLE": "Initialize your Dataset",
"OR": "OR",
"HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.",
"DESCRIPTION-TEMPLATE": "Description Template",
"PREFILLING-SOURCE": "Prefilling Source",
"SEARCH-HEADER": "Prefilled object",
"SEARCH": "Start typing to search for an entity to use for prefilling",
"ACTIONS": {
"NEXT": "Next",
"PREFILL": "Prefill",
"MANUALLY": "Manually"
}
},
"DATASET-PUBLIC-LISTING": {
"TITLE": "Published Datasets",
@ -1138,7 +1145,7 @@
"TITLE": "Description Templates",
"CREATE-DESCRIPTION-TEMPLATE": "Create Description Template",
"MESSAGES": {
"TEMPLATE-UPLOAD-SUCCESS":"Template successfully uploaded"
"TEMPLATE-UPLOAD-SUCCESS": "Template successfully uploaded"
},
"FIELDS": {
"NAME": "Name",
@ -1407,13 +1414,13 @@
"FIELDS": {
"SUBJECT": "Subject",
"TRACKING-STATE": "State",
"NOTIFICATION-TYPE":"Type",
"NOTIFICATION-TYPE": "Type",
"CREATED-AT": "Created"
},
"FILTER": {
"TITLE": "Filters",
"TRACKING-STATE":"State",
"NOTIFICATION-TYPE":"Type",
"TRACKING-STATE": "State",
"NOTIFICATION-TYPE": "Type",
"IS-ACTIVE": "Is Active",
"CANCEL": "Cancel",
"APPLY-FILTERS": "Apply filters"
@ -1431,9 +1438,7 @@
"UNSUCCESSFUL-DELETE": "This item could not be deleted."
},
"INAPP-NOTIFICATION-EDITOR": {
"FIELDS": {
},
"FIELDS": {},
"ACTIONS": {
"CANCEL": "Cancel",
"DELETE": "Delete"
@ -1662,7 +1667,7 @@
"FIELDS": {
"FIXED-VALUE-FIELDS": "Fixed Value Fields",
"FIELDS": "API Fields",
"SOURCE-CONFIGURATION":"Search Source Configuration",
"SOURCE-CONFIGURATION": "Search Source Configuration",
"GET-SOURCE-CONFIGURATION": "Get Source Configuration",
"LABEL": "Label",
"FIELD": "Field",
@ -1723,7 +1728,7 @@
"NEW-PROFILE-CLONE": "New Clone Of ",
"EDIT": "Edit",
"CLONE": "Clone DMP Blueprint",
"NEW-VERSION":"Create New Version of DMP Blueprint"
"NEW-VERSION": "Create New Version of DMP Blueprint"
},
"SECTIONS-REQUIRED": "Required",
"FIELDS-REQUIRED": "Required",
@ -1757,7 +1762,7 @@
"LABEL": "Label",
"VALUE": "Value"
},
"PREFILLING-SOURCES":"Prefilling Sources"
"PREFILLING-SOURCES": "Prefilling Sources"
},
"ACTIONS": {
"ADD-FIELD": "Add Field",
@ -1978,10 +1983,10 @@
}
},
"REFERENCE-FIELD": {
"PLACEHOLDER":"Select",
"COULD-NOT-FIND-MESSAGE":"Couldn't find it?",
"PLACEHOLDER": "Select",
"COULD-NOT-FIND-MESSAGE": "Couldn't find it?",
"ACTIONS": {
"INSERT-MANUALLY":"Insert it manually"
"INSERT-MANUALLY": "Insert it manually"
}
},
"DMP-CLONE-DIALOG": {
@ -2382,9 +2387,9 @@
"CURRENCY": "Currency",
"VALIDATION": "Validator"
},
"USER-DESCRIPTION-TEMPLATE-ROLE":{
"OWNER":"Owner",
"MEMBER":"Member"
"USER-DESCRIPTION-TEMPLATE-ROLE": {
"OWNER": "Owner",
"MEMBER": "Member"
},
"DATASET-PROFILE-UPLOAD-TYPE": {
"DOWNLOAD": "Download file"
@ -2532,14 +2537,14 @@
"PENDING": "Pending",
"PROCESSING": "Processing",
"SUCCESSFUL": "Successful",
"ERROR":"Error",
"ERROR": "Error",
"OMITTED": "Omitted"
},
"NOTIFICATION-TRACKING-STATE": {
"UNDEFINED": "Undefined",
"NA": "NA",
"QUEUED": "Queued",
"SENT":"Sent",
"SENT": "Sent",
"DELIVERED": "Delivered",
"UNDELIVERED": "Undelivered",
"FAILED": "Failed",
@ -2549,7 +2554,7 @@
"PENDING": "Pending",
"PROCESSING": "Processing",
"SUCCESSFUL": "Successful",
"ERROR":"Error",
"ERROR": "Error",
"OMITTED": "Omitted"
},
"DMP-ACCESS-TYPE": {
@ -2751,7 +2756,7 @@
"DESCRIPTIONS": "Descriptions",
"DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Datasets",
"PUBLIC-DMPS": "Public DMPs",
"PUBLIC-DATASETS": "Public Datasets",
"PUBLIC-DESCRIPTIONS": "Public Descriptions",
"RELATED-ORGANISATIONS": "Related Organizations",
"DRAFTS": "Drafts",
"ALL": "All",
@ -2907,20 +2912,22 @@
}
},
"DMP-FINALISE-DIALOG": {
"TITLE": "Finalize this item?",
"DMP": "DMP",
"DATASETS": "Datasets",
"EMPTY": "No Datasets for this DMP so far",
"SUBMIT": "Submit",
"FINALISE-TITLE": "Do you want to finalize any of the following Draft Datasets?",
"ALREADY-FINALISED-DATASETS": "Already Finalized Datasets",
"NONE": "None",
"DESCRPIPTIONS": "Descriptions",
"EMPTY": "No Descriptions for this DMP so far",
"FINALISE-TITLE": "Do you want to finalize any of the following Draft Descriptions?",
"VALIDATION": {
"AT-LEAST-ONE-DATASET-FINALISED": "You need to have at least one Dataset Finalized"
"AT-LEAST-ONE-DESCRPIPTION-FINALISED": "You need to have at least one Description Finalized"
},
"IMPACT": "This action will finalize your DMP, and you won't be able to edit it again.",
"AFTER-FINALIZATION-PUBLISH": "After finalizing your DMP, it'll be published and be publicly available to the {{ APP_NAME_CAPS }} tool.",
"AFTER-FINALIZATION-RESTRICT-ACCESS": "Your DMP can be published and be publicly available to the {{ APP_NAME_CAPS }} tool after finalization when its access rights are opened. Current access rights: restricted",
"INVALID": "Invalid"
"PUBLIC-DMP-MESSAGE": "After finalizing your DMP, it'll be published and be publicly available to the {{ APP_NAME_CAPS }} tool.",
"RESTRICTED-DMP-MESSAGE": "Your DMP can be published and be publicly available to the {{ APP_NAME_CAPS }} tool after finalization when its access rights are opened. Current access rights: restricted",
"INVALID": "Invalid",
"ACTIONS": {
"SUBMIT": "Submit",
"CANCEL": "Cancel"
}
},
"DRAFTS": {
"FOR-DMP": "For DMP:",
@ -3022,4 +3029,4 @@
"FINALIZED": "Finalized",
"DELETED": "Deleted"
}
}
}

View File

@ -63,13 +63,13 @@
</div>
</mat-menu>
<button mat-icon-button (click)="toggleMode()" *ngIf="(listItemTemplate || cardItemTemplate) && !hideModeSelection" >
<!-- <button mat-icon-button (click)="toggleMode()" *ngIf="(listItemTemplate || cardItemTemplate) && !hideModeSelection" >
<ng-container [ngSwitch]="mode">
<mat-icon *ngSwitchCase="HybridListingMode.List">table_view</mat-icon>
<mat-icon *ngSwitchCase="HybridListingMode.Table">list</mat-icon>
<mat-icon *ngSwitchCase="HybridListingMode.Card">table_view</mat-icon>
</ng-container>
</button>
</button> -->
<ng-content select="[download-listing-report]" />
</div>

View File

@ -1,4 +1,4 @@
<button mat-button [matMenuTriggerFor]="settingsMenu">
<!-- <button mat-button [matMenuTriggerFor]="settingsMenu">
<ng-container *ngIf="currentUserSetting">
@ -40,4 +40,4 @@
</button>
</ng-container>
</ng-container>
</mat-menu>
</mat-menu> -->