File

src/app/spreadsheet/spreadsheet-components/components/spreadsheet/smart/spreadsheet.component.ts

Implements

OnDestroy

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector spreadsheet
template
<spreadsheet-ui                 [rows]="rows$ | async"
                [columns]="columns$ | async"
                [activeCellPosition]="activeCellPosition$ | async"
                [activeCellValue]="activeCellValue$ | async"
                [activeCellFormGroup]="activeCellFormGroup"
                [cells]="spreadsheetCells$ | async"
                (cellClicked)="cellClick($event)"
                (addRowClicked)="addRow()"
                (addColumnClicked)="addColumn()"></spreadsheet-ui>

Index

Properties
Methods

Constructor

constructor(store: Store, fb: FormBuilder)
Parameters :
Name Type Optional
store Store<any> No
fb FormBuilder No

Methods

addColumn
addColumn()
Returns : void
addRow
addRow()
Returns : void
cellClick
cellClick(index: number)
Parameters :
Name Type Optional Description
index number No

0 based index, left to right, top to bottom

Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void

Properties

activeCellFormGroup
Type : FormGroup
activeCellPosition$
Type : Observable<CellPosition>
activeCellValue$
Type : Observable<CellValue>
columns$
Type : Observable<number>
rows$
Type : Observable<number>
spreadsheetCells$
Type : Observable<Cell[]>
subscriptions
Type : Subscription[]
Default value : []
import { Component, ChangeDetectionStrategy, OnDestroy } from "@angular/core"
import { FormGroup, FormBuilder } from '@angular/forms'
import { Store, select } from '@ngrx/store'

import { Observable, Subscription } from 'rxjs'
import { withLatestFrom, map, filter } from 'rxjs/operators'

import { Cell, CellValue, CellPosition } from '../../../../spreadsheet-data/models/cell.interfaces'
import { cellClicked, activeCellFormValueChange, addRowToSpreadsheet, addColumnToSpreadsheet } from '../../../../spreadsheet-data/actions/spreadsheet.actions'
import { selectAllSpreadsheetCells, selectSpreadsheetRowsCount, selectSpreadsheetColumnsCount, selectSpreadsheetActiveCellPosition } from '../../../../spreadsheet-data/selectors/spreadsheet-ui.selectors'

@Component({
  selector: 'spreadsheet',
  template: `<spreadsheet-ui 
                [rows]="rows$ | async"
                [columns]="columns$ | async"
                [activeCellPosition]="activeCellPosition$ | async"
                [activeCellValue]="activeCellValue$ | async"
                [activeCellFormGroup]="activeCellFormGroup"
                [cells]="spreadsheetCells$ | async"
                (cellClicked)="cellClick($event)"
                (addRowClicked)="addRow()"
                (addColumnClicked)="addColumn()"></spreadsheet-ui>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class SpreadsheetComponent implements OnDestroy {
  rows$: Observable<number>
  columns$: Observable<number>

  spreadsheetCells$: Observable<Cell[]>

  activeCellValue$: Observable<CellValue>
  activeCellPosition$: Observable<CellPosition>

  activeCellFormGroup: FormGroup

  subscriptions: Subscription[] = []

  constructor(private store: Store<any>, private fb: FormBuilder) {
    // Setup Spreadsheet
    this.activeCellPosition$ = store.pipe(
      select(selectSpreadsheetActiveCellPosition)
    )

    this.spreadsheetCells$ = store.pipe(
      select(selectAllSpreadsheetCells)
    )

    this.rows$ = store.pipe(
      select(selectSpreadsheetRowsCount)
    )

    this.columns$ = store.pipe(
      select(selectSpreadsheetColumnsCount)
    )

    this.activeCellValue$ = store.pipe(
      // 1. get cell position
      select(selectSpreadsheetActiveCellPosition),
      // 3. get cell value from spreadsheet
      withLatestFrom(this.spreadsheetCells$),
      map(([cellPosition, cells]) => {
        const cell = cells.filter(cell => cell.position.column == cellPosition.column && cell.position.row == cellPosition.row)

        return cell && cell[0] && cell[0].value ? cell[0].value : ''
      })
    )

    // Setup form
    this.activeCellFormGroup = fb.group({})
    this.activeCellFormGroup.addControl('active_cell', fb.control(''))

    // Update source of truth when data changes from source of truth
    this.subscriptions.push(
      this.activeCellFormGroup.valueChanges.pipe(
        map(form => form.active_cell),
        withLatestFrom(this.activeCellValue$),
        filter(([formCellValue, cellValue]) => formCellValue !== cellValue),
        map(([formCellValue]) => formCellValue)
      ).subscribe(value => store.dispatch(activeCellFormValueChange({value})))
    )

    // Sync form value with truth of source
    this.subscriptions.push(
      this.activeCellValue$.subscribe(value => {
        this.activeCellFormGroup.setValue({'active_cell': value})
      })
    )
  }

  /**
   * @description    Event handler for User clicking a Cell
   *            
   * @param index 0 based index, left to right, top to bottom
   */
  cellClick(index: number) {
    this.store.dispatch(cellClicked({cellIndex: index}))
  }

  /**
   * 
   */
  addRow() {
    this.store.dispatch(addRowToSpreadsheet())
  }

  /**
   * 
   */
  addColumn() {
    this.store.dispatch(addColumnToSpreadsheet())
  }

  /**
   * 
   */
  ngOnDestroy() {
    this.subscriptions.forEach(sub => sub.unsubscribe())
  }
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""