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 359f8461d76970a281ab5e43b3a739d8823e33b1..69f7e42a05c92af6d85a36308469d748b6e0e4a1 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 51e48cd369354016f522052e779720956d6618fc..df11571ef96203108eedbef0f5179aedb777704a 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 06554077d42d54419fa4259bcf80d11beb7bf178..2803e930060a54d0952a5b982b1128b789be282a 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 290e9ae456ef67d3554282b782ebfc251c0cb98c..ffe945f35d425e9433d6a8c6c077b2710256514b 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,