diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2017-03-03 13:13:03 +0300 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2017-03-03 19:39:30 +0300 |
commit | 5bb6a85b902c6096970d6c82bb63cae7985e55e8 (patch) | |
tree | 4621bdcade58234a3c97d6198ff7adde776a4d45 /app/assets | |
parent | 8fd5aeee7fee7506c44674d61f794ff8685b90e6 (diff) |
Refactor projects filtering by name
Reuse same search form and behavior for dashboard#projects, group#projects
and admin#projects. Repsect all other options like sorting, personal
filter when search projects by name. Create FilterableList JS class to
handle identical behaviour of projects and groups lists.
This change also makes filtering and sorting availabe on explore#projects
and explore#groups no matter if you are logged in or not.
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Diffstat (limited to 'app/assets')
-rw-r--r-- | app/assets/javascripts/dispatcher.js.es6 | 13 | ||||
-rw-r--r-- | app/assets/javascripts/filterable_list.js | 47 | ||||
-rw-r--r-- | app/assets/javascripts/groups_list.js | 44 | ||||
-rw-r--r-- | app/assets/javascripts/projects_list.js | 63 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/search.scss | 6 |
5 files changed, 81 insertions, 92 deletions
diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6 index fc25122aedc..ef5785b5532 100644 --- a/app/assets/javascripts/dispatcher.js.es6 +++ b/app/assets/javascripts/dispatcher.js.es6 @@ -36,6 +36,7 @@ /* global Shortcuts */ import GroupsList from './groups_list'; +import ProjectsList from './projects_list'; const ShortcutsBlob = require('./shortcuts_blob'); const UserCallout = require('./user_callout'); @@ -98,6 +99,14 @@ const UserCallout = require('./user_callout'); case 'dashboard:todos:index': new gl.Todos(); break; + case 'dashboard:projects:index': + case 'dashboard:projects:starred': + case 'explore:projects:index': + case 'explore:projects:trending': + case 'explore:projects:starred': + case 'admin:projects:index': + new ProjectsList(); + break; case 'dashboard:groups:index': case 'explore:groups:index': new GroupsList(); @@ -163,9 +172,6 @@ const UserCallout = require('./user_callout'); case 'dashboard:activity': new gl.Activities(); break; - case 'dashboard:projects:starred': - new gl.Activities(); - break; case 'projects:commit:show': new Commit(); new gl.Diff(); @@ -208,6 +214,7 @@ const UserCallout = require('./user_callout'); shortcut_handler = new ShortcutsNavigation(); new NotificationsForm(); new NotificationsDropdown(); + new ProjectsList(); break; case 'groups:group_members:index': new gl.MemberExpirationDate(); diff --git a/app/assets/javascripts/filterable_list.js b/app/assets/javascripts/filterable_list.js new file mode 100644 index 00000000000..f498c3ea973 --- /dev/null +++ b/app/assets/javascripts/filterable_list.js @@ -0,0 +1,47 @@ +/** + * 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) { + this.filterForm = form; + this.listFilterElement = filter; + this.listHolderElement = holder; + + this.initSearch(); + } + + initSearch() { + this.debounceFilter = _.debounce(this.filterResults.bind(this), 500); + + this.listFilterElement.removeEventListener('input', this.debounceFilter); + this.listFilterElement.addEventListener('input', this.debounceFilter); + } + + filterResults() { + const form = this.filterForm; + const filterUrl = `${form.getAttribute('action')}?${$(form).serialize()}`; + + $(this.listHolderElement).fadeTo(250, 0.5); + + return $.ajax({ + url: form.getAttribute('action'), + data: $(form).serialize(), + type: 'GET', + dataType: 'json', + context: this, + complete() { + $(this.listHolderElement).fadeTo(250, 1); + }, + success(data) { + this.listHolderElement.innerHTML = data.html; + + // Change url so if user reload a page - search results are saved + return window.history.replaceState({ + page: filterUrl, + + }, document.title, filterUrl); + }, + }); + } +} diff --git a/app/assets/javascripts/groups_list.js b/app/assets/javascripts/groups_list.js index 0ef81e49444..49b29affaa5 100644 --- a/app/assets/javascripts/groups_list.js +++ b/app/assets/javascripts/groups_list.js @@ -1,47 +1,15 @@ +import FilterableList from './filterable_list'; + /** - * Based on project list search. * Makes search request for groups when user types a value in the search input. * Updates the html content of the page with the received one. */ export default class GroupsList { constructor() { - this.groupsListFilterElement = document.querySelector('.js-groups-list-filter'); - this.groupsListHolderElement = document.querySelector('.js-groups-list-holder'); - - this.initSearch(); - } - - initSearch() { - this.debounceFilter = _.debounce(this.filterResults.bind(this), 500); - - this.groupsListFilterElement.removeEventListener('input', this.debounceFilter); - this.groupsListFilterElement.addEventListener('input', this.debounceFilter); - } - - filterResults() { - const form = document.querySelector('form#group-filter-form'); - const groupFilterUrl = `${form.getAttribute('action')}?${$(form).serialize()}`; - - $(this.groupsListHolderElement).fadeTo(250, 0.5); - - return $.ajax({ - url: form.getAttribute('action'), - data: $(form).serialize(), - type: 'GET', - dataType: 'json', - context: this, - complete() { - $(this.groupsListHolderElement).fadeTo(250, 1); - }, - success(data) { - this.groupsListHolderElement.innerHTML = data.html; - - // Change url so if user reload a page - search results are saved - return window.history.replaceState({ - page: groupFilterUrl, + var form = document.querySelector('form#group-filter-form'); + var filter = document.querySelector('.js-groups-list-filter'); + var holder = document.querySelector('.js-groups-list-holder'); - }, document.title, groupFilterUrl); - }, - }); + new FilterableList(form, filter, holder); } } diff --git a/app/assets/javascripts/projects_list.js b/app/assets/javascripts/projects_list.js index acdf9b7eb5a..383c2815457 100644 --- a/app/assets/javascripts/projects_list.js +++ b/app/assets/javascripts/projects_list.js @@ -1,50 +1,15 @@ -/* eslint-disable func-names, space-before-function-paren, object-shorthand, quotes, no-var, one-var, one-var-declaration-per-line, prefer-arrow-callback, consistent-return, no-unused-vars, camelcase, prefer-template, comma-dangle, max-len */ +import FilterableList from './filterable_list'; -(function() { - window.ProjectsList = { - init: function() { - $(".projects-list-filter").off('keyup'); - this.initSearch(); - return this.initPagination(); - }, - initSearch: function() { - var debounceFilter, projectsListFilter; - projectsListFilter = $('.projects-list-filter'); - debounceFilter = _.debounce(window.ProjectsList.filterResults, 500); - return projectsListFilter.on('keyup', function(e) { - if (projectsListFilter.val() !== '') { - return debounceFilter(); - } - }); - }, - filterResults: function() { - var form, project_filter_url, search; - $('.projects-list-holder').fadeTo(250, 0.5); - form = null; - form = $("form#project-filter-form"); - search = $(".projects-list-filter").val(); - project_filter_url = form.attr('action') + '?' + form.serialize(); - return $.ajax({ - type: "GET", - url: form.attr('action'), - data: form.serialize(), - complete: function() { - return $('.projects-list-holder').fadeTo(250, 1); - }, - success: function(data) { - $('.projects-list-holder').replaceWith(data.html); - return history.replaceState({ - page: project_filter_url - // Change url so if user reload a page - search results are saved - }, document.title, project_filter_url); - }, - dataType: "json" - }); - }, - initPagination: function() { - return $('.projects-list-holder .pagination').on('ajax:success', function(e, data) { - return $('.projects-list-holder').replaceWith(data.html); - }); - } - }; -}).call(window); +/** + * Makes search request for projects when user types a value in the search input. + * Updates the html content of the page with the received one. + */ +export default class ProjectsList { + constructor() { + var form = document.querySelector('form#project-filter-form'); + var filter = document.querySelector('.js-projects-list-filter'); + var holder = document.querySelector('.js-projects-list-holder'); + + new FilterableList(form, filter, holder); + } +} diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 88ea92c5afb..543d2ece3df 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -182,7 +182,8 @@ input[type="checkbox"]:hover { display: flex; } - .search-field-holder { + .search-field-holder, + .project-filter-form { -webkit-flex: 1 0 auto; flex: 1 0 auto; position: relative; @@ -201,7 +202,8 @@ input[type="checkbox"]:hover { pointer-events: none; } - .search-text-input { + .search-text-input, + .project-filter-form-field { padding-left: $gl-padding + 15px; padding-right: $gl-padding + 15px; } |