dmp blueprint editor fixes

This commit is contained in:
amentis 2024-01-29 13:13:30 +02:00
parent 37d349fa9b
commit 8fb3556acb
13 changed files with 229 additions and 98 deletions

View File

@ -138,7 +138,7 @@ public class SectionPersist {
.failOn(SectionPersist._hasTemplates).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._hasTemplates}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isListNullOrEmpty(item.getFields()))
.failOn(SectionPersist._fields).failWith(messageSource.getMessage("Validation_Required", new Object[]{eu.eudat.model.persist.descriptiontemplatedefinition.SectionPersist._fieldSets}, LocaleContextHolder.getLocale())),
.failOn(SectionPersist._fields).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._fields}, LocaleContextHolder.getLocale())),
this.navSpec()
.iff(() -> !this.isListNullOrEmpty(item.getFields()))
.on(SectionPersist._fields)

View File

@ -44,7 +44,9 @@ public class DescriptionTemplateQuery extends QueryBase<DescriptionTemplateEntit
private Collection<DescriptionTemplateStatus> statuses;
private Collection<UUID> excludedIds;
private Collection<UUID> excludedGroupIds;
private Collection<UUID> typeIds;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@ -159,6 +161,21 @@ public class DescriptionTemplateQuery extends QueryBase<DescriptionTemplateEntit
return this;
}
public DescriptionTemplateQuery excludedGroupIds(Collection<UUID> values) {
this.excludedGroupIds = values;
return this;
}
public DescriptionTemplateQuery excludedGroupIds(UUID value) {
this.excludedGroupIds = List.of(value);
return this;
}
public DescriptionTemplateQuery excludedGroupIds(UUID... value) {
this.excludedGroupIds = Arrays.asList(value);
return this;
}
public DescriptionTemplateQuery authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
@ -181,7 +198,7 @@ public class DescriptionTemplateQuery extends QueryBase<DescriptionTemplateEntit
@Override
protected Boolean isFalseQuery() {
return this.isEmpty(this.ids) || this.isEmpty(this.typeIds) || this.isEmpty(this.versionStatuses) || this.isEmpty(this.groupIds) ||this.isEmpty(this.isActives) || this.isEmpty(this.excludedIds) || this.isEmpty(this.statuses);
return this.isEmpty(this.ids) || this.isEmpty(this.typeIds) || this.isEmpty(this.versionStatuses) || this.isEmpty(this.groupIds) ||this.isEmpty(this.isActives) || this.isEmpty(this.excludedIds) || this.isEmpty(this.excludedGroupIds)|| this.isEmpty(this.statuses);
}
@Override
@ -263,6 +280,12 @@ public class DescriptionTemplateQuery extends QueryBase<DescriptionTemplateEntit
notInClause.value(item);
predicates.add(notInClause.not());
}
if (this.excludedGroupIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTemplateEntity._groupId));
for (UUID item : this.excludedGroupIds)
notInClause.value(item);
predicates.add(notInClause.not());
}
if (!predicates.isEmpty()) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray);

View File

@ -27,6 +27,8 @@ public class DescriptionTemplateLookup extends Lookup {
private List<UUID> excludedIds;
private List<UUID> excludedGroupIds;
public String getLike() {
return like;
}
@ -91,6 +93,14 @@ public class DescriptionTemplateLookup extends Lookup {
this.versionStatuses = versionStatuses;
}
public List<UUID> getExcludedGroupIds() {
return excludedGroupIds;
}
public void setExcludedGroupIds(List<UUID> excludedGroupIds) {
this.excludedGroupIds = excludedGroupIds;
}
public DescriptionTemplateQuery enrich(QueryFactory queryFactory) {
DescriptionTemplateQuery query = queryFactory.query(DescriptionTemplateQuery.class);
if (this.like != null) query.like(this.like);
@ -99,6 +109,7 @@ public class DescriptionTemplateLookup extends Lookup {
if (this.statuses != null) query.statuses(this.statuses);
if (this.ids != null) query.ids(this.ids);
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
if (this.excludedGroupIds != null) query.excludedGroupIds(this.excludedGroupIds);
if (this.typeIds != null) query.typeIds(this.typeIds);
if (this.versionStatuses != null) query.versionStatuses(this.versionStatuses);

View File

@ -12,6 +12,7 @@ export class DescriptionTemplateLookup extends Lookup implements DescriptionTemp
typeIds: Guid[];
statuses: DescriptionTemplateStatus[];
groupIds: Guid[];
excludedGroupIds: Guid[];
versionStatuses: DescriptionTemplateVersionStatus[];
constructor() {
@ -27,5 +28,6 @@ export interface DescriptionTemplateFilter {
typeIds: Guid[];
statuses: DescriptionTemplateStatus[];
groupIds: Guid[];
excludedGroupIds: Guid[];
versionStatuses: DescriptionTemplateVersionStatus[];
}

View File

@ -101,6 +101,7 @@ export class DescriptionTemplateService {
titleFn: (item: DescriptionTemplate) => item.label,
subtitleFn: (item: DescriptionTemplate) => item.description,
valueAssign: (item: DescriptionTemplate) => item.id,
popupItemActionIcon: 'visibility'
};
// tslint:disable-next-line: member-ordering
@ -145,6 +146,7 @@ export class DescriptionTemplateService {
titleFn: (item: DescriptionTemplate) => item.label,
subtitleFn: (item: DescriptionTemplate) => item.description,
valueAssign: (item: DescriptionTemplate) => item.groupId,
popupItemActionIcon: 'visibility'
};
// tslint:disable-next-line: member-ordering
@ -159,11 +161,13 @@ export class DescriptionTemplateService {
popupItemActionIcon: 'visibility'
};
public buildDescriptionTempalteGroupAutocompleteLookup(like?: string, excludedIds?: Guid[], groupIds?: Guid[]): DescriptionTemplateLookup {
public buildDescriptionTempalteGroupAutocompleteLookup(like?: string, excludedIds?: Guid[], groupIds?: Guid[], excludedGroupIds?: Guid[]): DescriptionTemplateLookup {
const lookup: DescriptionTemplateLookup = new DescriptionTemplateLookup();
lookup.page = { size: 100, offset: 0 };
if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; }
if (groupIds && groupIds.length > 0) { lookup.groupIds = groupIds; }
if (excludedGroupIds && excludedGroupIds.length > 0) { lookup.excludedGroupIds = excludedGroupIds; }
lookup.isActive = [IsActive.Active];
lookup.versionStatuses = [DescriptionTemplateVersionStatus.Current];
lookup.statuses = [DescriptionTemplateStatus.Finalized];

View File

@ -31,6 +31,8 @@ export interface SingleAutoCompleteConfiguration {
optionTemplate?: TemplateRef<any>;
// Selected value formating template
selectedValueTemplate?: TemplateRef<any>;
// Display icon that opens popup
popupItemActionIcon?: string;
// // To revert: "We set the items observable on focus to avoid the request being executed on component load."
// forceFocus?: boolean;

View File

@ -15,6 +15,7 @@
<span>{{_titleFn(item)}}</span>
<br *ngIf="_subtitleFn(item)">
<small *ngIf="_subtitleFn(item)">{{_subtitleFn(item)}}</small>
<span *ngIf="popupItemActionIcon" class="option-icon" (click)="_optionActionClick(item, $event)"><mat-icon>{{popupItemActionIcon}}</mat-icon></span>
</div>
</mat-option>
</mat-optgroup>
@ -31,6 +32,7 @@
<span *ngIf="!_optionTemplate(item)">{{_titleFn(item)}}</span>
<br *ngIf="_subtitleFn(item)">
<small *ngIf="_subtitleFn(item)">{{_subtitleFn(item)}}</small>
<span *ngIf="popupItemActionIcon" class="option-icon" (click)="_optionActionClick(item, $event)"><mat-icon>{{popupItemActionIcon}}</mat-icon></span>
</div>
</mat-option>
</ng-container>

View File

@ -35,6 +35,15 @@
}
}
.option-icon {
mat-icon {
margin: 0px 5px 0px 10px;
}
mat-icon:hover {
color: var(--primary-color);
}
}
.chip-list {
width: auto;
}

View File

@ -50,6 +50,7 @@ export class SingleAutoCompleteComponent extends _CustomComponentMixinBase imple
// Selected Option Event
@Output() optionSelected: EventEmitter<any> = new EventEmitter();
@Output() optionActionClicked: EventEmitter<any> = new EventEmitter();
id = `single-autocomplete-${SingleAutoCompleteComponent.nextId++}`;
stateChanges = new Subject<void>();
@ -192,6 +193,13 @@ export class SingleAutoCompleteComponent extends _CustomComponentMixinBase imple
this.optionSelectedInternal(event.option.value);
}
_optionActionClick(item: any, event: MouseEvent): void {
if (event != null) {
event.stopPropagation();
}
this.optionActionClicked.emit(item);
}
private optionSelectedInternal(item: any) {
const newValue = this._valueToAssign(item);
@ -331,6 +339,10 @@ export class SingleAutoCompleteComponent extends _CustomComponentMixinBase imple
return this.configuration.autoSelectFirstOptionOnBlur != null ? this.configuration.autoSelectFirstOptionOnBlur : false;
}
get popupItemActionIcon(): string {
return this.configuration.popupItemActionIcon != null ? this.configuration.popupItemActionIcon : '';
}
// get forceFocus(): boolean {
// return this.configuration.forceFocus != null ? this.configuration.forceFocus : false;
// }

View File

@ -87,8 +87,6 @@
<mat-select multiple [(ngModel)]="selectedSystemFields" [disabled]="formGroup.disabled" [ngModelOptions]="{standalone: true}" (selectionChange)= "addSystemField(sectionIndex, $event)">
<mat-option *ngFor="let systemFieldType of dmpBlueprintSystemFieldTypeEnum" [disabled]="systemFieldDisabled(systemFieldType)" [value]="systemFieldType">{{enumUtils.toDmpBlueprintSystemFieldTypeString(systemFieldType)}}</mat-option>
</mat-select>
<!-- <mat-error *ngIf="fieldsArray(sectionIndex).hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> -->
</mat-form-field>
</div>
<div class="col-auto">
@ -102,14 +100,13 @@
<div class="col-auto">
<span style="font-size: 15px;">{{fieldIndex + 1}}</span>
</div>
<div class="col-auto">
<mat-icon cdkDragHandle [ngClass]="{'drag-handle-disabled': formGroup.disabled}">drag_indicator</mat-icon>
</div>
<div class="col-auto d-flex"><mat-icon [ngClass]="{'drag-handle-disabled': formGroup.disabled}" cdkDragHandle class="drag-handle">drag_indicator</mat-icon></div>
<div class="col-auto" *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.SYSTEM">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.SYSTEM-FIELD' | translate}}</mat-label>
<input matInput disabled value="{{enumUtils.toDmpBlueprintSystemFieldTypeString(field.get('systemFieldType').value)}}" type="text" name="name">
<mat-error *ngIf="field.get('dataType').hasError('backendError')">{{field.get('dataType').getError('backendError').message}}</mat-error>
<mat-error *ngIf="field.get('dataType').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-auto" *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.EXTRA">
@ -137,6 +134,7 @@
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.FIELD-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="text" name="placeholder" [formControl]="field.get('placeholder')">
<mat-error *ngIf="field.get('placeholder').hasError('backendError')">{{field.get('placeholder').getError('backendError').message}}</mat-error>
<mat-error *ngIf="field.get('placeholder').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col">
@ -144,11 +142,13 @@
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.FIELD-DESCRIPTION' | translate}}</mat-label>
<input matInput type="text" name="description" [formControl]="field.get('description')">
<mat-error *ngIf="field.get('description').hasError('backendError')">{{field.get('description').getError('backendError').message}}</mat-error>
<mat-error *ngIf="field.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-auto">
<mat-checkbox [disabled]="field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.TEXT || field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.HTML_TEXT" [formControl]="field.get('required')"><span>{{'DMP-BLUEPRINT-EDITOR.FIELDS.FIELD-REQUIRED' | translate}}</span></mat-checkbox>
<mat-error *ngIf="field.get('systemFieldType').hasError('backendError')">{{field.get('systemFieldType').getError('backendError').message}}</mat-error>
<mat-error *ngIf="field.get('systemFieldType').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</div>
<div *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.SYSTEM" [hidden]="viewOnly" class="col-auto">
<button mat-icon-button matTooltip="{{'DMP-BLUEPRINT-EDITOR.ACTIONS.REMOVE-SYSTEM-FIELD' | translate}}" (click)="removeSystemField(sectionIndex, fieldIndex)" [disabled]="formGroup.disabled">
@ -161,6 +161,8 @@
</button>
</div>
</div>
<mat-error *ngIf="section.get('fields').dirty && section.get('fields').hasError('required')">{{'DMP-BLUEPRINT-EDITOR.FIELDS-REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="section.get('fields').hasError('backendError')">{{section.get('fields').getError('backendError').message}}</mat-error>
</div>
</div>
</mat-card-content>
@ -168,50 +170,62 @@
<div class="col-12">
<div class="row">
<div class="col-auto">
<!-- <mat-checkbox [formControl]="section.get('hasTemplates')" (change)="checkForBlueprints($event, sectionIndex)"> -->
<mat-checkbox [formControl]="section.get('hasTemplates')">
<mat-checkbox [formControl]="section.get('hasTemplates')" (change) = "removeAllDescriptionTemplates($event, sectionIndex)">
{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATES' | translate}}
<mat-error *ngIf="section.get('hasTemplates').hasError('backendError')">{{section.get('hasTemplates').getError('backendError').message}}</mat-error>
<mat-error *ngIf="section.get('hasTemplates').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-checkbox>
</div>
<div class="col-auto" *ngIf="section.get('hasTemplates').value == true">
<button mat-button class="action-btn" type="button" (click)="addDescriptionTemplate(sectionIndex)" [disabled]="formGroup.disabled">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.ADD-DESCRIPTION-TEMPLATE' | translate}}</button>
</div>
</div>
</div>
<div class="col-12" *ngIf="section.get('hasTemplates').value == true">
<div class="row">
<div class="col-12">
<div cdkDropList class="col-12" (cdkDropListDropped)="dropDescriptionTemplates($event, sectionIndex)">
<div *ngFor="let descriptionTemplate of section.get('descriptionTemplates').controls; let descriptionTemplateIndex=index;" cdkDrag class="row align-items-center" [cdkDragDisabled]="formGroup.disabled">
<div class="col-auto">
<span style="font-size: 15px;">{{descriptionTemplateIndex + 1}}</span>
</div>
<div class="col-auto d-flex"><mat-icon [ngClass]="{'drag-handle-disabled': formGroup.disabled}" cdkDragHandle class="drag-handle">drag_indicator</mat-icon></div>
<div class="col">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATES' | translate}}</mat-label>
<app-multiple-auto-complete [disabled]="formGroup.disabled" [hidePlaceholder]="true" required='false' [configuration]="descriptionTemplateService.descriptionTempalteGroupMultipleAutocompleteConfiguration" (optionRemoved)="onRemoveDescritionTemplate($event, sectionIndex)" (optionSelected)="onSelectDescritionTemplate($event, sectionIndex)" (optionActionClicked)="onPreviewDescriptionTemplate($event, i)"></app-multiple-auto-complete> </mat-form-field>
<app-single-auto-complete [formControl]="descriptionTemplate.get('descriptionTemplateGroupId')" [hidePlaceholder]="true" [configuration]="descriptionTempalteGroupSingleAutocompleteConfiguration" (optionActionClicked)="onPreviewDescriptionTemplate($event, i)"></app-single-auto-complete>
<mat-error *ngIf="descriptionTemplate.get('descriptionTemplateGroupId').hasError('backendError')">{{descriptionTemplate.get('descriptionTemplateGroupId').getError('backendError').message}}</mat-error>
<mat-error *ngIf="descriptionTemplate.get('descriptionTemplateGroupId').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
</div>
<div *ngFor="let descriptionTemplate of section.get('descriptionTemplates').controls; let j=index;" class="col-12">
<div class="col-12">
<div class="row">
<div class="col-4">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATE-LABEL' | translate}}</mat-label>
<input matInput type="text" value="descriptionTemplate.get('label')" name="label" [formControl]="descriptionTemplate.get('label')">
<mat-error *ngIf="descriptionTemplate.get('label').hasError('backendError')">{{descriptionTemplate.get('label').getError('backendError').message}}</mat-error>
</mat-form-field>
</div>
<div class="col-4">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATE-MIN-MULTIPLICITY' | translate}}</mat-label>
<input matInput type="number" min="0" name="minMultiplicity" [formControl]="descriptionTemplate.get('minMultiplicity')">
<mat-error *ngIf="descriptionTemplate.get('minMultiplicity').hasError('backendError')">{{descriptionTemplate.get('minMultiplicity').getError('backendError').message}}</mat-error>
</mat-form-field>
</div>
<div class="col-4">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATE-MAX-MULTIPLICITY' | translate}}</mat-label>
<input matInput type="number" min="1" name="maxMultiplicity" [formControl]="descriptionTemplate.get('maxMultiplicity')">
<mat-error *ngIf="descriptionTemplate.get('maxMultiplicity').hasError('backendError')">{{descriptionTemplate.get('maxMultiplicity').getError('backendError').message}}</mat-error>
</mat-form-field>
</div>
<div class="col">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATE-LABEL' | translate}}</mat-label>
<input matInput type="text" name="label" [formControl]="descriptionTemplate.get('label')">
<mat-error *ngIf="descriptionTemplate.get('label').hasError('backendError')">{{descriptionTemplate.get('label').getError('backendError').message}}</mat-error>
<mat-error *ngIf="descriptionTemplate.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
<div class="col">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATE-MIN-MULTIPLICITY' | translate}}</mat-label>
<input matInput type="number" min="0" name="minMultiplicity" [formControl]="descriptionTemplate.get('minMultiplicity')">
<mat-error *ngIf="descriptionTemplate.get('minMultiplicity').hasError('backendError')">{{descriptionTemplate.get('minMultiplicity').getError('backendError').message}}</mat-error>
<mat-error *ngIf="descriptionTemplate.get('minMultiplicity').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATE-MAX-MULTIPLICITY' | translate}}</mat-label>
<input matInput type="number" min="1" name="maxMultiplicity" [formControl]="descriptionTemplate.get('maxMultiplicity')">
<mat-error *ngIf="descriptionTemplate.get('maxMultiplicity').hasError('backendError')">{{descriptionTemplate.get('maxMultiplicity').getError('backendError').message}}</mat-error>
<mat-error *ngIf="descriptionTemplate.get('maxMultiplicity').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-auto d-flex">
<button mat-icon-button class="action-list-icon" matTooltip="{{'DMP-BLUEPRINT-EDITOR.ACTIONS.REMOVE-DESCRIPTION-TEMPLATE' | translate}}" (click)="removeDescriptionTemplate(sectionIndex, descriptionTemplateIndex)" [disabled]="formGroup.disabled">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
</div>
</mat-card>

View File

@ -17,7 +17,6 @@ import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DmpBlueprint, DmpBlueprintPersist } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { LoggingService } from '@app/core/services/logging/logging-service';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
@ -35,15 +34,12 @@ import { map, takeUntil } from 'rxjs/operators';
import { DescriptionTemplatesInSectionEditorModel, DmpBlueprintDefinitionSectionEditorModel, DmpBlueprintEditorModel, FieldInSectionEditorModel } from './dmp-blueprint-editor.model';
import { DmpBlueprintEditorResolver } from './dmp-blueprint-editor.resolver';
import { DmpBlueprintEditorService } from './dmp-blueprint-editor.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { DescriptionTemplateLookup } from '@app/core/query/description-template.lookup';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { nameof } from 'ts-simple-nameof';
import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status';
import { DescriptionTemplateVersionStatus } from '@app/core/common/enum/description-template-version-status';
import { MatSelectChange } from '@angular/material/select';
import { DescriptionTemplatePreviewDialogComponent } from '../../description-template/description-template-preview/description-template-preview-dialog.component';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { MatCheckboxChange } from '@angular/material/checkbox';
@Component({
@ -64,6 +60,16 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
public dmpBlueprintSystemFieldTypeEnum = this.enumUtils.getEnumValues<DmpBlueprintSystemFieldType>(DmpBlueprintSystemFieldType);
dmpBlueprintExtraFieldDataType = DmpBlueprintExtraFieldDataType;
public dmpBlueprintExtraFieldDataTypeEnum = this.enumUtils.getEnumValues<DmpBlueprintExtraFieldDataType>(DmpBlueprintExtraFieldDataType);
descriptionTempalteGroupSingleAutocompleteConfiguration: SingleAutoCompleteConfiguration = {
initialItems: (data?: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup(null, null, null, this.getUsedDescriptionTemplateGroupIds())).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup(searchQuery, null, null, this.getUsedDescriptionTemplateGroupIds() ? this.getUsedDescriptionTemplateGroupIds(): null)).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
displayFn: (item: DescriptionTemplate) => item.label,
titleFn: (item: DescriptionTemplate) => item.label,
subtitleFn: (item: DescriptionTemplate) => item.description,
valueAssign: (item: DescriptionTemplate) => item.groupId,
popupItemActionIcon: 'visibility'
}
protected get canDelete(): boolean {
return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeleteDmpBlueprint);
@ -289,9 +295,21 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
}
removeSystemField(sectionIndex: number, fieldIndex: number): void {
const formArray = ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields') as FormArray);
formArray.removeAt(fieldIndex);
formArray.controls.forEach((section, index) => {
const fieldsArray = (this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields') as FormArray;
const systemFieldType = fieldsArray.at(fieldIndex).get('systemFieldType').value
if(systemFieldType > -1) {
if (this.selectedSystemFields.length == 1){
this.selectedSystemFields = [];
}else{
const index = this.selectedSystemFields.indexOf(systemFieldType);
if (index > -1) {
this.selectedSystemFields.splice(index, 1);
this.selectedSystemFields = [...this.selectedSystemFields];
}
}
}
fieldsArray.removeAt(fieldIndex);
fieldsArray.controls.forEach((section, index) => {
section.get('ordinal').setValue(index + 1);
});
@ -301,7 +319,7 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
validationErrorModel: this.editorModel.validationErrorModel
}
);
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields').markAsDirty();
fieldsArray.markAsDirty();
}
addExtraField(sectionIndex: number): void {
@ -325,7 +343,6 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
}
);
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields').markAsDirty();
// ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields') as FormArray).at(fieldIndex).markAsDirty();
}
@ -346,51 +363,87 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields').markAsDirty();
}
//Description Templates
removeAllDescriptionTemplates(matCheckBox: MatCheckboxChange, sectionIndex: number){
if(matCheckBox.checked == false){
const descriptionTemplateSize = ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray).length;
for (let i=0; i< descriptionTemplateSize; i++) this.removeDescriptionTemplate(sectionIndex, 0);
}
}
addDescriptionTemplate(sectionIndex: number): void {
const descriptionTempaltesArray = (this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray ;
descriptionTempaltesArray.push(this.editorModel.createChildDescriptionTemplate(sectionIndex, ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray).length));
}
getUsedDescriptionTemplateGroupIds(): Guid[]{
let excludedGroupIds: Guid[] = [];
(this.formGroup.get('definition').get('sections') as FormArray).controls.forEach((section, index) => {
const descriptionTempaltesArray = (this.formGroup.get('definition').get('sections') as FormArray).at(index).get('descriptionTemplates') as FormArray;
if (descriptionTempaltesArray.length > 1){
descriptionTempaltesArray.controls.forEach((template, index) => {
if(template.get('descriptionTemplateGroupId').value != undefined) excludedGroupIds.push(template.get('descriptionTemplateGroupId').value as Guid);
})
}
});
return excludedGroupIds;
}
removeDescriptionTemplate(sectionIndex: number, descriptionTemplateIndex: number): void {
const descriptionTempaltesArray = (this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray;
descriptionTempaltesArray.removeAt(descriptionTemplateIndex);
DmpBlueprintEditorModel.reApplySectionValidators(
{
formGroup: this.formGroup,
validationErrorModel: this.editorModel.validationErrorModel
}
);
descriptionTempaltesArray.markAsDirty();
}
dropDescriptionTemplates(event: CdkDragDrop<string[]>, sectionIndex: number) {
const descriptionTemplatesFormArray = ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray);
moveItemInArray(descriptionTemplatesFormArray.controls, event.previousIndex, event.currentIndex);
descriptionTemplatesFormArray.updateValueAndValidity();
DmpBlueprintEditorModel.reApplySectionValidators({
formGroup: this.formGroup,
validationErrorModel: this.editorModel.validationErrorModel
}
);
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates').markAsDirty();
}
//
//
// Autocomplete configuration
//
//
private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): DescriptionTemplateLookup {
const lookup: DescriptionTemplateLookup = new DescriptionTemplateLookup();
lookup.page = { size: 100, offset: 0 };
if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; }
if (ids && ids.length > 0) { lookup.ids = ids; }
lookup.isActive = [IsActive.Active];
lookup.statuses = [DescriptionTemplateStatus.Finalized];
lookup.versionStatuses = [DescriptionTemplateVersionStatus.Current];
lookup.project = {
fields: [
nameof<DescriptionTemplate>(x => x.id),
nameof<DescriptionTemplate>(x => x.label)
]
};
lookup.order = { items: [nameof<DescriptionTemplate>(x => x.label)] };
if (like) { lookup.like = this.filterService.transformLike(like); }
return lookup;
}
// onRemoveDescritionTemplate(event, sectionIndex: number) {
// const descriptionTemplateFormArray = (this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray;
// const foundIndex = descriptionTemplateFormArray.controls.findIndex(blueprint => blueprint.get('descriptionTemplateId').value === event.id);
// if (foundIndex !== -1) {
// descriptionTemplateFormArray.removeAt(foundIndex);
// DmpBlueprintEditorModel.reApplySectionValidators(
// {
// formGroup: this.formGroup,
// validationErrorModel: this.editorModel.validationErrorModel
// }
// )
// this.formGroup.get('definition').get('sections').markAsDirty();
// }
// }
onRemoveDescritionTemplate(event, sectionIndex: number) {
const descriptionTemplateFormArray = (this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray;
const foundIndex = descriptionTemplateFormArray.controls.findIndex(blueprint => blueprint.get('descriptionTemplateId').value === event.id);
if (foundIndex !== -1) {
descriptionTemplateFormArray.removeAt(foundIndex);
DmpBlueprintEditorModel.reApplySectionValidators(
{
formGroup: this.formGroup,
validationErrorModel: this.editorModel.validationErrorModel
}
)
this.formGroup.get('definition').get('sections').markAsDirty();
}
}
// onSelectDescritionTemplate(item, sectionIndex) {
// ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray)
// .push(this.editorModel.createChildDescriptionTemplate(item, sectionIndex, ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray).length));
onSelectDescritionTemplate(item, sectionIndex) {
((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray)
.push(this.editorModel.createChildDescriptionTemplate(item, sectionIndex, ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray).length));
}
// }
// ngAfterViewInit() {

View File

@ -86,11 +86,8 @@ export class DmpBlueprintEditorModel extends BaseEditorModel implements DmpBluep
return field.buildForm({ rootPath: 'definition.sections[' + sectionIndex + '].fields[' + index + '].' });
}
createChildDescriptionTemplate(item: any, sectionIndex: number, index: number): UntypedFormGroup {
createChildDescriptionTemplate(sectionIndex: number, index: number, item?: any): UntypedFormGroup {
const descriptionTemplate: DescriptionTemplatesInSectionEditorModel = new DescriptionTemplatesInSectionEditorModel(this.validationErrorModel);
// descriptionTemplate.id = Guid.create();
descriptionTemplate.descriptionTemplateGroupId = item.descriptionTemplateGroupId;
descriptionTemplate.label = item.label;
return descriptionTemplate.buildForm({ rootPath: 'definition.sections[' + sectionIndex + '].descriptionTemplates[' + index + '].' });
}
@ -488,7 +485,7 @@ export class DescriptionTemplatesInSectionEditorModel implements DescriptionTemp
validationErrorModel
});
['id', 'descriptionTemplateId', 'label', 'minMultiplicity', 'maxMultiplicity'].forEach(keyField => {
['descriptionTemplateGroupId', 'label', 'minMultiplicity', 'maxMultiplicity'].forEach(keyField => {
const control = formGroup?.get(keyField);
control?.clearValidators();
control?.addValidators(context.getValidation(keyField).validators);

View File

@ -1625,10 +1625,12 @@
}
},
"ACTIONS": {
"ADD-EXTRA-FIELD": "Add extra field",
"ADD-EXTRA-FIELD": "Add Extra Field",
"REMOVE-SYSTEM-FIELD": "Delete",
"REMOVE-EXTRA-FIELD": "Delete",
"REMOVE-SECTION": "Remove Section",
"ADD-DESCRIPTION-TEMPLATE": "Add Description Template",
"REMOVE-DESCRIPTION-TEMPLATE": "Remove Description Template",
"ADD-SECTION": "Add Section",
"SAVE": "Save",
"CANCEL": "Cancel",
@ -2141,7 +2143,7 @@
"DATE": "Date",
"NUMBER": "Number",
"TEXT": "Text",
"EXTERNAL-AUTOCOMPLETE": "External AutoComplete"
"RICH-TEXT": "Rich Text"
},
"TYPE": {
"INPUT": "Input"