<commit_before>import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { isBlank } from '@ember/utils';
import { task, timeout } from 'ember-concurrency';
import { cleanQuery } from 'ilios-common/utils/query-utils';

const DEBOUNCE_MS = 250;
const MIN_INPUT = 3;

export default Component.extend({
  iliosConfig: service(),
  intl: service(),
  router: service(),
  search: service(),
  store: service(),

  classNames: ['manage-users-summary', 'large-component'],
  tagName: 'section',

  canCreate: false,
  searchValue: null,

  /**
   * Find users using the user API
   * @param {string} q
   */
  async apiSearch(q) {
    let params = {
      q,
      limit: 100,
      'order_by[lastName]': 'ASC',
      'order_by[firstName]': 'ASC',
    };

    return await this.store.query('user', params);
  },

  /**
   * Find users using the search index API
   * @param {string} q
   */
  async indexSearch(q) {
    return this.search.forUsers(q);
  },

  searchForUsers: task(function * (query) {
    const intl = this.intl;

    let q = cleanQuery(query);
    if (isBlank(q)) {
      yield timeout(1);
      return [];
    }
    yield timeout(DEBOUNCE_MS);

    if (q.length < MIN_INPUT) {
      return [{
        type: 'text',
        text: intl.t('general.moreInputRequiredPrompt')
      }];
    }
    const searchEnabled = yield this.iliosConfig.searchEnabled;
    const searchResults = searchEnabled ? yield this.indexSearch(q) : yield this.apiSearch(q);

    if (searchResults.length === 0) {
      return [{
        type: 'text',
        text: intl.t('general.noSearchResultsPrompt')
      }];
    }
    let mappedResults = searchResults.map(user => {
      return {
        type: 'user',
        user
      };
    });
    let results = [
      {
        type: 'summary',
        text: intl.t('general.resultsCount', {count: mappedResults.length})
      }
    ];
    results.pushObjects(mappedResults);

    return results;
  }).restartable(),

  clickUser: task(function* ({ id }) {
    yield this.router.transitionTo('user', id);
    this.set('searchValue', null);
    yield this.searchForUsers.perform(null);
  }).drop(),
});<commit_msg>Prevent polluting the URL with query params<commit_after>import Ember from 'ember';
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { isBlank } from '@ember/utils';
import { task, timeout } from 'ember-concurrency';
import { cleanQuery } from 'ilios-common/utils/query-utils';

const DEBOUNCE_MS = 250;
const MIN_INPUT = 3;

export default Component.extend({
  iliosConfig: service(),
  intl: service(),
  router: service(),
  search: service(),
  store: service(),

  classNames: ['manage-users-summary', 'large-component'],
  tagName: 'section',

  canCreate: false,
  searchValue: null,

  /**
   * Find users using the user API
   * @param {string} q
   */
  async apiSearch(q) {
    let params = {
      q,
      limit: 100,
      'order_by[lastName]': 'ASC',
      'order_by[firstName]': 'ASC',
    };

    return await this.store.query('user', params);
  },

  /**
   * Find users using the search index API
   * @param {string} q
   */
  async indexSearch(q) {
    return this.search.forUsers(q);
  },

  searchForUsers: task(function * (query) {
    const intl = this.intl;

    let q = cleanQuery(query);
    if (isBlank(q)) {
      yield timeout(1);
      return [];
    }
    yield timeout(DEBOUNCE_MS);

    if (q.length < MIN_INPUT) {
      return [{
        type: 'text',
        text: intl.t('general.moreInputRequiredPrompt')
      }];
    }
    const searchEnabled = yield this.iliosConfig.searchEnabled;
    const searchResults = searchEnabled ? yield this.indexSearch(q) : yield this.apiSearch(q);

    if (searchResults.length === 0) {
      return [{
        type: 'text',
        text: intl.t('general.noSearchResultsPrompt')
      }];
    }
    let mappedResults = searchResults.map(user => {
      return {
        type: 'user',
        user
      };
    });
    let results = [
      {
        type: 'summary',
        text: intl.t('general.resultsCount', {count: mappedResults.length})
      }
    ];
    results.pushObjects(mappedResults);

    return results;
  }).restartable(),

  clickUser: task(function* ({ id }) {
    yield this.router.transitionTo('user', id, {
      queryParams: {
        isManagingBio: Ember.DEFAULT_VALUE,
        isManagingRoles: Ember.DEFAULT_VALUE,
        isManagingCohorts: Ember.DEFAULT_VALUE,
        isManagingIcs: Ember.DEFAULT_VALUE,
        isManagingSchools: Ember.DEFAULT_VALUE
      }
    });
    this.set('searchValue', null);
    yield this.searchForUsers.perform(null);
  }).drop(),
});
{'fraction_non_alphanumeric': 0.14313058273075288, 'fraction_numerical': 0.0038281582305401958, 'mean_word_length': 2.7835880933226065, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '4610851', 'n_tokens_mistral': 1524, 'n_tokens_neox': 1481, 'n_words': 345}