This commit is contained in:
amentis 2024-03-07 17:14:39 +02:00
parent 8141d40ecf
commit 2c8982bfef
18 changed files with 65 additions and 28 deletions

View File

@ -59,7 +59,7 @@ public class UserDescriptionTemplateBuilder extends BaseBuilder<UserDescriptionT
FieldSet descriptionTemplateFields = fields.extractPrefixed(this.asPrefix(UserDescriptionTemplate._descriptionTemplate));
Map<UUID, DescriptionTemplate> descriptionTemplateMap = this.collectDescriptionTemplates(descriptionTemplateFields, data);
FieldSet userFields = fields.extractPrefixed(this.asPrefix(Description._createdBy));
FieldSet userFields = fields.extractPrefixed(this.asPrefix(UserDescriptionTemplate._user));
Map<UUID, User> userItemsMap = this.collectUsers(userFields, data);
List<UserDescriptionTemplate> models = new ArrayList<>();

View File

@ -186,7 +186,12 @@ public class DescriptionTemplatePersist {
.must(() -> !this.isNull(item.getDefinition()))
.failOn(DescriptionTemplatePersist._definition).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionTemplatePersist._definition}, LocaleContextHolder.getLocale())),
this.refSpec()
.iff(() -> !this.isNull(item.getDefinition()))
.iff(() -> !this.isNull(item.getDefinition()) && !this.isListNullOrEmpty(item.getDefinition().getPages()))
.on(DescriptionTemplatePersist._definition)
.over(item.getDefinition())
.using(() -> this.validatorFactory.validator(DefinitionPersist.DefinitionPersistValidator.class)),
this.refSpec()
.iff(() -> item.getStatus() == DescriptionTemplateStatus.Finalized)
.on(DescriptionTemplatePersist._definition)
.over(item.getDefinition())
.using(() -> this.validatorFactory.validator(DefinitionPersist.DefinitionPersistValidator.class)),

View File

@ -116,7 +116,7 @@ public class DescriptionController {
public Description publicGet(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("retrieving" + Description.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(DescriptionCensor.class).censor(fieldSet, null);
this.censorFactory.censor(PublicDescriptionCensor.class).censor(fieldSet);
DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).authorize(EnumSet.of(Public)).ids(id).dmpSubQuery(this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).statuses(DmpStatus.Finalized).accessTypes(DmpAccessType.Public));

View File

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

View File

@ -1,21 +1,21 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.REFERENCE-TYPE-TITLE'
<h5 style="font-weight: bold" class="col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.REFERENCE-TYPE-TITLE'
| translate}}</h5>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multipleSelect')">
{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.MULTIPLE-SELECT' | translate}}
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.MULTIPLE-SELECT' | translate}}
</mat-checkbox>
<div class="col-6">
<mat-form-field class="w-100">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.LABEL' | translate}}</mat-label>
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-LABEL' | translate}}</mat-label>
<input matInput type="string" [formControl]="form.get('data').get('label')">
<mat-error *ngIf="form.get('data').get('label').hasError('backendError')">{{form.get('data').get('label').getError('backendError').message}}</mat-error>
</mat-form-field>
</div>
<div class="col-6">
<mat-form-field class="w-100">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.REFERENCE-TYPE' | translate}}</mat-label>
<app-single-auto-complete placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.REFERENCE-TYPE' | translate}}" [required]="true" [formControl]="form.get('data').get('referenceTypeId')" [configuration]="referenceTypeService.singleAutocompleteConfiguration"></app-single-auto-complete>
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.REFERENCE-TYPE' | translate}}</mat-label>
<app-single-auto-complete placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.REFERENCE-TYPE' | translate}}" [required]="true" [formControl]="form.get('data').get('referenceTypeId')" [configuration]="referenceTypeService.singleAutocompleteConfiguration"></app-single-auto-complete>
<mat-error *ngIf="form.get('data').get('referenceTypeId').hasError('backendError')">{{form.get('data').get('referenceTypeId').getError('backendError').message}}</mat-error>
<mat-error *ngIf="form.get('data').get('referenceTypeId').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>

View File

@ -221,6 +221,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
formSubmit(): void {
this.formService.touchAllFormFields(this.formGroup);
console.log(this.formGroup);
if (!this.isFormValid()) {
return;
}

View File

@ -4,7 +4,7 @@ import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-
import { DescriptionTemplateFieldValidationType } from "@app/core/common/enum/description-template-field-validation-type";
import { DescriptionTemplateStatus } from "@app/core/common/enum/description-template-status";
import { UserDescriptionTemplateRole } from "@app/core/common/enum/user-description-template-role";
import { DescriptionTemplate, DescriptionTemplateDefinition, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelData, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection } from "@app/core/model/description-template/description-template";
import { DescriptionTemplate, DescriptionTemplateDefinition, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelData, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, UserDescriptionTemplate } from "@app/core/model/description-template/description-template";
import { DescriptionTemplateDefinitionPersist, DescriptionTemplateExternalDatasetDataPersist, DescriptionTemplateFieldPersist, DescriptionTemplateFieldSetPersist, DescriptionTemplateLabelAndMultiplicityDataPersist, DescriptionTemplateLabelDataPersist, DescriptionTemplateMultiplicityPersist, DescriptionTemplatePagePersist, DescriptionTemplatePersist, DescriptionTemplateRadioBoxDataPersist, DescriptionTemplateRadioBoxOptionPersist, DescriptionTemplateReferenceTypeFieldPersist, DescriptionTemplateRulePersist, DescriptionTemplateSectionPersist, DescriptionTemplateSelectDataPersist, DescriptionTemplateSelectOptionPersist, DescriptionTemplateUploadDataPersist, DescriptionTemplateUploadOptionPersist, UserDescriptionTemplatePersist } from "@app/core/model/description-template/description-template-persist";
import { BaseEditorModel } from "@common/base/base-form-editor-model";
import { BackendErrorValidator } from "@common/forms/validation/custom-validator";
@ -56,9 +56,7 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D
}),
users: this.formBuilder.array(
(this.users ?? []).map(
(item, index) => new UserDescriptionTemplateEditorModel(
this.validationErrorModel
).fromModel(item).buildForm({
(item, index) => item.buildForm({
rootPath: `users[${index}].`
})
), context.getValidation('users').validators
@ -77,7 +75,7 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D
baseValidationArray.push({ key: 'type', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'type')] });
baseValidationArray.push({ key: 'type', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'type')] });
baseValidationArray.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] });
baseValidationArray.push({ key: 'users', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'users')] });
baseValidationArray.push({ key: 'users', validators: [BackendErrorValidator(this.validationErrorModel, 'users')] });
baseValidationArray.push({ key: 'hash', validators: [] });
baseContext.validation = baseValidationArray;
@ -119,9 +117,9 @@ export class UserDescriptionTemplateEditorModel implements UserDescriptionTempla
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
public fromModel(item: UserDescriptionTemplatePersist): UserDescriptionTemplateEditorModel {
public fromModel(item: UserDescriptionTemplate): UserDescriptionTemplateEditorModel {
if (item) {
this.userId = item.userId;
this.userId = item.user?.id;
this.role = item.role;
}
return this;

View File

@ -1,8 +1,9 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type';
import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateDefinition, DescriptionTemplateExternalDatasetData, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelAndMultiplicityData, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData, DescriptionTemplateSelectOption, DescriptionTemplateUploadData, DescriptionTemplateUploadOption } from '@app/core/model/description-template/description-template';
import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateDefinition, DescriptionTemplateExternalDatasetData, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelAndMultiplicityData, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData, DescriptionTemplateSelectOption, DescriptionTemplateUploadData, DescriptionTemplateUploadOption, UserDescriptionTemplate } from '@app/core/model/description-template/description-template';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { User } from '@app/core/model/user/user';
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
import { BaseEditorResolver } from '@common/base/base-editor.resolver';
@ -79,6 +80,10 @@ export class DescriptionTemplateEditorResolver extends BaseEditorResolver {
[nameof<DescriptionTemplate>(x => x.definition), nameof<DescriptionTemplateDefinition>(x => x.pages), nameof<DescriptionTemplatePage>(x => x.sections), nameof<DescriptionTemplateSection>(x => x.fieldSets), nameof<DescriptionTemplateFieldSet>(x => x.fields), nameof<DescriptionTemplateField>(x => x.data), nameof<DescriptionTemplateUploadData>(x => x.types), nameof<DescriptionTemplateUploadOption>(x => x.label)].join('.'),
[nameof<DescriptionTemplate>(x => x.definition), nameof<DescriptionTemplateDefinition>(x => x.pages), nameof<DescriptionTemplatePage>(x => x.sections), nameof<DescriptionTemplateSection>(x => x.fieldSets), nameof<DescriptionTemplateFieldSet>(x => x.fields), nameof<DescriptionTemplateField>(x => x.data), nameof<DescriptionTemplateUploadData>(x => x.types), nameof<DescriptionTemplateUploadOption>(x => x.value)].join('.'),
[nameof<DescriptionTemplate>(x => x.users), nameof<UserDescriptionTemplate>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<DescriptionTemplate>(x => x.users), nameof<UserDescriptionTemplate>(x => x.user), nameof<User>(x => x.id),].join('.'),
[nameof<DescriptionTemplate>(x => x.users), nameof<UserDescriptionTemplate>(x => x.user), nameof<User>(x => x.name),].join('.'),
[nameof<DescriptionTemplate>(x => x.users), nameof<UserDescriptionTemplate>(x => x.role),].join('.'),
nameof<DescriptionTemplate>(x => x.createdAt),

View File

@ -94,11 +94,12 @@ export class DescriptionTemplateListingComponent extends BaseListingComponent<De
lookup.metadata = { countAll: true };
lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE };
lookup.isActive = [IsActive.Active];
lookup.versionStatuses = [DescriptionTemplateVersionStatus.Current, DescriptionTemplateVersionStatus.NotFinalized];
lookup.order = { items: [this.toDescSortField(nameof<DescriptionTemplate>(x => x.createdAt))] };
if (this.mode && this.mode == 'versions-listing') {
lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))];
lookup.versionStatuses = null;
}else{
lookup.versionStatuses = [DescriptionTemplateVersionStatus.Current, DescriptionTemplateVersionStatus.NotFinalized];
}
this.updateOrderUiFields(lookup.order);

View File

@ -259,8 +259,6 @@
</div>
</div>
<mat-error *ngIf="formGroup.get('definition').get('sections').dirty && formGroup.get('definition').get('sections').hasError('required')">{{'DMP-BLUEPRINT-EDITOR.SECTIONS-REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="formGroup.get('definition').get('sections').hasError('backendError')">{{formGroup.get('definition').get('sections').getError('backendError').message}}</mat-error>
</div>
@ -268,6 +266,8 @@
<div class="row">
<div class="col-auto">
<button mat-button class="action-btn" type="button" (click)="addSection()" [disabled]="formGroup.disabled">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.ADD-SECTION' | translate}}</button>
<mat-error *ngIf="formGroup.get('definition').get('sections').dirty && formGroup.get('definition').get('sections').hasError('required')">{{'DMP-BLUEPRINT-EDITOR.SECTIONS-REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="formGroup.get('definition').get('sections').hasError('backendError')">{{formGroup.get('definition').get('sections').getError('backendError').message}}</mat-error>
</div>
</div>
</div>

View File

@ -138,6 +138,9 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
this.route.data.subscribe(d => {
this.initModelFlags(d['action']);
});
if ((this.formGroup.get('definition').get('sections') as FormArray).length == 0) {
this.addSection();
}
}
private initModelFlags(action: string): void {
@ -225,6 +228,7 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
formSubmit(): void {
this.formService.touchAllFormFields(this.formGroup);
console.log(this.formGroup)
if (!this.isFormValid()) {
return;
}
@ -266,7 +270,9 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
//
//
addSection(): void {
(this.formGroup.get('definition').get('sections') as FormArray).push(this.editorModel.createChildSection((this.formGroup.get('definition').get('sections') as FormArray).controls.length));
const formArray = this.formGroup.get('definition').get('sections') as FormArray;
formArray.push(this.editorModel.createChildSection(formArray.length));
this.addField(formArray.length - 1);
}
removeSection(sectionIndex: number): void {

View File

@ -93,11 +93,12 @@ export class DmpBlueprintListingComponent extends BaseListingComponent<DmpBluepr
lookup.metadata = { countAll: true };
lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE };
lookup.isActive = [IsActive.Active];
lookup.versionStatuses = [DmpBlueprintVersionStatus.Current, DmpBlueprintVersionStatus.NotFinalized];
lookup.order = { items: [this.toDescSortField(nameof<DmpBlueprint>(x => x.createdAt))] };
if (this.mode && this.mode == 'versions-listing') {
lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))];
lookup.versionStatuses = null;
}else{
lookup.versionStatuses = [DmpBlueprintVersionStatus.Current, DmpBlueprintVersionStatus.NotFinalized];
}
this.updateOrderUiFields(lookup.order);

View File

@ -100,10 +100,11 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
}
updateUrl() {
let parameters = "?type=dmps" +
// let parameters = "?type=dmps" +
let parameters = "" +
(this.page != 1 ? "&page=" + this.page : "") +
//TODO refactor
//(((this.formGroup.get("order").value != this.order.MODIFIED && !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

@ -109,7 +109,7 @@
</button>
<p class="mb-0 mr-0 pl-2 frame-txt">{{ 'DESCRIPTION-OVERVIEW.ACTIONS.REVERSE' | translate }}</p>
</div>
<div class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<div class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" *ngIf="fileTransformerService.availableFormats.length > 0">
<button mat-mini-fab class="frame-btn" [matMenuTriggerFor]="exportMenu">
<mat-icon class="mat-mini-fab-icon">open_in_new</mat-icon>
</button>

View File

@ -11,7 +11,7 @@ import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description, DescriptionStatusPersist } from '@app/core/model/description/description';
import { Dmp, DmpUser, DmpUserRemovePersist } from '@app/core/model/dmp/dmp';
import { Dmp, DmpDescriptionTemplate, DmpUser, DmpUserRemovePersist } from '@app/core/model/dmp/dmp';
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { Reference } from '@app/core/model/reference/reference';
import { AuthService } from '@app/core/services/auth/auth.service';
@ -333,6 +333,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
formControl: formControl,
descriptionId: this.description.id,
descriptionTemplate: this.description.descriptionTemplate,
dmpDescriptionTemplate: this.description.dmpDescriptionTemplate,
descriptionProfileExist: false,
confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.COPY-DIALOG.COPY'),
cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.COPY-DIALOG.CANCEL')
@ -438,6 +439,9 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
[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.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.sectionId)].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('.'),

View File

@ -151,7 +151,7 @@
</button>
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-OVERVIEW.ACTIONS.REVERSE' | translate }}</p>
</div>
<div *ngIf="canExportDmp()" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<div *ngIf="canExportDmp() && fileTransformerService.availableFormats.length > 0" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<button mat-mini-fab class="frame-btn" [matMenuTriggerFor]="exportMenu">
<mat-icon class="mat-mini-fab-icon">open_in_new</mat-icon>
</button>

View File

@ -139,7 +139,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
this.isNew = false;
this.isFinalized = true;
this.isPublicView = true;
this.dmpService.getPublicSingle(itemId, this.lookupFields())
this.dmpService.getPublicSingle(publicId, this.lookupFields())
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmp = data;

View File

@ -397,6 +397,10 @@
"UNTITLED": "Untitled",
"QUESTION": "Question",
"TEMPLATE-OUTLINE": "Template outline",
"USERS": {
"NAME": "Name",
"ROLE": "Role"
},
"ERRORS": {
"USER-NOT-FOUND": "User not found."
}
@ -482,6 +486,10 @@
},
"FIELD": {
"FIELDS": {
"FIELD-LABEL":"Label",
"REFERENCE-TYPE": "Reference Type",
"REFERENCE-TYPE-TITLE": "Reference Type",
"MULTIPLE-SELECT": "Multiple Select",
"RULES-TITLE": "Conditional Questions",
"FIELD-RULES-VALUE": "Value",
"ID": "Section Unique Identifier",
@ -1671,6 +1679,8 @@
"CLONE": "Clone DMP Blueprint",
"NEW-VERSION":"Create New Version of DMP Blueprint"
},
"SECTIONS-REQUIRED": "Required",
"FIELDS-REQUIRED": "Required",
"FIELDS": {
"TITLE": "Fields",
"NAME": "Name",
@ -2321,6 +2331,10 @@
"CURRENCY": "Currency",
"VALIDATION": "Validator"
},
"USER-DESCRIPTION-TEMPLATE-ROLE":{
"OWNER":"Owner",
"MEMBER":"Member"
},
"DATASET-PROFILE-UPLOAD-TYPE": {
"DOWNLOAD": "Download file"
},