diff --git a/projects/editor/src/app/UnitFactory.ts b/projects/editor/src/app/UnitFactory.ts index 3ace59363739eef7aedb3bd41f0a5a854731d9f6..52bbf69caa9433cc950582e67faeba787f14fef6 100644 --- a/projects/editor/src/app/UnitFactory.ts +++ b/projects/editor/src/app/UnitFactory.ts @@ -40,7 +40,7 @@ export function createUnitPageSection(): UnitPageSection { }; } -function createUnitUIElement(type: string): UnitUIElement { +export function createUnitUIElement(type: string): UnitUIElement { return { type, id: 'id_placeholder', diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.html b/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.html index 93b7cfda9ab67273855a73417d0b0f897f5b5ab9..6dfc447b393dbd4a6d83c39b1e377ce297f7b444 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.html +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.html @@ -7,11 +7,12 @@ <div *ngFor="let section of page.sections; let i = index" [style.position]="'relative'"> <app-section-menu [class.open]="hoveredSection === i" class="section-menu" fxLayout="column" [style.left.px]="-45" [style.z-index]="1" [style.position]="'absolute'" - [section]="section" + [section]="section" [sectionIndex]="i" [allowMoveUp]="i != 0" [allowMoveDown]="i < page.sections.length - 1" [allowDelete]="page.sections.length > 1" (moveSection)="unitService.moveSection(section, page, $event)" + (duplicateSection)="unitService.duplicateSection(section, page, i)" (mouseover)="hoveredSection = i" (mouseleave)="hoveredSection = -1"> <!-- keep menu open--> </app-section-menu> <!-- TODO split section into static and dynamic--> diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts index 45d4b92d97569a0dc11c221f4957c0060c4545b8..3f730746b97cbb1066d957a499fb0ea308c5562c 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts @@ -7,6 +7,7 @@ import { takeUntil } from 'rxjs/operators'; import { UnitPageSection } from '../../../../../../../common/unit'; import { UnitService } from '../../../../unit.service'; import { DialogService } from '../../../../dialog.service'; +import { SelectionService } from '../../../../selection.service'; @Component({ selector: 'app-section-menu', @@ -102,6 +103,10 @@ import { DialogService } from '../../../../dialog.service'; (click)="this.moveSection.emit('down')"> <mat-icon>south</mat-icon> </button> + <button mat-mini-fab + (click)="duplicateSection.emit()"> + <mat-icon>content_copy</mat-icon> + </button> <button *ngIf="allowDelete" mat-mini-fab (click)="deleteSection()"> <mat-icon>clear</mat-icon> @@ -116,10 +121,12 @@ import { DialogService } from '../../../../dialog.service'; }) export class SectionMenuComponent implements OnInit, OnDestroy { @Input() section!: UnitPageSection; + @Input() sectionIndex!: number; @Input() allowMoveUp!: boolean; @Input() allowMoveDown!: boolean; @Input() allowDelete!: boolean; @Output() moveSection = new EventEmitter<'up' | 'down'>(); + @Output() duplicateSection = new EventEmitter(); @ViewChild('colorPicker') colorPicker!: ElementRef; columnSizes: { value: string, unit: string }[] = []; @@ -127,6 +134,7 @@ export class SectionMenuComponent implements OnInit, OnDestroy { private ngUnsubscribe = new Subject<void>(); constructor(public unitService: UnitService, + private selectionService: SelectionService, private dialogService: DialogService) { } ngOnInit(): void { @@ -143,6 +151,10 @@ export class SectionMenuComponent implements OnInit, OnDestroy { .subscribe((result: boolean) => { if (result) { this.unitService.deleteSection(this.section); + if (this.sectionIndex === this.selectionService.selectedPageSectionIndex && + this.selectionService.selectedPageSectionIndex > 0) { + this.selectionService.selectedPageSectionIndex -= 1; + } } }); } diff --git a/projects/editor/src/app/unit.service.ts b/projects/editor/src/app/unit.service.ts index 909fa9d816789a0428d1ab791559cb6c7305c1fe..c83d97a82aa478874ed05009cd7e13b626a5baed 100644 --- a/projects/editor/src/app/unit.service.ts +++ b/projects/editor/src/app/unit.service.ts @@ -117,6 +117,18 @@ export class UnitService { } } + duplicateSection(section: UnitPageSection, page: UnitPage, sectionIndex: number): void { + const newSection = { ...section }; + newSection.elements = []; + section.elements.forEach((element: UnitUIElement) => { + const newElement = UnitFactory.createUnitUIElement(element.type); + newSection.elements.push({ ...newElement, ...element, id: this.idService.getNewID(element.type) }); + }); + page.sections.splice(sectionIndex + 1, 0, newSection); + this._unit.next(this._unit.value); + this.veronaApiService.sendVoeDefinitionChangedNotification(); + } + moveSection(section: UnitPageSection, page: UnitPage, direction: 'up' | 'down'): void { UnitService.moveArrayItem(section, page.sections, direction); this._unit.next(this._unit.value);