Welcome to mirror list, hosted at ThFree Co, Russian Federation.

filterable_list.js « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a6781cffaec6ce3ad25f540a7eb972596055c0aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import $ from 'jquery';
import { debounce } from 'lodash';
import axios from './lib/utils/axios_utils';

/**
 * Makes search request for content when user types a value in the search input.
 * Updates the html content of the page with the received one.
 */

export default class FilterableList {
  constructor(form, filter, holder, filterInputField = 'filter_groups') {
    this.filterForm = form;
    this.listFilterElement = filter;
    this.listHolderElement = holder;
    this.filterInputField = filterInputField;
    this.isBusy = false;
  }

  getFilterEndpoint() {
    return this.getPagePath();
  }

  getPagePath() {
    const action = this.filterForm.getAttribute('action');
    // eslint-disable-next-line no-jquery/no-serialize
    const params = $(this.filterForm).serialize();
    return `${action}${action.indexOf('?') > 0 ? '&' : '?'}${params}`;
  }

  initSearch() {
    // Wrap to prevent passing event arguments to .filterResults;
    this.debounceFilter = debounce(this.onFilterInput.bind(this), 500);

    this.unbindEvents();
    this.bindEvents();
  }

  onFilterInput() {
    const $form = $(this.filterForm);
    const queryData = {};
    const filterGroupsParam = $form.find(`[name="${this.filterInputField}"]`).val();

    if (filterGroupsParam) {
      queryData[this.filterInputField] = filterGroupsParam;
    }

    this.filterResults(queryData);

    if (this.setDefaultFilterOption) {
      this.setDefaultFilterOption();
    }
  }

  bindEvents() {
    this.listFilterElement.addEventListener('input', this.debounceFilter);
  }

  unbindEvents() {
    this.listFilterElement.removeEventListener('input', this.debounceFilter);
  }

  filterResults(params) {
    if (this.isBusy) {
      return false;
    }

    $(this.listHolderElement).addClass('gl-opacity-5');

    this.isBusy = true;

    return axios
      .get(this.getFilterEndpoint(), {
        params,
      })
      .then((res) => {
        this.onFilterSuccess(res, params);
        this.onFilterComplete();
      })
      .catch(() => this.onFilterComplete());
  }

  onFilterSuccess(response, queryData) {
    if (response.data.html) {
      // eslint-disable-next-line no-unsanitized/property
      this.listHolderElement.innerHTML = response.data.html;
    }

    // Change url so if user reload a page - search results are saved
    const currentPath = this.getPagePath(queryData);

    return window.history.replaceState(
      {
        page: currentPath,
      },
      document.title,
      currentPath,
    );
  }

  onFilterComplete() {
    this.isBusy = false;
    $(this.listHolderElement).removeClass('gl-opacity-5');
  }
}