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

This commit is contained in:
Diamantis Tziotzios 2024-03-14 09:54:51 +02:00
commit 4b585bc8c4
17 changed files with 175 additions and 74 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

@ -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

@ -184,16 +184,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

@ -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

@ -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

@ -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

@ -1022,6 +1022,7 @@
"CANCEL": "Cancel"
},
"UNDO-FINALIZATION-DIALOG": {
"TITLE": "Undo Finalization?",
"CONFIRM": "Yes",
"NEGATIVE": "No"
},
@ -1102,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": {
@ -2748,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",