File

libs/rucken/ionic/src/lib/components/entity-list/entity-list.component.ts

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector entity-list
templateUrl entity-list.component.html

Inputs

classes

Type: string[]

Default value: undefined

columns

Type: string[]

Default value: undefined

columnsClasses

Type: { [key: string]: string; }

Default value: undefined

createClass

Default value: btn btn-primary

createTitle
deleteLink

Type: string

Default value: undefined

enableAppendFromGrid

Default value: true

enableCreate

Default value: true

enableDelete

Default value: true

enableUpdate

Default value: true

entityListFooterTemplate

Type: TemplateRef<any>

Default value: undefined

entityListHeaderTemplate

Type: TemplateRef<any>

Default value: undefined

gridCellActionContent

Type: TemplateRef<any>

Default value: undefined

gridCellContent

Type: TemplateRef<any>

Default value: undefined

gridCellTemplate

Type: TemplateRef<any>

Default value: undefined

gridCellTranslatedContent

Type: TemplateRef<any>

Default value: undefined

gridFieldActionContent

Type: TemplateRef<any>

Default value: undefined

gridFieldContent

Type: TemplateRef<any>

Default value: undefined

itemLabelTemplate

Type: TemplateRef<any>

Default value: undefined

items

Type: TModel[]

Default value: undefined

multiSelectColumns

Type: string[]

Default value: undefined

orderBy

Type: string

Default value: undefined

orderColumns

Type: string[]

Default value: undefined

paginationMeta

Type: PaginationMeta

Default value: undefined

processing

Type: boolean

Default value: undefined

readonly

Type: boolean

Default value: undefined

searchField

Type: FormControl

searchFieldTemplate

Type: TemplateRef<any>

Default value: undefined

selectFirst

Type: boolean

Default value: undefined

showSearchField

Default value: false

strings

Type: any

Default value: undefined

title

Type: string

Default value: undefined

translatedCells

Type: string[]

updateLink

Type: string

Default value: undefined

viewLink

Type: string

Default value: undefined

Outputs

appendFromGrid $event type: EventEmitter<boolean>
changeOrder $event type: EventEmitter<string>
changePage $event type: EventEmitter<{ page: number; itemsPerPage: number; }>
create $event type: EventEmitter<boolean>
dblClick $event type: EventEmitter<TModel>
delete $event type: EventEmitter<TModel>
nextPage $event type: EventEmitter<boolean>
search $event type: EventEmitter<string>
selected $event type: EventEmitter<TModel[]>
update $event type: EventEmitter<TModel>
view $event type: EventEmitter<TModel>

Constructor

constructor(_viewContainerRef: ViewContainerRef, _loadingController: LoadingController, _translateService: TranslateService)

Methods

calcProcessing
calcProcessing()
Returns: void
calcEnableOnlyUpdateOrDelete
calcEnableOnlyUpdateOrDelete()
Returns: void
calcEnableUpdateAndDelete
calcEnableUpdateAndDelete()
Returns: void
calcEnableAppendFromGrid
calcEnableAppendFromGrid()
Returns: void
calcEnableCreate
calcEnableCreate()
Returns: void
calcEnableDelete
calcEnableDelete()
Returns: void
calcEnableUpdate
calcEnableUpdate()
Returns: void
setColumns
setColumns(columns: string[])
Returns: void
setItems
setItems(items: TModel[])
Returns: void
calcParent
calcParent()
Returns: any
onChangeOrder
onChangeOrder(column: string)
Returns: void
onChangePage
onChangePage(meta: { page: number; itemsPerPage: number; })
Returns: void
onRefresh
onRefresh(event: any)
Returns: void
onNextPage
onNextPage(event: any)
Returns: void
onSearch
onSearch(text: string)
Returns: void
onDelete
onDelete(item: TModel, callback: () => void)
Returns: void
onUpdate
onUpdate(item: TModel, callback: () => void)
Returns: void
onCreate
onCreate()
Returns: void
onView
onView(item: TModel, callback: () => void)
Returns: void
onDblClick
onDblClick(item: TModel)
Returns: void
onAppendFromGrid
onAppendFromGrid()
Returns: void
clearSelected
clearSelected()
Returns: void
onSelected
onSelected(items: TModel[])
Returns: void
trackByFn
trackByFn(index: any, item: { id: any; })
Returns: void
isSelected
isSelected(item: TModel)
Returns: void
toggle
toggle(item: TModel, col: string)
Returns: void
isAllSelected
isAllSelected()
Returns: void
masterToggle
masterToggle()
Returns: void

Properties

Private _processingModal
_processingModal: any
Default value: undefined
Private _refresher
_refresher: any
Default value: undefined
Private _selected
_selected: TModel[]
Default value: undefined
defaultEntityListFooterTemplate
defaultEntityListFooterTemplate: TemplateRef<any>
defaultEntityListHeaderTemplate
defaultEntityListHeaderTemplate: TemplateRef<any>
defaultGridCellActionContent
defaultGridCellActionContent: TemplateRef<any>
defaultGridCellContent
defaultGridCellContent: TemplateRef<any>
defaultGridCellTemplate
defaultGridCellTemplate: TemplateRef<any>
defaultGridCellTranslatedContent
defaultGridCellTranslatedContent: TemplateRef<any>
defaultGridFieldActionContent
defaultGridFieldActionContent: TemplateRef<any>
defaultGridFieldContent
defaultGridFieldContent: TemplateRef<any>
defaultItemLabelTemplate
defaultItemLabelTemplate: TemplateRef<any>
defaultSearchFieldTemplate
defaultSearchFieldTemplate: TemplateRef<any>
enableOnlyUpdateOrDelete
enableOnlyUpdateOrDelete: boolean
Default value: undefined
enableOnlyUpdateOrDelete$
enableOnlyUpdateOrDelete$: Observable<boolean>
enableUpdateAndDelete
enableUpdateAndDelete: boolean
Default value: undefined
enableUpdateAndDelete$
enableUpdateAndDelete$: Observable<boolean>
filteredItems
filteredItems: TModel[]
Default value: undefined
filteredItems$
filteredItems$: Observable<TModel[]>
filtredColumns
filtredColumns: string[]
Default value: undefined
filtredColumns$
filtredColumns$: Observable<string[]>
notReadonlyAndEnableCreate
notReadonlyAndEnableCreate: boolean
Default value: undefined
notReadonlyAndEnableCreate$
notReadonlyAndEnableCreate$: Observable<boolean>
notReadonlyAndEnableDelete
notReadonlyAndEnableDelete: boolean
Default value: undefined
notReadonlyAndEnableDelete$
notReadonlyAndEnableDelete$: Observable<boolean>
notReadonlyAndEnableUpdate
notReadonlyAndEnableUpdate: boolean
Default value: undefined
notReadonlyAndEnableUpdate$
notReadonlyAndEnableUpdate$: Observable<boolean>
parent
parent: any
Default value: undefined
parent$
parent$: Observable<any>
import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, Input, isDevMode, OnChanges, Output, SimpleChanges, TemplateRef, ViewContainerRef } from '@angular/core';
import { FormControl } from '@angular/forms';
import { LoadingController } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
import { translate } from '@rucken/core';
import { BindObservable } from 'bind-observable';
import { BindIoInner } from 'ngx-bind-io';
import { IModel, PaginationMeta } from 'ngx-repository';
import { Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

@BindIoInner()
@Component({
  selector: 'entity-list',
  templateUrl: './entity-list.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class EntityListComponent<TModel extends IModel> implements OnChanges {

  @ContentChild('#defaultItemLabelTemplate')
  defaultItemLabelTemplate: TemplateRef<any>;
  @Input()
  itemLabelTemplate: TemplateRef<any> = undefined;

  @ContentChild('#defaultGridFieldContent')
  defaultGridFieldContent: TemplateRef<any>;
  @Input()
  gridFieldContent: TemplateRef<any> = undefined;

  @ContentChild('#defaultGridCellContent')
  defaultGridCellContent: TemplateRef<any>;
  @Input()
  gridCellContent: TemplateRef<any> = undefined;

  @ContentChild('#defaultEntityListHeaderTemplate')
  defaultEntityListHeaderTemplate: TemplateRef<any>;
  @Input()
  entityListHeaderTemplate: TemplateRef<any> = undefined;

  @ContentChild('#defaultEntityListFooterTemplate')
  defaultEntityListFooterTemplate: TemplateRef<any>;
  @Input()
  entityListFooterTemplate: TemplateRef<any> = undefined;

  @ContentChild('#defaultSearchFieldTemplate')
  defaultSearchFieldTemplate: TemplateRef<any>;
  @Input()
  searchFieldTemplate: TemplateRef<any> = undefined;

  @ContentChild('#defaultGridCellActionContent')
  defaultGridCellActionContent: TemplateRef<any>;
  @Input()
  gridCellActionContent: TemplateRef<any> = undefined;

  @ContentChild('#defaultGridCellTranslatedContent')
  defaultGridCellTranslatedContent: TemplateRef<any>;
  @Input()
  gridCellTranslatedContent: TemplateRef<any> = undefined;

  @ContentChild('#defaultGridFieldActionContent')
  defaultGridFieldActionContent: TemplateRef<any>;
  @Input()
  gridFieldActionContent: TemplateRef<any> = undefined;

  @ContentChild('#defaultGridCellTemplate')
  defaultGridCellTemplate: TemplateRef<any>;
  @Input()
  gridCellTemplate: TemplateRef<any> = undefined;

  @Input()
  viewLink: string = undefined;
  @Input()
  updateLink: string = undefined;
  @Input()
  deleteLink: string = undefined;

  @Input()
  showSearchField = false;
  @Input()
  selectFirst?: boolean = undefined;
  @Input()
  processing: boolean = undefined;
  @Input()
  searchField: FormControl = new FormControl();
  @Input()
  title: string = undefined;
  @Input()
  createTitle = translate('Create');
  @Input()
  createClass = 'btn btn-primary';
  @Input()
  translatedCells: string[] = [];
  @Input()
  orderColumns: string[] = undefined;
  @Input()
  columnsClasses: { [key: string]: string } = undefined;
  @Input()
  orderBy: string = undefined;
  @Input()
  multiSelectColumns: string[] = undefined;

  @Input()
  columns: string[] = undefined;
  @Input()
  classes: string[] = undefined;
  @Input()
  strings: any = undefined;
  @Input()
  items: TModel[] = undefined;

  @Output()
  delete: EventEmitter<TModel> = new EventEmitter<TModel>();
  @Output()
  create: EventEmitter<boolean> = new EventEmitter<boolean>();
  @Output()
  view: EventEmitter<TModel> = new EventEmitter<TModel>();
  @Output()
  update: EventEmitter<TModel> = new EventEmitter<TModel>();
  @Output()
  dblClick: EventEmitter<TModel> = new EventEmitter<TModel>();
  @Output()
  search: EventEmitter<string> = new EventEmitter<string>();
  @Output()
  changeOrder: EventEmitter<string> = new EventEmitter<string>();
  @Output()
  appendFromGrid: EventEmitter<boolean> = new EventEmitter<boolean>();
  @Output()
  selected: EventEmitter<TModel[]> = new EventEmitter<TModel[]>();
  @Output()
  changePage: EventEmitter<{
    page: number;
    itemsPerPage: number;
  }> = new EventEmitter<{ page: number; itemsPerPage: number }>();
  @Output()
  nextPage: EventEmitter<boolean> = new EventEmitter<boolean>();

  @Input()
  readonly: boolean = undefined;
  @Input()
  enableCreate = true;
  @Input()
  enableUpdate = true;
  @Input()
  enableDelete = true;
  @Input()
  enableAppendFromGrid = true;
  @Input()
  paginationMeta: PaginationMeta = undefined;

  @BindObservable()
  parent: any = undefined;
  parent$: Observable<any>;
  @BindObservable()
  filteredItems: TModel[] = undefined;
  filteredItems$: Observable<TModel[]>;
  @BindObservable()
  filtredColumns: string[] = undefined;
  filtredColumns$: Observable<string[]>;
  @BindObservable()
  enableOnlyUpdateOrDelete: boolean = undefined;
  enableOnlyUpdateOrDelete$: Observable<boolean>;
  @BindObservable()
  enableUpdateAndDelete: boolean = undefined;
  enableUpdateAndDelete$: Observable<boolean>;
  @BindObservable()
  notReadonlyAndEnableCreate: boolean = undefined;
  notReadonlyAndEnableCreate$: Observable<boolean>;
  @BindObservable()
  notReadonlyAndEnableDelete: boolean = undefined;
  notReadonlyAndEnableDelete$: Observable<boolean>;
  @BindObservable()
  notReadonlyAndEnableUpdate: boolean = undefined;
  notReadonlyAndEnableUpdate$: Observable<boolean>;

  private _refresher: any = undefined;
  private _processingModal: any = undefined;
  private _selected: TModel[] = undefined;

  constructor(
    private _viewContainerRef: ViewContainerRef,
    private _loadingController: LoadingController,
    private _translateService: TranslateService
  ) {
    this.searchField.valueChanges
      .pipe(
        debounceTime(400),
        distinctUntilChanged()
      )
      .subscribe(value => this.onSearch(value));
  }
  ngOnChanges(changes: SimpleChanges) {
    this.calcParent();
    this.calcEnableCreate();
    this.calcEnableDelete();
    this.calcEnableUpdate();
    this.calcEnableOnlyUpdateOrDelete();
    this.calcEnableUpdateAndDelete();
    this.calcEnableAppendFromGrid();
    if (changes.processing) {
      this.calcProcessing();
    }
    if (changes.columns || changes.readonly || changes.enableDelete || changes.enableUpdate) {
      this.setColumns(this.columns);
    }
    if (changes.items) {
      this.setItems(this.items);
    }
  }
  calcProcessing() {
    if (this._processingModal !== null) {
      if (this._processingModal === undefined) {
        this._processingModal = null;
        if (this.processing) {
          this._loadingController.create({
            message: this._translateService.instant('Loading...')
          }).then(element => {
            element.present().then(_ => {
              this._processingModal = element;
              if (this.processing === false) {
                this.processing = false;
                this.calcProcessing();
              }
            });
          });
        }
      } else {
        if (!this.processing) {
          this._processingModal.dismiss().then(() => {
            this._processingModal = undefined;
          });
        }
      }
    }
  }
  calcEnableOnlyUpdateOrDelete() {
    this.enableOnlyUpdateOrDelete =
      (
        this.notReadonlyAndEnableDelete &&
        !this.notReadonlyAndEnableUpdate
      ) || (
        !this.notReadonlyAndEnableDelete &&
        this.notReadonlyAndEnableUpdate
      );
  }
  calcEnableUpdateAndDelete() {
    this.enableUpdateAndDelete =
      this.notReadonlyAndEnableDelete &&
      this.notReadonlyAndEnableUpdate;
  }
  calcEnableAppendFromGrid() {
    this.enableAppendFromGrid = !this.readonly && this.enableAppendFromGrid;
  }
  calcEnableCreate() {
    this.notReadonlyAndEnableCreate = !this.readonly && this.enableCreate;
  }
  calcEnableDelete() {
    this.notReadonlyAndEnableDelete = !this.readonly && this.enableDelete;
  }
  calcEnableUpdate() {
    this.notReadonlyAndEnableUpdate = !this.readonly && this.enableUpdate;
  }
  setColumns(columns: string[]) {
    this.filtredColumns =
      (columns || []).filter(column =>
        column === 'action'
          ? (
            this.readonly === true || (
              !this.readonly &&
              !this.enableDelete &&
              !this.enableUpdate
            )
              ? false
              : true
          )
          : true
      );
  }
  setItems(items: TModel[]) {
    this.filteredItems = items;
    if (
      this.selectFirst !== false &&
      items &&
      items.length &&
      items.filter(item => this._selected && this._selected.length && this._selected[0].id === item.id).length === 0
    ) {
      this.onSelected([]);
    }
    if (this._refresher && this._refresher.target) {
      this._refresher.target.complete();
    }
  }
  calcParent(): any {
    if (this._viewContainerRef) {
      this.parent = this._viewContainerRef['_view'].component;
    }
  }
  onChangeOrder(column: string) {
    if (this.orderBy === `${column}`) {
      this.orderBy = `-${column}`;
    } else {
      this.orderBy = `${column}`;
    }
    this.changeOrder.emit(this.orderBy);
  }
  onChangePage(meta: { page: number; itemsPerPage: number }) {
    if (isDevMode() && this.changePage.observers.length === 0) {
      console.warn('No subscribers found for "onChangePage"', this.parent);
    }
    this.changePage.emit(meta);
  }
  onRefresh(event) {
    this._refresher = event;
    this.onSearch(this.searchField.value);
  }
  onNextPage(event) {
    if (isDevMode() && this.changePage.observers.length === 0) {
      console.warn('No subscribers found for "onNextPage"', this.parent);
    }
    if (event.target && event.target.complete) {
      if (this.paginationMeta.totalResults > this.items.length) {
        setTimeout(
          () =>
            event.target.complete()
          ,
          700
        );
        this.nextPage.emit(true);
      } else {
        event.target.complete();
      }
    }
  }
  onSearch(text: string) {
    if (isDevMode() && this.search.observers.length === 0) {
      console.warn('No subscribers found for "search"', this.parent);
    }
    this.search.emit(text);
  }
  onDelete(item: TModel, callback?: () => void) {
    if (isDevMode() && !this.notReadonlyAndEnableDelete) {
      console.warn('Delete action is disabled', this.parent);
    }
    if (isDevMode() && this.delete.observers.length === 0) {
      console.warn('No subscribers found for "delete"', this.parent);
    }
    if (callback) {
      setTimeout(() => callback(), 700);
    }
    this.delete.emit(item);
  }
  onUpdate(item: TModel, callback?: () => void) {
    if (isDevMode() && !this.notReadonlyAndEnableUpdate) {
      console.warn('Update action is disabled', this.parent);
    }
    if (isDevMode() && this.update.observers.length === 0) {
      console.warn('No subscribers found for "update"', this.parent);
    }
    if (callback) {
      setTimeout(() => callback(), 700);
    }
    this.update.emit(item);
  }
  onCreate() {
    if (isDevMode() && !this.notReadonlyAndEnableCreate) {
      console.warn('Create action is disabled', this.parent);
    }
    if (isDevMode() && this.create.observers.length === 0) {
      console.warn('No subscribers found for "create"', this.parent);
    }
    this.create.emit();
  }
  onView(item: TModel, callback?: () => void) {
    if (isDevMode() && this.view.observers.length === 0) {
      console.warn('No subscribers found for "view"', this.parent);
    }
    if (callback) {
      setTimeout(() => callback(), 700);
    }
    this.view.emit(item);
  }
  onDblClick(item: TModel) {
    if (this.dblClick.observers.length > 0) {
      this.dblClick.emit(item);
    } else {
      if (isDevMode() && this.dblClick.observers.length === 0) {
        console.warn('No subscribers found for "dblClick"', this.parent);
      }
      if (this.readonly === true || !this.notReadonlyAndEnableUpdate) {
        if (isDevMode() && this.dblClick.observers.length === 0) {
          console.warn('Try call "view" for "dblClick"', this.parent);
        }
        this.onView(item);
      } else {
        if (isDevMode() && this.dblClick.observers.length === 0) {
          console.warn('Try call "update" for "dblClick"', this.parent);
        }
        this.onUpdate(item);
      }
    }
  }
  onAppendFromGrid() {
    if (isDevMode() && !this.enableAppendFromGrid) {
      console.warn('Append from grid action is disabled', this.parent);
    }
    if (isDevMode() && this.appendFromGrid.observers.length === 0) {
      console.warn('No subscribers found for "appendFromGrid"', this.parent);
    }
    this.appendFromGrid.emit(true);
  }
  clearSelected() {
    this._selected = [];
  }
  onSelected(items: TModel[]) {
    if (this.selectFirst !== false && items && items.length === 0 && this.items && this.items.length) {
      items = [this.items[0]];
    }
    this._selected = items;
    if (this.selected) {
      this.selected.emit(items);
    }
  }
  trackByFn(index: any, item: { id: any; }) {
    return item.id;
  }
  isSelected(item: TModel) {
    const index = this._selected.findIndex(eachItem => eachItem && item && eachItem.id === item.id);
    return index !== -1;
  }
  toggle(item: TModel, col: string) {
    if (!this.multiSelectColumns || this.multiSelectColumns.indexOf(col) === -1) {
      this._selected = [];
    }
    const selected = this._selected ? this._selected : [];
    const index = selected.findIndex(eachItem => eachItem && item && eachItem.id === item.id);
    if (index === -1) {
      selected.push(item);
    } else {
      selected.splice(index, 1);
    }
    this.onSelected(selected);
  }
  isAllSelected() {
    const numSelected = this._selected ? this._selected.length : -1;
    const numRows = this.items ? this.items.length : 0;
    return numSelected === numRows;
  }
  masterToggle() {
    let selected = this._selected;
    if (this.isAllSelected()) {
      selected = [];
    } else {
      selected = [...this.items];
    }
    this.onSelected(selected);
  }
}

results matching ""

    No results matching ""