File

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

Index

Properties

Properties

columnOrder
columnOrder: string[]
Type : string[]
columnWidths
columnWidths: string[]
Type : string[]
filtering
filtering: FilteringExpressionsTree
Type : FilteringExpressionsTree
paging
paging: literal type
Type : literal type
pinned
pinned: string[]
Type : string[]
pinnedRows
pinnedRows: string[]
Type : string[]
selection
selection: any[]
Type : any[]
shownAttributes
shownAttributes: any[]
Type : any[]
sorting
sorting: ISortingExpression[]
Type : ISortingExpression[]
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 ""