<commit_before>import { HttpResponse } from '@angular/common/http';
import { Injector, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { QueryFilters } from 'app/api/models';
import { NextRequestState } from 'app/core/next-request-state';
import { HeadingAction } from 'app/shared/action';
import { ApiHelper } from 'app/shared/api-helper';
import { BasePageComponent } from 'app/shared/base-page.component';
import { PageData } from 'app/shared/page-data';
import { PagedResults } from 'app/shared/paged-results';
import { ResultType } from 'app/shared/result-type';
import { isEqual } from 'lodash';
import { BehaviorSubject, Observable } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

/**
 * Base class implemented by search pages.
 * @param D The data type
 * @param P The search parameters which extends the QueryFiters type with path variables
 * @param R The result type
 */
export abstract class BaseSearchPageComponent<D, P extends QueryFilters, R> extends BasePageComponent<D> implements OnInit {
  // Export ResultType to the template
  ResultType = ResultType;

  resultType$ = new BehaviorSubject<ResultType>(null);
  resultTypeControl = new FormControl(null);
  results$ = new BehaviorSubject<PagedResults<R>>(null);
  allowedResultTypes$ = new BehaviorSubject([ResultType.LIST]);
  rendering$ = new BehaviorSubject(false);
  moreFilters$ = new BehaviorSubject(false);
  previousResultType: ResultType;

  nextRequestState: NextRequestState;

  readonly form: FormGroup;
  previousValue: any;

  protected printable = false;
  private _moreFiltersAction: HeadingAction;

  protected onDataInitialized(_data: D) {
    this.stateManager.manage(this.form);
    this.stateManager.manage(this.resultTypeControl, 'resultType');
    this.stateManager.manageValue(this.moreFilters$, 'moreFilters');
    this.previousValue = this.form.value;
    this.previousResultType = this.resultType;
    this.resultType$.next(this.previousResultType);
    this.addSub(this.resultTypeControl.valueChanges.subscribe(rt => {
      if (this.shouldUpdateOnChange(this.form.value)) {
        this.update();
      }
      const previous = this.previousResultType;
      this.previousResultType = rt;
      this.resultType$.next(rt);
      if (previous == null || previous !== rt) {
        this.rendering = true;
        this.stateManager.set('resultType', rt);
        this.onResultTypeChanged(rt, previous);
      }
    }));

    // Only after finishing initialization add a listener to form values to update the results. This avoids duplicated searches.
    setTimeout(() =>
      this.addSub(this.form.valueChanges.pipe(debounceTime(ApiHelper.DEBOUNCE_TIME)).subscribe(value => {
        if (this.shouldUpdateOnChange(value)) {
          this.update();
        }
        this.previousValue = value;
      }), true),
      1);

    // When starting with categories, don't initially search
    if (this.previousResultType !== ResultType.CATEGORIES) {
      this.update();
    }
  }

  /**
   * By default will just skip the update if only the result type has changed
   * @param value The current form value
   */
  protected shouldUpdateOnChange(value: any): boolean {
    const previousResultType = this.previousResultType;
    const resultType = this.resultType;<commit_msg>Only do the initial search after fully initialized<commit_after>import { HttpResponse } from '@angular/common/http';
import { Injector, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { QueryFilters } from 'app/api/models';
import { NextRequestState } from 'app/core/next-request-state';
import { HeadingAction } from 'app/shared/action';
import { ApiHelper } from 'app/shared/api-helper';
import { BasePageComponent } from 'app/shared/base-page.component';
import { PageData } from 'app/shared/page-data';
import { PagedResults } from 'app/shared/paged-results';
import { ResultType } from 'app/shared/result-type';
import { isEqual } from 'lodash';
import { BehaviorSubject, Observable } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

/**
 * Base class implemented by search pages.
 * @param D The data type
 * @param P The search parameters which extends the QueryFiters type with path variables
 * @param R The result type
 */
export abstract class BaseSearchPageComponent<D, P extends QueryFilters, R> extends BasePageComponent<D> implements OnInit {
  // Export ResultType to the template
  ResultType = ResultType;

  resultType$ = new BehaviorSubject<ResultType>(null);
  resultTypeControl = new FormControl(null);
  results$ = new BehaviorSubject<PagedResults<R>>(null);
  allowedResultTypes$ = new BehaviorSubject([ResultType.LIST]);
  rendering$ = new BehaviorSubject(false);
  moreFilters$ = new BehaviorSubject(false);
  previousResultType: ResultType;

  nextRequestState: NextRequestState;

  readonly form: FormGroup;
  previousValue: any;

  protected printable = false;
  private _moreFiltersAction: HeadingAction;

  protected onDataInitialized(_data: D) {
    this.stateManager.manage(this.form);
    this.stateManager.manage(this.resultTypeControl, 'resultType');
    this.stateManager.manageValue(this.moreFilters$, 'moreFilters');
    this.previousValue = this.form.value;
    this.previousResultType = this.resultType;
    this.resultType$.next(this.previousResultType);
    this.addSub(this.resultTypeControl.valueChanges.subscribe(rt => {
      if (this.shouldUpdateOnChange(this.form.value)) {
        this.update();
      }
      const previous = this.previousResultType;
      this.previousResultType = rt;
      this.resultType$.next(rt);
      if (previous == null || previous !== rt) {
        this.rendering = true;
        this.stateManager.set('resultType', rt);
        this.onResultTypeChanged(rt, previous);
      }
    }));

    // Only after finishing initialization add a listener to form values to update the results. This avoids duplicated searches.
    setTimeout(() => {
      this.addSub(this.form.valueChanges.pipe(debounceTime(ApiHelper.DEBOUNCE_TIME)).subscribe(value => {
        if (this.shouldUpdateOnChange(value)) {
          this.update();
        }
        this.previousValue = value;
      }), true);
      // When starting with categories, don't initially search
      if (this.previousResultType !== ResultType.CATEGORIES) {
        this.update();
      }
    }, 1);
  }

  /**
   * By default will just skip the update if only the result type has changed
   * @param value The current form value
   */
  protected shouldUpdateOnChange(value: any): boolean {
    const previousResultType = this.previousResultType;
    const resultType = this.resultType;
{'fraction_non_alphanumeric': 0.11207282495149977, 'fraction_numerical': 0.00029846291598268916, 'mean_word_length': 4.005227781926811, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, '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': '3738869', 'n_tokens_mistral': 1888, 'n_tokens_neox': 1858, 'n_words': 490}