From da1aaed3a8d3052d411c9dc5cb2cb2da6ae0cfd7 Mon Sep 17 00:00:00 2001
From: rhenck <richard.henck@iqb.hu-berlin.de>
Date: Tue, 17 Aug 2021 17:53:10 +0200
Subject: [PATCH] [editor] Make page props panel use unit service

Instead of manipulating the page object directly via ngmodel.
This way the unit service may inform the host about changes. Also future
undo functionality is prepared.
---
 .../properties/page-properties.component.ts   | 32 ++++++++++++-------
 projects/editor/src/app/unit.service.ts       | 22 +++++++------
 2 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/projects/editor/src/app/components/unit-view/page-view/properties/page-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties/page-properties.component.ts
index 9852af3ba..3618e6c3d 100644
--- a/projects/editor/src/app/components/unit-view/page-view/properties/page-properties.component.ts
+++ b/projects/editor/src/app/components/unit-view/page-view/properties/page-properties.component.ts
@@ -1,7 +1,8 @@
-import { Component, OnDestroy, OnInit } from '@angular/core';
+import {
+  Component, OnInit, OnDestroy
+} from '@angular/core';
 import { Subject } from 'rxjs';
 import { takeUntil } from 'rxjs/operators';
-import { MatCheckboxChange } from '@angular/material/checkbox';
 import { UnitPage } from '../../../../../../../common/unit';
 import { UnitService } from '../../../../unit.service';
 import { SelectionService } from '../../../../selection.service';
@@ -12,18 +13,24 @@ import { SelectionService } from '../../../../selection.service';
     <div fxLayout="column">
       <mat-form-field>
         <mat-label>Breite</mat-label>
-        <input matInput type="number" [(ngModel)]="selectedPage.width">
+        <input matInput type="number"
+               [value]="selectedPage.width"
+               (change)="updateModel('width', $any($event.target).value)">
       </mat-form-field>
       <mat-form-field>
         <mat-label>Randbreite</mat-label>
-        <input matInput type="number" [(ngModel)]="selectedPage.margin">
+        <input matInput type="number"
+               [value]="selectedPage.margin"
+               (change)="updateModel('margin', $any($event.target).value)">
       </mat-form-field>
       <mat-form-field>
         <mat-label>Hintergrundfarbe</mat-label>
-        <input matInput type="text" [(ngModel)]="selectedPage.backgroundColor">
+        <input matInput type="text"
+               [value]="selectedPage.backgroundColor"
+               (change)="updateModel('backgroundColor', $any($event.target).value)">
       </mat-form-field>
-      <mat-checkbox [checked]="selectedPage.alwaysVisible"
-                    (change)="setPageAlwaysVisible($event)">
+      <mat-checkbox [disabled]="alwaysVisibleDisabled" [ngModel]="selectedPage.alwaysVisible"
+                    (change)="updateModel('alwaysVisible', $any($event.source).checked)">
         Immer angezeigt
       </mat-checkbox>
     </div>
@@ -31,22 +38,23 @@ import { SelectionService } from '../../../../selection.service';
 })
 export class PagePropertiesComponent implements OnInit, OnDestroy {
   selectedPage!: UnitPage;
+  alwaysVisibleDisabled: boolean = false;
   private ngUnsubscribe = new Subject<void>();
 
-  constructor(public selectionService: SelectionService, private unitService: UnitService) { }
+  constructor(public selectionService: SelectionService,
+              private unitService: UnitService) { }
 
   ngOnInit(): void {
     this.selectionService.selectedPage
       .pipe(takeUntil(this.ngUnsubscribe))
       .subscribe((page: UnitPage) => {
         this.selectedPage = page;
+        this.alwaysVisibleDisabled = this.unitService.isPageAlwaysVisibleSet() && !page.alwaysVisible;
       });
   }
 
-  setPageAlwaysVisible(event: MatCheckboxChange): void {
-    if (!this.unitService.setPageAlwaysVisible(event.checked)) {
-      event.source.checked = false;
-    }
+  updateModel(property: string, value: number | boolean): void {
+    this.unitService.updatePageProperty(this.selectedPage, property, value);
   }
 
   ngOnDestroy(): void {
diff --git a/projects/editor/src/app/unit.service.ts b/projects/editor/src/app/unit.service.ts
index 0b44b31a8..a3302680c 100644
--- a/projects/editor/src/app/unit.service.ts
+++ b/projects/editor/src/app/unit.service.ts
@@ -1,7 +1,7 @@
 import { Injectable } from '@angular/core';
 import { BehaviorSubject, Observable, Subject } from 'rxjs';
 import {
-  Unit, UnitPageSection, UnitUIElement
+  Unit, UnitPage, UnitPageSection, UnitUIElement
 } from '../../../common/unit';
 import { FileService } from '../../../common/file.service';
 import * as UnitFactory from './UnitFactory';
@@ -59,16 +59,18 @@ export class UnitService {
     this.veronaApiService.sendVoeDefinitionChangedNotification();
   }
 
-  /** Checks if a page already has this setting. Return false if so.
-   * When newState is false it is always okay. */
-  setPageAlwaysVisible(newState: boolean): boolean { // TODO make private
-    if (!newState || !this._unit.value.pages.find(page => page.alwaysVisible)) {
-      this._unit.value.pages[this.selectedPageIndex].alwaysVisible = newState;
-      this.veronaApiService.sendVoeDefinitionChangedNotification();
-      return true;
+  updatePageProperty(page: UnitPage, property: string, value: number | boolean): void {
+    if (property === 'alwaysVisible' && value === true && this.isPageAlwaysVisibleSet()) {
+      this.messageService.showError('Kann nur für eine Seite gesetzt werden');
+    } else {
+      page[property] = value;
     }
-    this.messageService.showError('Kann nur für eine Seite gesetzt werden');
-    return false;
+    this.veronaApiService.sendVoeDefinitionChangedNotification();
+  }
+
+  /** Check if a page already has this setting. */
+  isPageAlwaysVisibleSet(): boolean {
+    return this._unit.value.pages.find(page => page.alwaysVisible) !== undefined;
   }
 
   addSection(): void {
-- 
GitLab