diff options
-rw-r--r-- | app/assets/javascripts/gl_dropdown.js.coffee | 23 | ||||
-rw-r--r-- | app/assets/javascripts/issues.js.coffee | 10 | ||||
-rw-r--r-- | app/assets/javascripts/labels_select.js.coffee | 5 | ||||
-rw-r--r-- | app/assets/javascripts/milestone_select.js.coffee | 60 | ||||
-rw-r--r-- | app/assets/javascripts/users_select.js.coffee | 3 | ||||
-rw-r--r-- | app/controllers/projects/milestones_controller.rb | 2 | ||||
-rw-r--r-- | app/finders/issuable_finder.rb | 4 | ||||
-rw-r--r-- | app/helpers/issuables_helper.rb | 8 | ||||
-rw-r--r-- | app/models/global_milestone.rb | 1 | ||||
-rw-r--r-- | app/views/shared/issuable/_milestone_dropdown.html.haml | 4 | ||||
-rw-r--r-- | spec/features/issues/filter_by_milestone_spec.rb | 40 | ||||
-rw-r--r-- | spec/features/merge_requests/filter_by_milestone_spec.rb | 38 |
12 files changed, 139 insertions, 59 deletions
diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 2b56ab2e6de..dd0465b9358 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -145,11 +145,10 @@ class GitLabDropdown selector = ".dropdown-page-one .dropdown-content a" @dropdown.on "click", selector, (e) -> - e.preventDefault() - self.rowClicked $(@) + selected = self.rowClicked $(@) if self.options.clicked - self.options.clicked.call(@,e) + self.options.clicked(selected) toggleLoading: -> $('.dropdown-menu', @dropdown).toggleClass LOADING_CLASS @@ -285,17 +284,15 @@ class GitLabDropdown selectedObject = @renderedData[selectedIndex] value = if @options.id then @options.id(selectedObject, el) else selectedObject.id field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']") + if el.hasClass(ACTIVE_CLASS) el.removeClass(ACTIVE_CLASS) field.remove() - else - fieldName = @options.fieldName - selectedIndex = el.parent().index() - if @renderedData - selectedObject = @renderedData[selectedIndex] - selectedObject.selected = true - value = if @options.id then @options.id(selectedObject, el) else selectedObject.id + # Toggle the dropdown label + if @options.toggleLabel + $(@el).find(".dropdown-toggle-text").text @options.toggleLabel + else if !value? field.remove() @@ -304,7 +301,7 @@ class GitLabDropdown @dropdown.parent().find("input[name='#{fieldName}']").remove() # Toggle active class for the tick mark - el.toggleClass "is-active" + el.addClass ACTIVE_CLASS # Toggle the dropdown label if @options.toggleLabel @@ -313,11 +310,13 @@ class GitLabDropdown if !field.length # Create hidden input for form input = "<input type='hidden' name='#{fieldName}' value='#{value}' />" - if @options.inputId? + if @options.inputId? input = $(input) .attr('id', @options.inputId) @dropdown.before input + return selectedObject + selectFirstRow: -> selector = '.dropdown-content li:first-child a' if @dropdown.find(".dropdown-toggle-page").length diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee index 1127b289264..b1479bfb449 100644 --- a/app/assets/javascripts/issues.js.coffee +++ b/app/assets/javascripts/issues.js.coffee @@ -1,7 +1,6 @@ @Issues = init: -> Issues.initSearch() - Issues.initSelects() Issues.initChecks() $("body").on "ajax:success", ".close_issue, .reopen_issue", -> @@ -17,18 +16,9 @@ $(this).html totalIssues - 1 reload: -> - Issues.initSelects() Issues.initChecks() $('#filter_issue_search').val($('#issue_search').val()) - initSelects: -> - $("select#update_state_event").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#update_assignee_id").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#update_milestone_id").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#label_name").select2(width: 'resolve', dropdownAutoWidth: true) - $("#milestone_id, #assignee_id, #label_name").on "change", -> - $(this).closest("form").submit() - initChecks: -> $(".check_all_issues").click -> $(".selected_issue").prop("checked", @checked) diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee index b5c7af9a8ad..e69a9e3e4b1 100644 --- a/app/assets/javascripts/labels_select.js.coffee +++ b/app/assets/javascripts/labels_select.js.coffee @@ -231,13 +231,14 @@ class @LabelsSelect saveLabelData() multiSelect: $dropdown.hasClass 'js-multiselect' - - clicked: -> + clicked: (label) -> page = $('body').data 'page' isIssueIndex = page is 'projects:issues:index' isMRIndex = page is page is 'projects:merge_requests:index' if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex) + selectedLabel = label.title + Issues.filterResults $dropdown.closest('form') else if $dropdown.hasClass 'js-filter-submit' $dropdown.closest('form').submit() diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index d1746c38e74..d61d03791fa 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -11,6 +11,7 @@ class @MilestoneSelect selectedMilestone = $dropdown.data('selected') showNo = $dropdown.data('show-no') showAny = $dropdown.data('show-any') + showUpcoming = $dropdown.data('show-upcoming') useId = $dropdown.data('use-id') defaultLabel = $dropdown.data('default-label') issuableId = $dropdown.data('issuable-id') @@ -32,22 +33,32 @@ class @MilestoneSelect $.ajax( url: milestonesUrl ).done (data) -> - if $dropdown.hasClass "js-extra-options" - if showNo - data.unshift( - id: '0' - title: 'No Milestone' - ) + extraOptions = [] + if showAny + extraOptions.push( + id: 0 + name: '' + title: 'Any Milestone' + ) - if showAny - data.unshift( - isAny: true - title: 'Any Milestone' - ) + if showNo + extraOptions.push( + id: -1 + name: 'No Milestone' + title: 'No Milestone' + ) - if data.length > 2 - data.splice 2, 0, 'divider' - callback(data) + if showUpcoming + extraOptions.push( + id: -2 + name: '#upcoming' + title: 'Upcoming' + ) + + if extraOptions.length > 2 + extraOptions.push 'divider' + + callback(extraOptions.concat(data)) filterable: true search: fields: ['title'] @@ -62,22 +73,25 @@ class @MilestoneSelect milestone.title id: (milestone) -> if !useId - if !milestone.isAny? - milestone.title - else - '' + milestone.name else milestone.id isSelected: (milestone) -> - milestone.title is selectedMilestone + milestone.name is selectedMilestone hidden: -> $selectbox.hide() $value.show() - clicked: (e) -> + clicked: (selected) -> if $dropdown.hasClass 'js-filter-bulk-update' return - - if $dropdown.hasClass 'js-filter-submit' + + if $dropdown.hasClass('js-filter-submit') + if selected.name? + selectedMilestone = selected.name + else if selected.title? + selectedMilestone = selected.title + else + selectedMilestone = '' $dropdown.parents('form').submit() else selected = $selectbox @@ -104,4 +118,4 @@ class @MilestoneSelect $value.html(milestoneLinkTemplate(data.milestone)) else $value.html(milestoneLinkNoneTemplate) - )
\ No newline at end of file + ) diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee index 3262d8b8c90..aec13e54c98 100644 --- a/app/assets/javascripts/users_select.js.coffee +++ b/app/assets/javascripts/users_select.js.coffee @@ -133,7 +133,7 @@ class @UsersSelect $selectbox.hide() $value.show() - clicked: -> + clicked: (user) -> page = $('body').data 'page' isIssueIndex = page is 'projects:issues:index' isMRIndex = page is page is 'projects:merge_requests:index' @@ -141,6 +141,7 @@ class @UsersSelect return if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex) + selectedId = user.id Issues.filterResults $dropdown.closest('form') else if $dropdown.hasClass 'js-filter-submit' $dropdown.closest('form').submit() diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index 5b0a63a933c..f7b6d137bde 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -24,7 +24,7 @@ class Projects::MilestonesController < Projects::ApplicationController @milestones = @milestones.page(params[:page]) end format.json do - render json: @milestones + render json: @milestones.to_json(methods: :name) end end end diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 046286dd9e1..f1df6832bf6 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -243,7 +243,7 @@ class IssuableFinder end def filter_by_upcoming_milestone? - params[:milestone_title] == '#upcoming' + params[:milestone_title] == Milestone::Upcoming.name end def by_milestone(items) @@ -252,7 +252,7 @@ class IssuableFinder items = items.where(milestone_id: [-1, nil]) elsif filter_by_upcoming_milestone? upcoming = Milestone.where(project_id: projects).upcoming - items = items.joins(:milestone).where(milestones: { title: upcoming.title }) + items = items.joins(:milestone).where(milestones: { title: upcoming.try(:title) }) else items = items.joins(:milestone).where(milestones: { title: params[:milestone_title] }) diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 62050691a39..b14b8218d02 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -47,6 +47,14 @@ module IssuablesHelper end end + def milestone_dropdown_label(milestone_title, default_label = "Milestone") + if milestone_title == Milestone::Upcoming.name + milestone_title = Milestone::Upcoming.title + end + + h(milestone_title.presence || default_label) + end + private def sidebar_gutter_collapsed? diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb index 97bd79af083..da7c265a371 100644 --- a/app/models/global_milestone.rb +++ b/app/models/global_milestone.rb @@ -14,6 +14,7 @@ class GlobalMilestone def initialize(title, milestones) @title = title + @name = title @milestones = milestones end diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml index 1c79494f816..e52d2e39e6b 100644 --- a/app/views/shared/issuable/_milestone_dropdown.html.haml +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -1,7 +1,7 @@ - if params[:milestone_title] = hidden_field_tag(:milestone_title, params[:milestone_title]) -= dropdown_tag(h(params[:milestone_title].presence || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit js-extra-options', filter: true, dropdown_class: "dropdown-menu-selectable", - placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: @project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do += dropdown_tag(milestone_dropdown_label(params[:milestone_title]), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", + placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: true, show_upcoming: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: @project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do - if @project %ul.dropdown-footer-list - if can? current_user, :admin_milestone, @project diff --git a/spec/features/issues/filter_by_milestone_spec.rb b/spec/features/issues/filter_by_milestone_spec.rb index d8e2ecb9feb..99445185893 100644 --- a/spec/features/issues/filter_by_milestone_spec.rb +++ b/spec/features/issues/filter_by_milestone_spec.rb @@ -11,7 +11,41 @@ feature 'Issue filtering by Milestone', feature: true do visit_issues(project) filter_by_milestone(Milestone::None.title) - expect(page).to have_css('.issue .title', count: 1) + expect(page).to have_css('.issue', count: 1) + end + + context 'filters by upcoming milestone', js: true do + it 'should not show issues with no expiry' do + create(:issue, project: project) + create(:issue, project: project, milestone: milestone) + + visit_issues(project) + filter_by_milestone(Milestone::Upcoming.title) + + expect(page).to have_css('.issue', count: 0) + end + + it 'should show issues in future' do + milestone = create(:milestone, project: project, due_date: Date.tomorrow) + create(:issue, project: project) + create(:issue, project: project, milestone: milestone) + + visit_issues(project) + filter_by_milestone(Milestone::Upcoming.title) + + expect(page).to have_css('.issue', count: 1) + end + + it 'should not show issues in past' do + milestone = create(:milestone, project: project, due_date: Date.yesterday) + create(:issue, project: project) + create(:issue, project: project, milestone: milestone) + + visit_issues(project) + filter_by_milestone(Milestone::Upcoming.title) + + expect(page).to have_css('.issue', count: 0) + end end scenario 'filters by a specific Milestone', js: true do @@ -21,7 +55,7 @@ feature 'Issue filtering by Milestone', feature: true do visit_issues(project) filter_by_milestone(milestone.title) - expect(page).to have_css('.issue .title', count: 1) + expect(page).to have_css('.issue', count: 1) end def visit_issues(project) @@ -30,8 +64,6 @@ feature 'Issue filtering by Milestone', feature: true do def filter_by_milestone(title) find(".js-milestone-select").click - sleep 0.5 find(".milestone-filter .dropdown-content a", text: title).click - sleep 1 end end diff --git a/spec/features/merge_requests/filter_by_milestone_spec.rb b/spec/features/merge_requests/filter_by_milestone_spec.rb index b76e4c74c79..c57ab5f3b03 100644 --- a/spec/features/merge_requests/filter_by_milestone_spec.rb +++ b/spec/features/merge_requests/filter_by_milestone_spec.rb @@ -11,7 +11,41 @@ feature 'Merge Request filtering by Milestone', feature: true do visit_merge_requests(project) filter_by_milestone(Milestone::None.title) - expect(page).to have_css('.merge-request-title', count: 1) + expect(page).to have_css('.merge-request', count: 1) + end + + context 'filters by upcoming milestone', js: true do + it 'should not show issues with no expiry' do + create(:merge_request, :with_diffs, source_project: project) + create(:merge_request, :simple, source_project: project, milestone: milestone) + + visit_merge_requests(project) + filter_by_milestone(Milestone::Upcoming.title) + + expect(page).to have_css('.merge-request', count: 0) + end + + it 'should show issues in future' do + milestone = create(:milestone, project: project, due_date: Date.tomorrow) + create(:merge_request, :with_diffs, source_project: project) + create(:merge_request, :simple, source_project: project, milestone: milestone) + + visit_merge_requests(project) + filter_by_milestone(Milestone::Upcoming.title) + + expect(page).to have_css('.merge-request', count: 1) + end + + it 'should not show issues in past' do + milestone = create(:milestone, project: project, due_date: Date.yesterday) + create(:merge_request, :with_diffs, source_project: project) + create(:merge_request, :simple, source_project: project, milestone: milestone) + + visit_merge_requests(project) + filter_by_milestone(Milestone::Upcoming.title) + + expect(page).to have_css('.merge-request', count: 0) + end end scenario 'filters by a specific Milestone', js: true do @@ -21,7 +55,7 @@ feature 'Merge Request filtering by Milestone', feature: true do visit_merge_requests(project) filter_by_milestone(milestone.title) - expect(page).to have_css('.merge-request-title', count: 1) + expect(page).to have_css('.merge-request', count: 1) end def visit_merge_requests(project) |