From 6237ccb21eea289c5075d18d7c8a0c238c1bb23f Mon Sep 17 00:00:00 2001 From: rhenck <richard.henck@iqb.hu-berlin.de> Date: Fri, 18 Feb 2022 21:45:40 +0100 Subject: [PATCH] Refactor style interface - Unify font and surface props - Use intersection type for additional properties - Also rework editor props panel to properly create the combined properties recursively, passing the results to its child panel (tabs). New algorithm works without lodash, therefore the package is removed. --- package.json | 1 - .../ui-elements/button.component.ts | 16 +- .../ui-elements/checkbox.component.ts | 16 +- .../components/ui-elements/cloze.component.ts | 99 +++++----- .../ui-elements/drop-list-simple.component.ts | 22 +-- .../ui-elements/drop-list.component.ts | 20 +- .../ui-elements/dropdown.component.ts | 14 +- .../components/ui-elements/frame.component.ts | 14 +- .../ui-elements/likert.component.ts | 16 +- .../radio-button-group.component.ts | 16 +- .../radio-group-images.component.ts | 14 +- .../ui-elements/slider.component.ts | 44 ++--- .../ui-elements/spell-correct.component.ts | 26 +-- .../ui-elements/text-area.component.ts | 16 +- .../text-field-simple.component.ts | 14 +- .../ui-elements/text-field.component.ts | 28 +-- .../components/ui-elements/text.component.ts | 16 +- .../ui-elements/toggle-button.component.ts | 16 +- projects/common/interfaces/elements.ts | 178 ++++++------------ projects/common/util/element.factory.ts | 117 ++++++------ projects/editor/src/app/app.module.ts | 6 +- .../element-model-properties.component.ts | 2 +- ... element-position-properties.component.ts} | 92 ++++----- .../element-properties.component.html | 12 +- .../element-properties.component.ts | 67 +++---- .../element-style-properties.component.ts | 62 +++--- .../editor/src/app/services/unit.service.ts | 19 +- 27 files changed, 453 insertions(+), 510 deletions(-) rename projects/editor/src/app/components/unit-view/page-view/properties-panel/{element-sizing-properties.component.ts => element-position-properties.component.ts} (76%) diff --git a/package.json b/package.json index fa20ed454..2d2af702c 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,6 @@ "@tiptap/extension-text-style": "^2.0.0-beta.23", "@tiptap/extension-underline": "^2.0.0-beta.22", "@tiptap/starter-kit": "2.0.0-beta.171", - "lodash": "^4.17.21", "ngx-tiptap": "^3.0.4", "prosemirror-state": "^1.3.4", "rxjs": "~6.6.0", diff --git a/projects/common/components/ui-elements/button.component.ts b/projects/common/components/ui-elements/button.component.ts index e14db971d..85c51f7c8 100644 --- a/projects/common/components/ui-elements/button.component.ts +++ b/projects/common/components/ui-elements/button.component.ts @@ -13,14 +13,14 @@ import { ButtonElement } from '../../interfaces/elements'; elementModel.positionProps.fixedSize" [style.width]="elementModel.positionProps.fixedSize ? elementModel.width + 'px' : '100%'" [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : '100%'" - [style.background-color]="elementModel.surfaceProps.backgroundColor" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" - [style.border-radius.px]="elementModel.borderRadius" + [style.background-color]="elementModel.styles.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" + [style.border-radius.px]="elementModel.styles.borderRadius" (click)="elementModel.action ? navigationRequested.emit(elementModel.action) : false"> {{elementModel.label}} </button> diff --git a/projects/common/components/ui-elements/checkbox.component.ts b/projects/common/components/ui-elements/checkbox.component.ts index 70b61ae4e..d1b0a8726 100644 --- a/projects/common/components/ui-elements/checkbox.component.ts +++ b/projects/common/components/ui-elements/checkbox.component.ts @@ -11,18 +11,18 @@ import { CheckboxElement } from '../../interfaces/elements'; [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : '100%'" [class.center-content]="elementModel.positionProps.dynamicPositioning && elementModel.positionProps.fixedSize" - [style.background-color]="elementModel.surfaceProps.backgroundColor"> + [style.background-color]="elementModel.styles.backgroundColor"> <mat-checkbox #checkbox class="example-margin" [formControl]="elementFormControl" [checked]="$any(elementModel.value)" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" (click)="elementModel.readOnly ? $event.preventDefault() : null"> - <div [style.line-height.%]="elementModel.lineHeight" [innerHTML]="elementModel.label"></div> + <div [innerHTML]="elementModel.label"></div> </mat-checkbox> <mat-error *ngIf="elementFormControl.errors && elementFormControl.touched" class="error-message"> diff --git a/projects/common/components/ui-elements/cloze.component.ts b/projects/common/components/ui-elements/cloze.component.ts index 4b5f02c3f..598a5c108 100644 --- a/projects/common/components/ui-elements/cloze.component.ts +++ b/projects/common/components/ui-elements/cloze.component.ts @@ -8,6 +8,7 @@ import { ClozeElement, InputElement } from '../../interfaces/elements'; import { ClozeDocumentParagraph, ClozeDocumentParagraphPart } from '../../interfaces/cloze'; import { getClozeChildElements } from '../../util/cloze'; +// TODO background color implementieren @Component({ selector: 'aspect-cloze', template: ` @@ -50,13 +51,13 @@ import { getClozeChildElements } from '../../util/cloze'; <ng-template #paragraphs let-part> <p *ngIf="part.type === 'paragraph'" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" + [style.line-height.%]="elementModel.styles.lineHeight" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" [style.margin-bottom]="part.attrs?.margin + 'px'" [style.margin-left]="part.attrs?.hangingIndent ? '' : ($any(part.attrs?.indentSize) * $any(part.attrs?.indent)) + 'px'" @@ -68,73 +69,73 @@ import { getClozeChildElements } from '../../util/cloze'; </p> <h1 *ngIf="part.type === 'heading' && part.attrs.level === 1" [style.display]="'inline'" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.line-height.%]="elementModel.styles.lineHeight" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <ng-container [ngTemplateOutlet]="paragraphChildren" [ngTemplateOutletContext]="{ $implicit: part }"></ng-container> </h1> <h2 *ngIf="part.type === 'heading' && part.attrs.level === 2" [style.display]="'inline'" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.line-height.%]="elementModel.styles.lineHeight" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <ng-container [ngTemplateOutlet]="paragraphChildren" [ngTemplateOutletContext]="{ $implicit: part }"></ng-container> </h2> <h3 *ngIf="part.type === 'heading' && part.attrs.level === 3" [style.display]="'inline'" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.line-height.%]="elementModel.styles.lineHeight" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <ng-container [ngTemplateOutlet]="paragraphChildren" [ngTemplateOutletContext]="{ $implicit: part }"></ng-container> </h3> <h4 *ngIf="part.type === 'heading' && part.attrs.level === 4" [style.display]="'inline'" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.line-height.%]="elementModel.styles.lineHeight" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <ng-container [ngTemplateOutlet]="paragraphChildren" [ngTemplateOutletContext]="{ $implicit: part }"></ng-container> </h4> <h5 *ngIf="part.type === 'heading' && part.attrs.level === 5" [style.display]="'inline'" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.line-height.%]="elementModel.styles.lineHeight" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <ng-container [ngTemplateOutlet]="paragraphChildren" [ngTemplateOutletContext]="{ $implicit: part }"></ng-container> </h5> <h6 *ngIf="part.type === 'heading' && part.attrs.level === 6" [style.display]="'inline'" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.line-height.%]="elementModel.styles.lineHeight" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <ng-container [ngTemplateOutlet]="paragraphChildren" [ngTemplateOutletContext]="{ $implicit: part }"></ng-container> </h6> diff --git a/projects/common/components/ui-elements/drop-list-simple.component.ts b/projects/common/components/ui-elements/drop-list-simple.component.ts index e89ee7e6b..feefb843f 100644 --- a/projects/common/components/ui-elements/drop-list-simple.component.ts +++ b/projects/common/components/ui-elements/drop-list-simple.component.ts @@ -18,13 +18,13 @@ import { DragNDropValueObject, DropListSimpleElement } from '../../interfaces/el [class.dropList-highlight]="elementModel.highlightReceivingDropList" [style.border-color]="elementModel.highlightReceivingDropListColor" [style.border-width.px]="elementModel.highlightReceivingDropList ? 2 : 0" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" - [style.backgroundColor]="elementModel.surfaceProps.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" + [style.backgroundColor]="elementModel.styles.backgroundColor" cdkDropList [id]="elementModel.id" [cdkDropListData]="this" @@ -33,14 +33,14 @@ import { DragNDropValueObject, DropListSimpleElement } from '../../interfaces/el (cdkDropListDropped)="drop($event)"> <div class="item" *ngFor="let value of $any(elementModel.value)" [style.line-height.px]="elementModel.height - 4" - [style.background-color]="elementModel.itemBackgroundColor" + [style.background-color]="elementModel.styles.itemBackgroundColor" cdkDrag (cdkDragStarted)=dragStart() (cdkDragEnded)="dragEnd()"> <div *cdkDragPreview - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.background-color]="elementModel.itemBackgroundColor"> + [style.font-size.px]="elementModel.styles.fontSize" + [style.background-color]="elementModel.styles.itemBackgroundColor"> {{value.stringValue}} </div> - <div class="drag-placeholder" *cdkDragPlaceholder [style.min-height.px]="elementModel.fontProps.fontSize"> + <div class="drag-placeholder" *cdkDragPlaceholder [style.min-height.px]="elementModel.styles.fontSize"> </div> {{value.stringValue}} </div> diff --git a/projects/common/components/ui-elements/drop-list.component.ts b/projects/common/components/ui-elements/drop-list.component.ts index f5c41f579..70127ec30 100644 --- a/projects/common/components/ui-elements/drop-list.component.ts +++ b/projects/common/components/ui-elements/drop-list.component.ts @@ -20,13 +20,13 @@ import { DragNDropValueObject, DropListElement } from '../../interfaces/elements [ngClass]="{ 'align-flex' : elementModel.orientation === 'flex' }" [class.dropList-highlight]="elementModel.highlightReceivingDropList" [style.outline-color]="elementModel.highlightReceivingDropListColor" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" - [style.backgroundColor]="elementModel.surfaceProps.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" + [style.backgroundColor]="elementModel.styles.backgroundColor" [style.display]="elementModel.orientation === 'horizontal' ? 'flex' : ''" [style.flex-direction]="elementModel.orientation === 'horizontal' ? 'row' : ''" cdkDropList @@ -43,11 +43,11 @@ import { DragNDropValueObject, DropListElement } from '../../interfaces/elements [style.background-color]="elementModel.itemBackgroundColor" (cdkDragStarted)=dragStart() (cdkDragEnded)="dragEnd()"> <div *cdkDragPreview - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.background-color]="elementModel.itemBackgroundColor"> + [style.font-size.px]="elementModel.styles.fontSize" + [style.background-color]="elementModel.styles.itemBackgroundColor"> {{value.stringValue}} </div> - <div class="drag-placeholder" *cdkDragPlaceholder [style.min-height.px]="elementModel.fontProps.fontSize"> + <div class="drag-placeholder" *cdkDragPlaceholder [style.min-height.px]="elementModel.styles.fontSize"> </div> {{value.stringValue}} </div> diff --git a/projects/common/components/ui-elements/dropdown.component.ts b/projects/common/components/ui-elements/dropdown.component.ts index 1b2fcfbe4..e4f23a669 100644 --- a/projects/common/components/ui-elements/dropdown.component.ts +++ b/projects/common/components/ui-elements/dropdown.component.ts @@ -10,13 +10,13 @@ import { DropdownElement } from '../../interfaces/elements'; [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : '100%'" [class.center-content]="elementModel.positionProps.dynamicPositioning && elementModel.positionProps.fixedSize" - aspectInputBackgroundColor [backgroundColor]="elementModel.surfaceProps.backgroundColor"> - <mat-label [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + aspectInputBackgroundColor [backgroundColor]="elementModel.styles.backgroundColor"> + <mat-label [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> {{$any(elementModel).label}} </mat-label> <mat-select [formControl]="elementFormControl" [value]="elementModel.value"> diff --git a/projects/common/components/ui-elements/frame.component.ts b/projects/common/components/ui-elements/frame.component.ts index a67e705e5..952d16d91 100644 --- a/projects/common/components/ui-elements/frame.component.ts +++ b/projects/common/components/ui-elements/frame.component.ts @@ -9,15 +9,15 @@ import { FrameElement } from '../../interfaces/elements'; elementModel.positionProps.fixedSize" [style.width]="elementModel.positionProps.fixedSize ? elementModel.width + 'px' : - 'calc(100% - ' + (elementModel.borderWidth * 2) + 'px)'" + 'calc(100% - ' + (elementModel.styles.borderWidth * 2) + 'px)'" [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : - 'calc(100% - ' + (elementModel.borderWidth * 2) + 'px)'" - [style.border-style]="elementModel.borderStyle" - [style.border-width.px]="elementModel.borderWidth" - [style.border-color]="elementModel.borderColor" - [style.border-radius.px]="elementModel.borderRadius" - [style.background-color]="elementModel.surfaceProps.backgroundColor"> + 'calc(100% - ' + (elementModel.styles.borderWidth * 2) + 'px)'" + [style.border-style]="elementModel.styles.borderStyle" + [style.border-width.px]="elementModel.styles.borderWidth" + [style.border-color]="elementModel.styles.borderColor" + [style.border-radius.px]="elementModel.styles.borderRadius" + [style.background-color]="elementModel.styles.backgroundColor"> </div> ` }) diff --git a/projects/common/components/ui-elements/likert.component.ts b/projects/common/components/ui-elements/likert.component.ts index c26f79fea..80151c682 100644 --- a/projects/common/components/ui-elements/likert.component.ts +++ b/projects/common/components/ui-elements/likert.component.ts @@ -20,14 +20,14 @@ import { LikertElement, LikertRowElement } from '../../interfaces/elements'; [style.display]="'grid'" [style.grid-template-columns]="elementModel.firstColumnSizeRatio + 'fr ' + '1fr '.repeat(elementModel.columns.length)" - [style.background-color]="elementModel.surfaceProps.backgroundColor" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.background-color]="elementModel.styles.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.line-height.%]="elementModel.styles.lineHeight" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <div *ngFor="let column of elementModel.columns; let i = index" class="columns" fxLayout="column" fxLayoutAlign="end center" [style.grid-column-start]="2 + i" diff --git a/projects/common/components/ui-elements/radio-button-group.component.ts b/projects/common/components/ui-elements/radio-button-group.component.ts index d8c66e868..b608124f6 100644 --- a/projects/common/components/ui-elements/radio-button-group.component.ts +++ b/projects/common/components/ui-elements/radio-button-group.component.ts @@ -10,13 +10,13 @@ import { RadioButtonGroupElement } from '../../interfaces/elements'; [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : '100%'" [class.center-content]="elementModel.positionProps.dynamicPositioning && elementModel.positionProps.fixedSize" - [style.background-color]="elementModel.surfaceProps.backgroundColor" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.background-color]="elementModel.styles.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <label id="radio-group-label" [innerHTML]="elementModel.label"> </label> @@ -31,7 +31,7 @@ import { RadioButtonGroupElement } from '../../interfaces/elements'; elementFormControl.value !== i + 1 }" [value]="i + 1" [style.pointer-events]="elementModel.readOnly ? 'none' : 'unset'" - [style.line-height.%]="elementModel.fontProps.lineHeight"> + [style.line-height.%]="elementModel.styles.lineHeight"> {{option}} </mat-radio-button> <mat-error *ngIf="elementFormControl.errors && elementFormControl.touched" diff --git a/projects/common/components/ui-elements/radio-group-images.component.ts b/projects/common/components/ui-elements/radio-group-images.component.ts index 1853f9a69..9c4981adc 100644 --- a/projects/common/components/ui-elements/radio-group-images.component.ts +++ b/projects/common/components/ui-elements/radio-group-images.component.ts @@ -11,13 +11,13 @@ import { RadioButtonGroupComplexElement } from '../../interfaces/elements'; elementModel.positionProps.fixedSize" [style.display]="'grid !important'" [style.grid-template-columns]="'1fr '.repeat(elementModel.columns.length)" - [style.background-color]="elementModel.surfaceProps.backgroundColor" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.background-color]="elementModel.styles.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> <label id="radio-group-label" class="label" [style.grid-column-start]="1" [style.grid-column-end]="2 + elementModel.columns.length" diff --git a/projects/common/components/ui-elements/slider.component.ts b/projects/common/components/ui-elements/slider.component.ts index d2d589a28..a140bcf76 100644 --- a/projects/common/components/ui-elements/slider.component.ts +++ b/projects/common/components/ui-elements/slider.component.ts @@ -8,19 +8,19 @@ import { SliderElement } from '../../interfaces/elements'; selector: 'aspect-slider', template: ` <div fxLayout="column" - [style.background-color]="elementModel.surfaceProps.backgroundColor" + [style.background-color]="elementModel.styles.backgroundColor" [style.width]="elementModel.positionProps.fixedSize ? elementModel.width + 'px' : '100%'" [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : '100%'" [class.center-content]="elementModel.positionProps.dynamicPositioning && elementModel.positionProps.fixedSize"> <div *ngIf="elementModel.label" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.line-height.%]="elementModel.styles.lineHeight" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> {{elementModel.label}} </div> <div #valueContainer @@ -31,13 +31,13 @@ import { SliderElement } from '../../interfaces/elements'; <div *ngIf="elementModel.showValues" class="value-container"> <div - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.line-height.%]="elementModel.styles.lineHeight" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> {{elementModel.minValue | number:'':'de'}} </div> <div *ngIf="elementModel.barStyle" class="number-marker"></div> @@ -48,13 +48,13 @@ import { SliderElement } from '../../interfaces/elements'; <div *ngIf="elementModel.showValues" class="value-container"> <div - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"> + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.line-height.%]="elementModel.styles.lineHeight" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''"> {{elementModel.maxValue | number:'':'de'}} </div> <div *ngIf="elementModel.barStyle" diff --git a/projects/common/components/ui-elements/spell-correct.component.ts b/projects/common/components/ui-elements/spell-correct.component.ts index 24d69f074..a7d412ae6 100644 --- a/projects/common/components/ui-elements/spell-correct.component.ts +++ b/projects/common/components/ui-elements/spell-correct.component.ts @@ -11,7 +11,7 @@ import { SpellCorrectElement } from '../../interfaces/elements'; [class.center-content]="elementModel.positionProps.dynamicPositioning && elementModel.positionProps.fixedSize"> <div fxFlex fxLayout="column" - aspectInputBackgroundColor [backgroundColor]="elementModel.surfaceProps.backgroundColor" + aspectInputBackgroundColor [backgroundColor]="elementModel.styles.backgroundColor" [style.width.%]="100" [style.height.%]="100"> <mat-form-field class="small-input"> @@ -19,12 +19,12 @@ import { SpellCorrectElement } from '../../interfaces/elements'; [style.text-align]="'center'" autocomplete="off" [readonly]="elementModel.readOnly" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" [value]="elementModel.value" [formControl]="elementFormControl"> </mat-form-field> @@ -32,12 +32,12 @@ import { SpellCorrectElement } from '../../interfaces/elements'; mat-button type="button" [disabled]="elementModel.readOnly" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : '400'" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : '400'" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" [style.width.%]="100" [style.margin-top]="'-20px'" [style.text-decoration-line]= diff --git a/projects/common/components/ui-elements/text-area.component.ts b/projects/common/components/ui-elements/text-area.component.ts index 71a5b54f5..bceb3bde6 100644 --- a/projects/common/components/ui-elements/text-area.component.ts +++ b/projects/common/components/ui-elements/text-area.component.ts @@ -12,13 +12,13 @@ import { TextAreaElement } from '../../interfaces/elements'; [style.min-height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : '100%'" [class.center-content]="elementModel.positionProps.dynamicPositioning && elementModel.positionProps.fixedSize" - aspectInputBackgroundColor [backgroundColor]="elementModel.surfaceProps.backgroundColor" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" + aspectInputBackgroundColor [backgroundColor]="elementModel.styles.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" [appearance]="elementModel.appearance"> <mat-label *ngIf="elementModel.label">{{elementModel.label}}</mat-label> <textarea matInput #input @@ -27,7 +27,7 @@ import { TextAreaElement } from '../../interfaces/elements'; [value]="elementModel.value" [readonly]="elementModel.readOnly" [style.min-width.%]="100" - [style.line-height.%]="elementModel.fontProps.lineHeight" + [style.line-height.%]="elementModel.styles.lineHeight" [style.resize]="elementModel.resizeEnabled ? 'both' : 'none'" (focus)="elementModel.inputAssistancePreset !== 'none' ? onFocusChanged.emit(input) : null" (blur)="elementModel.inputAssistancePreset !== 'none' ? onFocusChanged.emit(null): null"> diff --git a/projects/common/components/ui-elements/text-field-simple.component.ts b/projects/common/components/ui-elements/text-field-simple.component.ts index 9fe0cb396..a7e259483 100644 --- a/projects/common/components/ui-elements/text-field-simple.component.ts +++ b/projects/common/components/ui-elements/text-field-simple.component.ts @@ -8,13 +8,13 @@ import { TextFieldSimpleElement } from '../../interfaces/elements'; <input type="text" form="parentForm" [style.width.px]="elementModel.width" [style.height.px]="elementModel.height" - [style.line-height.px]="elementModel.fontProps.fontSize" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" + [style.line-height.px]="elementModel.styles.fontSize" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" [formControl]="elementFormControl" value="{{elementModel.value}}"> `, diff --git a/projects/common/components/ui-elements/text-field.component.ts b/projects/common/components/ui-elements/text-field.component.ts index 8b20ff4c6..5d90aa3e6 100644 --- a/projects/common/components/ui-elements/text-field.component.ts +++ b/projects/common/components/ui-elements/text-field.component.ts @@ -13,13 +13,13 @@ import { TextFieldElement } from '../../interfaces/elements'; elementModel.positionProps.fixedSize" [style.width]="elementModel.positionProps.fixedSize ? elementModel.width + 'px' : '100%'" [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : '100%'" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" - aspectInputBackgroundColor [backgroundColor]="elementModel.surfaceProps.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" + aspectInputBackgroundColor [backgroundColor]="elementModel.styles.backgroundColor" [appearance]="elementModel.appearance"> <mat-label>{{elementModel.label}}</mat-label> <input matInput type="text" #input autocomplete="off" @@ -44,13 +44,13 @@ import { TextFieldElement } from '../../interfaces/elements'; elementModel.positionProps.fixedSize" [style.width]="elementModel.positionProps.fixedSize ? elementModel.width + 'px' : '100%'" [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : '100%'" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" - aspectInputBackgroundColor [backgroundColor]="elementModel.surfaceProps.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" + aspectInputBackgroundColor [backgroundColor]="elementModel.styles.backgroundColor" [appearance]="$any(elementModel.appearance)"> <input matInput type="text" #input autocomplete="off" [formControl]="elementFormControl" diff --git a/projects/common/components/ui-elements/text.component.ts b/projects/common/components/ui-elements/text.component.ts index bdaeed0bc..6f5b49161 100644 --- a/projects/common/components/ui-elements/text.component.ts +++ b/projects/common/components/ui-elements/text.component.ts @@ -23,14 +23,14 @@ import { TextElement, ValueChangeElement } from '../../interfaces/elements'; [class.yellow-selection]="selectedColor === 'yellow'" [class.turquoise-selection]="selectedColor === 'turquoise'" [class.delete-selection]="selectedColor === 'delete'" - [style.background-color]="elementModel.surfaceProps.backgroundColor" - [style.color]="elementModel.fontProps.fontColor" - [style.font-family]="elementModel.fontProps.font" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.line-height.%]="elementModel.fontProps.lineHeight" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" + [style.background-color]="elementModel.styles.backgroundColor" + [style.color]="elementModel.styles.fontColor" + [style.font-family]="elementModel.styles.font" + [style.font-size.px]="elementModel.styles.fontSize" + [style.line-height.%]="elementModel.styles.lineHeight" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" [innerHTML]="elementModel.text | safeResourceHTML" (mousedown)="elementModel.highlightableYellow || elementModel.highlightableTurquoise || diff --git a/projects/common/components/ui-elements/toggle-button.component.ts b/projects/common/components/ui-elements/toggle-button.component.ts index 58c36b1cc..176447931 100644 --- a/projects/common/components/ui-elements/toggle-button.component.ts +++ b/projects/common/components/ui-elements/toggle-button.component.ts @@ -16,17 +16,17 @@ import { ToggleButtonElement } from '../../interfaces/elements'; [ngClass]="{ 'strike' : elementModel.strikeOtherOptions && elementFormControl.value !== null && elementFormControl.value !== i + 1 }" - [style.color]="elementModel.fontProps.fontColor" - [style.font-size.px]="elementModel.fontProps.fontSize" - [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''" - [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''" - [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''" - [style.font-family]="elementModel.fontProps.font" + [style.color]="elementModel.styles.fontColor" + [style.font-size.px]="elementModel.styles.fontSize" + [style.font-weight]="elementModel.styles.bold ? 'bold' : ''" + [style.font-style]="elementModel.styles.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styles.underline ? 'underline' : ''" + [style.font-family]="elementModel.styles.font" [style.background-color]="elementFormControl.value !== null && elementFormControl.value === i + 1 ? elementModel.selectionColor : - elementModel.surfaceProps.backgroundColor" - [style.line-height.%]="elementModel.fontProps.lineHeight"> + elementModel.styles.backgroundColor" + [style.line-height.%]="elementModel.styles.lineHeight"> <!--Background color does not show in editor--> {{option}} </mat-button-toggle> diff --git a/projects/common/interfaces/elements.ts b/projects/common/interfaces/elements.ts index 8c9a836c2..78c4f81cb 100644 --- a/projects/common/interfaces/elements.ts +++ b/projects/common/interfaces/elements.ts @@ -12,28 +12,24 @@ export type DragNDropValueObject = { stringValue?: string; imgSrcValue?: string; }; +export type UIElementValue = string | number | boolean | undefined | UIElementType | InputElementValue | +LikertColumn[] | ClozeDocument | +PositionProperties | ElementStyles | PlayerProperties | BasicStyles; export interface UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; + [index: string]: UIElementValue; type: UIElementType; id: string; width: number; height: number; positionProps?: PositionProperties; - fontProps?: FontProperties; - surfaceProps?: SurfaceProperties; + styles: ElementStyles; playerProps?: PlayerProperties; } export interface InputElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; label?: string; - // value: InputElementValue; - value: string[] | string | number | boolean | DragNDropValueObject[] | null; + value: InputElementValue; required: boolean; requiredWarnMessage: string; readOnly: boolean; @@ -70,7 +66,7 @@ export interface PositionProperties { zIndex: number; } -export interface FontProperties { +export interface ElementStyles { [index: string]: string | number | boolean | undefined; fontColor?: string; font?: string; @@ -79,10 +75,23 @@ export interface FontProperties { bold?: boolean; italic?: boolean; underline?: boolean; + backgroundColor?: string; + borderRadius?: number; + itemBackgroundColor?: string; + borderWidth?: number; + borderColor?: string; + borderStyle?: 'solid' | 'dotted' | 'dashed' | 'double' | 'groove' | 'ridge' | 'inset' | 'outset'; + lineColoring?: boolean; + lineColoringColor?: string; } -export interface SurfaceProperties { - [index: string]: string; +export interface BasicStyles extends ElementStyles { + fontColor: string; + font: string; + fontSize: number; + bold: boolean; + italic: boolean; + underline: boolean; backgroundColor: string; } @@ -111,97 +120,74 @@ export interface PlayerProperties { } export interface ButtonElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'button'; label: string; imageSrc: string | null; - borderRadius: number; action: null | 'previous' | 'next' | 'first' | 'last' | 'end'; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles & { + borderRadius: number; + } } export interface CheckboxElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'checkbox'; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles; } export interface ClozeElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'cloze'; document: ClozeDocument; positionProps: PositionProperties; - fontProps: FontProperties; + styles: BasicStyles & { + lineHeight: number; + } } export interface DropdownElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'dropdown'; options: string[]; allowUnset: boolean; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles } export interface DropListElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'drop-list'; onlyOneItem: boolean; connectedTo: string[]; orientation: 'vertical' | 'horizontal' | 'flex'; - itemBackgroundColor: string; highlightReceivingDropList: boolean; highlightReceivingDropListColor: string; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles & { + itemBackgroundColor: string; + } } export interface DropListSimpleElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'drop-list'; connectedTo: string[]; - itemBackgroundColor: string; highlightReceivingDropList: boolean; highlightReceivingDropListColor: string; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles & { + itemBackgroundColor: string; + } } export interface FrameElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'frame'; - borderWidth: number; - borderColor: string; - borderStyle: 'solid' | 'dotted' | 'dashed' | 'double' | 'groove' | 'ridge' | 'inset' | 'outset'; - borderRadius: number; positionProps: PositionProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles & { + borderWidth: number; + borderColor: string; + borderStyle: 'solid' | 'dotted' | 'dashed' | 'double' | 'groove' | 'ridge' | 'inset' | 'outset'; + borderRadius: number; + } } export interface ImageElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'image'; src: string; scale: boolean; @@ -213,25 +199,20 @@ export interface ImageElement extends UIElement { } export interface LikertElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'likert'; rows: LikertRowElement[]; columns: LikertColumn[]; firstColumnSizeRatio: number; - lineColoring: boolean; - lineColoringColor: string; readOnly: boolean; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles & { + lineHeight: number; + lineColoring: boolean; + lineColoringColor: string; + }; } export interface LikertRowElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'likert-row'; text: string; columnCount: number; @@ -239,33 +220,22 @@ export interface LikertRowElement extends InputElement { } export interface RadioButtonGroupElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'radio'; options: string[]; alignment: 'column' | 'row'; strikeOtherOptions: boolean; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles; } export interface RadioButtonGroupComplexElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'radio-group-images' columns: LikertColumn[]; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles; } export interface SliderElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'slider'; minValue: number; maxValue: number; @@ -273,24 +243,16 @@ export interface SliderElement extends UIElement { barStyle: boolean; // TODO besserer name thumbLabel: boolean; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles; } export interface SpellCorrectElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'spell-correct'; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles; } export interface TextFieldElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'text-field'; appearance: 'fill' | 'outline'; minLength: number; @@ -303,14 +265,10 @@ export interface TextFieldElement extends InputElement { inputAssistancePosition: 'floating' | 'right'; clearable: boolean; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles; } export interface TextAreaElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'text-area'; appearance: 'fill' | 'outline'; resizeEnabled: boolean; @@ -318,50 +276,41 @@ export interface TextAreaElement extends InputElement { inputAssistancePreset: InputAssistancePreset; inputAssistancePosition: 'floating' | 'right'; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles & { + lineHeight: number; + }; } export interface TextFieldSimpleElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'text-field'; - fontProps: FontProperties; + styles: BasicStyles; // TODO okay? bg-color? } export interface TextElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'text'; text: string; highlightableOrange: boolean; highlightableTurquoise: boolean; highlightableYellow: boolean; positionProps: PositionProperties; - fontProps: FontProperties; - surfaceProps: SurfaceProperties; + styles: BasicStyles & { + lineHeight: number; + } } export interface ToggleButtonElement extends InputElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'toggle-button'; options: string[]; strikeOtherOptions: boolean; selectionColor: string; verticalOrientation: boolean; dynamicWidth: boolean; - fontProps: FontProperties, - surfaceProps: SurfaceProperties, + styles: BasicStyles & { + lineHeight: number; + }; } export interface AudioElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'audio'; src: string; positionProps: PositionProperties; @@ -369,9 +318,6 @@ export interface AudioElement extends UIElement { } export interface VideoElement extends UIElement { - [index: string]: string | number | boolean | undefined | UIElementType | InputElementValue | - LikertColumn[] | ClozeDocument | - PositionProperties | FontProperties | SurfaceProperties | PlayerProperties; type: 'video'; src: string; scale: boolean; // TODO besserer name diff --git a/projects/common/util/element.factory.ts b/projects/common/util/element.factory.ts index a728b0384..9ddf9932f 100644 --- a/projects/common/util/element.factory.ts +++ b/projects/common/util/element.factory.ts @@ -18,25 +18,24 @@ import { SpellCorrectComponent } from '../components/ui-elements/spell-correct.c import { FrameComponent } from '../components/ui-elements/frame.component'; import { ElementComponent } from '../directives/element-component.directive'; import { - AudioElement, + AudioElement, BasicStyles, ButtonElement, CheckboxElement, ClozeElement, DropdownElement, DropListElement, - DropListSimpleElement, FontProperties, + DropListSimpleElement, FrameElement, ImageElement, InputElement, LikertElement, LikertRowElement, PlayerProperties, PositionProperties, RadioButtonGroupComplexElement, - RadioButtonGroupElement, SliderElement, SpellCorrectElement, SurfaceProperties, + RadioButtonGroupElement, SliderElement, SpellCorrectElement, TextAreaElement, TextElement, TextFieldElement, TextFieldSimpleElement, ToggleButtonElement, UIElement, UIElementType, VideoElement } from '../interfaces/elements'; -import { IdService } from '../../editor/src/app/services/id.service'; export abstract class ElementFactory { static createElement(elementType: string, defaults?: Record<string, any>): UIElement { @@ -85,11 +84,12 @@ export abstract class ElementFactory { } static initElement(elementType: string, defaults: Record<string, number>): UIElement { - return <UIElement>{ + return { type: elementType as UIElementType, - id: defaults.id || 'id_placeholder', + id: String(defaults.id) || 'id_placeholder', width: defaults.width || 190, - height: defaults.height || 60 + height: defaults.height || 60, + styles: {} }; } @@ -123,20 +123,14 @@ export abstract class ElementFactory { }; } - static initFontProps(defaults: Record<string, any> = {}): FontProperties { + static initBasicStyles(defaults: Record<string, any>): BasicStyles { return { fontColor: defaults.fontColor || '#000000', font: defaults.font || 'Roboto', fontSize: defaults.fontSize || 20, - lineHeight: defaults.lineHeight || 120, bold: defaults.bold || false, italic: defaults.italic || false, - underline: defaults.underline || false - }; - } - - static initSurfaceProps(defaults: Record<string, any> = {}): SurfaceProperties { - return { + underline: defaults.underline || false, backgroundColor: defaults.backgroundColor || '#d3d3d3' }; } @@ -166,7 +160,7 @@ export abstract class ElementFactory { }; } - static getComponentFactory( + static getComponentFactory( // TODO weg hier elementType: string, componentFactoryResolver: ComponentFactoryResolver ): ComponentFactory<ElementComponent> { switch (elementType) { @@ -215,11 +209,12 @@ export abstract class ElementFactory { type: 'button', label: 'Knopf', imageSrc: null, - borderRadius: 0, action: null, positionProps: ElementFactory.initPositionProps(defaults.positionProps), - fontProps: ElementFactory.initFontProps(defaults.fontProps), - surfaceProps: ElementFactory.initSurfaceProps(defaults.surfaceProps) + styles: { + ...ElementFactory.initBasicStyles(defaults), + borderRadius: 0 + } }; } @@ -229,8 +224,7 @@ export abstract class ElementFactory { type: 'checkbox', value: false, positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: ElementFactory.initBasicStyles(defaults) }; } @@ -240,7 +234,10 @@ export abstract class ElementFactory { type: 'cloze', document: { type: 'doc', content: [] }, positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps(defaults) + styles: { + ...ElementFactory.initBasicStyles(defaults), + lineHeight: 135 + } }; } @@ -251,8 +248,7 @@ export abstract class ElementFactory { options: [], allowUnset: false, positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps(defaults) + styles: ElementFactory.initBasicStyles(defaults) }; } @@ -264,12 +260,13 @@ export abstract class ElementFactory { onlyOneItem: false, connectedTo: [], orientation: 'vertical', - itemBackgroundColor: '#c9e0e0', highlightReceivingDropList: false, highlightReceivingDropListColor: '#006064', positionProps: ElementFactory.initPositionProps({ useMinHeight: true, ...defaults }), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: '#f4f4f2', ...defaults }) + styles: { + ...ElementFactory.initBasicStyles({ backgroundColor: '#f4f4f2', ...defaults }), + itemBackgroundColor: '#c9e0e0' + } }; } @@ -279,11 +276,12 @@ export abstract class ElementFactory { type: 'drop-list', value: [], connectedTo: [], - itemBackgroundColor: '#add8e6', highlightReceivingDropList: false, highlightReceivingDropListColor: '#add8e6', - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: '#eeeeec', ...defaults }) + styles: { + ...ElementFactory.initBasicStyles({ backgroundColor: '#eeeeec', ...defaults }), + itemBackgroundColor: '#add8e6' + } }; } @@ -291,13 +289,14 @@ export abstract class ElementFactory { return { ...ElementFactory.initElement('frame', {}), type: 'frame', - borderWidth: 1, - borderColor: 'black', - borderStyle: 'solid', - borderRadius: 0, positionProps: ElementFactory.initPositionProps({ zIndex: -1, ...defaults }), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: { + ...ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }), + borderWidth: 1, + borderColor: 'black', + borderStyle: 'solid', + borderRadius: 0 + } }; } @@ -322,12 +321,14 @@ export abstract class ElementFactory { rows: [], columns: [], firstColumnSizeRatio: 5, - lineColoring: true, - lineColoringColor: '#c9e0e0', readOnly: false, positionProps: ElementFactory.initPositionProps({ marginBottom: 30, ...defaults }), - fontProps: ElementFactory.initFontProps({ lineHeight: 135, ...defaults }), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: { + ...ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }), + lineHeight: 135, + lineColoring: true, + lineColoringColor: '#c9e0e0' + } }; } @@ -349,8 +350,7 @@ export abstract class ElementFactory { alignment: 'column', strikeOtherOptions: false, positionProps: ElementFactory.initPositionProps({ marginBottom: 30, ...defaults }), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }) }; } @@ -360,8 +360,7 @@ export abstract class ElementFactory { type: 'radio-group-images', columns: [], positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }) }; } @@ -375,8 +374,7 @@ export abstract class ElementFactory { barStyle: false, thumbLabel: false, positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }) }; } @@ -385,8 +383,7 @@ export abstract class ElementFactory { ...ElementFactory.initInputElement('spell-correct', { width: 230, height: 80, ...defaults }), type: 'spell-correct', positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }) }; } @@ -399,8 +396,10 @@ export abstract class ElementFactory { highlightableTurquoise: false, highlightableYellow: false, positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps({ lineHeight: 135, ...defaults }), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: { + ...ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }), + lineHeight: 135 + } }; } @@ -414,8 +413,10 @@ export abstract class ElementFactory { inputAssistancePreset: 'none', inputAssistancePosition: 'floating', positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: { + ...ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }), + lineHeight: 135 + } }; } @@ -434,8 +435,7 @@ export abstract class ElementFactory { inputAssistancePosition: 'floating', clearable: false, positionProps: ElementFactory.initPositionProps(defaults), - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }) }; } @@ -444,8 +444,7 @@ export abstract class ElementFactory { ...ElementFactory.initInputElement('text-field', { height: 25, ...defaults }), type: 'text-field', label: undefined, - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps(defaults) + styles: ElementFactory.initBasicStyles(defaults) }; } @@ -458,8 +457,10 @@ export abstract class ElementFactory { selectionColor: 'lightgreen', verticalOrientation: false, dynamicWidth: true, - fontProps: ElementFactory.initFontProps(defaults), - surfaceProps: ElementFactory.initSurfaceProps({ backgroundColor: 'transparent', ...defaults }) + styles: { + ...ElementFactory.initBasicStyles({ backgroundColor: 'transparent', ...defaults }), + lineHeight: 135 + } }; } diff --git a/projects/editor/src/app/app.module.ts b/projects/editor/src/app/app.module.ts index ee5b83199..8e0f75cea 100644 --- a/projects/editor/src/app/app.module.ts +++ b/projects/editor/src/app/app.module.ts @@ -40,8 +40,8 @@ import { SectionDynamicComponent } from './components/unit-view/page-view/canvas import { RichTextEditorComponent } from './text-editor/rich-text-editor.component'; import { ElementStylePropertiesComponent } from './components/unit-view/page-view/properties-panel/element-style-properties.component'; -import { ElementSizingPropertiesComponent } from - './components/unit-view/page-view/properties-panel/element-sizing-properties.component'; +import { ElementPositionPropertiesComponent } from + './components/unit-view/page-view/properties-panel/element-position-properties.component'; import { ConfirmationDialogComponent } from './components/dialogs/confirmation-dialog.component'; import { TextEditDialogComponent } from './components/dialogs/text-edit-dialog.component'; import { TextEditMultilineDialogComponent } from './components/dialogs/text-edit-multiline-dialog.component'; @@ -76,7 +76,7 @@ import { DropListNodeviewComponent } from './text-editor/angular-node-views/drop TextFieldNodeviewComponent, DropListNodeviewComponent, ElementStylePropertiesComponent, - ElementSizingPropertiesComponent, + ElementPositionPropertiesComponent, ConfirmationDialogComponent, TextEditDialogComponent, TextEditMultilineDialogComponent, diff --git a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.ts index 0a7835b14..566eb5d70 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.ts @@ -20,7 +20,7 @@ import { LikertColumn, LikertRow } from '../../../../../../../common/interfaces/ styleUrls: ['./element-model-properties.component.css'] }) export class ElementModelPropertiesComponent { - @Input() combinedProperties: UIElement = {} as UIElement; + @Input() combinedProperties: Partial<UIElement> = {}; @Input() selectedElements: UIElement[] = []; @Output() updateModel = new EventEmitter<{ property: string; diff --git a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-sizing-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-position-properties.component.ts similarity index 76% rename from projects/editor/src/app/components/unit-view/page-view/properties-panel/element-sizing-properties.component.ts rename to projects/editor/src/app/components/unit-view/page-view/properties-panel/element-position-properties.component.ts index 9769f85d1..8da066528 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-sizing-properties.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-position-properties.component.ts @@ -1,26 +1,27 @@ import { - Component, Input, Output, EventEmitter + Component, Input, Output, EventEmitter, OnInit } from '@angular/core'; import { UnitService } from '../../../../services/unit.service'; import { SelectionService } from '../../../../services/selection.service'; -import { PositionedElement, UIElement } from '../../../../../../../common/interfaces/elements'; +import { PositionedElement, PositionProperties } from '../../../../../../../common/interfaces/elements'; +import { ElementPropertiesComponent } from './element-properties.component'; @Component({ - selector: 'aspect-element-sizing-properties', + selector: 'aspect-element-postion-properties', template: ` <div fxLayout="column"> - <mat-checkbox *ngIf="combinedProperties.dynamicWidth !== undefined" - [checked]="$any(combinedProperties.dynamicWidth)" + <mat-checkbox *ngIf="positionProperties.dynamicWidth !== undefined" + [checked]="$any(positionProperties.dynamicWidth)" (change)="updateModel.emit({ property: 'dynamicWidth', value: $event.checked })"> {{'propertiesPanel.dynamicWidth' | translate }} </mat-checkbox> - <ng-container *ngIf="!combinedProperties.dynamicPositioning; else elseBlock"> - <mat-form-field *ngIf="combinedProperties.dynamicWidth === undefined || - !combinedProperties.dynamicWidth" appearance="fill"> + <ng-container *ngIf="!positionProperties.dynamicPositioning; else elseBlock"> + <mat-form-field *ngIf="positionProperties.dynamicWidth === undefined || + !positionProperties.dynamicWidth" appearance="fill"> <mat-label>{{'propertiesPanel.width' | translate }}</mat-label> <input matInput type="number" #width="ngModel" min="0" - [ngModel]="combinedProperties.width" + [ngModel]="positionProperties.width" (ngModelChange)="updateModel.emit({ property: 'width', value: $event, isInputValid: width.valid && $event !== null})"> @@ -28,31 +29,31 @@ import { PositionedElement, UIElement } from '../../../../../../../common/interf <mat-form-field appearance="fill"> <mat-label>{{'propertiesPanel.height' | translate }}</mat-label> <input matInput type="number" #height="ngModel" min="0" - [ngModel]="combinedProperties.height" + [ngModel]="positionProperties.height" (ngModelChange)="updateModel.emit({ property: 'height', value: $event, isInputValid: height.valid && $event !== null})"> </mat-form-field> - <mat-form-field *ngIf="combinedProperties.xPosition !== undefined" appearance="fill"> + <mat-form-field *ngIf="positionProperties.xPosition !== undefined" appearance="fill"> <mat-label>{{'propertiesPanel.xPosition' | translate }}</mat-label> <input matInput type="number" #xPosition="ngModel" min="0" - [ngModel]="combinedProperties.xPosition" + [ngModel]="positionProperties.xPosition" (ngModelChange)="updateModel.emit( { property: 'xPosition', value: $event, isInputValid: xPosition.valid && $event !== null })"> </mat-form-field> - <mat-form-field *ngIf="combinedProperties.yPosition !== undefined" appearance="fill"> + <mat-form-field *ngIf="positionProperties.yPosition !== undefined" appearance="fill"> <mat-label>{{'propertiesPanel.yPosition' | translate }}</mat-label> <input matInput type="number" #yPosition="ngModel" min="0" - [ngModel]="combinedProperties.yPosition" + [ngModel]="positionProperties.yPosition" (ngModelChange)="updateModel.emit( { property: 'yPosition', value: $event, isInputValid: yPosition.valid && $event !== null })"> </mat-form-field> - <mat-form-field *ngIf="combinedProperties.zIndex !== undefined" appearance="fill"> + <mat-form-field *ngIf="positionProperties.zIndex !== undefined" appearance="fill"> <mat-label>{{'propertiesPanel.zIndex' | translate }}</mat-label> <input matInput type="number" #zIndex="ngModel" - [ngModel]="combinedProperties.zIndex" + [ngModel]="positionProperties.zIndex" (ngModelChange)="updateModel.emit({ property: 'zIndex', value: $event, isInputValid: zIndex.valid && $event !== null })" @@ -79,45 +80,45 @@ import { PositionedElement, UIElement } from '../../../../../../../common/interf </ng-container> </ng-container> <ng-template #elseBlock> - <mat-checkbox *ngIf="combinedProperties.positionProps !== undefined" + <mat-checkbox *ngIf="positionProperties.positionProps !== undefined" matTooltip="Element ist nicht mehr dynamisch. Die eingestellte Größe wird benutzt." - [checked]="$any(combinedProperties.fixedSize)" + [checked]="$any(positionProperties.fixedSize)" (change)="updateModel.emit({ property: 'fixedSize', value: $event.checked })"> {{'propertiesPanel.fixedSize' | translate }} </mat-checkbox> - <mat-form-field appearance="fill" *ngIf="combinedProperties.positionProps !== undefined"> - <mat-label *ngIf="!combinedProperties.fixedSize"> + <mat-form-field appearance="fill" *ngIf="positionProperties.positionProps !== undefined"> + <mat-label *ngIf="!positionProperties.fixedSize"> {{'propertiesPanel.minWidth' | translate }} </mat-label> - <mat-label *ngIf="combinedProperties.fixedSize"> + <mat-label *ngIf="positionProperties.fixedSize"> {{'propertiesPanel.width' | translate }} </mat-label> <input matInput type="number" #width="ngModel" min="0" - [ngModel]="combinedProperties.width" + [ngModel]="positionProperties.width" (ngModelChange)="updateModel.emit({ property: 'width', value: $event, isInputValid: width.valid && $event !== null })"> </mat-form-field> - <mat-checkbox *ngIf="combinedProperties.positionProps && !combinedProperties.fixedSize" - [checked]="$any(combinedProperties.useMinHeight)" + <mat-checkbox *ngIf="positionProperties.positionProps && !positionProperties.fixedSize" + [checked]="$any(positionProperties.useMinHeight)" (change)="updateModel.emit({ property: 'useMinHeight', value: $event.checked })"> {{'propertiesPanel.useMinHeight' | translate }} </mat-checkbox> - <mat-form-field *ngIf="combinedProperties.positionProps && - combinedProperties.useMinHeight || - combinedProperties.positionProps && - combinedProperties.fixedSize" appearance="fill"> - <mat-label *ngIf="!combinedProperties.fixedSize"> + <mat-form-field *ngIf="positionProperties.positionProps && + positionProperties.useMinHeight || + positionProperties.positionProps && + positionProperties.fixedSize" appearance="fill"> + <mat-label *ngIf="!positionProperties.fixedSize"> {{'propertiesPanel.minHeight' | translate }} </mat-label> - <mat-label *ngIf="combinedProperties.fixedSize"> + <mat-label *ngIf="positionProperties.fixedSize"> {{'propertiesPanel.height' | translate }} </mat-label> <input matInput type="number" #height="ngModel" min="0" - [ngModel]="combinedProperties.height" + [ngModel]="positionProperties.height" (ngModelChange)="updateModel.emit({ property: 'height', value: $event, isInputValid: height.valid && $event !== null })"> @@ -128,24 +129,24 @@ import { PositionedElement, UIElement } from '../../../../../../../common/interf <div fxLayoutAlign="row"> <mat-form-field class="small-input"> <mat-label>{{'propertiesPanel.startColumn' | translate }}</mat-label> - <input matInput type="number" [ngModel]="combinedProperties.gridColumnStart" + <input matInput type="number" [ngModel]="positionProperties.gridColumnStart" (ngModelChange)="updateModel.emit({ property: 'gridColumnStart', value: $event })"> </mat-form-field> <mat-form-field class="small-input"> <mat-label>{{'propertiesPanel.endColumn' | translate }}</mat-label> - <input matInput type="number" [ngModel]="combinedProperties.gridColumnEnd" + <input matInput type="number" [ngModel]="positionProperties.gridColumnEnd" (ngModelChange)="updateModel.emit({ property: 'gridColumnEnd', value: $event })"> </mat-form-field> </div> <div fxLayoutAlign="row"> <mat-form-field class="small-input"> <mat-label>{{'propertiesPanel.startRow' | translate }}</mat-label> - <input matInput type="number" [ngModel]="combinedProperties.gridRowStart" + <input matInput type="number" [ngModel]="positionProperties.gridRowStart" (ngModelChange)="updateModel.emit({ property: 'gridRowStart', value: $event })"> </mat-form-field> <mat-form-field class="small-input"> <mat-label>{{'propertiesPanel.endRow' | translate }}</mat-label> - <input matInput type="number" [ngModel]="combinedProperties.gridRowEnd" + <input matInput type="number" [ngModel]="positionProperties.gridRowEnd" (ngModelChange)="updateModel.emit({ property: 'gridRowEnd', value: $event })"> </mat-form-field> </div> @@ -156,7 +157,7 @@ import { PositionedElement, UIElement } from '../../../../../../../common/interf <mat-form-field class="centered-form-field small-input"> <mat-label>{{'propertiesPanel.top' | translate }}</mat-label> <input matInput type="number" #marginTop="ngModel" - [ngModel]="combinedProperties.marginTop" + [ngModel]="positionProperties.marginTop" (ngModelChange)="updateModel.emit( { property: 'marginTop', value: $event, isInputValid: marginTop.valid && $event !== null })"> </mat-form-field> @@ -164,14 +165,14 @@ import { PositionedElement, UIElement } from '../../../../../../../common/interf <mat-form-field class="small-input"> <mat-label>{{'propertiesPanel.left' | translate }}</mat-label> <input matInput type="number" #marginLeft="ngModel" - [ngModel]="combinedProperties.marginLeft" + [ngModel]="positionProperties.marginLeft" (ngModelChange)="updateModel.emit( { property: 'marginLeft', value: $event, isInputValid: marginLeft.valid && $event !== null })"> </mat-form-field> <mat-form-field class="right-form-field small-input"> <mat-label>{{'propertiesPanel.right' | translate }}</mat-label> <input matInput type="number" #marginRight="ngModel" - [ngModel]="combinedProperties.marginRight" + [ngModel]="positionProperties.marginRight" (ngModelChange)="updateModel.emit( { property: 'marginRight', value: $event, @@ -181,17 +182,17 @@ import { PositionedElement, UIElement } from '../../../../../../../common/interf <mat-form-field class="centered-form-field small-input"> <mat-label>{{'propertiesPanel.bottom' | translate }}</mat-label> <input matInput type="number" #marginBottom="ngModel" - [ngModel]="combinedProperties.marginBottom" + [ngModel]="positionProperties.marginBottom" (ngModelChange)="updateModel.emit( { property: 'marginBottom', value: $event, isInputValid: marginBottom .valid && $event !== null })"> </mat-form-field> </div> - <mat-form-field *ngIf="combinedProperties.zIndex !== undefined" appearance="fill"> + <mat-form-field *ngIf="positionProperties.zIndex !== undefined" appearance="fill"> <mat-label>{{'propertiesPanel.zIndex' | translate }}</mat-label> <input matInput type="number" #zIndex="ngModel" - [ngModel]="combinedProperties.zIndex" + [ngModel]="positionProperties.zIndex" (ngModelChange)="updateModel.emit({ property: 'zIndex', value: $event, isInputValid: zIndex.valid && $event !== null })" @@ -208,14 +209,19 @@ import { PositionedElement, UIElement } from '../../../../../../../common/interf '::ng-deep aspect-element-properties .small-input .mat-form-field-infix {width: 100px; margin: 0 5px;}' ] }) -export class ElementSizingPropertiesComponent { - @Input() combinedProperties: UIElement = {} as UIElement; +export class ElementPositionPropertiesComponent { + @Input() positionProperties: PositionProperties = {} as PositionProperties; @Output() updateModel = new EventEmitter<{ property: string; value: string | boolean, isInputValid?: boolean | null }>(); constructor(private unitService: UnitService, public selectionService: SelectionService) { } + // ngOnInit(): void { + // this.positionProperties = ElementPropertiesComponent.createCombinedProperties(this.positionProperties); + // } + alignElements(direction: 'left' | 'right' | 'top' | 'bottom'): void { this.unitService.alignElements(this.selectionService.getSelectedElements() as PositionedElement[], direction); } + } diff --git a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-properties.component.html b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-properties.component.html index 0014dd397..3ac02ee58 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-properties.component.html +++ b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-properties.component.html @@ -12,20 +12,20 @@ </aspect-element-model-properties-component> </mat-tab> - <mat-tab> + <mat-tab *ngIf="combinedProperties.positionProps"> <ng-template mat-tab-label> <mat-icon class="example-tab-icon">format_shapes</mat-icon> </ng-template> - <aspect-element-sizing-properties [combinedProperties]="combinedProperties" - (updateModel)="updateModel($event.property, $event.value, $event.isInputValid)"> - </aspect-element-sizing-properties> + <aspect-element-postion-properties [positionProperties]="$any(combinedProperties.positionProps)" + (updateModel)="updateModel($event.property, $event.value, $event.isInputValid)"> + </aspect-element-postion-properties> </mat-tab> - <mat-tab> + <mat-tab *ngIf="combinedProperties.styles"> <ng-template mat-tab-label> <mat-icon class="example-tab-icon">palette</mat-icon> </ng-template> - <aspect-element-style-properties [combinedProperties]="combinedProperties" + <aspect-element-style-properties [styles]="$any(combinedProperties.styles)" (updateModel)="updateModel($event.property, $event.value)"> </aspect-element-style-properties> </mat-tab> diff --git a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-properties.component.ts index 6833ecf68..6a837a082 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-properties.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-properties.component.ts @@ -5,11 +5,14 @@ import { DomSanitizer } from '@angular/platform-browser'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; -import { merge } from 'lodash'; import { UnitService } from '../../../../services/unit.service'; import { SelectionService } from '../../../../services/selection.service'; import { MessageService } from '../../../../../../../common/services/message.service'; -import { DragNDropValueObject, UIElement } from '../../../../../../../common/interfaces/elements'; +import { + DragNDropValueObject, + UIElement, + UIElementValue +} from '../../../../../../../common/interfaces/elements'; import { LikertColumn, LikertRow } from '../../../../../../../common/interfaces/likert'; @Component({ @@ -25,7 +28,7 @@ import { LikertColumn, LikertRow } from '../../../../../../../common/interfaces/ }) export class ElementPropertiesComponent implements OnInit, OnDestroy { selectedElements!: UIElement[]; - combinedProperties: UIElement = {} as UIElement; + combinedProperties: Partial<UIElement> = {}; private ngUnsubscribe = new Subject<void>(); constructor(private selectionService: SelectionService, public unitService: UnitService, @@ -38,7 +41,7 @@ export class ElementPropertiesComponent implements OnInit, OnDestroy { .pipe(takeUntil(this.ngUnsubscribe)) .subscribe( () => { - this.createCombinedProperties(); + this.combinedProperties = ElementPropertiesComponent.createCombinedProperties(this.selectedElements); } ); this.selectionService.selectedElements @@ -46,46 +49,36 @@ export class ElementPropertiesComponent implements OnInit, OnDestroy { .subscribe( (selectedElements: UIElement[]) => { this.selectedElements = selectedElements; - this.createCombinedProperties(); + this.combinedProperties = ElementPropertiesComponent.createCombinedProperties(this.selectedElements); } ); } - /* Create new object with properties of all selected elements. When values differ set prop to undefined. */ - createCombinedProperties(): void { - // Flatten all elements first, to make it easier to combine them - const flattenedSelectedElements = - this.selectedElements.map(element => ElementPropertiesComponent.flattenInterfaceProps(element)); - - if (flattenedSelectedElements.length === 0) { - this.combinedProperties = {} as UIElement; - } else { - this.combinedProperties = { ...flattenedSelectedElements[0] } as UIElement; + static createCombinedProperties(elements: Record<string, UIElementValue>[]): Record<string, UIElementValue> { + const combinedProperties: Record<string, UIElementValue> = { ...elements[0] }; - for (let i = 1; i < flattenedSelectedElements.length; i++) { - Object.keys(this.combinedProperties).forEach((property: keyof UIElement) => { - if (Object.prototype.hasOwnProperty.call(flattenedSelectedElements[i], property)) { - if (Array.isArray(flattenedSelectedElements[i][property])) { - if (flattenedSelectedElements[i][property]?.toString() === this.combinedProperties[property]?.toString()) { - this.combinedProperties[property] = flattenedSelectedElements[i][property]; - } - } - if (flattenedSelectedElements[i][property] !== this.combinedProperties[property]) { - this.combinedProperties[property] = null; - } - } else { - delete this.combinedProperties[property]; + for (let elementCounter = 1; elementCounter < elements.length; elementCounter++) { + const elementToMerge = elements[elementCounter]; + Object.keys(combinedProperties).forEach((property: keyof UIElement) => { + if (Object.prototype.hasOwnProperty.call(elementToMerge, property)) { + if (typeof combinedProperties[property] === 'object' && + !Array.isArray(combinedProperties[property]) && + combinedProperties[property] !== null) { + (combinedProperties[property] as Record<string, UIElementValue>) = + ElementPropertiesComponent.createCombinedProperties( + [(combinedProperties[property] as Record<string, UIElementValue>), + (elementToMerge[property] as Record<string, UIElementValue>)] + ); + } else if (JSON.stringify(combinedProperties[property]) !== JSON.stringify(elementToMerge[property])) { + combinedProperties[property] = null; } - }); - } + } else { + delete combinedProperties[property]; + } + }); } - // console.log('combined', this.combinedProperties); - } - - private static flattenInterfaceProps(element: UIElement): UIElement { - let flatElement = merge({ ...element }, element.positionProps); - flatElement = merge(flatElement, element.fontProps); - return merge(flatElement, element.surfaceProps) as unknown as UIElement; + // console.log('combined', combinedProperties); + return combinedProperties; } updateModel(property: string, diff --git a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-style-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-style-properties.component.ts index 8448d0af3..e1fe782ac 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-style-properties.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-style-properties.component.ts @@ -1,119 +1,119 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { UIElement } from '../../../../../../../common/interfaces/elements'; +import { ElementStyles } from '../../../../../../../common/interfaces/elements'; @Component({ selector: 'aspect-element-style-properties', template: ` <div fxLayout="column"> - <mat-form-field *ngIf="combinedProperties.selectionColor !== undefined" appearance="fill"> + <mat-form-field *ngIf="styles.selectionColor !== undefined" appearance="fill"> <mat-label>{{'propertiesPanel.selectionColor' | translate }}</mat-label> - <input matInput type="text" [value]="combinedProperties.selectionColor" + <input matInput type="text" [value]="styles.selectionColor" (input)="updateModel.emit({ property: 'selectionColor', value: $any($event.target).value })"> <button mat-icon-button matSuffix (click)="selectionColorInput.click()"> <mat-icon>edit</mat-icon> </button> </mat-form-field> <input matInput type="color" hidden #selectionColorInput - [value]="combinedProperties.selectionColor" + [value]="styles.selectionColor" (input)="updateModel.emit({ property: 'selectionColor', value: $any($event.target).value })"> - <mat-form-field *ngIf="combinedProperties.borderRadius !== undefined" appearance="fill"> + <mat-form-field *ngIf="styles.borderRadius !== undefined" appearance="fill"> <mat-label>{{'propertiesPanel.borderRadius' | translate }}</mat-label> - <input matInput type="number" [value]="combinedProperties.borderRadius" + <input matInput type="number" [ngModel]="styles.borderRadius" (input)="updateModel.emit({ property: 'borderRadius', value: $any($event.target).value })"> </mat-form-field> - <mat-form-field *ngIf="combinedProperties.itemBackgroundColor !== undefined" + <mat-form-field *ngIf="styles.itemBackgroundColor !== undefined" appearance="fill" class="mdInput textsingleline"> <mat-label>{{'propertiesPanel.itemBackgroundColor' | translate }}</mat-label> - <input matInput type="text" [value]="combinedProperties.itemBackgroundColor" + <input matInput type="text" [value]="styles.itemBackgroundColor" (input)="updateModel.emit({ property: 'itemBackgroundColor', value: $any($event.target).value })"> <button mat-icon-button matSuffix (click)="itembackgroundColorInput.click()"> <mat-icon>edit</mat-icon> </button> </mat-form-field> <input matInput type="color" hidden #itembackgroundColorInput - [value]="combinedProperties.itemBackgroundColor" + [value]="styles.itemBackgroundColor" (input)="updateModel.emit({ property: 'itemBackgroundColor', value: $any($event.target).value })"> - <mat-form-field *ngIf="combinedProperties.backgroundColor !== undefined" + <mat-form-field *ngIf="styles.backgroundColor !== undefined" appearance="fill" class="mdInput textsingleline"> <mat-label>{{'propertiesPanel.backgroundColor' | translate }}</mat-label> - <input matInput type="text" [value]="combinedProperties.backgroundColor" + <input matInput type="text" [value]="styles.backgroundColor" (input)="updateModel.emit({ property: 'backgroundColor', value: $any($event.target).value })"> <button mat-icon-button matSuffix (click)="backgroundColorInput.click()"> <mat-icon>edit</mat-icon> </button> </mat-form-field> <input matInput type="color" hidden #backgroundColorInput - [value]="combinedProperties.backgroundColor" + [value]="styles.backgroundColor" (input)="updateModel.emit({ property: 'backgroundColor', value: $any($event.target).value })"> - <mat-form-field *ngIf="combinedProperties.borderColor !== undefined" + <mat-form-field *ngIf="styles.borderColor !== undefined" appearance="fill" class="mdInput textsingleline"> <mat-label>{{'propertiesPanel.borderColor' | translate }}</mat-label> - <input matInput type="text" [value]="combinedProperties.borderColor" + <input matInput type="text" [value]="styles.borderColor" (input)="updateModel.emit({ property: 'borderColor', value: $any($event.target).value })"> <button mat-icon-button matSuffix (click)="borderColorInput.click()"> <mat-icon>edit</mat-icon> </button> </mat-form-field> <input matInput type="color" hidden #borderColorInput - [value]="combinedProperties.borderColor" + [value]="styles.borderColor" (input)="updateModel.emit({ property: 'borderColor', value: $any($event.target).value })"> - <mat-form-field *ngIf="combinedProperties.fontColor !== undefined" + <mat-form-field *ngIf="styles.fontColor !== undefined" appearance="fill" class="mdInput textsingleline"> <mat-label>{{'propertiesPanel.fontColor' | translate }}</mat-label> - <input matInput type="text" [value]="combinedProperties.fontColor" + <input matInput type="text" [value]="styles.fontColor" (input)="updateModel.emit({ property: 'fontColor', value: $any($event.target).value })"> <button mat-icon-button matSuffix (click)="fontColorInput.click()"> <mat-icon>edit</mat-icon> </button> </mat-form-field> <input matInput type="color" hidden #fontColorInput - [value]="combinedProperties.fontColor" + [value]="styles.fontColor" (input)="updateModel.emit({ property: 'fontColor', value: $any($event.target).value })"> - <mat-form-field *ngIf="combinedProperties.font !== undefined" + <mat-form-field *ngIf="styles.font !== undefined" appearance="fill" class="mdInput textsingleline"> <mat-label>{{'propertiesPanel.font' | translate }}</mat-label> - <input matInput type="text" [value]="combinedProperties.font" disabled + <input matInput type="text" [value]="styles.font" disabled (input)="updateModel.emit({ property: 'font', value: $any($event.target).value })"> </mat-form-field> - <mat-form-field *ngIf="combinedProperties.fontSize !== undefined" + <mat-form-field *ngIf="styles.fontSize !== undefined" appearance="fill" class="mdInput textsingleline"> <mat-label>{{'propertiesPanel.fontSize' | translate }}</mat-label> <input matInput type="number" #fontSize="ngModel" min="0" - [ngModel]="combinedProperties.fontSize" + [ngModel]="styles.fontSize" (ngModelChange)="updateModel.emit({ property: 'fontSize', value: $event, isInputValid: fontSize.valid && $event !== null})"> </mat-form-field> - <mat-form-field *ngIf="combinedProperties.lineHeight !== undefined" + <mat-form-field *ngIf="styles.lineHeight !== undefined" appearance="fill" class="mdInput textsingleline"> <mat-label>{{'propertiesPanel.lineHeight' | translate }}</mat-label> <input matInput type="number" #lineHeight="ngModel" min="0" - [ngModel]="combinedProperties.lineHeight" + [ngModel]="styles.lineHeight" (ngModelChange)="updateModel.emit({ property: 'lineHeight', value: $event, isInputValid: lineHeight.valid && $event !== null })"> </mat-form-field> - <mat-checkbox *ngIf="combinedProperties.bold !== undefined" - [checked]="$any(combinedProperties.bold)" + <mat-checkbox *ngIf="styles.bold !== undefined" + [checked]="$any(styles.bold)" (change)="updateModel.emit({ property: 'bold', value: $event.checked })"> {{'propertiesPanel.bold' | translate }} </mat-checkbox> - <mat-checkbox *ngIf="combinedProperties.italic !== undefined" - [checked]="$any(combinedProperties.italic)" + <mat-checkbox *ngIf="styles.italic !== undefined" + [checked]="$any(styles.italic)" (change)="updateModel.emit({ property: 'italic', value: $event.checked })"> {{'propertiesPanel.italic' | translate }} </mat-checkbox> - <mat-checkbox *ngIf="combinedProperties.underline !== undefined" - [checked]="$any(combinedProperties.underline)" + <mat-checkbox *ngIf="styles.underline !== undefined" + [checked]="$any(styles.underline)" (change)="updateModel.emit({ property: 'underline', value: $event.checked })"> {{'propertiesPanel.underline' | translate }} </mat-checkbox> @@ -121,7 +121,7 @@ import { UIElement } from '../../../../../../../common/interfaces/elements'; ` }) export class ElementStylePropertiesComponent { - @Input() combinedProperties: UIElement = {} as UIElement; + @Input() styles: ElementStyles = {}; @Output() updateModel = new EventEmitter<{ property: string; value: string | boolean, diff --git a/projects/editor/src/app/services/unit.service.ts b/projects/editor/src/app/services/unit.service.ts index 7e0b498a6..6ad9edad4 100644 --- a/projects/editor/src/app/services/unit.service.ts +++ b/projects/editor/src/app/services/unit.service.ts @@ -164,9 +164,6 @@ export class UnitService { } } as unknown as Partial<UIElement>) as PositionedElement; } - console.log('newElement', newElement); - console.log('ccord', coordinates); - console.log('section', section); if (coordinates && section.dynamicPositioning) { newElement.positionProps.gridColumnStart = coordinates.x; newElement.positionProps.gridColumnEnd = coordinates.x + 1; @@ -259,7 +256,8 @@ export class UnitService { this.veronaApiService.sendVoeDefinitionChangedNotification(); } - updateElementProperty(elements: UIElement[], property: string, + updateElementProperty(elements: UIElement[], + property: string, value: InputElementValue | LikertColumn[] | LikertRow[] | ClozeDocument | DragNDropValueObject[] | null): boolean { console.log('updateElementProperty', elements, property, value); @@ -288,15 +286,14 @@ export class UnitService { 'gridColumnEnd', 'gridRowStart', 'gridRowEnd', 'marginLeft', 'marginRight', 'marginTop', 'marginBottom', 'zIndex'].includes(property)) { element.positionProps![property] = Copy.getCopy(value); - } else if (['fontColor', 'font', 'fontSize', 'lineHeight', 'bold', 'italic', 'underline'].includes(property)) { - element.fontProps![property] = Copy.getCopy(value); - } else if (['backgroundColor'].includes(property)) { - element.surfaceProps![property] = Copy.getCopy(value); + } else if (['fontColor', 'font', 'fontSize', 'lineHeight', 'bold', 'italic', 'underline', + 'backgroundColor', 'borderRadius', 'itemBackgroundColor', 'borderWidth', 'borderColor', + 'borderStyle', 'lineColoring', 'lineColoringColor'].includes(property)) { + element.styles![property] = Copy.getCopy(value); } else { element[property] = Copy.getCopy(value); } }); - console.log('fffff'); this.elementPropertyUpdated.next(); this.veronaApiService.sendVoeDefinitionChangedNotification(); return true; @@ -446,7 +443,7 @@ export class UnitService { case 'text': this.dialogService.showRichTextEditDialog( (element as TextElement).text, - (element as TextElement).fontProps.fontSize as number + (element as TextElement).styles.fontSize ).subscribe((result: string) => { if (result) { // TODO add proper sanitization @@ -461,7 +458,7 @@ export class UnitService { case 'cloze': this.dialogService.showClozeTextEditDialog( (element as ClozeElement).document, - (element as ClozeElement).fontProps.fontSize as number + (element as ClozeElement).styles.fontSize ).subscribe((result: string) => { if (result) { // TODO add proper sanitization -- GitLab