parent
ea531e1eff
commit
323a326c73
|
@ -8,7 +8,15 @@ export default class FilterableList {
|
|||
this.filterForm = form;
|
||||
this.listFilterElement = filter;
|
||||
this.listHolderElement = holder;
|
||||
this.filterUrl = `${this.filterForm.getAttribute('action')}?${$(this.filterForm).serialize()}`;
|
||||
this.isBusy = false;
|
||||
}
|
||||
|
||||
getFilterEndpoint() {
|
||||
return `${this.filterForm.getAttribute('action')}?${$(this.filterForm).serialize()}`;
|
||||
}
|
||||
|
||||
getPagePath() {
|
||||
return this.getFilterEndpoint();
|
||||
}
|
||||
|
||||
initSearch() {
|
||||
|
@ -20,9 +28,19 @@ export default class FilterableList {
|
|||
}
|
||||
|
||||
onFilterInput() {
|
||||
const url = this.filterForm.getAttribute('action');
|
||||
const data = $(this.filterForm).serialize();
|
||||
this.filterResults(url, data, 'filter-input');
|
||||
const $form = $(this.filterForm);
|
||||
const queryData = {};
|
||||
const filterGroupsParam = $form.find('[name="filter_groups"]').val();
|
||||
|
||||
if (filterGroupsParam) {
|
||||
queryData.filter_groups = filterGroupsParam;
|
||||
}
|
||||
|
||||
this.filterResults(queryData);
|
||||
|
||||
if (this.setDefaultFilterOption) {
|
||||
this.setDefaultFilterOption();
|
||||
}
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
|
@ -33,42 +51,44 @@ export default class FilterableList {
|
|||
this.listFilterElement.removeEventListener('input', this.debounceFilter);
|
||||
}
|
||||
|
||||
filterResults(url, data, comingFrom) {
|
||||
const endpoint = url || this.filterForm.getAttribute('action');
|
||||
const additionalData = data || $(this.filterForm).serialize();
|
||||
filterResults(queryData) {
|
||||
if (this.isBusy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$(this.listHolderElement).fadeTo(250, 0.5);
|
||||
|
||||
return $.ajax({
|
||||
url: endpoint,
|
||||
data: additionalData,
|
||||
url: this.getFilterEndpoint(),
|
||||
data: queryData,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
context: this,
|
||||
complete: this.onFilterComplete,
|
||||
beforeSend: () => {
|
||||
this.isBusy = true;
|
||||
},
|
||||
success: (response, textStatus, xhr) => {
|
||||
if (this.preOnFilterSuccess) {
|
||||
this.preOnFilterSuccess(comingFrom);
|
||||
}
|
||||
|
||||
this.onFilterSuccess(response, xhr);
|
||||
this.onFilterSuccess(response, xhr, queryData);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onFilterSuccess(data) {
|
||||
if (data.html) {
|
||||
this.listHolderElement.innerHTML = data.html;
|
||||
onFilterSuccess(response, xhr, queryData) {
|
||||
if (response.html) {
|
||||
this.listHolderElement.innerHTML = response.html;
|
||||
}
|
||||
|
||||
// Change url so if user reload a page - search results are saved
|
||||
return window.history.replaceState({
|
||||
page: this.filterUrl,
|
||||
// Change url so if user reload a page - search results are saved
|
||||
const currentPath = this.getPagePath(queryData);
|
||||
|
||||
}, document.title, this.filterUrl);
|
||||
return window.history.replaceState({
|
||||
page: currentPath,
|
||||
}, document.title, currentPath);
|
||||
}
|
||||
|
||||
onFilterComplete() {
|
||||
this.isBusy = false;
|
||||
$(this.listHolderElement).fadeTo(250, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import TablePaginationComponent from '~/vue_shared/components/table_pagination';
|
||||
import TablePaginationComponent from '~/vue_shared/components/table_pagination.vue';
|
||||
import eventHub from '../event_hub';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -16,11 +17,10 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
change(pageNumber) {
|
||||
const param = gl.utils.setParamInURL('page', pageNumber);
|
||||
|
||||
gl.utils.visitUrl(param);
|
||||
return param;
|
||||
change(page) {
|
||||
const filterGroupsParam = gl.utils.getParameterByName('filter_groups');
|
||||
const sortParam = gl.utils.getParameterByName('sort');
|
||||
eventHub.$emit('fetchPage', page, filterGroupsParam, sortParam);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,12 +2,24 @@ import FilterableList from '~/filterable_list';
|
|||
import eventHub from './event_hub';
|
||||
|
||||
export default class GroupFilterableList extends FilterableList {
|
||||
constructor(form, filter, holder) {
|
||||
constructor({ form, filter, holder, filterEndpoint, pagePath }) {
|
||||
super(form, filter, holder);
|
||||
|
||||
this.form = form;
|
||||
this.filterEndpoint = filterEndpoint;
|
||||
this.pagePath = pagePath;
|
||||
this.$dropdown = $('.js-group-filter-dropdown-wrap');
|
||||
}
|
||||
|
||||
getFilterEndpoint() {
|
||||
return this.filterEndpoint;
|
||||
}
|
||||
|
||||
getPagePath(queryData) {
|
||||
const params = queryData ? $.param(queryData) : '';
|
||||
const queryString = params ? `?${params}` : '';
|
||||
return `${this.pagePath}${queryString}`;
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
super.bindEvents();
|
||||
|
||||
|
@ -21,26 +33,45 @@ export default class GroupFilterableList extends FilterableList {
|
|||
onFormSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
this.filterResults();
|
||||
const $form = $(this.form);
|
||||
const filterGroupsParam = $form.find('[name="filter_groups"]').val();
|
||||
const queryData = {};
|
||||
|
||||
if (filterGroupsParam) {
|
||||
queryData.filter_groups = filterGroupsParam;
|
||||
}
|
||||
|
||||
this.filterResults(queryData);
|
||||
this.setDefaultFilterOption();
|
||||
}
|
||||
|
||||
setDefaultFilterOption() {
|
||||
const defaultOption = $.trim(this.$dropdown.find('.dropdown-menu a:first-child').text());
|
||||
this.$dropdown.find('.dropdown-label').text(defaultOption);
|
||||
}
|
||||
|
||||
onOptionClick(e) {
|
||||
e.preventDefault();
|
||||
const currentOption = $.trim(e.currentTarget.text);
|
||||
|
||||
this.filterUrl = e.currentTarget.href;
|
||||
this.$dropdown.find('.dropdown-label').text(currentOption);
|
||||
this.filterResults(this.filterUrl);
|
||||
}
|
||||
const queryData = {};
|
||||
const sortParam = gl.utils.getParameterByName('sort', e.currentTarget.href);
|
||||
|
||||
preOnFilterSuccess(comingFrom) {
|
||||
if (comingFrom === 'filter-input') {
|
||||
this.filterUrl = `${this.filterForm.getAttribute('action')}?${$(this.filterForm).serialize()}`;
|
||||
if (sortParam) {
|
||||
queryData.sort = sortParam;
|
||||
}
|
||||
|
||||
this.filterResults(queryData);
|
||||
|
||||
// Active selected option
|
||||
this.$dropdown.find('.dropdown-label').text($.trim(e.currentTarget.text));
|
||||
|
||||
// Clear current value on search form
|
||||
this.form.querySelector('[name="filter_groups"]').value = '';
|
||||
}
|
||||
|
||||
onFilterSuccess(data, xhr) {
|
||||
super.onFilterSuccess(data);
|
||||
onFilterSuccess(data, xhr, queryData) {
|
||||
super.onFilterSuccess(data, xhr, queryData);
|
||||
|
||||
const paginationData = {
|
||||
'X-Per-Page': xhr.getResponseHeader('X-Per-Page'),
|
||||
'X-Page': xhr.getResponseHeader('X-Page'),
|
||||
|
|
|
@ -37,7 +37,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
let parentId = null;
|
||||
let getGroups = null;
|
||||
let page = null;
|
||||
let sort = null;
|
||||
let pageParam = null;
|
||||
let sortParam = null;
|
||||
let filterGroups = null;
|
||||
let filterGroupsParam = null;
|
||||
|
||||
|
@ -55,9 +57,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
filterGroups = filterGroupsParam;
|
||||
}
|
||||
|
||||
getGroups = this.service.getGroups(parentId, page, filterGroups);
|
||||
sortParam = gl.utils.getParameterByName('sort');
|
||||
if (sortParam) {
|
||||
sort = sortParam;
|
||||
}
|
||||
|
||||
getGroups = this.service.getGroups(parentId, page, filterGroups, sort);
|
||||
getGroups.then((response) => {
|
||||
eventHub.$emit('updateGroups', response.json(), parentGroup);
|
||||
this.updateGroups(response.json(), parentGroup);
|
||||
})
|
||||
.catch(() => {
|
||||
// TODO: Handle error
|
||||
|
@ -65,6 +72,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
|
||||
return getGroups;
|
||||
},
|
||||
fetchPage(page, filterGroups, sort) {
|
||||
this.service.getGroups(null, page, filterGroups, sort)
|
||||
.then((response) => {
|
||||
this.updateGroups(response.json());
|
||||
this.updatePagination(response.headers);
|
||||
$.scrollTo(0);
|
||||
})
|
||||
.catch(() => {
|
||||
// TODO: Handle error
|
||||
});
|
||||
},
|
||||
toggleSubGroups(parentGroup = null) {
|
||||
if (!parentGroup.isOpen) {
|
||||
this.store.resetGroups(parentGroup);
|
||||
|
@ -95,9 +113,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
const filter = document.querySelector('.js-groups-list-filter');
|
||||
const holder = document.querySelector('.js-groups-list-holder');
|
||||
|
||||
groupFilterList = new GroupFilterableList(form, filter, holder);
|
||||
const opts = {
|
||||
form,
|
||||
filter,
|
||||
holder,
|
||||
filterEndpoint: el.dataset.endpoint,
|
||||
pagePath: el.dataset.path,
|
||||
};
|
||||
|
||||
groupFilterList = new GroupFilterableList(opts);
|
||||
groupFilterList.initSearch();
|
||||
|
||||
eventHub.$on('fetchPage', this.fetchPage);
|
||||
eventHub.$on('toggleSubGroups', this.toggleSubGroups);
|
||||
eventHub.$on('leaveGroup', this.leaveGroup);
|
||||
eventHub.$on('updateGroups', this.updateGroups);
|
||||
|
@ -106,7 +133,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
mounted() {
|
||||
this.fetchGroups()
|
||||
.then((response) => {
|
||||
eventHub.$emit('updatePagination', response.headers);
|
||||
this.updatePagination(response.headers);
|
||||
})
|
||||
.catch(() => {
|
||||
// TODO: Handle error
|
||||
|
|
|
@ -8,7 +8,7 @@ export default class GroupsService {
|
|||
this.groups = Vue.resource(endpoint);
|
||||
}
|
||||
|
||||
getGroups(parentId, page, filterGroups) {
|
||||
getGroups(parentId, page, filterGroups, sort) {
|
||||
const data = {};
|
||||
|
||||
if (parentId) {
|
||||
|
@ -22,6 +22,10 @@ export default class GroupsService {
|
|||
if (filterGroups) {
|
||||
data.filter_groups = filterGroups;
|
||||
}
|
||||
|
||||
if (sort) {
|
||||
data.sort = sort;
|
||||
}
|
||||
}
|
||||
|
||||
return this.groups.get(data);
|
||||
|
|
|
@ -167,8 +167,8 @@
|
|||
if the name does not exist this function will return `null`
|
||||
otherwise it will return the value of the param key provided
|
||||
*/
|
||||
w.gl.utils.getParameterByName = (name) => {
|
||||
const url = window.location.href;
|
||||
w.gl.utils.getParameterByName = (name, parseUrl) => {
|
||||
const url = parseUrl || window.location.href;
|
||||
name = name.replace(/[[\]]/g, '\\$&');
|
||||
const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`);
|
||||
const results = regex.exec(url);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
.js-groups-list-holder
|
||||
#dashboard-group-app{ data: { endpoint: dashboard_groups_path(format: :json) } }
|
||||
#dashboard-group-app{ data: { endpoint: dashboard_groups_path(format: :json), path: dashboard_groups_path } }
|
||||
%groups-component{ ':groups' => 'state.groups', ':page-info' => 'state.pageInfo' }
|
||||
|
|
Loading…
Reference in New Issue