<commit_before>import { EventEmitter, Input, isDevMode, Output } from '@angular/core';
import { ErrorsExtractor, translate } from '@rucken/core';
import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
import { IFactoryModel, IMockProviderOptions, IModel, IPaginationMeta, IRestProviderOptions, Repository } from 'ngx-repository';
import { BehaviorSubject, forkJoin, Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { IBaseEntityListModal } from '../base/base-entity-list-modal.interface';
import { IEntityGridFilter } from '../components/entity-grid/entity-grid-filter.interface';
import { EntityModalComponent } from '../components/entity-modal/entity-modal.component';
import { MessageModalService } from '../modals/message-modal/message-modal.service';
import { IBaseEntityList } from './base-entity-list.interface';
import { IBaseEntityModalOptions, IBaseEntityModals } from './base-entity-modals.interface';

export class BaseEntityListComponent<TModel extends IModel>
  implements IBaseEntityList<TModel>, IBaseEntityModals {
  @Input()
  modalItem: IBaseEntityModalOptions = {};
  @Input()
  modalDelete: IBaseEntityModalOptions = {};
  @Input()
  modalCreate: IBaseEntityModalOptions = {};
  @Input()
  modalUpdate: IBaseEntityModalOptions = {};
  @Input()
  modalView: IBaseEntityModalOptions = {};
  @Input()
  modalAppendFromGrid: IBaseEntityModalOptions = {};
  @Input()
  set processing(value: boolean) {
    this.processing$.next(value);
  }
  get processing() {
    return this.processing$.getValue();
  }
  processing$ = new BehaviorSubject(false);
  @Input()
  apiUrl?: string;
  @Input()
  set mockedItems(items: TModel[]) {
    this._mockedItems = items;
  }
  get mockedItems() {
    return this._mockedItems;
  }
  @Output()
  mockedItemsChange: EventEmitter<TModel[]> = new EventEmitter<TModel[]>();
  @Input()
  strings: {
    viewTitle?: string;
    createTitle?: string;
    updateTitle?: string;
    deleteTitle?: string;
    deleteMessage?: string;
    selectTitle?: string;
    [key: string]: string;
  };
  @Output()
  selected: EventEmitter<TModel[]> = new EventEmitter<TModel[]>();
  @Input()
  readonly: boolean;
  @Input()
  title: string;
  @Input()
  filter: IEntityGridFilter = { searchText: '', sort: '-id' };

  paginationMeta$: Observable<IPaginationMeta>;
  items$: Observable<TModel[]>;
  createData: any;
  appendFromGridData: any;

  private _mockedItems: TModel[];
  private _selected: TModel[] = [];

  constructor(
    public repository: Repository<TModel>,
    public modalService: BsModalService,
    public factoryModel: IFactoryModel<TModel>,
    protected errorsExtractor?: ErrorsExtractor,
    protected messageModalService?: MessageModalService
  ) {
    if (factoryModel.strings) {
      this.strings = factoryModel.strings;
    } else {
      this.strings = Object.keys(new factoryModel()).reduce((acc, cur, i) => {
        acc[cur] = cur;
        return acc;
      }, {});
    }
  }
  useRest(options?: IRestProviderOptions<TModel>) {
    this.repository.useRest(options);
    this.items$ = this.repository.items$;
    this.paginationMeta$ = this.repository.paginationMeta$;
  }
  useMock(options?: IMockProviderOptions<TModel>) {
    this.repository.useMock(options);
    this.items$ = this.repository.items$;
    this.paginationMeta$ = this.repository.paginationMeta$;
  }
  getSelected() {
    return this._selected;
  }
  onSelected(selected: TModel[]) {
    this._selected = selected;
    this.selected.emit(this._selected);
  }
  onChangePage(meta: { page: number; itemsPerPage: number }) {
    this.repository.setOptions({
      paginationMeta: { curPage: meta.page, perPage: meta.itemsPerPage }
    });
  }
  onChangeFilter(filter?: IEntityGridFilter) {
    if (!filter) {
      filter = {};
    }
    this.processing = true;
    for (const key in filter) {
      if (filter.hasOwnProperty(key)) {
        if (key === 'searchText') {
          this.filter.searchText =
            typeof filter.searchText === 'string' ? filter.searchText : '';
        } else {
          this.filter[key] = filter[key];
        }
      }
    }
    this.repository
      .loadAll(this.filter)
      .pipe(first())
      .subscribe(items => this.onSuccess(items), error => this.onError(error));
  }
  onReload() {
    this.onChangeFilter();
  }
  onSearch(searchText: string) {
    this.onChangeFilter({ searchText });
  }
  onChangeOrder(fieldName: string) {
    this.onChangeFilter({ sort: fieldName });
  }
  onSuccess(items: TModel[]) {
    this.processing = false;
  }
  onError(error: any) {
    this.processing = false;
    if (isDevMode()) {
      console.warn('Method "onError" is not defined', this);
    }
    if (this.messageModalService) {
      this.messageModalService
        .error({
          error: error
        })
        .subscribe();
    } else {
      if (isDevMode()) {
        console.warn('MessageModalService is not injected', this);
      }<commit_msg>fix(base): Add check typeof searchText === 'string' in onSearch method<commit_after>import { EventEmitter, Input, isDevMode, Output } from '@angular/core';
import { ErrorsExtractor, translate } from '@rucken/core';
import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
import { IFactoryModel, IMockProviderOptions, IModel, IPaginationMeta, IRestProviderOptions, Repository } from 'ngx-repository';
import { BehaviorSubject, forkJoin, Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { IBaseEntityListModal } from '../base/base-entity-list-modal.interface';
import { IEntityGridFilter } from '../components/entity-grid/entity-grid-filter.interface';
import { EntityModalComponent } from '../components/entity-modal/entity-modal.component';
import { MessageModalService } from '../modals/message-modal/message-modal.service';
import { IBaseEntityList } from './base-entity-list.interface';
import { IBaseEntityModalOptions, IBaseEntityModals } from './base-entity-modals.interface';

export class BaseEntityListComponent<TModel extends IModel>
  implements IBaseEntityList<TModel>, IBaseEntityModals {
  @Input()
  modalItem: IBaseEntityModalOptions = {};
  @Input()
  modalDelete: IBaseEntityModalOptions = {};
  @Input()
  modalCreate: IBaseEntityModalOptions = {};
  @Input()
  modalUpdate: IBaseEntityModalOptions = {};
  @Input()
  modalView: IBaseEntityModalOptions = {};
  @Input()
  modalAppendFromGrid: IBaseEntityModalOptions = {};
  @Input()
  set processing(value: boolean) {
    this.processing$.next(value);
  }
  get processing() {
    return this.processing$.getValue();
  }
  processing$ = new BehaviorSubject(false);
  @Input()
  apiUrl?: string;
  @Input()
  set mockedItems(items: TModel[]) {
    this._mockedItems = items;
  }
  get mockedItems() {
    return this._mockedItems;
  }
  @Output()
  mockedItemsChange: EventEmitter<TModel[]> = new EventEmitter<TModel[]>();
  @Input()
  strings: {
    viewTitle?: string;
    createTitle?: string;
    updateTitle?: string;
    deleteTitle?: string;
    deleteMessage?: string;
    selectTitle?: string;
    [key: string]: string;
  };
  @Output()
  selected: EventEmitter<TModel[]> = new EventEmitter<TModel[]>();
  @Input()
  readonly: boolean;
  @Input()
  title: string;
  @Input()
  filter: IEntityGridFilter = { searchText: '', sort: '-id' };

  paginationMeta$: Observable<IPaginationMeta>;
  items$: Observable<TModel[]>;
  createData: any;
  appendFromGridData: any;

  private _mockedItems: TModel[];
  private _selected: TModel[] = [];

  constructor(
    public repository: Repository<TModel>,
    public modalService: BsModalService,
    public factoryModel: IFactoryModel<TModel>,
    protected errorsExtractor?: ErrorsExtractor,
    protected messageModalService?: MessageModalService
  ) {
    if (factoryModel.strings) {
      this.strings = factoryModel.strings;
    } else {
      this.strings = Object.keys(new factoryModel()).reduce((acc, cur, i) => {
        acc[cur] = cur;
        return acc;
      }, {});
    }
  }
  useRest(options?: IRestProviderOptions<TModel>) {
    this.repository.useRest(options);
    this.items$ = this.repository.items$;
    this.paginationMeta$ = this.repository.paginationMeta$;
  }
  useMock(options?: IMockProviderOptions<TModel>) {
    this.repository.useMock(options);
    this.items$ = this.repository.items$;
    this.paginationMeta$ = this.repository.paginationMeta$;
  }
  getSelected() {
    return this._selected;
  }
  onSelected(selected: TModel[]) {
    this._selected = selected;
    this.selected.emit(this._selected);
  }
  onChangePage(meta: { page: number; itemsPerPage: number }) {
    this.repository.setOptions({
      paginationMeta: { curPage: meta.page, perPage: meta.itemsPerPage }
    });
  }
  onChangeFilter(filter?: IEntityGridFilter) {
    if (!filter) {
      filter = {};
    }
    this.processing = true;
    for (const key in filter) {
      if (filter.hasOwnProperty(key)) {
        if (key === 'searchText') {
          this.filter.searchText =
            typeof filter.searchText === 'string' ? filter.searchText : '';
        } else {
          this.filter[key] = filter[key];
        }
      }
    }
    this.repository
      .loadAll(this.filter)
      .pipe(first())
      .subscribe(items => this.onSuccess(items), error => this.onError(error));
  }
  onReload() {
    this.onChangeFilter();
  }
  onSearch(searchText: string ) {
    if (typeof searchText === 'string') {
      this.onChangeFilter({ searchText });
    }
  }
  onChangeOrder(fieldName: string) {
    this.onChangeFilter({ sort: fieldName });
  }
  onSuccess(items: TModel[]) {
    this.processing = false;
  }
  onError(error: any) {
    this.processing = false;
    if (isDevMode()) {
      console.warn('Method "onError" is not defined', this);
    }
    if (this.messageModalService) {
      this.messageModalService
        .error({
          error: error
        })
        .subscribe();
    } else {
      if (isDevMode()) {
        console.warn('MessageModalService is not injected', this);
      }
{'fraction_non_alphanumeric': 0.13885566188197768, 'fraction_numerical': 0.0, 'mean_word_length': 3.632040627885503, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3869377', 'n_tokens_mistral': 3025, 'n_tokens_neox': 3033, 'n_words': 616}