File

src/app/shared/widgets/data-list/data-list-state.directive.ts

Implements

AfterViewInit OnChanges OnDestroy

Metadata

selector [statefulDataList]

Index

Widget inputs
Widget outputs
Properties
Methods
Inputs
Outputs
HostListeners

Constructor

constructor(grid: IgxGridComponent, hgrid: IgxHierarchicalGridComponent, tgrid: IgxTreeGridComponent, _localStorageService: LocalStorageService)
Parameters :
Name Type Optional
grid IgxGridComponent no
hgrid IgxHierarchicalGridComponent no
tgrid IgxTreeGridComponent no
_localStorageService LocalStorageService no

Inputs

dataList

Type: DataListComponent

storingEnabled

Type: boolean

Default value: false

tableIdentifier

Type: string

Outputs

columnOrderChanged $event type: EventEmitter<any>

HostListeners

columnMovingEnd
Arguments : '$event'
columnMovingEnd(event: )
columnPinning
Arguments : '$event'
columnPinning(event: )
columnResized
Arguments : '$event'
columnResized(event: )
filteringDone
Arguments : '$event'
filteringDone(event: )
onRowPinning
Arguments : '$event'
onRowPinning(event: )
pagingDone
Arguments : '$event'
pagingDone(event: )
rowSelected
Arguments : '$event'
rowSelected(event: )
sortingDone
Arguments : '$event'
sortingDone(event: )

Methods

Public clearStorage
clearStorage()
Returns : void
Public getStoredState
getStoredState(action: string)
Parameters :
Name Type Optional
action string no
Returns : any
Public loadGridState
loadGridState()
Returns : GridState
Public ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges no
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
Public restoreFiltering
restoreFiltering(gridState: GridState)
Parameters :
Name Type Optional Default value
gridState GridState no this.loadGridState()
Returns : void
Public restoreGridState
restoreGridState()
Returns : void
Public storeOrder
storeOrder(sortedColumns: string[])
Parameters :
Name Type Optional
sortedColumns string[] no
Returns : void
Public storeState
storeState(action: string, args: any)
Parameters :
Name Type Optional
action string no
args any no
Returns : void
Public toggleAction
toggleAction(checked: boolean, action: string)
Parameters :
Name Type Optional
checked boolean no
action string no
Returns : void

Properties

Public _localStorageService
_localStorageService: LocalStorageService
Type : LocalStorageService
Public columnFilterInput
columnFilterInput: any
Type : any
Default value : {}
Public columnOrder
columnOrder:
Default value : true
Public columnWidths
columnWidths:
Default value : true
Public columnWidthsList
columnWidthsList: any
Type : any
Default value : {}
Public filtering
filtering:
Default value : false
Public grid
grid: IgxGridComponent
Type : IgxGridComponent
Decorators : HostSelfOptional
Public gridComponent
gridComponent: IgxGridComponent | IgxHierarchicalGridComponent | IgxTreeGridComponent
Type : IgxGridComponent | IgxHierarchicalGridComponent | IgxTreeGridComponent
Public hgrid
hgrid: IgxHierarchicalGridComponent
Type : IgxHierarchicalGridComponent
Decorators : HostSelfOptional
Public initialState
initialState: GridState
Type : GridState
Default value : { filtering: new FilteringExpressionsTree(0), paging: { index: 0, recordsPerPage: this.perPage }, selection: [], sorting: [], pinned: [], columnWidths: [], pinnedRows: [], columnOrder: [], shownAttributes: [], }
Public paging
paging:
Default value : true
Public perPage
perPage: number
Type : number
Default value : 15
Public pinned
pinned: any[]
Type : any[]
Default value : []
Public pinnedRows
pinnedRows: any[]
Type : any[]
Default value : []
Public pinning
pinning:
Default value : true
Public rowPinning
rowPinning:
Default value : true
Public selection
selection:
Default value : false
Public shownAttributes
shownAttributes:
Default value : true
Public sorting
sorting:
Default value : true
Public tgrid
tgrid: IgxTreeGridComponent
Type : IgxTreeGridComponent
Decorators : HostSelfOptional
Private unsubscribe
unsubscribe:
Default value : NgUnsubscribe.create()
import {
  AfterViewInit,
  Directive,
  EventEmitter,
  Host,
  HostListener,
  Input,
  OnChanges,
  OnDestroy,
  Optional,
  Output,
  Self,
  SimpleChanges,
} from "@angular/core";
import {
  DefaultSortingStrategy,
  FilteringExpressionsTree,
  IFilteringExpression,
  IgxGridBaseDirective,
  IgxGridComponent,
  IgxHierarchicalGridComponent,
  IgxTreeGridComponent,
  ISortingExpression,
} from "@infragistics/igniteui-angular";
import { LocalStorageService } from "../../components/local-storage/local-storage.service";
import {
  DeletionMode,
  Scope,
} from "../../components/local-storage/local-storage-constants";
import { DataListComponent } from "./data-list-component/data-list.component";
import { NgUnsubscribe } from "../../ng-unsubscribe";
import { takeUntil } from "rxjs/operators";

interface GridState {
  paging: { index: number; recordsPerPage: number };
  selection: any[];
  filtering: FilteringExpressionsTree;
  sorting: ISortingExpression[];
  pinned: string[];
  columnWidths: string[];
  pinnedRows: string[];
  columnOrder: string[];
  shownAttributes: any[];
}

@Directive({
  selector: "[statefulDataList]",
})
export class DataListStateDirective
  implements AfterViewInit, OnChanges, OnDestroy
{
  private unsubscribe = NgUnsubscribe.create();

  @Input() tableIdentifier: string;
  @Input() storingEnabled: boolean = false;
  @Input() dataList: DataListComponent;

  @Output() columnOrderChanged: EventEmitter<any> = new EventEmitter();

  public perPage = 15;
  public selection = false;
  public filtering = false;
  public paging = true;
  public sorting = true;
  public pinning = true;
  public columnWidths = true;
  public rowPinning = true;
  public columnOrder = true;
  public shownAttributes = true;

  public columnFilterInput: any = {};
  public columnWidthsList: any = {};
  public pinned: any[] = [];
  public pinnedRows: any[] = [];
  public gridComponent:
    | IgxGridComponent
    | IgxHierarchicalGridComponent
    | IgxTreeGridComponent;

  public initialState: GridState = {
    filtering: new FilteringExpressionsTree(0),
    paging: { index: 0, recordsPerPage: this.perPage },
    selection: [],
    sorting: [],
    pinned: [],
    columnWidths: [],
    pinnedRows: [],
    columnOrder: [],
    shownAttributes: [],
  };

  constructor(
    @Host() @Self() @Optional() public grid: IgxGridComponent,
    @Host() @Self() @Optional() public hgrid: IgxHierarchicalGridComponent,
    @Host() @Self() @Optional() public tgrid: IgxTreeGridComponent,
    public _localStorageService: LocalStorageService
  ) {}

  public ngAfterViewInit() {
    if (this.grid) {
      this.gridComponent = this.grid;
    } else if (this.hgrid) {
      this.gridComponent = this.hgrid;
    } else if (this.tgrid) {
      this.gridComponent = this.tgrid;
    }
    this.restoreGridState();

    this.dataList.shownAttributesOutput
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((shownAttributes) => {
        const state = { shownAttributes };
        this.storeState("shownAttributes", state);
      });
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes.tableIdentifier && this.shownAttributes) {
      const gridState = this.loadGridState();
      this.dataList.updateDynamicColumns(gridState.shownAttributes || []);
    }
  }

  @HostListener("pagingDone", ["$event"])
  public onPagingDone(event) {
    setTimeout(() => {
      const state = { paging: this.gridComponent.pagingState };
      this.storeState("paging", state);
    });
  }

  @HostListener("sortingDone", ["$event"])
  public onSortingDone(event) {
    const state = { sorting: this.gridComponent.sortingExpressions };
    this.storeState("sorting", state);
  }

  @HostListener("rowSelected", ["$event"])
  public rowSelected(event) {
    const state = { selection: event.newSelection };
    this.storeState("selection", state);
  }

  @HostListener("filteringDone", ["$event"])
  public onFilteringDone(event) {
    const state = { filtering: this.gridComponent.filteringExpressionsTree };
    this.storeState("filtering", state);
  }

  @HostListener("columnResized", ["$event"])
  public onColumnResized(event) {
    if (event.newWidth) {
      this.columnWidthsList[event.column.field] = event.newWidth;
    }

    const state = { columnWidths: this.columnWidthsList };
    this.storeState("columnWidths", state);
  }

  @HostListener("columnPinning", ["$event"])
  public onColumnPinning(event) {
    if (event.isPinned) {
      this.pinned.push(event.column.field);
    } else {
      this.pinned.splice(this.pinned.indexOf(event.column.field), 1);
    }
    const state = { pinned: this.pinned };
    this.storeState("pinned", state);
  }

  @HostListener("columnMovingEnd", ["$event"])
  public onColumnMovingEnd(event) {
    if (this.storingEnabled) {
      this.storeOrder(
        this.gridComponent.columns
          .sort((a, b) => a.visibleIndex - b.visibleIndex)
          .map((a) => a.field)
      );
    }
  }

  @HostListener("onRowPinning", ["$event"])
  public onRowPinning(event) {
    if (event.isPinned) {
      this.pinnedRows.push(event.rowID);
    } else {
      this.pinnedRows.splice(this.pinnedRows.indexOf(event.rowID), 1);
    }
    const state = { pinnedRows: this.pinnedRows };
    this.storeState("pinnedRows", state);
  }

  public loadGridState(): GridState {
    const gridState = Object.assign({}, this.initialState);
    for (const propt in gridState) {
      if ((gridState as any).hasOwnProperty(propt)) {
        gridState[propt] = this.getStoredState(propt);
      }
    }

    return gridState;
  }

  public storeOrder(sortedColumns: string[]) {
    const state = { columnOrder: sortedColumns };
    this.storeState("columnOrder", state);
  }

  public restoreGridState() {
    this.storingEnabled = true;
    const gridState = this.loadGridState();

    //restore filtering
    this.restoreFiltering(gridState);

    // restore column Order
    if (this.columnOrder && gridState.columnOrder) {
      this.columnOrderChanged.emit(gridState.columnOrder);
    }

    // restore paging
    if (this.paging && gridState.paging) {
      if (this.gridComponent.perPage !== gridState.paging.recordsPerPage) {
        this.gridComponent.perPage = gridState.paging.recordsPerPage;
      }
      if (this.gridComponent.page !== gridState.paging.index) {
        this.gridComponent.paginate(gridState.paging.index);
      }
    }

    // restore sorting
    if (this.sorting && gridState.sorting) {
      const strategy = DefaultSortingStrategy.instance();
      gridState.sorting.forEach((expr) => (expr.strategy = strategy));
      this.gridComponent.sortingExpressions = gridState.sorting;
    }

    // restore selection
    if (this.selection && gridState.selection) {
      this.gridComponent.selectRows(gridState.selection);
    }

    // restore pinning
    if (this.pinning && gridState.pinned) {
      gridState.pinned.forEach((pinnedColumn) => {
        if (this.gridComponent.getColumnByName(pinnedColumn)) {
          this.gridComponent.pinColumn(pinnedColumn);
        }
      });
    }

    // restore columnWidths
    if (this.columnWidths && gridState.columnWidths) {
      for (let column in gridState.columnWidths) {
        if (gridState.columnWidths.hasOwnProperty(column)) {
          if (this.gridComponent.getColumnByName(column)) {
            this.gridComponent.getColumnByName(column).width =
              gridState.columnWidths[column];
          }
        }
      }
    }

    this.gridComponent.cdr.markForCheck();
  }

  public storeState(action: string, args: any) {
    if (this[action]) {
      const storageEntry = this._localStorageService.getLocalStorageEntry(
        this.tableIdentifier + "-" + action,
        Scope.USER_AND_CLIENT,
        DeletionMode.NEVER
      );
      storageEntry.value = JSON.stringify(args);
    }
  }

  public getStoredState(action: string): any {
    const storageEntry = this._localStorageService.getLocalStorageEntry(
      this.tableIdentifier + "-" + action,
      Scope.USER_AND_CLIENT,
      DeletionMode.NEVER
    );

    if (storageEntry.exists() && storageEntry.value != undefined) {
      const item = JSON.parse(storageEntry.value);
      return item ? item[action] : null;
    }

    return null;
  }

  public toggleAction(checked: boolean, action: string) {
    window.localStorage.removeItem(action);
    // if we want to restore paging, it makes sense to work over the same data set
    // therefore we need to reapply filtering as wel
    if (checked) {
      this.filtering = true;
    }
  }

  public clearStorage() {
    this.columnFilterInput = {};

    const gridState: any = this.loadGridState();
    for (const propt in gridState) {
      if (gridState.hasOwnProperty(propt)) {
        const storageEntry = this._localStorageService.getLocalStorageEntry(
          this.tableIdentifier + "-" + propt,
          Scope.USER_AND_CLIENT,
          DeletionMode.NEVER
        );

        storageEntry.clear();
      }
    }
  }

  public restoreFiltering(gridState: GridState = this.loadGridState()) {
    if (!this.filtering || !gridState.filtering) {
      return;
    }
    const gridFilteringExpressionsTree = new FilteringExpressionsTree(
      gridState.filtering.operator
    );

    for (const f of gridState.filtering.filteringOperands) {
      const filtOperand = f as FilteringExpressionsTree;
      const column = this.gridComponent.columns.filter(
        (col) => col.field === filtOperand.fieldName
      )[0];

      if (!column) {
        break;
      }

      const columnFilteringExpressionsTree = new FilteringExpressionsTree(
        filtOperand.operator,
        filtOperand.fieldName
      );

      let columnsFiltOperands = filtOperand.filteringOperands[0] as any;
      if (Array.isArray(columnsFiltOperands.filteringOperands)) {
        columnsFiltOperands = columnsFiltOperands.filteringOperands;
      } else {
        columnsFiltOperands = [columnsFiltOperands];
      }

      for (const fo of columnsFiltOperands) {
        const columnFiltOperand = fo as IFilteringExpression;
        columnFiltOperand.condition = column.filters.condition(
          columnFiltOperand.condition.name
        );

        if (!columnFiltOperand.condition) {
          continue;
        }

        columnFilteringExpressionsTree.filteringOperands.push(
          columnFiltOperand
        );
        if (
          columnFiltOperand.condition.name === "contains" ||
          columnFiltOperand.condition.name === "object"
        ) {
          this.columnFilterInput[columnFiltOperand.fieldName] =
            columnFiltOperand.searchVal;
        }
      }

      gridFilteringExpressionsTree.filteringOperands.push(
        columnFilteringExpressionsTree
      );
    }

    gridFilteringExpressionsTree.filteringOperands =
      gridFilteringExpressionsTree.filteringOperands.filter(
        (columnFilteringOperands: FilteringExpressionsTree) =>
          columnFilteringOperands.filteringOperands.length > 0
      );
    this.gridComponent.filteringExpressionsTree = gridFilteringExpressionsTree;

    // restore row pinning
    if (this.rowPinning && gridState.pinnedRows) {
      gridState.pinnedRows.forEach((pinnedRow) => {
        if (this.gridComponent.getRowByKey(pinnedRow)) {
          this.grid.pinRow(pinnedRow);
        }
      });
    }
  }

  ngOnDestroy() {
    this.unsubscribe.destroy();
  }
}

results matching ""

    No results matching ""