Skip to content
Snippets Groups Projects
dynamic-section-helper-grid.component.ts 4.89 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { CdkDragDrop } from '@angular/cdk/drag-drop';
    
    import {
    
    rhenck's avatar
    rhenck committed
      Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges
    
    } from '@angular/core';
    
    import { UIElement, UIElementType } from 'common/models/elements/element';
    import { Section } from 'common/models/section';
    
    rhenck's avatar
    rhenck committed
    import { UnitService } from '../../services/unit.service';
    
    
    @Component({
      selector: '[app-dynamic-section-helper-grid]',
      template: `
        <ng-container *ngFor="let column of columnCountArray; let x = index">
          <ng-container *ngFor="let row of rowCountArray; let y = index">
            <div class="grid-placeholder"
                 [style.grid-column-start]="x + 1"
                 [style.grid-column-end]="x + 1"
                 [style.grid-row-start]="y + 1"
                 [style.grid-row-end]="y + 1"
                 cdkDropList [cdkDropListData]="{ sectionIndex: sectionIndex, gridCoordinates: [x + 1, y + 1] }"
    
                 (cdkDropListDropped)="drop($event)"
    
                 id="list-{{sectionIndex}}-{{x+1}}-{{y+1}}"
                 (dragover)="$event.preventDefault()"
                 (drop)="newElementDropped( $event, x + 1, y + 1)">
              {{x + 1}} / {{y + 1}}
            </div>
          </ng-container>
        </ng-container>
    
        <ng-content></ng-content>
      `,
      styles: [
    
    rhenck's avatar
    rhenck committed
        '.grid-placeholder {border: 5px solid aliceblue; color: lightblue; text-align: center; z-index: -100;}'
    
    rhenck's avatar
    rhenck committed
    })
    
    export class DynamicSectionHelperGridComponent implements OnInit, OnChanges {
      @Input() autoColumnSize!: boolean;
      @Input() autoRowSize!: boolean;
    
      @Input() gridColumnSizes!: { value: number; unit: string }[];
      @Input() gridRowSizes!: { value: number; unit: string }[];
    
      @Input() section!: Section;
      @Input() sectionIndex!: number;
      @Output() transferElement = new EventEmitter<{ previousSectionIndex: number, newSectionIndex: number }>();
    
      columnCountArray: unknown[] = [];
      rowCountArray: unknown[] = [];
    
    
    rhenck's avatar
    rhenck committed
      constructor(public unitService: UnitService) {}
    
    
      ngOnInit(): void {
        this.calculateColumnCount();
        this.calculateRowCount();
      }
    
      ngOnChanges(changes: SimpleChanges): void {
    
        if (changes.autoColumnSize || changes.gridColumnSizes || changes.gridRowSizes) {
    
          this.calculateColumnCount();
          this.calculateRowCount();
        }
      }
    
      refresh(): void {
        this.calculateColumnCount();
        this.calculateRowCount();
      }
    
      private calculateColumnCount(): void {
        let numberOfColumns;
        if (this.autoColumnSize) {
          numberOfColumns = this.section.elements
    
            .reduce((accumulator, currentValue) => (
              currentValue.position.gridColumn ?
                Math.max(accumulator, currentValue.position.gridColumn + currentValue.position.gridColumnRange) :
                accumulator
            ),
            0) - 1;
    
        } else {
    
          numberOfColumns = this.gridColumnSizes.length;
    
        }
        this.columnCountArray = Array(Math.max(numberOfColumns, 1));
      }
    
      private calculateRowCount(): void {
        let numberOfRows;
        if (this.autoRowSize) {
          numberOfRows = this.section.elements
    
            .reduce((accumulator, currentValue) => (
              currentValue.position.gridRow ?
                Math.max(accumulator, currentValue.position.gridRow + currentValue.position.gridRowRange) :
                accumulator
            ),
            0) - 1;
    
        } else {
    
          numberOfRows = this.gridRowSizes.length;
    
        }
        this.rowCountArray = Array(Math.max(numberOfRows, 1));
      }
    
    
      drop(event: CdkDragDrop<{ sectionIndex: number; gridCoordinates: number[]; }>): void {
    
        const dragItemData: { dragType: string; element: UIElement; } = event.item.data;
    
        // Move element to other section - handled by parent (page-canvas).
        if (event.previousContainer.data.sectionIndex !== event.container.data.sectionIndex) {
          this.transferElement.emit({
            previousSectionIndex: event.previousContainer.data.sectionIndex,
            newSectionIndex: event.container.data.sectionIndex
          });
        }
        if (dragItemData.dragType === 'move') {
    
          this.unitService.updateElementsPositionProperty(
    
            [event.item.data.element],
    
            event.container.data.gridCoordinates[0]
    
          this.unitService.updateElementsPositionProperty(
    
            [dragItemData.element],
    
            event.container.data.gridCoordinates[1]
    
          );
        } else if (event.item.data.dragType === 'resize') {
    
          this.unitService.updateElementsPositionProperty(
    
            [dragItemData.element],
            'gridColumnEnd',
    
            event.container.data.gridCoordinates[0] + 1
    
          this.unitService.updateElementsPositionProperty(
    
            [dragItemData.element],
            'gridRowEnd',
    
            event.container.data.gridCoordinates[1] + 1
    
          );
        } else {
          throw new Error('Unknown drop event');
        }
      }
    
      newElementDropped(event: DragEvent, gridX: number, gridY: number): void {
        event.preventDefault();
        this.unitService.addElementToSection(
          event.dataTransfer?.getData('elementType') as UIElementType,
          this.section,
          { x: gridX, y: gridY }
        );
      }
    }