diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardServiceImpl.java index 8eb8a2231..d4ba31741 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardServiceImpl.java @@ -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); } } diff --git a/dmp-backend/web/src/main/resources/config/deposit.yml b/dmp-backend/web/src/main/resources/config/deposit.yml index 84b70f957..46cb35c1a 100644 --- a/dmp-backend/web/src/main/resources/config/deposit.yml +++ b/dmp-backend/web/src/main/resources/config/deposit.yml @@ -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 diff --git a/dmp-backend/web/src/main/resources/config/transformer.yml b/dmp-backend/web/src/main/resources/config/transformer.yml index 7cb90d96a..0b7659490 100644 --- a/dmp-backend/web/src/main/resources/config/transformer.yml +++ b/dmp-backend/web/src/main/resources/config/transformer.yml @@ -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:} diff --git a/dmp-frontend/src/app/core/common/enum/recent-activity-order.ts b/dmp-frontend/src/app/core/common/enum/recent-activity-order.ts index 183e6ad23..47439b208 100644 --- a/dmp-frontend/src/app/core/common/enum/recent-activity-order.ts +++ b/dmp-frontend/src/app/core/common/enum/recent-activity-order.ts @@ -2,5 +2,4 @@ export enum RecentActivityOrder { UpdatedAt = 0, Label = 1, Status = 2, - Published = 3 } diff --git a/dmp-frontend/src/app/core/model/dashboard/dashboard-statistics.ts b/dmp-frontend/src/app/core/model/dashboard/dashboard-statistics.ts index e7ad0f895..7fb360a2c 100644 --- a/dmp-frontend/src/app/core/model/dashboard/dashboard-statistics.ts +++ b/dmp-frontend/src/app/core/model/dashboard/dashboard-statistics.ts @@ -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 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp.ts b/dmp-frontend/src/app/core/model/dmp/dmp.ts index bb39635fc..c05256f4f 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp.ts @@ -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; diff --git a/dmp-frontend/src/app/core/services/description/description.service.ts b/dmp-frontend/src/app/core/services/description/description.service.ts index e0b02e453..b363ad425 100644 --- a/dmp-frontend/src/app/core/services/description/description.service.ts +++ b/dmp-frontend/src/app/core/services/description/description.service.ts @@ -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 { + return of(new Array()); + } + // public downloadPDF(id: string): Observable> { // return this.httpClient.get(`${this.apiBase}/${id}/export/Pdf`, { responseType: 'blob', observe: 'response', headers: this.headers }); // } diff --git a/dmp-frontend/src/app/core/services/reference-type/reference-type.service.ts b/dmp-frontend/src/app/core/services/reference-type/reference-type.service.ts index b0588c97e..100a0a5bd 100644 --- a/dmp-frontend/src/app/core/services/reference-type/reference-type.service.ts +++ b/dmp-frontend/src/app/core/services/reference-type/reference-type.service.ts @@ -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'; + } } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.html b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.html index 3b3e4992b..ef7805ef3 100644 --- a/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.html @@ -28,9 +28,9 @@ {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.NEW' | translate}} -
-
- +
+
+ {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.NOTIFICATION-TYPE' | translate}} @@ -80,16 +80,18 @@
-
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-SECTION' | translate}}

- - {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-TEXT' | translate}} - - {{formGroup.get('value').get('subjectText').getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
- +
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-TEXT' | translate}} + + {{formGroup.get('value').get('subjectText').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-KEY' | translate}} {{formGroup.get('value').get('subjectKey').getError('backendError').message}} @@ -113,8 +115,8 @@

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-SECTION' | translate}}

-
- +
+ {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-KEY' | translate}} {{formGroup.get('value').get('bodyKey').getError('backendError').message}} @@ -123,7 +125,7 @@
{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-TEXT' | translate}} - {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-FIELD-OPTIONS' | translate}} -
+ -
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.EXTRA-OPTIONS' | translate}}

diff --git a/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.html b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.html index 27fe99d60..38bcd3e85 100644 --- a/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.html +++ b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.html @@ -85,7 +85,8 @@
-
+ +
diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html index ca9d9bbeb..ff6346b73 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html @@ -64,7 +64,7 @@
0
{{'DASHBOARD.DMPS' | translate}}
0
- {{'DASHBOARD.DESCRIPTIONS' | translate}} + {{'DASHBOARD.DESCRIPTIONS' | translate}}
0
{{'DASHBOARD.GRANTS' | translate}}
0
@@ -78,12 +78,12 @@ {{'DASHBOARD.DMPS' | translate}}
{{dashboardStatistics?.descriptionCount}}
- {{'DASHBOARD.DESCRIPTIONS' | translate}} -
- {{dashboardStatistics?.grantCount}}
+ {{'DASHBOARD.DESCRIPTIONS' | translate}} +
+ {{grantCount}}
{{'DASHBOARD.GRANTS' | translate}} -
- {{dashboardStatistics?.organizationCount}}
+
+ {{organizationCount}}
{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}
@@ -151,12 +151,12 @@ {{'DASHBOARD.PUBLIC-DMPS' | translate}}
{{dashboardStatistics?.descriptionCount}}
- {{'DASHBOARD.PUBLIC-DATASETS' | translate}} -
- {{dashboardStatistics?.grantCount}}
+ {{'DASHBOARD.PUBLIC-DESCRIPTIONS' | translate}} +
+ {{grantCount}}
{{'DASHBOARD.GRANTS' | translate}} -
- {{dashboardStatistics?.organizationCount}}
+
+ {{organizationCount}}
{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}
diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts b/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts index e9bdb74cf..b65323e76 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts @@ -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; } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts index 9626195e1..4ff40a54d 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts @@ -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); } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts index c0d755343..6f416d7a2 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts @@ -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(x => x.id)].join('.'), - [nameof(x => x.label)].join('.'), - [nameof(x => x.status)].join('.'), - [nameof(x => x.updatedAt)].join('.'), - [nameof(x => x.descriptionTemplate), nameof(x => x.id)].join('.'), - [nameof(x => x.descriptionTemplate), nameof(x => x.label)].join('.'), - [nameof(x => x.descriptionTemplate), nameof(x => x.groupId)].join('.'), - [nameof(x => x.dmp), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.label)].join('.'), - [nameof(x => x.dmp), nameof(x => x.accessType)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.user.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.role)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.label)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.type), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.isActive)].join('.'), + [nameof(x => x.description), nameof(x => x.id)].join('.'), + [nameof(x => x.description), nameof(x => x.label)].join('.'), + [nameof(x => x.description), nameof(x => x.status)].join('.'), + [nameof(x => x.description), nameof(x => x.updatedAt)].join('.'), + [nameof(x => x.description), nameof(x => x.descriptionTemplate), nameof(x => x.id)].join('.'), + [nameof(x => x.description), nameof(x => x.descriptionTemplate), nameof(x => x.label)].join('.'), + [nameof(x => x.description), nameof(x => x.descriptionTemplate), nameof(x => x.groupId)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.id)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.label)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.accessType)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.id)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.user.id)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.role)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.id)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.id)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.label)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.type), nameof(x => x.id)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), + [nameof(x => x.description), nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.isActive)].join('.'), ] }; diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.html b/dmp-frontend/src/app/ui/description/editor/description-editor.component.html index 9e791de12..44ba7f5cd 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.html @@ -55,7 +55,7 @@
- - +
diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts index 162d18d83..64bdb821c 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts @@ -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 { + this.finalize(); + }, 0); + } // if (this.itemId != null && this.newDmpId == null) { // this.isNew = false; @@ -639,10 +645,11 @@ export class DescriptionEditorComponent extends BaseEditor { + 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) + }); + }}); } } diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts index c183330c7..125bf9237 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts @@ -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(); - 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(); - 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; } diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts index dae06b876..a7ea6406a 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts @@ -121,6 +121,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver { return [ (prefix ? prefix + '.' : '') + [nameof(x => x.id)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.label)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.status)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.isActive)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.id)].join('.'), diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts index 3a3ee6cad..2f952c7e2 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts @@ -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], diff --git a/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts b/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts index e96308fda..7a945171a 100644 --- a/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts @@ -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(x => x.description), nameof(x => x.status), nameof(x => x.updatedAt), + nameof(x => x.hash), [nameof(x => x.descriptionTemplate), nameof(x => x.id)].join('.'), [nameof(x => x.descriptionTemplate), nameof(x => x.label)].join('.'), [nameof(x => x.descriptionTemplate), nameof(x => x.groupId)].join('.'), @@ -447,6 +448,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni [nameof(x => x.dmp), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.label)].join('.'), [nameof(x => x.dmp), nameof(x => x.accessType)].join('.'), + [nameof(x => x.dmp), nameof(x => x.status)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.user.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.user.name)].join('.'), diff --git a/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.html b/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.html new file mode 100644 index 000000000..11cb41d9f --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.html @@ -0,0 +1,82 @@ +
+
{{ 'DMP-FINALISE-DIALOG.TITLE' | translate }}
+
+ close +
+
+
+
+ + + + + {{ 'DMP-FINALISE-DIALOG.DMP' | translate }} + + + {{ dmp.label }} + + + {{ dmp.description }} + + + + + {{ 'DMP-FINALISE-DIALOG.DESCRPIPTIONS' | translate }} + + + +
+
+ bookmark + bookmark +

+ {{ 'TYPES.DATASET-STATUS.DRAFT' | translate }} + + ({{'DMP-FINALISE-DIALOG.INVALID' | translate}}) + + : + {{ description.label }} + +

+

{{ description.label }}

+
+
+
{{ 'DMP-FINALISE-DIALOG.EMPTY' | translate }}
+
+
+ +
+

{{'DMP-FINALISE-DIALOG.FINALISE-TITLE' | translate}}

+ +
+ + {{ description.label }} + +
+
+
+ + {{'DMP-FINALISE-DIALOG.VALIDATION.AT-LEAST-ONE-DESCRPIPTION-FINALISED' | translate}} + +
+
+
+
+ {{ 'DMP-FINALISE-DIALOG.IMPACT' | translate }} +
+
+ {{ 'DMP-FINALISE-DIALOG.PUBLIC-DMP-MESSAGE' | translate }} +
+
+ {{ 'DMP-FINALISE-DIALOG.RESTRICTED-DMP-MESSAGE' | translate }} +
+
+ +
+
+ +
+
+ +
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.scss b/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.scss similarity index 97% rename from dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.scss rename to dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.scss index ef8f400c4..c18623a32 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.scss +++ b/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.scss @@ -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); } diff --git a/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.ts new file mode 100644 index 000000000..892d9091d --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component.ts @@ -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, + 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 +} diff --git a/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.module.ts b/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.module.ts new file mode 100644 index 000000000..3ba72d62f --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.module.ts @@ -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() { } +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.html b/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.html deleted file mode 100644 index a19f9cc0d..000000000 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.html +++ /dev/null @@ -1,188 +0,0 @@ -
-
{{ data.message }}
-
- close -
-
-
-
- - - - - {{ 'DMP-FINALISE-DIALOG.DMP' | translate }} - - - {{ inputModel.dmpLabel }} - - - {{ inputModel.dmpDescription }} - - - - - {{ 'DMP-FINALISE-DIALOG.DATASETS' | translate }} - - - -
-
- bookmark - bookmark -

- {{ 'TYPES.DATASET-STATUS.DRAFT' | translate }} - - ({{'DMP-FINALISE-DIALOG.INVALID' | translate}}) - - : - {{ dataset.label }} - -

-

{{ dataset.label }}

-
-
-
{{ 'DMP-FINALISE-DIALOG.EMPTY' | translate }}
-
-
- -
-

{{'DMP-FINALISE-DIALOG.FINALISE-TITLE' | translate}}

- -
- - {{ dataset.label }} - -
-
-
- - {{'DMP-FINALISE-DIALOG.VALIDATION.AT-LEAST-ONE-DATASET-FINALISED' | translate}} - -
-
-
-
- {{ 'DMP-FINALISE-DIALOG.IMPACT' | translate }} -
-
- {{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION-PUBLISH' | translate }} -
-
- {{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION-RESTRICT-ACCESS' | translate }} -
-
- -
-
- -
-
- -
-
- - diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.ts deleted file mode 100644 index 8c7475e2e..000000000 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.ts +++ /dev/null @@ -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, - 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{ - 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" -} diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index 7f37bdead..5399d4ddb 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -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) + // ); + } + }); } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.module.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.module.ts index f94e89ffd..4df17f6f4 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.module.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.module.ts @@ -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, diff --git a/dmp-frontend/src/app/ui/dmp/user-field/user-field.component.ts b/dmp-frontend/src/app/ui/dmp/user-field/user-field.component.ts index 3ef6f78fb..1bd5b72f6 100644 --- a/dmp-frontend/src/app/ui/dmp/user-field/user-field.component.ts +++ b/dmp-frontend/src/app/ui/dmp/user-field/user-field.component.ts @@ -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 { diff --git a/dmp-frontend/src/app/ui/tag/tags-field/tags-field.component.ts b/dmp-frontend/src/app/ui/tag/tags-field/tags-field.component.ts index f0fdaf6d7..4a0eb444b 100644 --- a/dmp-frontend/src/app/ui/tag/tags-field/tags-field.component.ts +++ b/dmp-frontend/src/app/ui/tag/tags-field/tags-field.component.ts @@ -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); } } diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 8b21481b7..98c8c2e76 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -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" } -} +} \ No newline at end of file diff --git a/dmp-frontend/src/common/modules/hybrid-listing/hybrid-listing.component.html b/dmp-frontend/src/common/modules/hybrid-listing/hybrid-listing.component.html index 66952b0ad..e8607f816 100644 --- a/dmp-frontend/src/common/modules/hybrid-listing/hybrid-listing.component.html +++ b/dmp-frontend/src/common/modules/hybrid-listing/hybrid-listing.component.html @@ -63,13 +63,13 @@
-
diff --git a/dmp-frontend/src/common/modules/user-settings/user-settings-picker/user-settings-picker.component.html b/dmp-frontend/src/common/modules/user-settings/user-settings-picker/user-settings-picker.component.html index b72771a24..99e89ce76 100644 --- a/dmp-frontend/src/common/modules/user-settings/user-settings-picker/user-settings-picker.component.html +++ b/dmp-frontend/src/common/modules/user-settings/user-settings-picker/user-settings-picker.component.html @@ -1,4 +1,4 @@ -