From d67f72f74295fd58eff95c2e2b10db23b0ff475b Mon Sep 17 00:00:00 2001 From: rhenck <richard.henck@iqb.hu-berlin.de> Date: Tue, 22 Feb 2022 13:25:24 +0100 Subject: [PATCH] [editor] Refactor page view component - Now does unit (page) manipulation itself instead of delegating everything to the UnitService. Still need to call the UnitService to make it notify the API about the change to the unit. - Also improve the hack for refreshing the tab view. --- .../unit-view/unit-view.component.html | 4 +- .../unit-view/unit-view.component.ts | 60 ++++++++++++++----- .../editor/src/app/services/unit.service.ts | 40 +------------ .../src/app/services/verona-api.service.ts | 2 +- 4 files changed, 49 insertions(+), 57 deletions(-) diff --git a/projects/editor/src/app/components/unit-view/unit-view.component.html b/projects/editor/src/app/components/unit-view/unit-view.component.html index 359f8461d..69f7e42a0 100644 --- a/projects/editor/src/app/components/unit-view/unit-view.component.html +++ b/projects/editor/src/app/components/unit-view/unit-view.component.html @@ -15,7 +15,7 @@ [style.height.%]="100" mat-align-tabs="start" [selectedIndex]="selectedPageIndex" (selectedIndexChange)="selectPage($event)"> - <mat-tab *ngFor="let page of unitService.unit.pages; let i = index"> + <mat-tab *ngFor="let page of unit.pages; let i = index"> <ng-template mat-tab-label> <ng-container *ngIf="page.alwaysVisible"> <mat-icon class="page-alwaysVisible-icon">assignment</mat-icon> @@ -102,7 +102,7 @@ </mat-menu> </ng-template> - <aspect-page-canvas [page]="page" fxLayout="column"></aspect-page-canvas> + <aspect-page-canvas *ngIf="pagesLoaded" [page]="page" fxLayout="column"></aspect-page-canvas> </mat-tab> <mat-tab disabled> <ng-template mat-tab-label> diff --git a/projects/editor/src/app/components/unit-view/unit-view.component.ts b/projects/editor/src/app/components/unit-view/unit-view.component.ts index 51e48cd36..df11571ef 100644 --- a/projects/editor/src/app/components/unit-view/unit-view.component.ts +++ b/projects/editor/src/app/components/unit-view/unit-view.component.ts @@ -5,7 +5,9 @@ import { UnitService } from '../../services/unit.service'; import { DialogService } from '../../services/dialog.service'; import { SelectionService } from '../../services/selection.service'; import { MessageService } from '../../../../../common/services/message.service'; -import { Page } from '../../../../../common/interfaces/unit'; +import { Page, Unit } from '../../../../../common/interfaces/unit'; +import { ArrayUtils } from '../../../../../common/util/array'; +import { UnitFactory } from '../../../../../common/util/unit.factory'; @Component({ selector: 'aspect-unit-view', @@ -13,6 +15,7 @@ import { Page } from '../../../../../common/interfaces/unit'; styleUrls: ['./unit-view.component.css'] }) export class UnitViewComponent implements OnInit, OnDestroy { + unit!: Unit; selectedPageIndex: number = 0; pagesLoaded = true; private ngUnsubscribe = new Subject<void>(); @@ -23,16 +26,7 @@ export class UnitViewComponent implements OnInit, OnDestroy { private messageService: MessageService) { } ngOnInit(): void { - // The following is a hack. The tab element gets bugged when changing the underlying array. - // With this we can temporarily remove it from the DOM and then add it again, re-initializing it. - this.unitService.pageMoved - .pipe(takeUntil(this.ngUnsubscribe)) - .subscribe(() => { - this.pagesLoaded = false; - setTimeout(() => { - this.pagesLoaded = true; - }); - }); + this.unit = this.unitService.unit; } selectPage(newIndex: number): void { @@ -42,14 +36,26 @@ export class UnitViewComponent implements OnInit, OnDestroy { } addPage(): void { - this.unitService.addPage(); + this.unit.pages.push(UnitFactory.generateEmptyPage()); + this.selectedPageIndex = this.unitService.unit.pages.length - 1; this.selectionService.selectedPageIndex = this.selectedPageIndex; this.selectionService.selectedPageSectionIndex = 0; + + this.unitService.unitUpdated(); } movePage(page: Page, direction: 'up' | 'down'): void { - this.unitService.movePage(page, direction); + if ((direction === 'up' && this.unit.pages.indexOf(page) === 1 && this.unit.pages[0].alwaysVisible) || + (direction === 'up' && this.unit.pages.indexOf(page) === 0) || + (direction === 'down' && this.unit.pages.indexOf(page) === this.unit.pages.length - 1)) { + this.messageService.showWarning('page can\'t be moved'); // TODO translate + return; + } + ArrayUtils.moveArrayItem(page, this.unitService.unit.pages, direction); + this.refreshTabs(); + direction === 'up' ? this.selectedPageIndex -= 1 : this.selectedPageIndex += 1; + this.unitService.unitUpdated(); } deletePage(page: Page): void { @@ -57,7 +63,8 @@ export class UnitViewComponent implements OnInit, OnDestroy { .pipe(takeUntil(this.ngUnsubscribe)) .subscribe((result: boolean) => { if (result) { - this.unitService.deletePage(page); + this.unit.pages.splice(this.unit.pages.indexOf(page), 1); + this.unitService.unitUpdated(); this.selectedPageIndex -= 1; } }); @@ -67,15 +74,36 @@ export class UnitViewComponent implements OnInit, OnDestroy { updateModel(page: Page, property: string, value: number | boolean, isInputValid: boolean | null = true): void { if (isInputValid && value != null) { - this.unitService.updatePageProperty(page, property, value); - if (property === 'alwaysVisible') { + if (property === 'alwaysVisible' && value === true) { + this.movePageToFront(page); + page.alwaysVisible = true; this.selectedPageIndex = 0; + this.refreshTabs(); } + page[property] = value; + this.unitService.unitUpdated(); } else { this.messageService.showWarning('Eingabe ungültig'); } } + private movePageToFront(page: Page): void { + const pageIndex = this.unit.pages.indexOf(page); + if (pageIndex !== 0) { + this.unit.pages.splice(pageIndex, 1); + this.unit.pages.splice(0, 0, page); + } + } + + /* This is a hack. The tab element gets bugged when changing the underlying array. + With this we can temporarily remove it from the DOM and then add it again, re-initializing it. */ + private refreshTabs(): void { + this.pagesLoaded = false; + setTimeout(() => { + this.pagesLoaded = true; + }); + } + ngOnDestroy(): void { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); diff --git a/projects/editor/src/app/services/unit.service.ts b/projects/editor/src/app/services/unit.service.ts index 06554077d..2803e9300 100644 --- a/projects/editor/src/app/services/unit.service.ts +++ b/projects/editor/src/app/services/unit.service.ts @@ -35,7 +35,6 @@ export class UnitService { unit: Unit; elementPropertyUpdated: Subject<void> = new Subject<void>(); - pageMoved: Subject<void> = new Subject<void>(); constructor(private selectionService: SelectionService, private idService: IdService, @@ -60,43 +59,8 @@ export class UnitService { }); } - addPage(): void { - this.unit.pages.push(UnitFactory.generateEmptyPage()); - this.veronaApiService.sendVoeDefinitionChangedNotification(); - } - - deletePage(page: Page): void { - this.unit.pages.splice(this.unit.pages.indexOf(page), 1); - this.veronaApiService.sendVoeDefinitionChangedNotification(); - } - - movePage(selectedPage: Page, direction: 'up' | 'down'): void { - if (direction === 'up' && - this.unit.pages.indexOf(selectedPage) === 1 && - this.unit.pages[0].alwaysVisible) { - return; - } - moveArrayItem(selectedPage, this.unit.pages, direction); - this.pageMoved.next(); - this.veronaApiService.sendVoeDefinitionChangedNotification(); - } - - updatePageProperty(page: Page, property: string, value: number | boolean): void { - if (property === 'alwaysVisible' && value === true) { - this.handlePageAlwaysVisiblePropertyChange(page); - } - page[property] = value; - this.veronaApiService.sendVoeDefinitionChangedNotification(); - } - - private handlePageAlwaysVisiblePropertyChange(page: Page): void { - const pageIndex = this.unit.pages.indexOf(page); - if (pageIndex !== 0) { - this.unit.pages.splice(pageIndex, 1); - this.unit.pages.splice(0, 0, page); - this.pageMoved.next(); - } - page.alwaysVisible = true; + unitUpdated(): void { + this.veronaApiService.sendVoeDefinitionChangedNotification(JSON.stringify(this.unit)); } addSection(page: Page): void { diff --git a/projects/editor/src/app/services/verona-api.service.ts b/projects/editor/src/app/services/verona-api.service.ts index 290e9ae45..ffe945f35 100644 --- a/projects/editor/src/app/services/verona-api.service.ts +++ b/projects/editor/src/app/services/verona-api.service.ts @@ -51,7 +51,7 @@ export class VeronaAPIService { }); } - sendVoeDefinitionChangedNotification(unitDefinition: string = ''): void { + sendVoeDefinitionChangedNotification(unitDefinition: string = ''): void { // TODO empty string?! this.send({ type: 'voeDefinitionChangedNotification', sessionId: this.sessionID, -- GitLab