diff --git a/projects/common/util/id-manager.ts b/projects/common/util/id-manager.ts index 09bc3eb92a4458c4a671b5d1d9601ab585a36745..71c523239dfce0c81cb971e87db923e4a0356d85 100644 --- a/projects/common/util/id-manager.ts +++ b/projects/common/util/id-manager.ts @@ -28,8 +28,11 @@ export class IDManager { value: 0 }; - static getInstance() { - return this.instance || (this.instance = new this()); + static getInstance(): IDManager { + if (!this.instance) { + this.instance = new this(); + } + return this.instance; } getNewID(type: string): string { diff --git a/projects/editor/src/app/app.component.ts b/projects/editor/src/app/app.component.ts index 518cfb9ee1ad4a0cb50f08f67ab9a07dcde40212..09a99e46fa02d5fec443e64208374ba84fbf8423 100644 --- a/projects/editor/src/app/app.component.ts +++ b/projects/editor/src/app/app.component.ts @@ -9,7 +9,7 @@ import { UnitService } from './services/unit.service'; selector: 'aspect-editor', template: ` <div fxLayout="column" class="mainView"> - <aspect-toolbar *ngIf="isStandalone()"></aspect-toolbar> + <aspect-toolbar *ngIf="isStandalone"></aspect-toolbar> <aspect-unit-view fxFlex></aspect-unit-view> </div> `, @@ -18,7 +18,7 @@ import { UnitService } from './services/unit.service'; ] }) export class AppComponent implements OnInit { - isStandalone = (): boolean => window === window.parent; + isStandalone = window === window.parent; constructor(private unitService: UnitService, private translateService: TranslateService, diff --git a/projects/editor/src/app/components/canvas/canvas.component.ts b/projects/editor/src/app/components/canvas/canvas.component.ts index 4fc948d6be6d257dbd081aa5b354b9941f5442b1..ff640c329afa5b5068e0d9c279038fe0d7fcef39 100644 --- a/projects/editor/src/app/components/canvas/canvas.component.ts +++ b/projects/editor/src/app/components/canvas/canvas.component.ts @@ -2,14 +2,14 @@ import { Component, Input, QueryList, ViewChildren } from '@angular/core'; import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { PositionedUIElement, UIElement } from 'common/models/elements/element'; +import { Page } from 'common/models/page'; +import { Section } from 'common/models/section'; import { UnitService } from '../../services/unit.service'; import { SelectionService } from '../../services/selection.service'; import { CanvasElementOverlay } from './overlays/canvas-element-overlay'; import { SectionStaticComponent } from './section-static.component'; import { SectionDynamicComponent } from './section-dynamic.component'; -import { PositionedUIElement, UIElement } from 'common/models/elements/element'; -import { Page } from 'common/models/page'; -import { Section } from 'common/models/section'; @Component({ selector: 'aspect-page-canvas', diff --git a/projects/editor/src/app/components/canvas/dynamic-section-helper-grid.component.ts b/projects/editor/src/app/components/canvas/dynamic-section-helper-grid.component.ts index f8c898252a7e5a65c19df8988a3519727aba2084..9776e95363a122fb3cadfee176a0cd3b7041d54a 100644 --- a/projects/editor/src/app/components/canvas/dynamic-section-helper-grid.component.ts +++ b/projects/editor/src/app/components/canvas/dynamic-section-helper-grid.component.ts @@ -2,9 +2,9 @@ import { CdkDragDrop } from '@angular/cdk/drag-drop/drag-events'; import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; -import { UnitService } from '../../services/unit.service'; import { UIElement, UIElementType } from 'common/models/elements/element'; import { Section } from 'common/models/section'; +import { UnitService } from '../../services/unit.service'; @Component({ selector: '[app-dynamic-section-helper-grid]', diff --git a/projects/editor/src/app/components/canvas/overlays/canvas-element-overlay.ts b/projects/editor/src/app/components/canvas/overlays/canvas-element-overlay.ts index 1388d7d083fd83c859ec15bce599e5434caac81e..426b903acd86271523ef6fcc0eef1db129b031ee 100644 --- a/projects/editor/src/app/components/canvas/overlays/canvas-element-overlay.ts +++ b/projects/editor/src/app/components/canvas/overlays/canvas-element-overlay.ts @@ -4,14 +4,14 @@ import { } from '@angular/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; -import { UnitService } from '../../../services/unit.service'; import { ElementComponent } from 'common/directives/element-component.directive'; -import { SelectionService } from '../../../services/selection.service'; import { CompoundElementComponent } from 'common/directives/compound-element.directive'; import { ClozeComponent } from 'common/components/compound-elements/cloze/cloze.component'; import { CompoundChildOverlayComponent } from 'common/components/compound-elements/cloze/compound-child-overlay.component'; import { UIElement } from 'common/models/elements/element'; +import { UnitService } from '../../../services/unit.service'; +import { SelectionService } from '../../../services/selection.service'; @Directive() export abstract class CanvasElementOverlay implements OnInit, OnDestroy { diff --git a/projects/editor/src/app/components/canvas/overlays/static-canvas-overlay.component.ts b/projects/editor/src/app/components/canvas/overlays/static-canvas-overlay.component.ts index 1b6ee4fb6475f743f5d9fb892218d5e7aae64aa8..3f1b302a733d0ac4b79067a55bb8296c66d528e5 100644 --- a/projects/editor/src/app/components/canvas/overlays/static-canvas-overlay.component.ts +++ b/projects/editor/src/app/components/canvas/overlays/static-canvas-overlay.component.ts @@ -1,8 +1,8 @@ import { Component } from '@angular/core'; import { take } from 'rxjs/operators'; import { CdkDragEnd, CdkDragMove } from '@angular/cdk/drag-drop'; -import { CanvasElementOverlay } from './canvas-element-overlay'; import { UIElement } from 'common/models/elements/element'; +import { CanvasElementOverlay } from './canvas-element-overlay'; @Component({ selector: 'aspect-static-canvas-overlay', diff --git a/projects/editor/src/app/components/canvas/section-dynamic.component.ts b/projects/editor/src/app/components/canvas/section-dynamic.component.ts index c0b2ff0015750ed9f5edec94c04fccbb10746a80..93d8af2610d3987831bd0592a7d9c40a90e37438 100644 --- a/projects/editor/src/app/components/canvas/section-dynamic.component.ts +++ b/projects/editor/src/app/components/canvas/section-dynamic.component.ts @@ -2,9 +2,9 @@ import { Component, Input, Output, EventEmitter, ViewChildren, QueryList, ViewChild } from '@angular/core'; +import { Section } from 'common/models/section'; import { CanvasElementOverlay } from './overlays/canvas-element-overlay'; import { DynamicSectionHelperGridComponent } from './dynamic-section-helper-grid.component'; -import { Section } from 'common/models/section'; @Component({ selector: 'aspect-section-dynamic', diff --git a/projects/editor/src/app/components/canvas/section-menu.component.ts b/projects/editor/src/app/components/canvas/section-menu.component.ts index b3ce0f25425cdfaa65f000d18d65ec4176607c73..6aba70d35d5adce4444370e4ab38c808026d0fcf 100644 --- a/projects/editor/src/app/components/canvas/section-menu.component.ts +++ b/projects/editor/src/app/components/canvas/section-menu.component.ts @@ -5,12 +5,12 @@ import { import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { Clipboard } from '@angular/cdk/clipboard'; -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 { UIElement } from 'common/models/elements/element'; import { Section } from 'common/models/section'; +import { UnitService } from '../../services/unit.service'; +import { DialogService } from '../../services/dialog.service'; +import { SelectionService } from '../../services/selection.service'; @Component({ selector: 'aspect-section-menu', diff --git a/projects/editor/src/app/components/canvas/section-static.component.ts b/projects/editor/src/app/components/canvas/section-static.component.ts index 07ff70cd9f928f100896f5f1bc799f7efe27becb..79766c964a138d3ba56dc6fe6b0dca99481780f2 100644 --- a/projects/editor/src/app/components/canvas/section-static.component.ts +++ b/projects/editor/src/app/components/canvas/section-static.component.ts @@ -1,10 +1,10 @@ import { Component, ElementRef, EventEmitter, Input, Output, QueryList, ViewChild, ViewChildren } from '@angular/core'; -import { UnitService } from '../../services/unit.service'; -import { CanvasElementOverlay } from './overlays/canvas-element-overlay'; import { Section } from 'common/models/section'; import { UIElementType } from 'common/models/elements/element'; +import { UnitService } from '../../services/unit.service'; +import { CanvasElementOverlay } from './overlays/canvas-element-overlay'; @Component({ selector: 'aspect-section-static', diff --git a/projects/editor/src/app/components/new-ui-element-panel/ui-element-toolbox.component.ts b/projects/editor/src/app/components/new-ui-element-panel/ui-element-toolbox.component.ts index baa034c751a2b6c792658788f91d61bf7dfc167d..5b9c08243c4aa2af123ae566aac5c7b58ff5aac8 100644 --- a/projects/editor/src/app/components/new-ui-element-panel/ui-element-toolbox.component.ts +++ b/projects/editor/src/app/components/new-ui-element-panel/ui-element-toolbox.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; +import { UIElementType } from 'common/models/elements/element'; import { UnitService } from '../../services/unit.service'; import { SelectionService } from '../../services/selection.service'; -import { UIElementType } from 'common/models/elements/element'; @Component({ selector: 'aspect-ui-element-toolbox', 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 64d2869a47ece0ceea8182a50a7f948bf739324a..0a6e36624fe98188234f5ee7b8141bc4b84a4070 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 @@ -1,12 +1,12 @@ import { Component, OnDestroy } from '@angular/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; -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 { ArrayUtils } from 'common/util/array'; import { Page } from 'common/models/page'; +import { UnitService } from '../../services/unit.service'; +import { DialogService } from '../../services/dialog.service'; +import { SelectionService } from '../../services/selection.service'; @Component({ selector: 'aspect-unit-view', diff --git a/projects/editor/src/app/services/dialog.service.ts b/projects/editor/src/app/services/dialog.service.ts index 86f6863805a82d8287a9e5e7224da278ae976c6d..7ab5debdab7e7745b36352474d06a84daac435dd 100644 --- a/projects/editor/src/app/services/dialog.service.ts +++ b/projects/editor/src/app/services/dialog.service.ts @@ -1,6 +1,11 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { MatDialog } from '@angular/material/dialog'; +import { DragNDropValueObject, PlayerProperties, TextImageLabel } from 'common/models/elements/element'; +import { ClozeDocument } from 'common/models/elements/compound-elements/cloze/cloze'; +import { LikertRowElement } from 'common/models/elements/compound-elements/likert/likert-row'; +import { Section } from 'common/models/section'; +import { SectionInsertDialogComponent } from 'editor/src/app/components/dialogs/section-insert-dialog.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'; @@ -10,11 +15,6 @@ import { ColumnHeaderEditDialogComponent } from '../components/dialogs/column-he import { LikertRowEditDialogComponent } from '../components/dialogs/likert-row-edit-dialog.component'; import { DropListOptionEditDialogComponent } from '../components/dialogs/drop-list-option-edit-dialog.component'; import { RichTextSimpleEditDialogComponent } from '../components/dialogs/rich-text-simple-edit-dialog.component'; -import { DragNDropValueObject, PlayerProperties, TextImageLabel } from 'common/models/elements/element'; -import { ClozeDocument } from 'common/models/elements/compound-elements/cloze/cloze'; -import { LikertRowElement } from 'common/models/elements/compound-elements/likert/likert-row'; -import { SectionInsertDialogComponent } from 'editor/src/app/components/dialogs/section-insert-dialog.component'; -import { Section } from 'common/models/section'; @Injectable({ providedIn: 'root' diff --git a/projects/editor/src/app/services/unit.service.ts b/projects/editor/src/app/services/unit.service.ts index 0545daf1028fe77324ce126dd52ac6855a03eade..5f294e6aa70231b4d66d20f0e2e0c6f74703325d 100644 --- a/projects/editor/src/app/services/unit.service.ts +++ b/projects/editor/src/app/services/unit.service.ts @@ -4,16 +4,13 @@ import { Subject } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { FileService } from 'common/services/file.service'; import { MessageService } from 'common/services/message.service'; -import { DialogService } from './dialog.service'; -import { VeronaAPIService } from './verona-api.service'; -import { SelectionService } from './selection.service'; import { ArrayUtils } from 'common/util/array'; import { SanitizationService } from 'common/services/sanitization.service'; import { Unit } from 'common/models/unit'; import { DragNDropValueObject, InputElement, InputElementValue, PlayerElement, PlayerProperties, PositionedUIElement, TextImageLabel, - UIElement, UIElementType + UIElement, UIElementType, UIElementValue } from 'common/models/elements/element'; import { LikertElement } from 'common/models/elements/compound-elements/likert/likert'; import { ClozeDocument, ClozeElement } from 'common/models/elements/compound-elements/cloze/cloze'; @@ -24,12 +21,16 @@ import { Page } from 'common/models/page'; import { Section } from 'common/models/section'; import { ElementFactory } from 'common/util/element.factory'; import { IDManager } from 'common/util/id-manager'; +import { DialogService } from './dialog.service'; +import { VeronaAPIService } from './verona-api.service'; +import { SelectionService } from './selection.service'; @Injectable({ providedIn: 'root' }) export class UnitService { unit: Unit; + idManager = IDManager.getInstance(); elementPropertyUpdated: Subject<void> = new Subject<void>(); @@ -44,13 +45,13 @@ export class UnitService { } loadUnitDefinition(unitDefinition: string): void { - IDManager.getInstance().reset(); + this.idManager.reset(); const unitDef = JSON.parse(unitDefinition); if (SanitizationService.isUnitDefinitionOutdated(unitDef)) { this.unit = new Unit(this.sanitizationService.sanitizeUnitDefinition(unitDef)); this.messageService.showMessage(this.translateService.instant('outdatedUnit')); } else { - this.unit = new Unit(unitDef, IDManager.getInstance()); + this.unit = new Unit(unitDef, this.idManager); } } @@ -139,14 +140,17 @@ export class UnitService { this.veronaApiService.sendVoeDefinitionChangedNotification(this.unit); } - private freeUpIds(elements: UIElement[]): void { // TODO free up child and value IDs + private freeUpIds(elements: UIElement[]): void { elements.forEach(element => { if (element.type === 'drop-list') { ((element as DropListElement).value as DragNDropValueObject[]).forEach((value: DragNDropValueObject) => { - IDManager.getInstance().removeId(value.id); + this.idManager.removeId(value.id); }); } - IDManager.getInstance().removeId(element.id); + element.getChildElements().forEach((childElement: UIElement) => { + this.idManager.removeId(childElement.id); + }); + this.idManager.removeId(element.id); }); } @@ -177,23 +181,22 @@ export class UnitService { if ('value' in newElement && newElement.value instanceof Object) { // replace value Ids with fresh ones (dropList) (newElement.value as DragNDropValueObject[]).forEach((valueObject: { id: string }) => { - valueObject.id = IDManager.getInstance().getNewID('value'); + valueObject.id = this.idManager.getNewID('value'); }); } if ('row' in newElement && newElement.rows instanceof Object) { // replace row Ids with fresh ones (likert) (newElement.rows as LikertRowElement[]).forEach((rowObject: { id: string }) => { - rowObject.id = IDManager.getInstance().getNewID('likert_row'); + rowObject.id = this.idManager.getNewID('likert_row'); }); } - if (newElement instanceof ClozeElement) { element.getChildElements().forEach((childElement: UIElement) => { - childElement.id = IDManager.getInstance().getNewID(childElement.type); + childElement.id = this.idManager.getNewID(childElement.type); if (childElement.type === 'drop-list-simple') { // replace value Ids with fresh ones (dropList) (childElement.value as DragNDropValueObject[]).forEach((valueObject: DragNDropValueObject) => { - valueObject.id = IDManager.getInstance().getNewID('value'); + valueObject.id = this.idManager.getNewID('value'); }); } }); @@ -218,14 +221,14 @@ export class UnitService { property: string, value: InputElementValue | TextImageLabel | TextImageLabel[] | ClozeDocument | DragNDropValueObject[] | null): void { - console.log('updateElementProperty', elements, property, value); + // console.log('updateElementProperty', elements, property, value); elements.forEach(element => { if (property === 'id') { - if (!IDManager.getInstance().isIdAvailable((value as string))) { // prohibit existing IDs + if (!this.idManager.isIdAvailable((value as string))) { // prohibit existing IDs this.messageService.showError(this.translateService.instant('idTaken')); } else { - IDManager.getInstance().removeId(element.id); - IDManager.getInstance().addID(value as string); + this.idManager.removeId(element.id); + this.idManager.addID(value as string); element.id = value as string; } } else if (element.type === 'likert' && property === 'columns') { @@ -244,11 +247,11 @@ export class UnitService { this.veronaApiService.sendVoeDefinitionChangedNotification(this.unit); } - updateSelectedElementsPositionProperty(property: string, value: any): void { + updateSelectedElementsPositionProperty(property: string, value: UIElementValue): void { this.updateElementsPositionProperty(this.selectionService.getSelectedElements(), property, value); } - updateElementsPositionProperty(elements: UIElement[], property: string, value: any): void { + updateElementsPositionProperty(elements: UIElement[], property: string, value: UIElementValue): void { elements.forEach(element => { element.setPositionProperty(property, value); }); @@ -256,7 +259,7 @@ export class UnitService { this.veronaApiService.sendVoeDefinitionChangedNotification(this.unit); } - updateSelectedElementsStyleProperty(property: string, value: any): void { + updateSelectedElementsStyleProperty(property: string, value: UIElementValue): void { const elements = this.selectionService.getSelectedElements(); elements.forEach(element => { element.setStyleProperty(property, value); @@ -265,7 +268,7 @@ export class UnitService { this.veronaApiService.sendVoeDefinitionChangedNotification(this.unit); } - updateElementsPlayerProperty(elements: UIElement[], property: string, value: any): void { + updateElementsPlayerProperty(elements: UIElement[], property: string, value: UIElementValue): void { elements.forEach(element => { element.setPlayerProperty(property, value); }); @@ -379,7 +382,9 @@ export class UnitService { case 'video': this.dialogService.showPlayerEditDialog((element as PlayerElement).player) .subscribe((result: PlayerProperties) => { - Object.keys(result).forEach(key => this.updateElementsPlayerProperty([element], key, result[key])); + Object.keys(result).forEach( + key => this.updateElementsPlayerProperty([element], key, result[key] as UIElementValue) + ); }); break; // no default @@ -387,7 +392,7 @@ export class UnitService { } getNewValueID(): string { - return IDManager.getInstance().getNewID('value'); + return this.idManager.getNewID('value'); } /* Used by props panel to show available dropLists to connect */ diff --git a/projects/editor/src/app/services/verona-api.service.ts b/projects/editor/src/app/services/verona-api.service.ts index 5a4bbb195be4bc81346ed4ededcb861fb5c6d0a8..6288f1db335857fba5323eb69474809c9c81d897 100644 --- a/projects/editor/src/app/services/verona-api.service.ts +++ b/projects/editor/src/app/services/verona-api.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { fromEvent, Observable, Subject } from 'rxjs'; -import packageJSON from '../../../../../package.json'; import { Unit } from 'common/models/unit'; +import packageJSON from '../../../../../package.json'; @Injectable({ providedIn: 'root' @@ -11,7 +11,7 @@ export class VeronaAPIService { private _voeStartCommand = new Subject<VoeStartCommand>(); // TODO proper interfaces private _voeGetDefinitionRequest = new Subject<VoeGetDefinitionRequest>(); - private isStandalone = (): boolean => window === window.parent; + private isStandalone = window === window.parent; constructor() { fromEvent(window, 'message') @@ -36,7 +36,7 @@ export class VeronaAPIService { private send(message: Record<string, string>): void { // prevent posts in local (dev) mode - if (!this.isStandalone()) { + if (!this.isStandalone) { window.parent.postMessage(message, '*'); } else { // console.log(`player: ${message.type}`);