From b3af3930c6c9a635cf21192c2d5a50dc51a9f5da Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 14:13:21 +0100 Subject: [PATCH 01/15] Started updating search UI --- app/assets/javascripts/dispatcher.js.coffee | 2 ++ .../javascripts/search_dropdowns.js.coffee | 6 +++++ app/assets/stylesheets/framework/common.scss | 1 + app/assets/stylesheets/pages/search.scss | 26 +++++++++++-------- app/helpers/search_helper.rb | 10 +++++++ app/views/search/_filter.html.haml | 20 +++++++------- app/views/search/_form.html.haml | 8 +++--- app/views/search/_results.html.haml | 7 +---- 8 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 app/assets/javascripts/search_dropdowns.js.coffee diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 2fdb7562515..8c9cb8ef792 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -108,6 +108,8 @@ class Dispatcher new BuildArtifacts() when 'projects:group_links:index' new GroupsSelect() + when 'search:show' + new SearchDropdowns() switch path.first() when 'admin' diff --git a/app/assets/javascripts/search_dropdowns.js.coffee b/app/assets/javascripts/search_dropdowns.js.coffee new file mode 100644 index 00000000000..37c5c94d8b0 --- /dev/null +++ b/app/assets/javascripts/search_dropdowns.js.coffee @@ -0,0 +1,6 @@ +class @SearchDropdowns + constructor: -> + $('.js-search-group-dropdown').glDropdown( + selectable: true + filterable: true + ) diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 2ade341c9dd..3386523dbf7 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -11,6 +11,7 @@ .prepend-top-10 { margin-top: 10px } .prepend-top-default { margin-top: $gl-padding !important; } .prepend-top-20 { margin-top: 20px } +.prepend-left-5 { margin-left: 5px } .prepend-left-10 { margin-left: 10px } .prepend-left-default { margin-left: $gl-padding; } .prepend-left-20 { margin-left: 20px } diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index f0f3744c6fa..4a5149ee64d 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -10,17 +10,6 @@ } } -.search-holder { - max-width: 600px; - margin: 0 auto; - margin-bottom: 20px; - - input { - border-color: #bbb; - font-weight: bold; - } -} - .search { margin-right: 10px; margin-left: 10px; @@ -163,3 +152,18 @@ } } } + +.search-holder { + display: -webkit-flex; + display: flex; + + .search-field-holder { + position: relative; + width: 100%; + } + + .dropdown-toggle { + width: 160px; + text-align: left; + } +} diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 8a97a74ad73..c8a7a686651 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -19,6 +19,16 @@ module SearchHelper end end + def search_entries_info(collection) + if collection.count > 0 + from = collection.offset_value + 1 + to = collection.offset_value + collection.length + count = collection.count + + "Showing #{from} - #{to} of #{count} results for All projects: \"#{@search_term}\"" + end + end + private # Autocomplete results for various settings pages diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index 4ef544136a8..091dae24f4c 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -1,16 +1,17 @@ -.dropdown.inline - %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} - %span.light Group: +.dropdown.append-right-5.prepend-left-5 + %button.dropdown-toggle.btn.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown" } } + Group: - if @group.present? %strong= @group.name - else Any %b.caret - .dropdown-menu.dropdown-select.dropdown-menu-selectable + .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-align-right .dropdown-title %span Filter results by group - %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + %button.dropdown-title-button.dropdown-menu-close{ aria: { label: "Close" } } = icon('times') + = dropdown_filter("Search groups") .dropdown-content %ul %li @@ -22,19 +23,20 @@ = link_to search_filter_path(group_id: group.id, project_id: nil), class: ("is-active" if params[:group_id] == group.id.to_s) do = group.name -.dropdown.inline.prepend-left-10.project-filter - %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} - %span.light Project: +.dropdown.project-filter.append-right-5.prepend-left-5 + %button.dropdown-toggle.btn{ type: "button", data: { toggle: "dropdown" } } + Project: - if @project.present? %strong= @project.name_with_namespace - else Any %b.caret - .dropdown-menu.dropdown-select.dropdown-menu-selectable + .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-align-right .dropdown-title %span Filter results by project %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} = icon('times') + = dropdown_filter("Search projects") .dropdown-content %ul %li diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml index a9dbc84da29..b05e8d4d908 100644 --- a/app/views/search/_form.html.haml +++ b/app/views/search/_form.html.haml @@ -4,11 +4,9 @@ = hidden_field_tag :snippets, params[:snippets] = hidden_field_tag :scope, params[:scope] - .search-holder.clearfix - .input-group + .search-holder + .search-field-holder.append-right-5 = search_field_tag :search, params[:search], placeholder: "Search for projects, issues etc", class: "form-control search-text-input", id: "dashboard_search", autofocus: true, spellcheck: false - %span.input-group-btn - = button_tag 'Search', class: "btn btn-primary" - unless params[:snippets].eql? 'true' - %br = render 'filter' if current_user + = button_tag 'Search', class: "btn btn-success btn-search prepend-left-5" diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index 60df348891c..a7615f580f0 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -2,9 +2,7 @@ = render partial: "search/results/empty" - else .gray-content-block - Search results for - %code - = @search_term + = search_entries_info @objects - unless @show_snippets - if @project in project #{link_to @project.name_with_namespace, [@project.namespace.becomes(Namespace), @project]} @@ -21,6 +19,3 @@ - if @scope != 'projects' = paginate @objects, theme: 'gitlab' - -:javascript - $(".search-results .term").highlight("#{escape_javascript(params[:search])}"); From bb50edb16d426fad1544f08cae7d2dbe41152e26 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 15:12:04 +0100 Subject: [PATCH 02/15] Loads group & projects on search page with ajax --- .../javascripts/search_dropdowns.js.coffee | 38 ++++++++++++++++++ app/views/search/_filter.html.haml | 40 +++++++++---------- app/views/search/_form.html.haml | 4 +- 3 files changed, 58 insertions(+), 24 deletions(-) diff --git a/app/assets/javascripts/search_dropdowns.js.coffee b/app/assets/javascripts/search_dropdowns.js.coffee index 37c5c94d8b0..747483d1d8b 100644 --- a/app/assets/javascripts/search_dropdowns.js.coffee +++ b/app/assets/javascripts/search_dropdowns.js.coffee @@ -3,4 +3,42 @@ class @SearchDropdowns $('.js-search-group-dropdown').glDropdown( selectable: true filterable: true + fieldName: 'group_id' + data: (term, callback) -> + Api.groups term, null, (data) -> + data.unshift( + name: 'Any' + ) + data.splice 1, 0, 'divider' + + callback(data) + id: (obj) -> + obj.id + text: (obj) -> + obj.name + clicked: => + @submitSearch() ) + + $('.js-search-project-dropdown').glDropdown( + selectable: true + filterable: true + fieldName: 'project_id' + data: (term, callback) -> + Api.projects term, 'id', (data) -> + data.unshift( + name_with_namespace: 'Any' + ) + data.splice 1, 0, 'divider' + + callback(data) + id: (obj) -> + obj.id + text: (obj) -> + obj.name_with_namespace + clicked: => + @submitSearch() + ) + + submitSearch: -> + $('.js-search-form').submit() diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index 091dae24f4c..a1562215e8b 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -1,3 +1,7 @@ +- if params[:group_id].present? + = hidden_field_tag :group_id, params[:group_id] +- if params[:project_id].present? + = hidden_field_tag :project_id, params[:project_id] .dropdown.append-right-5.prepend-left-5 %button.dropdown-toggle.btn.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown" } } Group: @@ -12,19 +16,11 @@ %button.dropdown-title-button.dropdown-menu-close{ aria: { label: "Close" } } = icon('times') = dropdown_filter("Search groups") - .dropdown-content - %ul - %li - = link_to search_filter_path(group_id: nil), class: ("is-active" if !params[:group_id].present?) do - Any - %li.divider - - current_user.authorized_groups.sort_by(&:name).each do |group| - %li - = link_to search_filter_path(group_id: group.id, project_id: nil), class: ("is-active" if params[:group_id] == group.id.to_s) do - = group.name + = dropdown_content + = dropdown_loading .dropdown.project-filter.append-right-5.prepend-left-5 - %button.dropdown-toggle.btn{ type: "button", data: { toggle: "dropdown" } } + %button.dropdown-toggle.btn.js-search-project-dropdown{ type: "button", data: { toggle: "dropdown" } } Project: - if @project.present? %strong= @project.name_with_namespace @@ -37,13 +33,15 @@ %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} = icon('times') = dropdown_filter("Search projects") - .dropdown-content - %ul - %li - = link_to search_filter_path(project_id: nil), class: ("is-active" if !params[:project_id].present?) do - Any - %li.divider - - current_user.authorized_projects.sort_by(&:name_with_namespace).each do |project| - %li - = link_to search_filter_path(project_id: project.id, group_id: nil), class: ("is-active" if params[:project_id] == project.id.to_s) do - = project.name_with_namespace + = dropdown_content + = dropdown_loading + -# .dropdown-content + -# %ul + -# %li + -# = link_to search_filter_path(project_id: nil), class: ("is-active" if !params[:project_id].present?) do + -# Any + -# %li.divider + -# - current_user.authorized_projects.sort_by(&:name_with_namespace).each do |project| + -# %li + -# = link_to search_filter_path(project_id: project.id, group_id: nil), class: ("is-active" if params[:project_id] == project.id.to_s) do + -# = project.name_with_namespace diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml index b05e8d4d908..6e550cc7621 100644 --- a/app/views/search/_form.html.haml +++ b/app/views/search/_form.html.haml @@ -1,6 +1,4 @@ -= form_tag search_path, method: :get do |f| - = hidden_field_tag :project_id, params[:project_id] - = hidden_field_tag :group_id, params[:group_id] += form_tag search_path, method: :get, class: 'js-search-form' do |f| = hidden_field_tag :snippets, params[:snippets] = hidden_field_tag :scope, params[:scope] From 8e4aa6e3910899e3907a9ea76415e616f175767b Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 15:32:30 +0100 Subject: [PATCH 03/15] Mobile updates for search UI --- app/assets/stylesheets/pages/search.scss | 40 +++++++++++++++++++++--- app/helpers/search_helper.rb | 2 +- app/views/search/_filter.html.haml | 22 ++++--------- app/views/search/_form.html.haml | 4 +-- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 4a5149ee64d..4f5b4bae208 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -154,16 +154,46 @@ } .search-holder { - display: -webkit-flex; - display: flex; + @media (min-width: $screen-sm-min) { + display: -webkit-flex; + display: flex; + } .search-field-holder { position: relative; width: 100%; + margin-right: 0; + + @media (min-width: $screen-sm-min) { + margin-right: 5px; + } } - .dropdown-toggle { - width: 160px; - text-align: left; + .btn-search { + width: 100%; + margin-top: 5px; + + @media (min-width: $screen-sm-min) { + width: auto; + margin-top: 0; + margin-left: 5px; + } + } + + .dropdown { + @media (min-width: $screen-sm-min) { + margin-left: 5px; + margin-right: 5px; + } + } + + .dropdown-menu-toggle { + width: 100%; + margin-top: 5px; + + @media (min-width: $screen-sm-min) { + width: 160px; + margin-top: 0; + } } } diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index c8a7a686651..1b8053d1b1c 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -25,7 +25,7 @@ module SearchHelper to = collection.offset_value + collection.length count = collection.count - "Showing #{from} - #{to} of #{count} results for All projects: \"#{@search_term}\"" + "Showing #{from} - #{to} of #{count} results for \"#{@search_term}\"" end end diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index a1562215e8b..58dac4b7bc0 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -2,11 +2,11 @@ = hidden_field_tag :group_id, params[:group_id] - if params[:project_id].present? = hidden_field_tag :project_id, params[:project_id] -.dropdown.append-right-5.prepend-left-5 - %button.dropdown-toggle.btn.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown" } } +.dropdown + %button.dropdown-menu-toggle.btn.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown" } } Group: - if @group.present? - %strong= @group.name + = @group.name - else Any %b.caret @@ -19,11 +19,11 @@ = dropdown_content = dropdown_loading -.dropdown.project-filter.append-right-5.prepend-left-5 - %button.dropdown-toggle.btn.js-search-project-dropdown{ type: "button", data: { toggle: "dropdown" } } +.dropdown.project-filter + %button.dropdown-menu-toggle.btn.js-search-project-dropdown{ type: "button", data: { toggle: "dropdown" } } Project: - if @project.present? - %strong= @project.name_with_namespace + = @project.name_with_namespace - else Any %b.caret @@ -35,13 +35,3 @@ = dropdown_filter("Search projects") = dropdown_content = dropdown_loading - -# .dropdown-content - -# %ul - -# %li - -# = link_to search_filter_path(project_id: nil), class: ("is-active" if !params[:project_id].present?) do - -# Any - -# %li.divider - -# - current_user.authorized_projects.sort_by(&:name_with_namespace).each do |project| - -# %li - -# = link_to search_filter_path(project_id: project.id, group_id: nil), class: ("is-active" if params[:project_id] == project.id.to_s) do - -# = project.name_with_namespace diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml index 6e550cc7621..24115ec3298 100644 --- a/app/views/search/_form.html.haml +++ b/app/views/search/_form.html.haml @@ -3,8 +3,8 @@ = hidden_field_tag :scope, params[:scope] .search-holder - .search-field-holder.append-right-5 + .search-field-holder = search_field_tag :search, params[:search], placeholder: "Search for projects, issues etc", class: "form-control search-text-input", id: "dashboard_search", autofocus: true, spellcheck: false - unless params[:snippets].eql? 'true' = render 'filter' if current_user - = button_tag 'Search', class: "btn btn-success btn-search prepend-left-5" + = button_tag 'Search', class: "btn btn-success btn-search" From be521d7d76fac2daa48ad17d330a61d3bbc236ba Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 15:55:31 +0100 Subject: [PATCH 04/15] icons on search bar --- app/assets/javascripts/dispatcher.js.coffee | 2 +- ...h_dropdowns.js.coffee => search.js.coffee} | 26 +++++++++++++++- app/assets/stylesheets/pages/search.scss | 30 +++++++++++++++++++ app/views/search/_filter.html.haml | 4 +-- app/views/search/_form.html.haml | 9 ++++-- 5 files changed, 65 insertions(+), 6 deletions(-) rename app/assets/javascripts/{search_dropdowns.js.coffee => search.js.coffee} (64%) diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 8c9cb8ef792..f91aa3c5ad7 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -109,7 +109,7 @@ class Dispatcher when 'projects:group_links:index' new GroupsSelect() when 'search:show' - new SearchDropdowns() + new Search() switch path.first() when 'admin' diff --git a/app/assets/javascripts/search_dropdowns.js.coffee b/app/assets/javascripts/search.js.coffee similarity index 64% rename from app/assets/javascripts/search_dropdowns.js.coffee rename to app/assets/javascripts/search.js.coffee index 747483d1d8b..cf978390aed 100644 --- a/app/assets/javascripts/search_dropdowns.js.coffee +++ b/app/assets/javascripts/search.js.coffee @@ -1,5 +1,7 @@ -class @SearchDropdowns +class @Search constructor: -> + @eventListeners() + $('.js-search-group-dropdown').glDropdown( selectable: true filterable: true @@ -40,5 +42,27 @@ class @SearchDropdowns @submitSearch() ) + eventListeners: -> + $(document) + .off 'keyup', '.js-search-input' + .on 'keyup', '.js-search-input', @searchKeyUp + + $(document) + .off 'click', '.js-search-clear' + .on 'click', '.js-search-clear', @clearSearchField + submitSearch: -> $('.js-search-form').submit() + + searchKeyUp: -> + $input = $(@) + + if $input.val() is '' + $('.js-search-clear').addClass 'hidden' + else + $('.js-search-clear').removeClass 'hidden' + + clearSearchField: -> + $('.js-search-input') + .val '' + .trigger 'keyup' diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 4f5b4bae208..2b2ba2c7862 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -169,6 +169,19 @@ } } + .search-icon { + position: absolute; + left: 10px; + top: 10px; + color: $gray-darkest; + pointer-events: none; + } + + .search-text-input { + padding-left: $gl-padding + 15px; + padding-right: $gl-padding + 15px; + } + .btn-search { width: 100%; margin-top: 5px; @@ -197,3 +210,20 @@ } } } + +.search-clear { + position: absolute; + right: 10px; + top: 10px; + padding: 0; + color: $gray-darkest; + line-height: 0; + background: none; + border: 0; + + &:hover, + &:focus { + color: $gl-link-color; + outline: none; + } +} diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index 58dac4b7bc0..fd598767393 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -9,7 +9,7 @@ = @group.name - else Any - %b.caret + = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-align-right .dropdown-title %span Filter results by group @@ -26,7 +26,7 @@ = @project.name_with_namespace - else Any - %b.caret + = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-align-right .dropdown-title %span Filter results by project diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml index 24115ec3298..3139be1cd37 100644 --- a/app/views/search/_form.html.haml +++ b/app/views/search/_form.html.haml @@ -4,7 +4,12 @@ .search-holder .search-field-holder - = search_field_tag :search, params[:search], placeholder: "Search for projects, issues etc", class: "form-control search-text-input", id: "dashboard_search", autofocus: true, spellcheck: false + = search_field_tag :search, params[:search], placeholder: "Search for projects, issues etc", class: "form-control search-text-input js-search-input", id: "dashboard_search", autofocus: true, spellcheck: false + = icon("search", class: "search-icon") + %button.search-clear.js-search-clear{ class: ("hidden" if !params[:search].present?), type: "button", tabindex: "-1" } + = icon("times-circle") + %span.sr-only + Clear search - unless params[:snippets].eql? 'true' = render 'filter' if current_user - = button_tag 'Search', class: "btn btn-success btn-search" + = button_tag "Search", class: "btn btn-success btn-search" From 1c8d01b05ac3e0c19d0ac21c06d6419ab884939b Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 15:58:40 +0100 Subject: [PATCH 05/15] Removed category icons --- app/views/search/_category.html.haml | 105 ++++++++++----------------- 1 file changed, 39 insertions(+), 66 deletions(-) diff --git a/app/views/search/_category.html.haml b/app/views/search/_category.html.haml index 2c3fca439f3..2c378231237 100644 --- a/app/views/search/_category.html.haml +++ b/app/views/search/_category.html.haml @@ -2,97 +2,70 @@ - if @project %li{class: ("active" if @scope == 'blobs')} = link_to search_filter_path(scope: 'blobs') do - = icon('code fw') - %span - Code - %span.badge - = @search_results.blobs_count + Code + %span.badge + = @search_results.blobs_count %li{class: ("active" if @scope == 'issues')} = link_to search_filter_path(scope: 'issues') do - = icon('exclamation-circle fw') - %span - Issues - %span.badge - = @search_results.issues_count + Issues + %span.badge + = @search_results.issues_count %li{class: ("active" if @scope == 'merge_requests')} = link_to search_filter_path(scope: 'merge_requests') do - = icon('tasks fw') - %span - Merge requests - %span.badge - = @search_results.merge_requests_count + Merge requests + %span.badge + = @search_results.merge_requests_count %li{class: ("active" if @scope == 'milestones')} = link_to search_filter_path(scope: 'milestones') do - = icon('clock-o fw') - %span - Milestones - %span.badge - = @search_results.milestones_count + Milestones + %span.badge + = @search_results.milestones_count %li{class: ("active" if @scope == 'notes')} = link_to search_filter_path(scope: 'notes') do - = icon('comments fw') - %span - Comments - %span.badge - = @search_results.notes_count + Comments + %span.badge + = @search_results.notes_count %li{class: ("active" if @scope == 'wiki_blobs')} = link_to search_filter_path(scope: 'wiki_blobs') do - = icon('book fw') - %span - Wiki - %span.badge - = @search_results.wiki_blobs_count + Wiki + %span.badge + = @search_results.wiki_blobs_count %li{class: ("active" if @scope == 'commits')} = link_to search_filter_path(scope: 'commits') do - = icon('history fw') - %span - Commits - %span.badge - = @search_results.commits_count + Commits + %span.badge + = @search_results.commits_count - elsif @show_snippets %li{class: ("active" if @scope == 'snippet_blobs')} = link_to search_filter_path(scope: 'snippet_blobs', snippets: true, group_id: nil, project_id: nil) do - = icon('code fw') - %span - Snippet Contents - %span.badge - = @search_results.snippet_blobs_count + Snippet Contents + %span.badge + = @search_results.snippet_blobs_count %li{class: ("active" if @scope == 'snippet_titles')} = link_to search_filter_path(scope: 'snippet_titles', snippets: true, group_id: nil, project_id: nil) do - = icon('book fw') - %span - Titles and Filenames - %span.badge - = @search_results.snippet_titles_count + Titles and Filenames + %span.badge + = @search_results.snippet_titles_count - else %li{class: ("active" if @scope == 'projects')} = link_to search_filter_path(scope: 'projects') do - = icon('bookmark fw') - %span - Projects - %span.badge - = @search_results.projects_count + Projects + %span.badge + = @search_results.projects_count %li{class: ("active" if @scope == 'issues')} = link_to search_filter_path(scope: 'issues') do - = icon('exclamation-circle fw') - %span - Issues - %span.badge - = @search_results.issues_count + Issues + %span.badge + = @search_results.issues_count %li{class: ("active" if @scope == 'merge_requests')} = link_to search_filter_path(scope: 'merge_requests') do - = icon('tasks fw') - %span - Merge requests - %span.badge - = @search_results.merge_requests_count + Merge requests + %span.badge + = @search_results.merge_requests_count %li{class: ("active" if @scope == 'milestones')} = link_to search_filter_path(scope: 'milestones') do - = icon('clock-o fw') - %span - Milestones - %span.badge - = @search_results.milestones_count - + Milestones + %span.badge + = @search_results.milestones_count From aa316cbfff8a3a1c416a3de6054608c96106d39f Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 16:06:21 +0100 Subject: [PATCH 06/15] Changes dropdown toggle on search dropdowns --- app/assets/javascripts/search.js.coffee | 10 ++++++++-- app/views/search/_filter.html.haml | 26 +++++++++++++------------ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/assets/javascripts/search.js.coffee b/app/assets/javascripts/search.js.coffee index cf978390aed..f435e2a33a4 100644 --- a/app/assets/javascripts/search.js.coffee +++ b/app/assets/javascripts/search.js.coffee @@ -1,8 +1,10 @@ class @Search constructor: -> + $groupDropdown = $('.js-search-group-dropdown') + $projectDropdown = $('.js-search-project-dropdown') @eventListeners() - $('.js-search-group-dropdown').glDropdown( + $groupDropdown.glDropdown( selectable: true filterable: true fieldName: 'group_id' @@ -18,11 +20,13 @@ class @Search obj.id text: (obj) -> obj.name + toggleLabel: (obj) -> + "#{$groupDropdown.data('default-label')} #{obj.name}" clicked: => @submitSearch() ) - $('.js-search-project-dropdown').glDropdown( + $projectDropdown.glDropdown( selectable: true filterable: true fieldName: 'project_id' @@ -38,6 +42,8 @@ class @Search obj.id text: (obj) -> obj.name_with_namespace + toggleLabel: (obj) -> + "#{$projectDropdown.data('default-label')} #{obj.name_with_namespace}" clicked: => @submitSearch() ) diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index fd598767393..678d620d21b 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -3,12 +3,13 @@ - if params[:project_id].present? = hidden_field_tag :project_id, params[:project_id] .dropdown - %button.dropdown-menu-toggle.btn.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown" } } - Group: - - if @group.present? - = @group.name - - else - Any + %button.dropdown-menu-toggle.btn.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown", default_label: "Group:" } } + %span.dropdown-toggle-text + Group: + - if @group.present? + = @group.name + - else + Any = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-align-right .dropdown-title @@ -20,12 +21,13 @@ = dropdown_loading .dropdown.project-filter - %button.dropdown-menu-toggle.btn.js-search-project-dropdown{ type: "button", data: { toggle: "dropdown" } } - Project: - - if @project.present? - = @project.name_with_namespace - - else - Any + %button.dropdown-menu-toggle.btn.js-search-project-dropdown{ type: "button", data: { toggle: "dropdown", default_label: "Project:" } } + %span.dropdown-toggle-text + Project: + - if @project.present? + = @project.name_with_namespace + - else + Any = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-align-right .dropdown-title From 6ac549c1dea7a30d6c2245024879ec5761c40061 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 16:09:34 +0100 Subject: [PATCH 07/15] Use helper method --- app/views/search/_filter.html.haml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index 678d620d21b..ef1c0296d49 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -12,10 +12,7 @@ Any = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-align-right - .dropdown-title - %span Filter results by group - %button.dropdown-title-button.dropdown-menu-close{ aria: { label: "Close" } } - = icon('times') + = dropdown_title("Filter results by group") = dropdown_filter("Search groups") = dropdown_content = dropdown_loading @@ -30,10 +27,7 @@ Any = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-align-right - .dropdown-title - %span Filter results by project - %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} - = icon('times') + = dropdown_title("Filter results by project") = dropdown_filter("Search projects") = dropdown_content = dropdown_loading From d369d529380167ac926ec916eea85419ee65e5b9 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 16:29:35 +0100 Subject: [PATCH 08/15] Focus field --- app/assets/javascripts/search.js.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/search.js.coffee b/app/assets/javascripts/search.js.coffee index f435e2a33a4..661e1195f60 100644 --- a/app/assets/javascripts/search.js.coffee +++ b/app/assets/javascripts/search.js.coffee @@ -72,3 +72,4 @@ class @Search $('.js-search-input') .val '' .trigger 'keyup' + .focus() From 3b5879e50c11baf3039512107c114c595baaf14e Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 16:32:25 +0100 Subject: [PATCH 09/15] Truncate issue description --- app/views/search/results/_issue.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/search/results/_issue.html.haml b/app/views/search/results/_issue.html.haml index 710f5613c81..640890fbe92 100644 --- a/app/views/search/results/_issue.html.haml +++ b/app/views/search/results/_issue.html.haml @@ -7,7 +7,7 @@ - if issue.description.present? .description.term = preserve do - = search_md_sanitize(markdown(issue.description, { project: issue.project })) + = search_md_sanitize(markdown(truncate(issue.description, length: 200, separator: " "), { project: issue.project })) %span.light #{issue.project.name_with_namespace} - if issue.closed? From 262a3dd482680466b5bdc3fa1b94e06491e7a906 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Apr 2016 17:00:53 +0100 Subject: [PATCH 10/15] Humanize scope text --- app/helpers/search_helper.rb | 4 ++-- app/views/search/_results.html.haml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 1b8053d1b1c..43169d1c9db 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -19,13 +19,13 @@ module SearchHelper end end - def search_entries_info(collection) + def search_entries_info(collection, scope, term) if collection.count > 0 from = collection.offset_value + 1 to = collection.offset_value + collection.length count = collection.count - "Showing #{from} - #{to} of #{count} results for \"#{@search_term}\"" + "Showing #{from} - #{to} of #{count} #{scope.humanize(capitalize: false)} for \"#{term}\"" end end diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index a7615f580f0..252c1508a50 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -2,7 +2,7 @@ = render partial: "search/results/empty" - else .gray-content-block - = search_entries_info @objects + = search_entries_info @objects, @scope, @search_term - unless @show_snippets - if @project in project #{link_to @project.name_with_namespace, [@project.namespace.becomes(Namespace), @project]} From f5bea9df5325fe136042fb32fe282cc04c2ec91a Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 18 Apr 2016 09:22:36 +0100 Subject: [PATCH 11/15] Fixed tests --- app/assets/stylesheets/pages/search.scss | 8 ++++++-- features/search.feature | 5 +++++ features/steps/search.rb | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 2b2ba2c7862..0252f464133 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -156,12 +156,15 @@ .search-holder { @media (min-width: $screen-sm-min) { display: -webkit-flex; - display: flex; + display: -ms-flexbox; + display: flex; } .search-field-holder { + -webkit-flex: 1 0 auto; + -ms-flex: 1 0 auto; + flex: 1 0 auto; position: relative; - width: 100%; margin-right: 0; @media (min-width: $screen-sm-min) { @@ -203,6 +206,7 @@ .dropdown-menu-toggle { width: 100%; margin-top: 5px; + border-radius: $border-radius-base; @media (min-width: $screen-sm-min) { width: 160px; diff --git a/features/search.feature b/features/search.feature index 3cd52810e59..a946a836525 100644 --- a/features/search.feature +++ b/features/search.feature @@ -30,11 +30,13 @@ Feature: Search Then I should see "Foo" link in the search results And I should not see "Bar" link in the search results + @javascript Scenario: I should see project code I am looking for When I click project "Shop" link And I search for "rspec" Then I should see code results for project "Shop" + @javascript Scenario: I should see project issues And project has issues When I click project "Shop" link @@ -43,6 +45,7 @@ Feature: Search Then I should see "Foo" link in the search results And I should not see "Bar" link in the search results + @javascript Scenario: I should see project merge requests And project has merge requests When I click project "Shop" link @@ -51,6 +54,7 @@ Feature: Search Then I should see "Foo" link in the search results And I should not see "Bar" link in the search results + @javascript Scenario: I should see project milestones And project has milestones When I click project "Shop" link @@ -59,6 +63,7 @@ Feature: Search Then I should see "Foo" link in the search results And I should not see "Bar" link in the search results + @javascript Scenario: I should see Wiki blobs And project has Wiki content When I click project "Shop" link diff --git a/features/steps/search.rb b/features/steps/search.rb index 0ad837ebe1d..f885baf8453 100644 --- a/features/steps/search.rb +++ b/features/steps/search.rb @@ -35,6 +35,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps end step 'I click project "Shop" link' do + click_button 'Project' page.within '.project-filter' do click_link project.name_with_namespace end From 3137559dfd45ff0e7fa6653ed1ba3d75836e4c45 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 19 Apr 2016 08:52:15 +0100 Subject: [PATCH 12/15] Fixed issue with dropdown option not sticking CHANGELOG item --- CHANGELOG | 1 + app/controllers/search_controller.rb | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a4794485476..083b5893696 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -133,6 +133,7 @@ v 8.6.7 - Fix persistent XSS vulnerability in `commit_person_link` helper - Fix persistent XSS vulnerability in Label and Milestone dropdowns - Fix vulnerability that made it possible to enumerate private projects belonging to group + - Updated search UI v 8.6.6 - Expire the exists cache before deletion to ensure project dir actually exists (Stan Hu). !3413 diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index e42d2d73947..8263bb5b0ac 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -6,10 +6,6 @@ class SearchController < ApplicationController layout 'search' def show - return if params[:search].nil? || params[:search].blank? - - @search_term = params[:search] - if params[:project_id].present? @project = Project.find_by(id: params[:project_id]) @project = nil unless can?(current_user, :download_code, @project) @@ -20,6 +16,9 @@ class SearchController < ApplicationController @group = nil unless can?(current_user, :read_group, @group) end + return if params[:search].nil? || params[:search].blank? + @search_term = params[:search] + @scope = params[:scope] @show_snippets = params[:snippets].eql? 'true' From 06276bd3550e589c520027c16f108b92a48fb44a Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 21 Apr 2016 11:05:50 +0100 Subject: [PATCH 13/15] Correctly shows no results text Correct search results count --- app/helpers/search_helper.rb | 2 +- app/views/search/_results.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 43169d1c9db..7f585cd5dd9 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -23,7 +23,7 @@ module SearchHelper if collection.count > 0 from = collection.offset_value + 1 to = collection.offset_value + collection.length - count = collection.count + count = collection.total_count "Showing #{from} - #{to} of #{count} #{scope.humanize(capitalize: false)} for \"#{term}\"" end diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index 252c1508a50..204f5a36f85 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -1,4 +1,4 @@ -- if @search_results.empty? +- if @objects.empty? = render partial: "search/results/empty" - else .gray-content-block From 7ee5de19804842033c3cfdc2bf1209c27adcd7b7 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 21 Apr 2016 17:21:03 +0100 Subject: [PATCH 14/15] Consistent border radius --- app/assets/stylesheets/framework/dropdowns.scss | 4 ++-- app/assets/stylesheets/framework/variables.scss | 1 - app/assets/stylesheets/pages/search.scss | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 239eaf15cc1..4bf3a050403 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -42,7 +42,7 @@ font-size: 15px; text-align: left; border: 1px solid $dropdown-toggle-border-color; - border-radius: $dropdown-border-radius; + border-radius: $border-radius-base; outline: 0; text-overflow: ellipsis; white-space: nowrap; @@ -80,7 +80,7 @@ padding: 10px 0; background-color: $dropdown-bg; border: 1px solid $dropdown-border-color; - border-radius: $dropdown-border-radius; + border-radius: $border-radius-base; box-shadow: 0 2px 4px $dropdown-shadow-color; &.is-loading { diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index ef37ade3b7b..ecadbf32f6a 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -183,7 +183,6 @@ $regular_font: 'Source Sans Pro', "Helvetica Neue", Helvetica, Arial, sans-serif /* * Dropdowns */ -$dropdown-border-radius: 2px; $dropdown-width: 300px; $dropdown-bg: #fff; $dropdown-link-color: #555; diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 0252f464133..7f642d9edbf 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -206,7 +206,6 @@ .dropdown-menu-toggle { width: 100%; margin-top: 5px; - border-radius: $border-radius-base; @media (min-width: $screen-sm-min) { width: 160px; From 97c1a1ef64cdce75afa24075ea77333e76c9ccbf Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 26 Apr 2016 09:02:28 +0100 Subject: [PATCH 15/15] Updated based on feedback Changed some variable names Fixed CHANGELOG entry --- CHANGELOG | 2 +- app/controllers/search_controller.rb | 5 +++-- app/helpers/search_helper.rb | 12 ++++++------ app/views/search/_results.html.haml | 10 +++++----- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 083b5893696..e66f8a61b95 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ v 8.8.0 (unreleased) - Remove future dates from contribution calendar graph. - Fix error when visiting commit builds page before build was updated - Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project + - Updated search UI v 8.7.1 (unreleased) - Fix .gitlab-ci.yml parsing issue when hidde job is a template without script definition. !3849 @@ -133,7 +134,6 @@ v 8.6.7 - Fix persistent XSS vulnerability in `commit_person_link` helper - Fix persistent XSS vulnerability in Label and Milestone dropdowns - Fix vulnerability that made it possible to enumerate private projects belonging to group - - Updated search UI v 8.6.6 - Expire the exists cache before deletion to ensure project dir actually exists (Stan Hu). !3413 diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 8263bb5b0ac..69c92d2bed2 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -6,6 +6,8 @@ class SearchController < ApplicationController layout 'search' def show + return if params[:search].nil? || params[:search].blank? + if params[:project_id].present? @project = Project.find_by(id: params[:project_id]) @project = nil unless can?(current_user, :download_code, @project) @@ -16,7 +18,6 @@ class SearchController < ApplicationController @group = nil unless can?(current_user, :read_group, @group) end - return if params[:search].nil? || params[:search].blank? @search_term = params[:search] @scope = params[:scope] @@ -43,7 +44,7 @@ class SearchController < ApplicationController Search::GlobalService.new(current_user, params).execute end - @objects = @search_results.objects(@scope, params[:page]) + @search_objects = @search_results.objects(@scope, params[:page]) end def autocomplete diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 7f585cd5dd9..24c4c098c65 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -20,13 +20,13 @@ module SearchHelper end def search_entries_info(collection, scope, term) - if collection.count > 0 - from = collection.offset_value + 1 - to = collection.offset_value + collection.length - count = collection.total_count + return unless collection.count > 0 - "Showing #{from} - #{to} of #{count} #{scope.humanize(capitalize: false)} for \"#{term}\"" - end + from = collection.offset_value + 1 + to = collection.offset_value + collection.length + count = collection.total_count + + "Showing #{from} - #{to} of #{count} #{scope.humanize(capitalize: false)} for \"#{term}\"" end private diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index 204f5a36f85..711337f308e 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -1,8 +1,8 @@ -- if @objects.empty? +- if @search_objects.empty? = render partial: "search/results/empty" - else .gray-content-block - = search_entries_info @objects, @scope, @search_term + = search_entries_info(@search_objects, @scope, @search_term) - unless @show_snippets - if @project in project #{link_to @project.name_with_namespace, [@project.namespace.becomes(Namespace), @project]} @@ -13,9 +13,9 @@ .search-results - if @scope == 'projects' .term - = render 'shared/projects/list', projects: @objects + = render 'shared/projects/list', projects: @search_objects - else - = render partial: "search/results/#{@scope.singularize}", collection: @objects + = render partial: "search/results/#{@scope.singularize}", collection: @search_objects - if @scope != 'projects' - = paginate @objects, theme: 'gitlab' + = paginate(@search_objects, theme: 'gitlab')