debian-mirror-gitlab/app/assets/javascripts/filterable_list.js

104 lines
2.5 KiB
JavaScript
Raw Normal View History

2018-05-09 12:01:36 +05:30
import $ from 'jquery';
2020-04-22 19:07:51 +05:30
import { debounce } from 'lodash';
2018-03-17 18:26:18 +05:30
import axios from './lib/utils/axios_utils';
2017-09-10 17:25:29 +05:30
2017-08-17 22:00:37 +05:30
/**
* 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 {
2018-03-17 18:26:18 +05:30
constructor(form, filter, holder, filterInputField = 'filter_groups') {
2017-08-17 22:00:37 +05:30
this.filterForm = form;
this.listFilterElement = filter;
this.listHolderElement = holder;
2018-03-17 18:26:18 +05:30
this.filterInputField = filterInputField;
2017-09-10 17:25:29 +05:30
this.isBusy = false;
}
getFilterEndpoint() {
2019-09-30 21:07:59 +05:30
return this.getPagePath();
2017-09-10 17:25:29 +05:30
}
getPagePath() {
2019-09-30 21:07:59 +05:30
const action = this.filterForm.getAttribute('action');
2019-12-21 20:55:43 +05:30
// eslint-disable-next-line no-jquery/no-serialize
2019-09-30 21:07:59 +05:30
const params = $(this.filterForm).serialize();
return `${action}${action.indexOf('?') > 0 ? '&' : '?'}${params}`;
2017-08-17 22:00:37 +05:30
}
initSearch() {
2017-09-10 17:25:29 +05:30
// Wrap to prevent passing event arguments to .filterResults;
2020-04-22 19:07:51 +05:30
this.debounceFilter = debounce(this.onFilterInput.bind(this), 500);
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
this.unbindEvents();
this.bindEvents();
}
onFilterInput() {
const $form = $(this.filterForm);
const queryData = {};
2018-03-17 18:26:18 +05:30
const filterGroupsParam = $form.find(`[name="${this.filterInputField}"]`).val();
2017-09-10 17:25:29 +05:30
if (filterGroupsParam) {
2018-03-17 18:26:18 +05:30
queryData[this.filterInputField] = filterGroupsParam;
2017-09-10 17:25:29 +05:30
}
this.filterResults(queryData);
if (this.setDefaultFilterOption) {
this.setDefaultFilterOption();
}
}
bindEvents() {
2017-08-17 22:00:37 +05:30
this.listFilterElement.addEventListener('input', this.debounceFilter);
}
2017-09-10 17:25:29 +05:30
unbindEvents() {
this.listFilterElement.removeEventListener('input', this.debounceFilter);
}
2018-03-17 18:26:18 +05:30
filterResults(params) {
2017-09-10 17:25:29 +05:30
if (this.isBusy) {
return false;
}
2017-08-17 22:00:37 +05:30
2021-02-22 17:27:13 +05:30
$(this.listHolderElement).addClass('gl-opacity-5');
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
this.isBusy = true;
2018-12-13 13:39:08 +05:30
return axios
.get(this.getFilterEndpoint(), {
params,
})
2021-03-08 18:12:59 +05:30
.then((res) => {
2018-12-13 13:39:08 +05:30
this.onFilterSuccess(res, params);
this.onFilterComplete();
})
.catch(() => this.onFilterComplete());
2017-08-17 22:00:37 +05:30
}
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
onFilterSuccess(response, queryData) {
if (response.data.html) {
this.listHolderElement.innerHTML = response.data.html;
2017-09-10 17:25:29 +05:30
}
// Change url so if user reload a page - search results are saved
const currentPath = this.getPagePath(queryData);
2018-12-13 13:39:08 +05:30
return window.history.replaceState(
{
page: currentPath,
},
document.title,
currentPath,
);
2017-09-10 17:25:29 +05:30
}
onFilterComplete() {
this.isBusy = false;
2021-02-22 17:27:13 +05:30
$(this.listHolderElement).removeClass('gl-opacity-5');
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
}