From eaaa07306c6fd64613e5ba64eaeea9462e9465c2 Mon Sep 17 00:00:00 2001 From: rhenck <richard.henck@iqb.hu-berlin.de> Date: Thu, 7 Oct 2021 17:37:24 +0200 Subject: [PATCH] [editor] Refactor properties panel The different tabs are now separate components, which makes them a lot smaller and better to handle. --- projects/editor/src/app/app.module.ts | 6 +- .../element-properties.component.html | 178 +----------------- .../element-properties.component.ts | 4 - .../element-sizing-properties.component.ts | 157 +++++++++++++++ .../element-style-properties.component.ts | 55 ++++++ 5 files changed, 223 insertions(+), 177 deletions(-) create mode 100644 projects/editor/src/app/components/unit-view/page-view/properties/element-sizing-properties.component.ts create mode 100644 projects/editor/src/app/components/unit-view/page-view/properties/element-style-properties.component.ts diff --git a/projects/editor/src/app/app.module.ts b/projects/editor/src/app/app.module.ts index 9a49daf71..3163f7763 100644 --- a/projects/editor/src/app/app.module.ts +++ b/projects/editor/src/app/app.module.ts @@ -29,6 +29,8 @@ import { SectionMenuComponent } from './components/unit-view/page-view/canvas/se import { SectionStaticComponent } from './components/unit-view/page-view/canvas/section-static.component'; import { SectionDynamicComponent } from './components/unit-view/page-view/canvas/section-dynamic.component'; import { RichTextEditorComponent } from './components/unit-view/page-view/rich-text-editor.component'; +import { ElementStylePropertiesComponent } from './components/unit-view/page-view/properties/element-style-properties.component'; +import { ElementSizingPropertiesComponent } from './components/unit-view/page-view/properties/element-sizing-properties.component'; @NgModule({ declarations: [ @@ -48,7 +50,9 @@ import { RichTextEditorComponent } from './components/unit-view/page-view/rich-t SectionMenuComponent, SectionStaticComponent, SectionDynamicComponent, - RichTextEditorComponent + RichTextEditorComponent, + ElementStylePropertiesComponent, + ElementSizingPropertiesComponent ], imports: [ BrowserModule, diff --git a/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.html b/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.html index 7d8f984db..8ef8bba42 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.html +++ b/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.html @@ -218,184 +218,18 @@ <ng-template mat-tab-label> <mat-icon class="example-tab-icon">format_shapes</mat-icon> </ng-template> - <div fxLayout="column"> - - <ng-container *ngIf="!combinedProperties.dynamicPositioning; else elseBlock"> - <mat-form-field *ngIf="combinedProperties.width" appearance="fill"> - <mat-label>Breite</mat-label> - <input matInput type="number" #width="ngModel" min="0" - [ngModel]="combinedProperties.width" - (ngModelChange)="updateModel('width', $event, width.valid)"> - </mat-form-field> - <mat-form-field *ngIf="combinedProperties.height" appearance="fill"> - <mat-label>Hoehe</mat-label> - <input matInput type="number" #height="ngModel" min="0" - [ngModel]="combinedProperties.height" - (ngModelChange)="updateModel('height', $event, height.valid)"> - </mat-form-field> - - <mat-form-field *ngIf="combinedProperties.xPosition" appearance="fill"> - <mat-label>X Position</mat-label> - <input matInput type="number" #xPosition="ngModel" min="0" - [ngModel]="combinedProperties.xPosition" - (ngModelChange)="updateModel('xPosition', $event, xPosition.valid)"> - </mat-form-field> - - <mat-form-field *ngIf="combinedProperties.yPosition" appearance="fill"> - <mat-label>Y Position</mat-label> - <input matInput type="number" #yPosition="ngModel" min="0" - [ngModel]="combinedProperties.yPosition" - (ngModelChange)="updateModel('yPosition', $event, yPosition.valid)"> - </mat-form-field> - </ng-container> - <ng-template #elseBlock> - <mat-form-field *ngIf="combinedProperties.width" appearance="fill"> - <mat-label>Mindestbreite</mat-label> - <input matInput type="number" #width="ngModel" min="0" - [ngModel]="combinedProperties.width" - (ngModelChange)="updateModel('width', $event, width.valid)"> - </mat-form-field> - <mat-form-field *ngIf="combinedProperties.height" appearance="fill"> - <mat-label>Mindesthöhe</mat-label> - <input matInput type="number" #height="ngModel" min="0" - [ngModel]="combinedProperties.height" - (ngModelChange)="updateModel('height', $event, height.valid)"> - </mat-form-field> - Grid - <div class="input-group"> - <div fxLayoutAlign="row"> - <mat-form-field *ngIf="combinedProperties.gridColumnStart" class="small-input"> - <mat-label>Start-Spalte</mat-label> - <input matInput type="number" [ngModel]="combinedProperties.gridColumnStart" - (ngModelChange)="updateModel('gridColumnStart', $event)"> - </mat-form-field> - <mat-form-field *ngIf="combinedProperties.gridColumnEnd" class="small-input"> - <mat-label>End-Spalte</mat-label> - <input matInput type="number" [ngModel]="combinedProperties.gridColumnEnd" - (ngModelChange)="updateModel('gridColumnEnd', $event)"> - </mat-form-field> - </div> - <div fxLayoutAlign="row"> - <mat-form-field *ngIf="combinedProperties.gridRowStart" class="small-input"> - <mat-label>Start-Zeile</mat-label> - <input matInput type="number" [ngModel]="combinedProperties.gridRowStart" - (ngModelChange)="updateModel('gridRowStart', $event)"> - </mat-form-field> - <mat-form-field *ngIf="combinedProperties.gridRowEnd" class="small-input"> - <mat-label>End-Zeile</mat-label> - <input matInput type="number" [ngModel]="combinedProperties.gridRowEnd" - (ngModelChange)="updateModel('gridRowEnd', $event)"> - </mat-form-field> - </div> - </div> - - Abstand - <div class="input-group"> - <mat-form-field *ngIf="combinedProperties.marginTop" - class="centered-form-field"> - <mat-label>oben</mat-label> - <input matInput type="number" #marginTop="ngModel" min="0" - [ngModel]="combinedProperties.marginTop" - (ngModelChange)="updateModel('marginTop', $event, marginTop.valid)"> - </mat-form-field> - <div fxLayoutAlign="row"> - <mat-form-field *ngIf="combinedProperties.marginLeft"> - <mat-label>links</mat-label> - <input matInput type="number" #marginLeft="ngModel" min="0" - [ngModel]="combinedProperties.marginLeft" - (ngModelChange)="updateModel('marginLeft', $event, marginLeft.valid)"> - </mat-form-field> - <mat-form-field *ngIf="combinedProperties.marginRight" - class="right-form-field"> - <mat-label>rechts</mat-label> - <input matInput type="number" #marginRight="ngModel" min="0" - [ngModel]="combinedProperties.marginRight" - (ngModelChange)="updateModel('marginRight', $event, marginRight.valid)"> - </mat-form-field> - </div> - <mat-form-field *ngIf="combinedProperties.marginBottom" - class="centered-form-field"> - <mat-label>unten</mat-label> - <input matInput type="number" #marginBottom="ngModel" min="0" - [ngModel]="combinedProperties.marginBottom" - (ngModelChange)="updateModel('marginBottom', $event, marginBottom.valid)"> - </mat-form-field> - </div> - </ng-template> - - <mat-form-field *ngIf="combinedProperties.zIndex" appearance="fill"> - <mat-label>Z-Index</mat-label> - <input matInput type="number" #zIndex="ngModel" min="0" - [ngModel]="combinedProperties.zIndex" - (ngModelChange)="updateModel('zIndex', $event, zIndex.valid)" - matTooltip="Priorität beim Stapeln von Elementen. Der höhere Index erscheint vorne."> - </mat-form-field> - <ng-container *ngIf="selectedElements.length > 1"> - Ausrichtung - <div class="alignment-button-group" fxLayout="row" fxLayoutAlign="center center"> - <button (click)="alignElements('left')"> - <mat-icon>align_horizontal_left</mat-icon> - </button> - <button (click)="alignElements('right')"> - <mat-icon>align_horizontal_right</mat-icon> - </button> - <button (click)="alignElements('top')"> - <mat-icon>align_vertical_top</mat-icon> - </button> - <button (click)="alignElements('bottom')"> - <mat-icon>align_vertical_bottom</mat-icon> - </button> - </div> - </ng-container> - </div> + <app-element-sizing-properties [combinedProperties]="combinedProperties" + (updateModel)="updateModel($event.property, $event.value, $event.isInputValid)"> + </app-element-sizing-properties> </mat-tab> <mat-tab> <ng-template mat-tab-label> <mat-icon class="example-tab-icon">palette</mat-icon> </ng-template> - <div fxLayout="column"> - <mat-form-field *ngIf="combinedProperties.backgroundColor" - appearance="fill" class="mdInput textsingleline"> - <mat-label>Hintergrundfarbe</mat-label> - <input matInput type="color" [value]="combinedProperties.backgroundColor" - (input)="updateModel('backgroundColor', $any($event.target).value)"> - </mat-form-field> - <mat-form-field *ngIf="combinedProperties.fontColor" - appearance="fill" class="mdInput textsingleline"> - <mat-label>Schriftfarbe</mat-label> - <input matInput type="color" [value]="combinedProperties.fontColor" - (input)="updateModel('fontColor', $any($event.target).value)"> - </mat-form-field> - <mat-form-field *ngIf="combinedProperties.font" - appearance="fill" class="mdInput textsingleline"> - <mat-label>Schriftart</mat-label> - <input matInput type="text" [value]="combinedProperties.font" - (input)="updateModel('font', $any($event.target).value)"> - </mat-form-field> - <mat-form-field *ngIf="combinedProperties.fontSize" - appearance="fill" class="mdInput textsingleline"> - <mat-label>Schriftgröße</mat-label> - <input matInput type="text" [value]="combinedProperties.fontSize" - (input)="updateModel('fontSize', $any($event.target).value)"> - </mat-form-field> - - <mat-checkbox *ngIf="combinedProperties.bold" - [checked]="$any(combinedProperties.bold)" - (change)="updateModel('bold', $event.checked)"> - Fett - </mat-checkbox> - <mat-checkbox *ngIf="combinedProperties.italic" - [checked]="$any(combinedProperties.italic)" - (change)="updateModel('italic', $event.checked)"> - Kursiv - </mat-checkbox> - <mat-checkbox *ngIf="combinedProperties.underline" - [checked]="$any(combinedProperties.underline)" - (change)="updateModel('underline', $event.checked)"> - Unterstrichen - </mat-checkbox> - </div> + <app-element-style-properties [combinedProperties]="combinedProperties" + (updateModel)="updateModel($event.property, $event.value)"> + </app-element-style-properties> </mat-tab> </mat-tab-group> </ng-container> diff --git a/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.ts index 77dcd8935..f1f43c1bf 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.ts @@ -75,10 +75,6 @@ export class ElementPropertiesComponent implements OnInit, OnDestroy { } } - alignElements(direction: 'left' | 'right' | 'top' | 'bottom'): void { - this.unitService.alignElements(this.selectionService.getSelectedElements(), direction); - } - deleteElement(): void { this.unitService.deleteElementsFromSectionByIndex( this.selectedElements, diff --git a/projects/editor/src/app/components/unit-view/page-view/properties/element-sizing-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties/element-sizing-properties.component.ts new file mode 100644 index 000000000..b3dc0807e --- /dev/null +++ b/projects/editor/src/app/components/unit-view/page-view/properties/element-sizing-properties.component.ts @@ -0,0 +1,157 @@ +import { + Component, Input, Output, EventEmitter +} from '@angular/core'; +import { UnitService } from '../../../../unit.service'; +import { SelectionService } from '../../../../selection.service'; + +@Component({ + selector: 'app-element-sizing-properties', + template: ` + <div fxLayout="column"> + <ng-container *ngIf="!combinedProperties.dynamicPositioning; else elseBlock"> + <mat-form-field *ngIf="combinedProperties.width" appearance="fill"> + <mat-label>Breite</mat-label> + <input matInput type="number" #width="ngModel" min="0" + [ngModel]="combinedProperties.width" + (ngModelChange)="updateModel.emit({ property: 'width', value: $event, isInputValid: width.valid })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.height" appearance="fill"> + <mat-label>Hoehe</mat-label> + <input matInput type="number" #height="ngModel" min="0" + [ngModel]="combinedProperties.height" + (ngModelChange)="updateModel.emit({ property: 'height', value: $event, isInputValid: height.valid })"> + </mat-form-field> + + <mat-form-field *ngIf="combinedProperties.xPosition" appearance="fill"> + <mat-label>X Position</mat-label> + <input matInput type="number" #xPosition="ngModel" min="0" + [ngModel]="combinedProperties.xPosition" + (ngModelChange)="updateModel.emit( + { property: 'xPosition', value: $event, isInputValid: xPosition.valid })"> + </mat-form-field> + + <mat-form-field *ngIf="combinedProperties.yPosition" appearance="fill"> + <mat-label>Y Position</mat-label> + <input matInput type="number" #yPosition="ngModel" min="0" + [ngModel]="combinedProperties.yPosition" + (ngModelChange)="updateModel.emit( + { property: 'yPosition', value: $event, isInputValid: yPosition.valid })"> + </mat-form-field> + </ng-container> + <ng-template #elseBlock> + <mat-form-field *ngIf="combinedProperties.width" appearance="fill"> + <mat-label>Mindestbreite</mat-label> + <input matInput type="number" #width="ngModel" min="0" + [ngModel]="combinedProperties.width" + (ngModelChange)="updateModel.emit({ property: 'width', value: $event, isInputValid: width.valid })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.height" appearance="fill"> + <mat-label>Mindesthöhe</mat-label> + <input matInput type="number" #height="ngModel" min="0" + [ngModel]="combinedProperties.height" + (ngModelChange)="updateModel.emit({ property: 'height', value: $event, isInputValid: height.valid })"> + </mat-form-field> + Grid + <div class="input-group"> + <div fxLayoutAlign="row"> + <mat-form-field *ngIf="combinedProperties.gridColumnStart" class="small-input"> + <mat-label>Start-Spalte</mat-label> + <input matInput type="number" [ngModel]="combinedProperties.gridColumnStart" + (ngModelChange)="updateModel.emit({ property: 'gridColumnStart', value: $event })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.gridColumnEnd" class="small-input"> + <mat-label>End-Spalte</mat-label> + <input matInput type="number" [ngModel]="combinedProperties.gridColumnEnd" + (ngModelChange)="updateModel.emit({ property: 'gridColumnEnd', value: $event })"> + </mat-form-field> + </div> + <div fxLayoutAlign="row"> + <mat-form-field *ngIf="combinedProperties.gridRowStart" class="small-input"> + <mat-label>Start-Zeile</mat-label> + <input matInput type="number" [ngModel]="combinedProperties.gridRowStart" + (ngModelChange)="updateModel.emit({ property: 'gridRowStart', value: $event })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.gridRowEnd" class="small-input"> + <mat-label>End-Zeile</mat-label> + <input matInput type="number" [ngModel]="combinedProperties.gridRowEnd" + (ngModelChange)="updateModel.emit({ property: 'gridRowEnd', value: $event })"> + </mat-form-field> + </div> + </div> + + Abstand + <div class="input-group"> + <mat-form-field *ngIf="combinedProperties.marginTop" + class="centered-form-field"> + <mat-label>oben</mat-label> + <input matInput type="number" #marginTop="ngModel" min="0" + [ngModel]="combinedProperties.marginTop" + (ngModelChange)="updateModel.emit( + { property: 'marginTop', value: $event, isInputValid: marginTop.valid })"> + </mat-form-field> + <div fxLayoutAlign="row"> + <mat-form-field *ngIf="combinedProperties.marginLeft"> + <mat-label>links</mat-label> + <input matInput type="number" #marginLeft="ngModel" min="0" + [ngModel]="combinedProperties.marginLeft" + (ngModelChange)="updateModel.emit( + { property: 'marginLeft', value: $event, isInputValid: marginLeft.valid })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.marginRight" + class="right-form-field"> + <mat-label>rechts</mat-label> + <input matInput type="number" #marginRight="ngModel" min="0" + [ngModel]="combinedProperties.marginRight" + (ngModelChange)="updateModel.emit( + { property: 'marginRight', value: $event, isInputValid: marginRight.valid })"> + </mat-form-field> + </div> + <mat-form-field *ngIf="combinedProperties.marginBottom" + class="centered-form-field"> + <mat-label>unten</mat-label> + <input matInput type="number" #marginBottom="ngModel" min="0" + [ngModel]="combinedProperties.marginBottom" + (ngModelChange)="updateModel.emit( + { property: 'marginBottom', value: $event, isInputValid: marginBottom.valid })"> + </mat-form-field> + </div> + </ng-template> + + <mat-form-field *ngIf="combinedProperties.zIndex" appearance="fill"> + <mat-label>Z-Index</mat-label> + <input matInput type="number" #zIndex="ngModel" min="0" + [ngModel]="combinedProperties.zIndex" + (ngModelChange)="updateModel.emit({ property: 'zIndex', value: $event, isInputValid: zIndex.valid })" + matTooltip="Priorität beim Stapeln von Elementen. Der höhere Index erscheint vorne."> + </mat-form-field> + <ng-container *ngIf="(selectionService.selectedElements | async)!.length > 1"> + Ausrichtung + <div class="alignment-button-group" fxLayout="row" fxLayoutAlign="center center"> + <button (click)="alignElements('left')"> + <mat-icon>align_horizontal_left</mat-icon> + </button> + <button (click)="alignElements('right')"> + <mat-icon>align_horizontal_right</mat-icon> + </button> + <button (click)="alignElements('top')"> + <mat-icon>align_vertical_top</mat-icon> + </button> + <button (click)="alignElements('bottom')"> + <mat-icon>align_vertical_bottom</mat-icon> + </button> + </div> + </ng-container> + </div> + ` +}) +export class ElementSizingPropertiesComponent { + @Input() combinedProperties: Record<string, string | number | boolean | string[] | undefined> = {}; + @Output() updateModel = + new EventEmitter<{ property: string; value: string | boolean, isInputValid?: boolean | null }>(); + + constructor(private unitService: UnitService, public selectionService: SelectionService) { } + + alignElements(direction: 'left' | 'right' | 'top' | 'bottom'): void { + this.unitService.alignElements(this.selectionService.getSelectedElements(), direction); + } +} diff --git a/projects/editor/src/app/components/unit-view/page-view/properties/element-style-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties/element-style-properties.component.ts new file mode 100644 index 000000000..013193f7d --- /dev/null +++ b/projects/editor/src/app/components/unit-view/page-view/properties/element-style-properties.component.ts @@ -0,0 +1,55 @@ +import { + Component, EventEmitter, Input, Output +} from '@angular/core'; + +@Component({ + selector: 'app-element-style-properties', + template: ` + <div fxLayout="column"> + <mat-form-field *ngIf="combinedProperties.backgroundColor" + appearance="fill" class="mdInput textsingleline"> + <mat-label>Hintergrundfarbe</mat-label> + <input matInput type="color" [value]="combinedProperties.backgroundColor" + (input)="updateModel.emit({ property: 'backgroundColor', value: $any($event.target).value })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.fontColor" + appearance="fill" class="mdInput textsingleline"> + <mat-label>Schriftfarbe</mat-label> + <input matInput type="color" [value]="combinedProperties.fontColor" + (input)="updateModel.emit({ property: 'fontColor', value: $any($event.target).value })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.font" + appearance="fill" class="mdInput textsingleline"> + <mat-label>Schriftart</mat-label> + <input matInput type="text" [value]="combinedProperties.font" + (input)="updateModel.emit({ property: 'font', value: $any($event.target).value })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.fontSize" + appearance="fill" class="mdInput textsingleline"> + <mat-label>Schriftgröße</mat-label> + <input matInput type="text" [value]="combinedProperties.fontSize" + (input)="updateModel.emit({ property: 'fontSize', value: $any($event.target).value })"> + </mat-form-field> + + <mat-checkbox *ngIf="combinedProperties.bold" + [checked]="$any(combinedProperties.bold)" + (change)="updateModel.emit({ property: 'bold', value: $event.checked })"> + Fett + </mat-checkbox> + <mat-checkbox *ngIf="combinedProperties.italic" + [checked]="$any(combinedProperties.italic)" + (change)="updateModel.emit({ property: 'italic', value: $event.checked })"> + Kursiv + </mat-checkbox> + <mat-checkbox *ngIf="combinedProperties.underline" + [checked]="$any(combinedProperties.underline)" + (change)="updateModel.emit({ property: 'underline', value: $event.checked })"> + Unterstrichen + </mat-checkbox> + </div> + ` +}) +export class ElementStylePropertiesComponent { + @Input() combinedProperties: Record<string, string | number | boolean | string[] | undefined> = {}; + @Output() updateModel = new EventEmitter<{ property: string; value: string | boolean }>(); +} -- GitLab