2023-10-30 14:30:46 +01:00
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
import { Component, OnInit, QueryList, ViewChild } from '@angular/core';
|
2023-11-24 17:42:23 +01:00
|
|
|
import { FormArray, FormControl, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
2023-10-30 14:30:46 +01:00
|
|
|
import { MatDialog } from '@angular/material/dialog';
|
|
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
|
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
|
|
|
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
|
|
|
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
2023-10-31 10:19:52 +01:00
|
|
|
import { CdkStep, StepperSelectionEvent } from '@angular/cdk/stepper';
|
2023-10-30 14:30:46 +01:00
|
|
|
import { DatePipe } from '@angular/common';
|
2023-10-31 10:19:52 +01:00
|
|
|
import { MatStepper } from '@angular/material/stepper';
|
2023-10-30 14:30:46 +01:00
|
|
|
import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status';
|
|
|
|
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
|
|
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
2023-12-29 16:04:16 +01:00
|
|
|
import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role';
|
2023-10-30 14:30:46 +01:00
|
|
|
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
2024-02-08 15:48:50 +01:00
|
|
|
import { DescriptionTemplatePersist, NewVersionDescriptionTemplatePersist } from '@app/core/model/description-template/description-template-persist';
|
2023-10-31 10:19:52 +01:00
|
|
|
import { LanguageInfo } from '@app/core/model/language-info';
|
2023-11-24 17:42:23 +01:00
|
|
|
import { User } from '@app/core/model/user/user';
|
2023-10-30 14:30:46 +01:00
|
|
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
2023-10-31 10:19:52 +01:00
|
|
|
import { LanguageInfoService } from '@app/core/services/culture/language-info-service';
|
|
|
|
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
|
|
|
|
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
|
2023-10-30 14:30:46 +01:00
|
|
|
import { LoggingService } from '@app/core/services/logging/logging-service';
|
|
|
|
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
2023-11-24 17:42:23 +01:00
|
|
|
import { UserService } from '@app/core/services/user/user.service';
|
2023-10-30 14:30:46 +01:00
|
|
|
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
|
|
|
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
|
|
|
import { BaseEditor } from '@common/base/base-editor';
|
|
|
|
import { FormService } from '@common/forms/form-service';
|
|
|
|
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
|
|
|
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
|
|
|
import { FilterService } from '@common/modules/text-filter/filter-service';
|
|
|
|
import { Guid } from '@common/types/guid';
|
|
|
|
import { TranslateService } from '@ngx-translate/core';
|
2023-12-29 16:04:16 +01:00
|
|
|
import { map, takeUntil } from 'rxjs/operators';
|
2023-10-31 10:19:52 +01:00
|
|
|
import { GENERAL_ANIMATIONS, STEPPER_ANIMATIONS } from './animations/animations';
|
2023-11-24 17:42:23 +01:00
|
|
|
import { DescriptionTemplateEditorModel, DescriptionTemplateFieldEditorModel, DescriptionTemplateFieldSetEditorModel, DescriptionTemplatePageEditorModel, DescriptionTemplateSectionEditorModel, UserDescriptionTemplateEditorModel } from './description-template-editor.model';
|
2023-10-30 14:30:46 +01:00
|
|
|
import { DescriptionTemplateEditorResolver } from './description-template-editor.resolver';
|
|
|
|
import { DescriptionTemplateEditorService } from './description-template-editor.service';
|
2023-10-31 10:19:52 +01:00
|
|
|
import { NewEntryType, ToCEntry, ToCEntryType } from './table-of-contents/description-template-table-of-contents-entry';
|
2023-10-30 14:30:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-description-template-editor-component',
|
|
|
|
templateUrl: 'description-template-editor.component.html',
|
|
|
|
styleUrls: ['./description-template-editor.component.scss'],
|
2023-10-31 10:19:52 +01:00
|
|
|
animations: [...STEPPER_ANIMATIONS, ...GENERAL_ANIMATIONS],
|
2023-10-30 14:30:46 +01:00
|
|
|
providers: [DescriptionTemplateEditorService]
|
|
|
|
})
|
|
|
|
export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTemplateEditorModel, DescriptionTemplate> implements OnInit {
|
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
@ViewChild('stepper') stepper: MatStepper;
|
|
|
|
|
2023-10-30 14:30:46 +01:00
|
|
|
isNew = true;
|
|
|
|
isDeleted = false;
|
|
|
|
formGroup: UntypedFormGroup = null;
|
2023-11-24 17:42:23 +01:00
|
|
|
item: DescriptionTemplate;
|
2023-10-30 14:30:46 +01:00
|
|
|
showInactiveDetails = false;
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
availableLanguages: LanguageInfo[] = this.languageInfoService.getLanguageInfoValues();
|
|
|
|
|
|
|
|
isNewVersion = false;
|
|
|
|
isClone = false;
|
|
|
|
steps: QueryList<CdkStep>;
|
|
|
|
toCEntries: ToCEntry[];
|
|
|
|
selectedTocEntry: ToCEntry;
|
|
|
|
colorizeInvalid: boolean = false;
|
2023-11-24 17:42:23 +01:00
|
|
|
tocEntryEnumValues = ToCEntryType;
|
|
|
|
|
|
|
|
usersMap: Map<Guid, User> = new Map<Guid, User>();
|
|
|
|
userFormControl = new FormControl();
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-03-20 11:35:55 +01:00
|
|
|
//Preview
|
|
|
|
previewFieldSet: DescriptionTemplate = null;
|
|
|
|
previewPropertiesFormGroup: UntypedFormGroup = null;
|
2023-10-30 14:30:46 +01:00
|
|
|
|
|
|
|
protected get canDelete(): boolean {
|
|
|
|
return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeleteDescriptionTemplate);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected get canSave(): boolean {
|
|
|
|
return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDescriptionTemplate);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected get canFinalize(): boolean {
|
|
|
|
return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDescriptionTemplate);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private hasPermission(permission: AppPermission): boolean {
|
|
|
|
return this.authService.hasPermission(permission) || this.editorModel?.permissions?.includes(permission);
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
// BaseFormEditor injected dependencies
|
|
|
|
protected dialog: MatDialog,
|
|
|
|
protected language: TranslateService,
|
|
|
|
protected formService: FormService,
|
|
|
|
protected router: Router,
|
|
|
|
protected uiNotificationService: UiNotificationService,
|
|
|
|
protected httpErrorHandlingService: HttpErrorHandlingService,
|
|
|
|
protected filterService: FilterService,
|
|
|
|
protected datePipe: DatePipe,
|
|
|
|
protected route: ActivatedRoute,
|
|
|
|
protected queryParamsService: QueryParamsService,
|
|
|
|
// Rest dependencies. Inject any other needed deps here:
|
|
|
|
public authService: AuthService,
|
|
|
|
public enumUtils: EnumUtils,
|
|
|
|
private descriptionTemplateService: DescriptionTemplateService,
|
2023-10-31 10:19:52 +01:00
|
|
|
public descriptionTemplateTypeService: DescriptionTemplateTypeService,
|
2023-10-30 14:30:46 +01:00
|
|
|
private logger: LoggingService,
|
|
|
|
private descriptionTemplateEditorService: DescriptionTemplateEditorService,
|
|
|
|
private fileUtils: FileUtils,
|
|
|
|
private matomoService: MatomoService,
|
2023-11-24 17:42:23 +01:00
|
|
|
private languageInfoService: LanguageInfoService,
|
|
|
|
public userService: UserService
|
2023-10-30 14:30:46 +01:00
|
|
|
) {
|
|
|
|
super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, datePipe, route, queryParamsService);
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnInit(): void {
|
|
|
|
this.matomoService.trackPageView('Admin: DMP Blueprints');
|
|
|
|
super.ngOnInit();
|
2024-03-12 13:07:47 +01:00
|
|
|
this.initModelFlags(this.route.snapshot.data['action']);
|
|
|
|
}
|
|
|
|
|
|
|
|
private initModelFlags(action: string): void {
|
|
|
|
if (action == 'clone') {
|
|
|
|
this.isNew = false;
|
|
|
|
this.isClone = true;
|
|
|
|
this.isNewVersion = false;
|
|
|
|
} else if (action == 'new-version') {
|
|
|
|
this.isNew = false;
|
|
|
|
this.isClone = false;
|
|
|
|
this.isNewVersion = true;
|
|
|
|
} else {
|
|
|
|
this.isClone = false;
|
|
|
|
this.isNewVersion = false;
|
|
|
|
}
|
2023-10-30 14:30:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
getItem(itemId: Guid, successFunction: (item: DescriptionTemplate) => void) {
|
|
|
|
this.descriptionTemplateService.getSingle(itemId, DescriptionTemplateEditorResolver.lookupFields())
|
|
|
|
.pipe(map(data => data as DescriptionTemplate), takeUntil(this._destroyed))
|
|
|
|
.subscribe(
|
|
|
|
data => successFunction(data),
|
|
|
|
error => this.onCallbackError(error)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
prepareForm(data: DescriptionTemplate) {
|
|
|
|
try {
|
|
|
|
this.editorModel = data ? new DescriptionTemplateEditorModel().fromModel(data) : new DescriptionTemplateEditorModel();
|
2023-11-24 17:42:23 +01:00
|
|
|
this.item = data;
|
|
|
|
// Add user info to Map, to present them.
|
2023-12-29 16:04:16 +01:00
|
|
|
(this.item?.users ?? []).forEach(obj => { this.usersMap.set(obj.user.id, obj.user); });
|
2023-10-30 14:30:46 +01:00
|
|
|
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
|
|
|
this.buildForm();
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
this.steps = this.stepper.steps;
|
|
|
|
});
|
|
|
|
this._initializeToCEntries();
|
|
|
|
|
2023-10-30 14:30:46 +01:00
|
|
|
} catch (error) {
|
2023-11-24 17:42:23 +01:00
|
|
|
console.error(error);
|
2023-10-30 14:30:46 +01:00
|
|
|
this.logger.error('Could not parse descriptionTemplate item: ' + data + error);
|
|
|
|
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
buildForm() {
|
|
|
|
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditDescriptionTemplate));
|
|
|
|
this.descriptionTemplateEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
|
2024-01-25 19:55:42 +01:00
|
|
|
if (this.editorModel.status == DescriptionTemplateStatus.Finalized || this.isDeleted) {
|
2023-10-30 14:30:46 +01:00
|
|
|
this.formGroup.disable();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshData(): void {
|
|
|
|
this.getItem(this.editorModel.id, (data: DescriptionTemplate) => this.prepareForm(data));
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshOnNavigateToData(id?: Guid): void {
|
|
|
|
this.formGroup.markAsPristine();
|
|
|
|
let route = [];
|
|
|
|
|
|
|
|
if (id === null) {
|
|
|
|
route.push('../..');
|
|
|
|
} else if (this.isNew) {
|
|
|
|
route.push('../' + id);
|
|
|
|
} else {
|
|
|
|
route.push('..');
|
|
|
|
}
|
|
|
|
|
|
|
|
this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route });
|
|
|
|
}
|
|
|
|
|
|
|
|
persistEntity(onSuccess?: (response) => void): void {
|
2024-03-12 13:07:47 +01:00
|
|
|
if (this.isNewVersion == false){
|
2024-02-08 15:48:50 +01:00
|
|
|
const formData = this.formService.getValue(this.formGroup.value) as DescriptionTemplatePersist;
|
|
|
|
|
|
|
|
this.descriptionTemplateService.persist(formData)
|
|
|
|
.pipe(takeUntil(this._destroyed)).subscribe(
|
|
|
|
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
|
|
|
error => this.onCallbackError(error)
|
|
|
|
);
|
2024-03-12 13:07:47 +01:00
|
|
|
} else if (this.isNewVersion== true && this.isNew == false && this.isClone == false) {
|
2024-02-08 15:48:50 +01:00
|
|
|
const formData = this.formService.getValue(this.formGroup.value) as NewVersionDescriptionTemplatePersist;
|
|
|
|
|
|
|
|
this.descriptionTemplateService.newVersion(formData)
|
|
|
|
.pipe(takeUntil(this._destroyed)).subscribe(
|
|
|
|
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
|
|
|
error => this.onCallbackError(error)
|
|
|
|
);
|
2024-02-13 17:26:26 +01:00
|
|
|
}
|
2023-10-30 14:30:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
formSubmit(): void {
|
2024-03-11 14:20:09 +01:00
|
|
|
this.formService.removeAllBackEndErrors(this.formGroup);
|
2023-10-30 14:30:46 +01:00
|
|
|
this.formService.touchAllFormFields(this.formGroup);
|
2024-02-13 17:26:26 +01:00
|
|
|
if (!this.isFormValid()) {
|
|
|
|
return;
|
|
|
|
}
|
2023-10-30 14:30:46 +01:00
|
|
|
|
|
|
|
this.persistEntity();
|
|
|
|
}
|
|
|
|
|
|
|
|
public delete() {
|
|
|
|
const value = this.formGroup.value;
|
|
|
|
if (value.id) {
|
|
|
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
|
|
maxWidth: '300px',
|
|
|
|
data: {
|
|
|
|
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
|
|
|
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
|
|
|
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL')
|
|
|
|
}
|
|
|
|
});
|
|
|
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
|
|
|
if (result) {
|
|
|
|
this.descriptionTemplateService.delete(value.id).pipe(takeUntil(this._destroyed))
|
|
|
|
.subscribe(
|
|
|
|
complete => this.onCallbackSuccess(),
|
|
|
|
error => this.onCallbackError(error)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
clearErrorModel() {
|
|
|
|
this.editorModel.validationErrorModel.clear();
|
|
|
|
this.formService.validateAllFormFields(this.formGroup);
|
|
|
|
}
|
|
|
|
|
2023-11-24 17:42:23 +01:00
|
|
|
//
|
|
|
|
//
|
|
|
|
// Description Template User
|
|
|
|
//
|
|
|
|
//
|
|
|
|
addUser(user: User) {
|
|
|
|
console.log(user);
|
2024-02-13 17:26:26 +01:00
|
|
|
const userArray = (this.formGroup.get('users') as FormArray)
|
|
|
|
const newUser: UserDescriptionTemplateEditorModel = new UserDescriptionTemplateEditorModel(this.editorModel.validationErrorModel);
|
2023-11-24 17:42:23 +01:00
|
|
|
newUser.userId = user.id;
|
|
|
|
newUser.role = UserDescriptionTemplateRole.Owner;
|
|
|
|
this.usersMap.set(user.id, user);
|
2024-02-13 17:26:26 +01:00
|
|
|
(this.formGroup.get('users') as FormArray).push(newUser.buildForm({ rootPath: 'users[' + userArray.length + '].' }));
|
2023-11-24 17:42:23 +01:00
|
|
|
this.userFormControl.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
removeUser(index: number) {
|
|
|
|
(this.formGroup.get('users') as FormArray).controls.splice(index, 1);
|
|
|
|
this.formGroup.get('users').updateValueAndValidity();
|
2024-02-13 17:26:26 +01:00
|
|
|
this.reaplyValidators();
|
|
|
|
this.formGroup.get('users').markAsDirty();
|
2023-11-24 17:42:23 +01:00
|
|
|
}
|
|
|
|
|
2023-12-29 16:04:16 +01:00
|
|
|
verifyAndRemoveUser(index: number) {
|
2023-11-24 17:42:23 +01:00
|
|
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
|
|
restoreFocus: false,
|
|
|
|
data: {
|
|
|
|
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
|
|
|
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
|
|
|
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
|
|
|
isDeleteConfirmation: true
|
|
|
|
}
|
|
|
|
});
|
|
|
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(approve => {
|
|
|
|
if (approve) {
|
|
|
|
this.removeUser(index);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
//
|
|
|
|
//
|
|
|
|
// Stepper
|
|
|
|
//
|
|
|
|
//
|
|
|
|
onMatStepperSelectionChange(event: StepperSelectionEvent) {
|
|
|
|
|
|
|
|
if (event.selectedIndex === (this.steps.length - 1)) {//preview selected
|
2024-03-20 11:35:55 +01:00
|
|
|
this.generatePreviewForm();
|
2023-10-31 10:19:52 +01:00
|
|
|
} else {
|
|
|
|
// this.formGroup = null;
|
|
|
|
}
|
|
|
|
this.formGroup.markAsUntouched();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
isStepCompleted(stepIndex: number) {
|
|
|
|
|
|
|
|
let stepCompleted = false;
|
|
|
|
this.steps.forEach((step, index) => {
|
|
|
|
if (stepIndex === index) {
|
|
|
|
stepCompleted = step.completed;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return stepCompleted;
|
|
|
|
}
|
|
|
|
|
|
|
|
isStepUnlocked(stepIndex: number): boolean {
|
|
|
|
if (stepIndex === 0) return true;
|
|
|
|
if (stepIndex < 0) return false;
|
|
|
|
//if previous step is valid then unlock
|
|
|
|
let stepUnlocked: boolean = false;
|
|
|
|
|
|
|
|
if (!this.isStepUnlocked(stepIndex - 1)) return false;
|
|
|
|
|
|
|
|
this.steps.forEach((step, index) => {
|
|
|
|
|
|
|
|
if (index + 1 == stepIndex) {//previous step
|
|
|
|
|
|
|
|
if (step.completed) {
|
|
|
|
stepUnlocked = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return stepUnlocked;
|
|
|
|
}
|
|
|
|
|
|
|
|
validateStep(selectedIndex) {
|
|
|
|
|
|
|
|
if (selectedIndex === 1) {//form description
|
|
|
|
if (this.formGroup.invalid) {
|
|
|
|
this.checkFormValidation();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-20 11:35:55 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Preview
|
|
|
|
//
|
|
|
|
//
|
|
|
|
generatePreviewForm() {
|
|
|
|
// const formValue: DescriptionTemplatePersist = this.formGroup.getRawValue();
|
|
|
|
|
|
|
|
// const fields: DescriptionTemplateField[] = formValue.fields.map(editorField => {
|
|
|
|
// return {
|
|
|
|
// id: editorField.id,
|
|
|
|
// ordinal: editorField.ordinal,
|
|
|
|
// numbering: '',
|
|
|
|
// schematics: editorField.schematics,
|
|
|
|
// defaultValue: editorField.defaultValue,
|
|
|
|
// visibilityRules: editorField.visibilityRules,
|
|
|
|
// validations: editorField.validations,
|
|
|
|
// includeInExport: editorField.includeInExport,
|
|
|
|
// data: editorField.data
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
|
|
|
|
// const fieldSet: DescriptionTemplateFieldSet = {
|
|
|
|
// id: formValue.id,
|
|
|
|
// ordinal: formValue.ordinal,
|
|
|
|
// numbering: '',
|
|
|
|
// title: formValue.title,
|
|
|
|
// description: formValue.description,
|
|
|
|
// extendedDescription: formValue.extendedDescription,
|
|
|
|
// additionalInformation: formValue.additionalInformation,
|
|
|
|
// multiplicity: {
|
|
|
|
// max: formValue.multiplicity.max, min: formValue.multiplicity.min,
|
|
|
|
// placeholder: formValue.multiplicity.placeholder, tableView: formValue.multiplicity.tableView
|
|
|
|
// },
|
|
|
|
// hasCommentField: formValue.hasCommentField,
|
|
|
|
// fields: fields
|
|
|
|
// }
|
|
|
|
|
|
|
|
// const mockDescription: Description = {
|
|
|
|
// descriptionTemplate: {
|
|
|
|
// definition: {
|
|
|
|
// pages: [
|
|
|
|
// {
|
|
|
|
// sections: [{
|
|
|
|
// fieldSets: [fieldSet]
|
|
|
|
// }]
|
|
|
|
// }
|
|
|
|
// ]
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// const descriptionEditorModel = new DescriptionEditorModel().fromModel(mockDescription, mockDescription.descriptionTemplate);
|
|
|
|
// this.previewPropertiesFormGroup = descriptionEditorModel.properties.fieldSets.get(fieldSet.id).buildForm() as UntypedFormGroup;
|
|
|
|
// this.previewFieldSet = fieldSet;
|
|
|
|
// let data = this.form.getRawValue();
|
|
|
|
// this.datasetProfileService.preview(data).subscribe(x => {
|
|
|
|
// this.datasetWizardModel = new DatasetWizardEditorModel().fromModel({
|
|
|
|
// datasetProfileDefinition: x
|
|
|
|
// });
|
|
|
|
// this.updateVisibilityRules();
|
|
|
|
// this.formGroup = <FormGroup>this.datasetWizardModel.buildForm().get('datasetProfileDefinition');
|
|
|
|
// });
|
|
|
|
}
|
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
//
|
|
|
|
//
|
|
|
|
// Table of Contents
|
|
|
|
//
|
|
|
|
//
|
|
|
|
private _initializeToCEntries() {
|
|
|
|
const tocentries = this.refreshToCEntries();//tocentries are sorted based on their ordinal value
|
|
|
|
|
|
|
|
this._updateOrdinals(tocentries);
|
|
|
|
|
|
|
|
if (tocentries && tocentries.length) {
|
|
|
|
this.selectedTocEntry = tocentries[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
//Checking invalid visibilty RULES
|
|
|
|
const fieldsetEntries = this._getAllFieldSets(this.toCEntries);
|
|
|
|
const fieldSetHavingInvalidVisibilityRules: ToCEntry[] = fieldsetEntries
|
|
|
|
.filter(entry => {
|
|
|
|
const fieldsFormGroup = entry.form.get('fields');
|
|
|
|
const invalid = (fieldsFormGroup as UntypedFormArray).controls.filter(field => {
|
|
|
|
return this.hasInvalidVisibilityRule(field as UntypedFormGroup);
|
|
|
|
|
|
|
|
});
|
|
|
|
if (invalid && invalid.length) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (fieldSetHavingInvalidVisibilityRules.length) {
|
|
|
|
const occurences = fieldSetHavingInvalidVisibilityRules.map(record => record.numbering).join(' , ');
|
|
|
|
this.dialog.open(ConfirmationDialogComponent, {
|
|
|
|
data: {
|
2023-11-24 17:42:23 +01:00
|
|
|
message: this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.MESSAGE-START') + occurences + this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.MESSAGE-END'),
|
|
|
|
confirmButton: this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.CONFIRM-YES'),
|
|
|
|
cancelButton: this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.CONFIRM-NO')
|
2023-10-31 10:19:52 +01:00
|
|
|
},
|
|
|
|
maxWidth: '30em'
|
|
|
|
})
|
|
|
|
.afterClosed()
|
|
|
|
.subscribe(confirm => {
|
|
|
|
if (confirm) {
|
|
|
|
this.removeFieldSetVisibilityRules(fieldSetHavingInvalidVisibilityRules);
|
2023-11-24 17:42:23 +01:00
|
|
|
this.uiNotificationService.snackBarNotification(this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.REMOVE-SUCCESS'), SnackBarNotificationLevel.Success);
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
console.log('User not confirmed');
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private refreshToCEntries(): ToCEntry[] {
|
|
|
|
this.toCEntries = this.getTocEntries();
|
|
|
|
//update selected tocentry
|
|
|
|
if (this.selectedTocEntry) {
|
|
|
|
this.selectedTocEntry = this._findTocEntryById(this.selectedTocEntry.id, this.toCEntries);
|
|
|
|
}
|
|
|
|
return this.toCEntries;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates entries ordinal form value
|
|
|
|
* based on the index they have on the tocentry array.
|
|
|
|
* Tocentries that are on the same level have distinct ordinal value
|
|
|
|
*
|
|
|
|
* @param tocentries
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
private _updateOrdinals(tocentries: ToCEntry[]) {
|
|
|
|
|
|
|
|
if (!tocentries || !tocentries.length) return;
|
|
|
|
tocentries.forEach((e, idx) => {
|
|
|
|
const ordinalControl = e.form.get('ordinal');
|
|
|
|
if (ordinalControl) {
|
|
|
|
ordinalControl.setValue(idx);
|
|
|
|
ordinalControl.updateValueAndValidity();
|
|
|
|
}
|
|
|
|
this._updateOrdinals(e.subEntries);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
getTocEntries(): ToCEntry[] {
|
|
|
|
if (this.formGroup == null) { return []; }
|
|
|
|
const result: ToCEntry[] = [];
|
|
|
|
|
|
|
|
//build parent pages
|
2023-11-24 17:42:23 +01:00
|
|
|
(this.formGroup.get('definition').get('pages') as UntypedFormArray).controls.forEach((pageElement, i) => {
|
2024-01-31 20:16:39 +01:00
|
|
|
|
|
|
|
const page = {
|
2023-10-31 10:19:52 +01:00
|
|
|
id: pageElement.get('id').value,
|
|
|
|
label: pageElement.get('title').value,
|
|
|
|
type: ToCEntryType.Page,
|
|
|
|
form: pageElement,
|
|
|
|
numbering: (i + 1).toString(),
|
2024-01-31 20:16:39 +01:00
|
|
|
subEntriesType: ToCEntryType.Section,
|
2024-02-08 16:14:25 +01:00
|
|
|
subEntries: [],
|
|
|
|
validationRootPath: 'definition.pages[' + i + ']'
|
2023-10-31 10:19:52 +01:00
|
|
|
} as ToCEntry;
|
2024-01-31 20:16:39 +01:00
|
|
|
|
|
|
|
const subEntries = [];
|
|
|
|
(pageElement.get('sections') as UntypedFormArray).controls.forEach((sectionElement, i) => {
|
|
|
|
|
|
|
|
const item = {
|
|
|
|
id: sectionElement.get('id').value,
|
|
|
|
label: sectionElement.get('title').value,
|
|
|
|
type: ToCEntryType.Section,
|
|
|
|
form: sectionElement,
|
2024-02-08 16:14:25 +01:00
|
|
|
numbering: page.numbering + '.' + (subEntries.length + 1),
|
|
|
|
validationRootPath: page.validationRootPath + '.sections[' + i + ']'
|
2024-01-31 20:16:39 +01:00
|
|
|
} as ToCEntry;
|
2024-02-08 16:14:25 +01:00
|
|
|
const sectionItems = this.populateSections(sectionElement.get('sections') as UntypedFormArray, item.numbering, item.validationRootPath);
|
|
|
|
const fieldSetItems = this.populateFieldSets(sectionElement.get('fieldSets') as UntypedFormArray, item.numbering, item.validationRootPath);
|
2024-01-31 20:16:39 +01:00
|
|
|
|
|
|
|
if (sectionItems != null) {
|
|
|
|
item.subEntries = sectionItems;
|
|
|
|
item.subEntriesType = ToCEntryType.Section;
|
2023-10-31 10:19:52 +01:00
|
|
|
}
|
|
|
|
|
2024-01-31 20:16:39 +01:00
|
|
|
if (fieldSetItems != null) {
|
|
|
|
if (item.subEntries == null) {
|
|
|
|
item.subEntries = fieldSetItems;
|
|
|
|
} else {
|
|
|
|
item.subEntries.push(...fieldSetItems);
|
|
|
|
}
|
|
|
|
item.subEntriesType = ToCEntryType.FieldSet;
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-01-31 20:16:39 +01:00
|
|
|
}
|
|
|
|
subEntries.push(item);
|
|
|
|
});
|
|
|
|
|
|
|
|
page.subEntries = subEntries;
|
|
|
|
result.push(page);
|
2023-10-31 10:19:52 +01:00
|
|
|
});
|
2024-01-31 20:16:39 +01:00
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
this._sortToCentries(result);//ordeby ordinal
|
|
|
|
this._updateNumbering(result, '');//update nubering if needed
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-02-08 16:14:25 +01:00
|
|
|
private populateSections(sections: UntypedFormArray, existingNumbering: string, validationRootPath: string): ToCEntry[] {
|
2023-10-31 10:19:52 +01:00
|
|
|
if (sections == null || sections.controls == null || sections.controls.length == 0) { return null; }
|
|
|
|
|
|
|
|
const result: ToCEntry[] = [];
|
|
|
|
sections.controls.forEach((sectionElement, i) => {
|
|
|
|
|
|
|
|
const item = {
|
|
|
|
id: sectionElement.get('id').value,
|
|
|
|
label: sectionElement.get('title').value,
|
|
|
|
type: ToCEntryType.Section,
|
|
|
|
form: sectionElement,
|
2024-02-08 16:14:25 +01:00
|
|
|
numbering: existingNumbering + '.' + (i + 1),
|
|
|
|
validationRootPath: validationRootPath + '.sections[' + i + ']'
|
2023-10-31 10:19:52 +01:00
|
|
|
} as ToCEntry;
|
2024-02-08 16:14:25 +01:00
|
|
|
const sectionItems = this.populateSections(sectionElement.get('sections') as UntypedFormArray, item.numbering, item.validationRootPath);
|
|
|
|
const fieldSetItems = this.populateFieldSets(sectionElement.get('fieldSets') as UntypedFormArray, item.numbering, item.validationRootPath);
|
2023-10-31 10:19:52 +01:00
|
|
|
if (sectionItems != null) {
|
|
|
|
item.subEntries = sectionItems;
|
|
|
|
item.subEntriesType = ToCEntryType.Section;
|
|
|
|
}
|
|
|
|
if (fieldSetItems != null) {
|
|
|
|
if (item.subEntries == null) {
|
|
|
|
item.subEntries = fieldSetItems;
|
|
|
|
} else {
|
|
|
|
item.subEntries.push(...fieldSetItems);
|
|
|
|
}
|
|
|
|
item.subEntriesType = ToCEntryType.FieldSet;
|
|
|
|
}
|
|
|
|
result.push(item);
|
|
|
|
});
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-02-08 16:14:25 +01:00
|
|
|
private populateFieldSets(fieldSets: UntypedFormArray, existingNumbering: string, validationRootPath: string): ToCEntry[] {
|
2023-10-31 10:19:52 +01:00
|
|
|
if (fieldSets == null || fieldSets.controls == null || fieldSets.controls.length == 0) { return null; }
|
|
|
|
|
|
|
|
const result: ToCEntry[] = [];
|
|
|
|
fieldSets.controls.forEach((fieldSetElement, i) => {
|
|
|
|
|
|
|
|
result.push({
|
|
|
|
id: fieldSetElement.get('id').value,
|
|
|
|
label: fieldSetElement.get('title').value,
|
|
|
|
type: ToCEntryType.FieldSet,
|
|
|
|
//subEntries: this.populateSections((fieldSetElement.get('fieldSets') as FormArray), existingNumbering + '.' + i),
|
|
|
|
form: fieldSetElement,
|
2024-02-08 16:14:25 +01:00
|
|
|
numbering: existingNumbering + '.' + (i + 1),
|
|
|
|
validationRootPath: validationRootPath
|
2023-10-31 10:19:52 +01:00
|
|
|
} as ToCEntry)
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry {
|
|
|
|
if (!tocentries || !tocentries.length) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
let tocEntryFound = tocentries.find(entry => entry.id === id);
|
|
|
|
|
|
|
|
if (tocEntryFound) {
|
|
|
|
return tocEntryFound;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let entry of tocentries) {
|
|
|
|
const result = this._findTocEntryById(id, entry.subEntries);
|
|
|
|
if (result) {
|
|
|
|
tocEntryFound = result;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return tocEntryFound ? tocEntryFound : null;
|
|
|
|
}
|
|
|
|
|
2024-01-31 20:16:39 +01:00
|
|
|
private reaplyValidators() {
|
2024-01-24 10:40:32 +01:00
|
|
|
DescriptionTemplateEditorModel.reApplyDefinitionValidators(
|
|
|
|
{
|
|
|
|
formGroup: this.formGroup,
|
|
|
|
validationErrorModel: this.editorModel.validationErrorModel
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-01-24 10:40:32 +01:00
|
|
|
addNewEntry(tce: NewEntryType) {
|
2023-10-31 10:19:52 +01:00
|
|
|
const parent = tce.parent;
|
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
const pages = this.formGroup.get('definition').get('pages') as FormArray;
|
|
|
|
let pageIndex = -1;
|
|
|
|
|
2024-01-31 20:16:39 +01:00
|
|
|
// define entry type
|
2023-10-31 10:19:52 +01:00
|
|
|
switch (tce.childType) {
|
|
|
|
case ToCEntryType.Page:
|
2024-01-24 10:40:32 +01:00
|
|
|
const page: DescriptionTemplatePageEditorModel = new DescriptionTemplatePageEditorModel(this.editorModel.validationErrorModel);
|
2023-12-20 08:20:38 +01:00
|
|
|
page.id = Guid.create().toString();
|
2024-02-05 16:59:11 +01:00
|
|
|
if (isNaN(pages.length)) { page.ordinal = 0; } else { page.ordinal = pages.length; }
|
|
|
|
const pageForm = page.buildForm({ rootPath: 'definition.pages[' + pages.length + '].' });
|
2024-02-08 16:14:25 +01:00
|
|
|
console.log('definition.pages[' + pages.length + '].');
|
2023-10-31 10:19:52 +01:00
|
|
|
// this.dataModel.pages.push(page);
|
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
pages.push(pageForm);
|
2023-10-31 10:19:52 +01:00
|
|
|
// this.form.updateValueAndValidity();
|
|
|
|
this.refreshToCEntries();
|
|
|
|
this.selectedTocEntry = this._findTocEntryById(pageForm.get('id').value, this.toCEntries);
|
|
|
|
|
|
|
|
break;
|
|
|
|
case ToCEntryType.Section:
|
|
|
|
|
2024-01-24 10:40:32 +01:00
|
|
|
const section: DescriptionTemplateSectionEditorModel = new DescriptionTemplateSectionEditorModel(this.editorModel.validationErrorModel);
|
2023-12-20 08:20:38 +01:00
|
|
|
section.id = Guid.create().toString();
|
2023-10-31 10:19:52 +01:00
|
|
|
let sectionsArray: UntypedFormArray;
|
|
|
|
|
|
|
|
if (parent.type === ToCEntryType.Page) {//FIRST LEVEL SECTION
|
2024-02-05 16:59:11 +01:00
|
|
|
for (let i = 0; i < pages?.length; i++) {
|
|
|
|
let page = pages.at(i);
|
|
|
|
let pageId = page.get('id').value;
|
|
|
|
|
|
|
|
if (pageId == parent.id) {
|
|
|
|
pageIndex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sectionsArray = pages.controls.find(x => x.get('id')?.value === parent.id).get('sections') as UntypedFormArray;
|
2023-10-31 10:19:52 +01:00
|
|
|
try {
|
2024-01-31 20:16:39 +01:00
|
|
|
const max = sectionsArray.controls.map(control => control.get('ordinal').value)
|
2023-10-31 10:19:52 +01:00
|
|
|
.reduce((a, b) => Math.max(a, b));
|
|
|
|
|
|
|
|
section.ordinal = max + 1;
|
|
|
|
} catch {
|
|
|
|
section.ordinal = sectionsArray.length;
|
|
|
|
|
|
|
|
}
|
2024-02-07 17:44:17 +01:00
|
|
|
|
2024-02-08 16:14:25 +01:00
|
|
|
sectionsArray.push(section.buildForm({ rootPath: 'definition.pages[' + pageIndex + '].sections[' + sectionsArray.length + '].' }));
|
2023-10-31 10:19:52 +01:00
|
|
|
// this.form.updateValueAndValidity();
|
|
|
|
|
|
|
|
} else if (parent.type == ToCEntryType.Section) { //SUBSECTION OF SECTION
|
2024-02-05 16:59:11 +01:00
|
|
|
let sectionIndexes: number[] = [];
|
|
|
|
for (let j = 0; j < pages.length; j++) {
|
|
|
|
const parentSections = pages.at(j).get('sections') as UntypedFormArray;
|
|
|
|
sectionIndexes = this.findSectionIndex(parentSections, parent.id);
|
2024-02-08 16:14:25 +01:00
|
|
|
if (sectionIndexes && sectionIndexes.length > 0) {
|
2024-02-05 16:59:11 +01:00
|
|
|
pageIndex = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let parentSectionRootPath = '';
|
2024-02-08 16:14:25 +01:00
|
|
|
if (sectionIndexes.length > 0) {
|
2024-02-05 16:59:11 +01:00
|
|
|
sectionIndexes.forEach(index => {
|
2024-02-08 16:14:25 +01:00
|
|
|
parentSectionRootPath = parentSectionRootPath + 'sections[' + index + '].'
|
2024-02-05 16:59:11 +01:00
|
|
|
});
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-02-07 17:44:17 +01:00
|
|
|
sectionsArray = parent.form.get('sections') as UntypedFormArray;
|
|
|
|
|
|
|
|
//adding page parent MAYBE NOT NEEDED
|
|
|
|
try {
|
|
|
|
const maxOrdinal = sectionsArray.controls.map(control => control.get('ordinal').value).reduce((a, b) => Math.max(a, b));
|
|
|
|
section.ordinal = maxOrdinal + 1;
|
|
|
|
} catch {
|
|
|
|
section.ordinal = sectionsArray.length;
|
|
|
|
}
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-02-08 16:14:25 +01:00
|
|
|
sectionsArray.push(section.buildForm({ rootPath: 'definition.pages[' + pageIndex + '].' + parentSectionRootPath + 'sections[' + sectionsArray.length + '].' }));
|
2024-02-07 17:44:17 +01:00
|
|
|
// (child.form.parent as FormArray).push(section.buildForm());
|
|
|
|
|
|
|
|
}
|
2023-10-31 10:19:52 +01:00
|
|
|
} else {
|
|
|
|
console.error('Section can only be child of a page or another section');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const sectionAdded = sectionsArray.at(sectionsArray.length - 1) as UntypedFormGroup;
|
|
|
|
// sectionAdded.setValidators(this.customEditorValidators.sectionHasAtLeastOneChildOf('fieldSets','sections'));
|
|
|
|
// sectionAdded.updateValueAndValidity();
|
|
|
|
|
|
|
|
|
|
|
|
this.refreshToCEntries();
|
|
|
|
this.selectedTocEntry = this._findTocEntryById(sectionAdded.get('id').value, this.toCEntries);
|
|
|
|
|
|
|
|
break;
|
|
|
|
case ToCEntryType.FieldSet:
|
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
let sectionIndexes: number[] = [];
|
2024-01-31 20:16:39 +01:00
|
|
|
for (let j = 0; j < pages.length; j++) {
|
2024-02-05 16:59:11 +01:00
|
|
|
const parentSections = pages.at(j).get('sections') as UntypedFormArray;
|
|
|
|
sectionIndexes = this.findSectionIndex(parentSections, parent.id);
|
2024-02-08 16:14:25 +01:00
|
|
|
if (sectionIndexes && sectionIndexes.length > 0) {
|
2024-02-05 16:59:11 +01:00
|
|
|
pageIndex = j;
|
|
|
|
break;
|
2024-01-24 10:40:32 +01:00
|
|
|
}
|
2024-01-31 20:16:39 +01:00
|
|
|
}
|
2024-02-05 16:59:11 +01:00
|
|
|
let parentSectionRootPath = '';
|
2024-02-08 16:14:25 +01:00
|
|
|
if (sectionIndexes.length > 0) {
|
2024-02-05 16:59:11 +01:00
|
|
|
sectionIndexes.forEach(index => {
|
2024-02-08 16:14:25 +01:00
|
|
|
parentSectionRootPath = parentSectionRootPath + 'sections[' + index + '].'
|
2024-02-05 16:59:11 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
if (sectionIndexes.length > 0) {
|
2024-01-24 10:40:32 +01:00
|
|
|
//create one field form fieldset
|
|
|
|
const field: DescriptionTemplateFieldEditorModel = new DescriptionTemplateFieldEditorModel(this.editorModel.validationErrorModel);
|
|
|
|
field.id = Guid.create().toString();
|
|
|
|
field.ordinal = 0;//first filed in the fields list
|
|
|
|
|
|
|
|
const fieldSetsArray = parent.form.get('fieldSets') as UntypedFormArray
|
2024-02-08 17:47:19 +01:00
|
|
|
const fieldForm = field.buildForm({ rootPath:'definition.pages[' + pageIndex + '].' + parentSectionRootPath + 'fieldSets[' + fieldSetsArray.length + '].' + 'fields[' + 0 + '].' });
|
2024-01-24 10:40:32 +01:00
|
|
|
|
|
|
|
//give fieldset id and ordinal
|
|
|
|
const fieldSet: DescriptionTemplateFieldSetEditorModel = new DescriptionTemplateFieldSetEditorModel(this.editorModel.validationErrorModel);
|
|
|
|
const fieldSetId = Guid.create().toString();
|
|
|
|
fieldSet.id = fieldSetId;
|
|
|
|
|
|
|
|
try {
|
|
|
|
const maxOrdinal = fieldSetsArray.controls.map(control => control.get('ordinal').value).reduce((a, b) => Math.max(a, b));
|
|
|
|
fieldSet.ordinal = maxOrdinal + 1;
|
|
|
|
} catch {
|
|
|
|
fieldSet.ordinal = fieldSetsArray.length;
|
|
|
|
}
|
2024-02-08 16:14:25 +01:00
|
|
|
const fieldsetForm = fieldSet.buildForm({ rootPath: 'definition.pages[' + pageIndex + '].' + parentSectionRootPath + 'fieldSets[' + fieldSetsArray.length + '].' });
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-01-24 10:40:32 +01:00
|
|
|
(fieldsetForm.get('fields') as UntypedFormArray).push(fieldForm);
|
|
|
|
fieldSetsArray.push(fieldsetForm);
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-01-24 10:40:32 +01:00
|
|
|
this.refreshToCEntries();
|
|
|
|
this.selectedTocEntry = this._findTocEntryById(fieldSetId.toString(), this.toCEntries);
|
|
|
|
// fieldForm.updateValueAndValidity();
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-01-24 10:40:32 +01:00
|
|
|
break;
|
2024-01-31 20:16:39 +01:00
|
|
|
}
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.formGroup.updateValueAndValidity();
|
|
|
|
}
|
|
|
|
|
2024-02-08 16:14:25 +01:00
|
|
|
private findSectionIndex(sectionFormArray: UntypedFormArray, parentId: string): number[] {
|
2024-02-05 16:59:11 +01:00
|
|
|
for (let i = 0; i < sectionFormArray?.length; i++) {
|
|
|
|
let sectionFormGroup = sectionFormArray.at(i);
|
|
|
|
let sectionId = sectionFormGroup.get('id').value;
|
|
|
|
|
|
|
|
const parentSections = sectionFormGroup.get('sections') as UntypedFormArray;
|
2024-02-08 16:14:25 +01:00
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
if (sectionId == parentId) {
|
|
|
|
return [i];
|
2024-02-08 16:14:25 +01:00
|
|
|
} else if (parentSections && parentSections.length > 0) {
|
|
|
|
const indexes: number[] = this.findSectionIndex(parentSections, parentId);
|
|
|
|
if (indexes && indexes.length > 0) {
|
2024-02-05 16:59:11 +01:00
|
|
|
indexes.unshift(i);
|
|
|
|
return indexes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-02-08 16:14:25 +01:00
|
|
|
private getUpdatedSectionFormArray(sectionFormArray: UntypedFormArray, tceId: string): UntypedFormArray {
|
2024-02-06 15:00:52 +01:00
|
|
|
for (let i = 0; i < sectionFormArray?.length; i++) {
|
|
|
|
let sectionFormGroup = sectionFormArray.at(i);
|
|
|
|
let sectionId = sectionFormGroup.get('id').value;
|
|
|
|
|
|
|
|
const parentSections = sectionFormGroup.get('sections') as UntypedFormArray;
|
2024-02-08 16:14:25 +01:00
|
|
|
|
2024-02-06 15:00:52 +01:00
|
|
|
if (sectionId == tceId) {
|
|
|
|
sectionFormArray.removeAt(i);
|
|
|
|
return sectionFormArray;
|
|
|
|
// sectionFormArray.at(i).get('ordinal').patchValue(i);
|
2024-02-08 16:14:25 +01:00
|
|
|
} else if (parentSections && parentSections.length > 0) {
|
2024-02-06 15:00:52 +01:00
|
|
|
const currentSectionFormArray = this.getUpdatedSectionFormArray(parentSections, tceId);
|
2024-02-08 16:14:25 +01:00
|
|
|
if (currentSectionFormArray != null || currentSectionFormArray != undefined) {
|
2024-02-06 15:00:52 +01:00
|
|
|
return currentSectionFormArray;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
onRemoveEntry(tce: ToCEntry) {
|
|
|
|
|
|
|
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
|
|
restoreFocus: false,
|
|
|
|
data: {
|
|
|
|
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
|
|
|
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
|
|
|
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
|
|
|
isDeleteConfirmation: true
|
|
|
|
}
|
|
|
|
});
|
|
|
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
|
|
|
if (result) {
|
|
|
|
this._deleteEntry(tce);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private _deleteEntry(tce: ToCEntry) {
|
2024-02-05 16:59:11 +01:00
|
|
|
const pages = this.formGroup.get('definition').get('pages') as UntypedFormArray;
|
|
|
|
let pageIndex = -1;
|
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
//define entry type
|
|
|
|
switch (tce.type) {
|
|
|
|
case ToCEntryType.Page:
|
|
|
|
//get the index
|
|
|
|
for (let i = 0; i < pages.length; i++) {
|
|
|
|
let page = pages.at(i) as UntypedFormGroup;
|
|
|
|
|
|
|
|
if (page.controls.id.value === tce.id) {
|
|
|
|
pageIndex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pageIndex >= 0) {
|
|
|
|
//remove page
|
|
|
|
this._updateSelectedItem(tce);
|
|
|
|
pages.removeAt(pageIndex);
|
|
|
|
|
|
|
|
//update page ordinals
|
|
|
|
for (let i = 0; i < pages.length; i++) {
|
|
|
|
pages.at(i).get('ordinal').patchValue(i);
|
|
|
|
}
|
|
|
|
|
2024-01-24 10:40:32 +01:00
|
|
|
this.reaplyValidators();
|
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
//update validity
|
|
|
|
// this.form.controls.sections.updateValueAndValidity();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ToCEntryType.Section:
|
|
|
|
|
|
|
|
//FIRST LEVEL SECTION CASE
|
2024-02-05 16:59:11 +01:00
|
|
|
let sectionIndex = -1;
|
|
|
|
for (let j = 0; j < pages.length; j++) {
|
|
|
|
const sections = pages.at(j).get('sections') as UntypedFormArray;
|
|
|
|
for (let i = 0; i < sections?.length; i++) {
|
|
|
|
let section = sections.at(i);
|
|
|
|
let sectionId = section.get('id').value;
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
if (sectionId == tce.id) {
|
|
|
|
sectionIndex = i;
|
|
|
|
pageIndex = j;
|
|
|
|
break;
|
|
|
|
}
|
2023-10-31 10:19:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
if (sectionIndex >= 0) { //section found
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
const sections = pages.at(pageIndex).get('sections') as UntypedFormArray;
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
//remove section
|
2024-02-06 15:00:52 +01:00
|
|
|
// this._updateSelectedItem(tce);
|
2024-02-05 16:59:11 +01:00
|
|
|
sections.removeAt(sectionIndex);
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
//update ordinal
|
|
|
|
for (let i = 0; i < sections.length; i++) {
|
|
|
|
sections.at(i).get('ordinal').patchValue(i);
|
|
|
|
}
|
|
|
|
} else {//NOT FOUND IN FIRST LEVEL CASE
|
|
|
|
|
|
|
|
//LOOK FOR SUBSECTION CASE
|
2024-02-06 15:00:52 +01:00
|
|
|
// let parentSectionIndex = -1;
|
|
|
|
// let sectionIndex = -1;
|
|
|
|
// for (let j = 0; j < pages.length; j++) {
|
|
|
|
// const parentSections = pages.at(j).get('sections') as UntypedFormArray;
|
|
|
|
|
|
|
|
// for (let i = 0; i < parentSections?.length; i++) {
|
|
|
|
// const sections = (pages.at(j).get('sections') as UntypedFormArray).at(i).get('sections') as UntypedFormArray;
|
|
|
|
|
|
|
|
// for (let k = 0; i < sections?.length; i++) {
|
|
|
|
// let section = sections.at(i);
|
|
|
|
// let sectionId = section.get('id').value;
|
|
|
|
|
|
|
|
// if (sectionId == tce.id) {
|
|
|
|
// sectionIndex = k;
|
|
|
|
// parentSectionIndex = i;
|
|
|
|
// pageIndex = j;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
2024-02-05 16:59:11 +01:00
|
|
|
|
|
|
|
|
|
|
|
// let parentFormArray = tce.form.parent as UntypedFormArray;
|
|
|
|
|
|
|
|
// for (let i = 0; i < parentFormArray.length; i++) {
|
|
|
|
// let section = parentFormArray.at(i);
|
|
|
|
|
|
|
|
// if (section.get('id').value == tce.id) {
|
|
|
|
// index = i;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// }
|
2024-02-06 15:00:52 +01:00
|
|
|
// if (sectionIndex >= 0) {
|
|
|
|
// this._updateSelectedItem(tce);
|
|
|
|
// const parentFormArray = (pages.at(pageIndex).get('sections') as UntypedFormArray).at(parentSectionIndex).get('sections') as UntypedFormArray;
|
|
|
|
// parentFormArray.removeAt(sectionIndex);
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-02-06 15:00:52 +01:00
|
|
|
// //update odrinal
|
2023-10-31 10:19:52 +01:00
|
|
|
|
2024-02-06 15:00:52 +01:00
|
|
|
// for (let i = 0; i < parentFormArray.length; i++) {
|
|
|
|
// parentFormArray.at(i).get('ordinal').patchValue(i);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
for (let j = 0; j < pages.length; j++) {
|
|
|
|
const parentSections = pages.at(j).get('sections') as UntypedFormArray;
|
|
|
|
const sectionFormArray = this.getUpdatedSectionFormArray(parentSections, tce.id);
|
|
|
|
|
2024-02-08 16:14:25 +01:00
|
|
|
if (sectionFormArray) {
|
2024-02-06 15:00:52 +01:00
|
|
|
//update ordinal
|
|
|
|
for (let i = 0; i < sectionFormArray.length; i++) {
|
|
|
|
sectionFormArray.at(i).get('ordinal').patchValue(i);
|
|
|
|
}
|
|
|
|
break;
|
2023-10-31 10:19:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2024-01-24 10:40:32 +01:00
|
|
|
this.reaplyValidators();
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
case ToCEntryType.FieldSet:
|
|
|
|
const parentFormArray = tce.form.parent as UntypedFormArray;
|
|
|
|
|
|
|
|
|
|
|
|
let idx = -1;
|
|
|
|
|
|
|
|
for (let i = 0; i < parentFormArray.length; i++) {
|
|
|
|
let inspectingField = parentFormArray.at(i);
|
|
|
|
|
|
|
|
if (inspectingField.get('id').value === tce.id) {
|
|
|
|
//fieldset found
|
|
|
|
idx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx >= 0) {//fieldset found
|
|
|
|
this._updateSelectedItem(tce);
|
|
|
|
parentFormArray.removeAt(idx);
|
|
|
|
|
|
|
|
//patching order
|
|
|
|
for (let i = 0; i < parentFormArray.length; i++) {
|
|
|
|
parentFormArray.at(i).get('ordinal').patchValue(i);
|
|
|
|
}
|
2024-01-24 10:40:32 +01:00
|
|
|
this.reaplyValidators();
|
2023-10-31 10:19:52 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//in case selectedtocentrhy is child of the removed element
|
|
|
|
|
|
|
|
// this.refreshToCEntries();
|
|
|
|
this.onDataNeedsRefresh();
|
|
|
|
this.formGroup.updateValueAndValidity();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private _updateSelectedItem(tce: ToCEntry) {
|
|
|
|
|
|
|
|
if (this.selectedTocEntry) {
|
|
|
|
|
|
|
|
if (this.tocEntryIsChildOf(this.selectedTocEntry, tce)) {
|
|
|
|
if (this.selectedTocEntry.type == ToCEntryType.Page) {
|
|
|
|
this.selectedTocEntry = null;
|
|
|
|
} else {
|
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
const pages = this.formGroup.get('definition').get('pages') as UntypedFormArray;
|
2023-10-31 10:19:52 +01:00
|
|
|
//if first level section
|
2024-02-05 16:59:11 +01:00
|
|
|
// const firstLevelSections = (this.formGroup.get('definition').get('sections') as UntypedFormArray);
|
|
|
|
// let isFirstLevel: boolean = false;
|
|
|
|
// firstLevelSections.controls.forEach(section => {
|
|
|
|
// if (section.get('id').value === tce.id) {
|
|
|
|
// isFirstLevel = true;
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
let isFirstLevel: boolean = false;
|
2024-02-05 16:59:11 +01:00
|
|
|
for (let j = 0; j < pages.length; j++) {
|
|
|
|
const sections = pages.at(j).get('sections') as UntypedFormArray;
|
|
|
|
for (let i = 0; i < sections?.length; i++) {
|
|
|
|
let section = sections.at(i);
|
|
|
|
let sectionId = section.get('id').value;
|
|
|
|
|
|
|
|
if (sectionId == tce.id) {
|
|
|
|
isFirstLevel = true;
|
|
|
|
break;
|
|
|
|
}
|
2023-10-31 10:19:52 +01:00
|
|
|
}
|
2024-02-05 16:59:11 +01:00
|
|
|
}
|
|
|
|
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
let parentId = null;
|
|
|
|
if (isFirstLevel) {
|
|
|
|
parentId = tce.form.get('page').value;
|
|
|
|
} else {
|
|
|
|
parentId = tce.form.parent.parent.get('id').value
|
|
|
|
}
|
|
|
|
|
|
|
|
// const parentId = tce.form.parent.parent.get('id').value;
|
|
|
|
if (parentId) {
|
|
|
|
const tocentries = this.getTocEntries();
|
|
|
|
const parent = this._findTocEntryById(parentId, tocentries);
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
this.selectedTocEntry = parent;
|
|
|
|
} else {
|
|
|
|
this.selectedTocEntry = null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.selectedTocEntry = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tocEntryIsChildOf(testingChild: ToCEntry, parent: ToCEntry): boolean {
|
|
|
|
|
|
|
|
if (!testingChild || !parent) return false;
|
|
|
|
|
|
|
|
if (testingChild.id == parent.id) { return true; }
|
|
|
|
|
|
|
|
if (parent.subEntries) {
|
|
|
|
let childFound: boolean = false;
|
|
|
|
|
|
|
|
parent.subEntries.forEach(subEntry => {
|
|
|
|
if (this.tocEntryIsChildOf(testingChild, subEntry)) {
|
|
|
|
childFound = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return childFound;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
onDataNeedsRefresh(params?) {
|
|
|
|
|
|
|
|
const tocentries = this.refreshToCEntries();
|
|
|
|
|
|
|
|
if (params && params.draggedItemId) {
|
|
|
|
if (params.draggedItemId) {
|
|
|
|
this.displayItem(this._findTocEntryById(params.draggedItemId, tocentries));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.formGroup.markAsDirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
displayItem(entry: ToCEntry): void {
|
|
|
|
this.selectedTocEntry = entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all filedsets in a tocentry array;
|
|
|
|
* @param entries Tocentries to search in
|
|
|
|
* @returns The tocentries that are Fieldsets provided in the entries
|
|
|
|
*/
|
|
|
|
private _getAllFieldSets(entries: ToCEntry[]): ToCEntry[] {
|
|
|
|
|
|
|
|
const fieldsets: ToCEntry[] = [];
|
|
|
|
if (!entries || !entries.length) return fieldsets;
|
|
|
|
|
|
|
|
|
|
|
|
entries.forEach(e => {
|
|
|
|
if (e.type === ToCEntryType.FieldSet) {
|
|
|
|
fieldsets.push(e);
|
|
|
|
} else {
|
|
|
|
fieldsets.push(...this._getAllFieldSets(e.subEntries));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return fieldsets;
|
|
|
|
}
|
|
|
|
|
|
|
|
private _sortToCentries(entries: ToCEntry[]) {
|
|
|
|
if (!entries || !entries.length) return;
|
|
|
|
entries.sort(this._compareOrdinals);
|
|
|
|
entries.forEach(e => {
|
|
|
|
this._sortToCentries(e.subEntries)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
private _compareOrdinals(a, b) {
|
|
|
|
|
|
|
|
const aValue = a.form.get('ordinal').value as number;
|
|
|
|
const bValue = b.form.get('ordinal').value as number;
|
|
|
|
|
|
|
|
// if(!aValue || !bValue) return 0;
|
|
|
|
return aValue - bValue;
|
|
|
|
}
|
|
|
|
private _updateNumbering(entries: ToCEntry[], parentNumbering: string) {
|
|
|
|
if (!entries || !entries.length) return;
|
|
|
|
let prefix = '';
|
|
|
|
if (parentNumbering.length) {
|
|
|
|
prefix = parentNumbering + '.';
|
|
|
|
}
|
|
|
|
entries.forEach((entry, index) => {
|
|
|
|
const numbering = prefix + (index + 1);
|
|
|
|
entry.numbering = numbering;
|
|
|
|
this._updateNumbering(entry.subEntries, numbering);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Visibility Rules
|
|
|
|
//
|
|
|
|
//
|
|
|
|
private hasInvalidVisibilityRule(field: UntypedFormGroup): boolean {
|
2023-11-24 17:42:23 +01:00
|
|
|
// const renderStyle = field.get('viewStyle').get('renderStyle').value;
|
|
|
|
// if (renderStyle && ![
|
|
|
|
// DatasetProfileFieldViewStyle.TextArea,
|
|
|
|
// DatasetProfileFieldViewStyle.RichTextArea,
|
|
|
|
// DatasetProfileFieldViewStyle.Upload,
|
|
|
|
// DatasetProfileFieldViewStyle.FreeText,
|
|
|
|
// DatasetProfileFieldViewStyle.BooleanDecision,
|
|
|
|
// DatasetProfileFieldViewStyle.RadioBox,
|
|
|
|
// DatasetProfileFieldViewStyle.CheckBox,
|
|
|
|
// DatasetProfileFieldViewStyle.DatePicker,
|
|
|
|
// DatasetProfileFieldViewStyle.ComboBox,
|
|
|
|
// ].includes(renderStyle)) {
|
2024-01-30 18:27:55 +01:00
|
|
|
// if (((renderStyle === DatasetProfileFieldViewStyle) && (field.get('data').get('type').value === DatasetProfileComboBoxType.Select))) {
|
2023-11-24 17:42:23 +01:00
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// try {
|
|
|
|
// if (field.get('visible').get('rules').value.length) {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
// return false;
|
|
|
|
|
|
|
|
// } catch {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// } else {
|
|
|
|
return false;
|
|
|
|
// }
|
2023-10-31 10:19:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private removeFieldSetVisibilityRules(fieldsets: ToCEntry[]) {
|
|
|
|
|
|
|
|
if (!fieldsets || !fieldsets.length) return;
|
|
|
|
|
|
|
|
fieldsets.forEach(fieldset => {
|
|
|
|
if (fieldset.type != ToCEntryType.FieldSet) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const fields = fieldset.form.get('fields') as UntypedFormArray;
|
|
|
|
|
|
|
|
fields.controls.forEach(fieldControl => {
|
|
|
|
if (this.hasInvalidVisibilityRule(fieldControl as UntypedFormGroup)) {
|
|
|
|
try {
|
|
|
|
(fieldControl.get('visible').get('rules') as UntypedFormArray).clear();
|
|
|
|
} catch { }
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Other
|
|
|
|
//
|
|
|
|
//
|
|
|
|
scrollOnTop() {
|
|
|
|
try {
|
|
|
|
const topPage = document.getElementById('main-content');
|
|
|
|
topPage.scrollIntoView({ behavior: 'smooth' });
|
2023-11-24 17:42:23 +01:00
|
|
|
} catch (e) {
|
|
|
|
console.log(e);
|
2023-10-31 10:19:52 +01:00
|
|
|
console.log('coulnd not scroll');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-29 16:04:16 +01:00
|
|
|
get numOfPages() {
|
2024-01-30 18:27:55 +01:00
|
|
|
return (<UntypedFormArray>this.formGroup.get('definition').get('pages'))?.length;
|
2023-11-24 17:42:23 +01:00
|
|
|
}
|
2023-10-31 10:19:52 +01:00
|
|
|
|
|
|
|
checkFormValidation() {
|
|
|
|
this.colorizeInvalid = true;
|
|
|
|
}
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
get progressStyle() {
|
|
|
|
// return {'transform': 'translateX('+this.barPercentage+'%) skewX(-25deg)'}
|
|
|
|
const diff = 3;
|
|
|
|
|
|
|
|
return {
|
|
|
|
'clip-path': `polygon(0 0, ${Math.round(this.barPercentage + diff)}% 0, ${Math.round(this.barPercentage)}% 100%, 0 100%)`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
get barPercentage() {
|
|
|
|
if (!this.stepper || !this.steps) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
const selectedIndex = this.stepper.selectedIndex + 1;
|
|
|
|
return (selectedIndex / this.stepper.steps.length) * 100;
|
|
|
|
}
|
2023-10-30 14:30:46 +01:00
|
|
|
|
|
|
|
public cancel(): void {
|
|
|
|
this.router.navigate(['/description-templates']);
|
|
|
|
}
|
|
|
|
}
|