Skip to content
Snippets Groups Projects
Commit fc4dbd9d authored by Annabel Dunstone Gray's avatar Annabel Dunstone Gray
Browse files

Merge branch...

Merge branch '36409-frontend-for-clarifying-the-usefulness-of-the-search-bar-resting-state' into '36409-frontend-for-clarifying-the-usefulness-of-the-search-bar'

Improve search bar: resting state

See merge request gitlab-org/gitlab-ce!20882
parents 09897b3b 53a7020a
No related branches found
No related tags found
Loading
Pipeline #27064969 failed
/* eslint-disable no-return-assign, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-unused-vars, consistent-return, object-shorthand, prefer-template, quotes, class-methods-use-this, no-lonely-if, no-else-return, vars-on-top, max-len */
/* eslint-disable no-return-assign, one-var, no-var, one-var-declaration-per-line, no-unused-vars, consistent-return, object-shorthand, prefer-template, class-methods-use-this, no-lonely-if, vars-on-top, max-len */
import $ from 'jquery';
import axios from './lib/utils/axios_utils';
import DropdownUtils from './filtered_search/dropdown_utils';
import { isInGroupsPage, isInProjectPage, getGroupSlug, getProjectSlug } from './lib/utils/common_utils';
import {
isInGroupsPage,
isInProjectPage,
getGroupSlug,
getProjectSlug,
} from './lib/utils/common_utils';
/**
* Search input in top navigation bar.
......@@ -70,7 +75,6 @@ export default class SearchAutocomplete {
this.dropdown = this.wrap.find('.dropdown');
this.dropdownToggle = this.wrap.find('.js-dropdown-search-toggle');
this.dropdownContent = this.dropdown.find('.dropdown-content');
this.locationBadgeEl = this.getElement('.location-badge');
this.scopeInputEl = this.getElement('#scope');
this.searchInput = this.getElement('.search-input');
this.projectInputEl = this.getElement('#search_project_id');
......@@ -104,11 +108,11 @@ export default class SearchAutocomplete {
}
saveOriginalState() {
return this.originalState = this.serializeState();
return (this.originalState = this.serializeState());
}
saveTextLength() {
return this.lastTextLength = this.searchInput.val().length;
return (this.lastTextLength = this.searchInput.val().length);
}
createAutocomplete() {
......@@ -150,60 +154,63 @@ export default class SearchAutocomplete {
this.loadingSuggestions = true;
return axios.get(this.autocompletePath, {
params: {
project_id: this.projectId,
project_ref: this.projectRef,
term: term,
},
}).then((response) => {
// Hide dropdown menu if no suggestions returns
if (!response.data.length) {
this.disableAutocomplete();
return;
}
return axios
.get(this.autocompletePath, {
params: {
project_id: this.projectId,
project_ref: this.projectRef,
term: term,
},
})
.then(response => {
// Hide dropdown menu if no suggestions returns
if (!response.data.length) {
this.disableAutocomplete();
return;
}
const data = [];
// List results
let firstCategory = true;
let lastCategory;
for (let i = 0, len = response.data.length; i < len; i += 1) {
const suggestion = response.data[i];
// Add group header before list each group
if (lastCategory !== suggestion.category) {
if (!firstCategory) {
data.push('separator');
}
if (firstCategory) {
firstCategory = false;
const data = [];
// List results
let firstCategory = true;
let lastCategory;
for (let i = 0, len = response.data.length; i < len; i += 1) {
const suggestion = response.data[i];
// Add group header before list each group
if (lastCategory !== suggestion.category) {
if (!firstCategory) {
data.push('separator');
}
if (firstCategory) {
firstCategory = false;
}
data.push({
header: suggestion.category,
});
lastCategory = suggestion.category;
}
data.push({
header: suggestion.category,
id: `${suggestion.category.toLowerCase()}-${suggestion.id}`,
category: suggestion.category,
text: suggestion.label,
url: suggestion.url,
});
}
// Add option to proceed with the search
if (data.length) {
data.push('separator');
data.push({
text: `Result name contains "${term}"`,
url: `/search?search=${term}&project_id=${this.projectInputEl.val()}&group_id=${this.groupInputEl.val()}`,
});
lastCategory = suggestion.category;
}
data.push({
id: `${suggestion.category.toLowerCase()}-${suggestion.id}`,
category: suggestion.category,
text: suggestion.label,
url: suggestion.url,
});
}
// Add option to proceed with the search
if (data.length) {
data.push('separator');
data.push({
text: `Result name contains "${term}"`,
url: `/search?search=${term}&project_id=${this.projectInputEl.val()}&group_id=${this.groupInputEl.val()}`,
});
}
callback(data);
callback(data);
this.loadingSuggestions = false;
}).catch(() => {
this.loadingSuggestions = false;
});
this.loadingSuggestions = false;
})
.catch(() => {
this.loadingSuggestions = false;
});
}
getCategoryContents() {
......@@ -268,8 +275,6 @@ export default class SearchAutocomplete {
search_code: this.searchCodeInputEl.val(),
repository_ref: this.repositoryInputEl.val(),
scope: this.scopeInputEl.val(),
// Location badge
_location: this.locationBadgeEl.text(),
};
}
......@@ -279,7 +284,6 @@ export default class SearchAutocomplete {
this.searchInput.on('focus', this.onSearchInputFocus);
this.searchInput.on('blur', this.onSearchInputBlur);
this.clearInput.on('click', this.onClearInputClick);
this.locationBadgeEl.on('click', () => this.searchInput.focus());
}
enableAutocomplete() {
......@@ -304,10 +308,6 @@ export default class SearchAutocomplete {
onSearchInputKeyUp(e) {
switch (e.keyCode) {
case KEYCODE.BACKSPACE:
// when trying to remove the location badge
if (this.lastTextLength === 0 && this.badgePresent()) {
this.removeLocationBadge();
}
// When removing the last character and no badge is present
if (this.lastTextLength === 1) {
this.disableAutocomplete();
......@@ -368,37 +368,13 @@ export default class SearchAutocomplete {
}
}
addLocationBadge(item) {
var badgeText, category, value;
category = item.category != null ? item.category + ": " : '';
value = item.value != null ? item.value : '';
badgeText = "" + category + value;
this.locationBadgeEl.text(badgeText).show();
return this.wrap.addClass('has-location-badge');
}
hasLocationBadge() {
return this.wrap.is('.has-location-badge');
}
restoreOriginalState() {
var i, input, inputs, len;
inputs = Object.keys(this.originalState);
for (i = 0, len = inputs.length; i < len; i += 1) {
input = inputs[i];
this.getElement("#" + input).val(this.originalState[input]);
this.getElement('#' + input).val(this.originalState[input]);
}
if (this.originalState._location === '') {
return this.locationBadgeEl.hide();
} else {
return this.addLocationBadge({
value: this.originalState._location,
});
}
}
badgePresent() {
return this.locationBadgeEl.length;
}
resetSearchState() {
......@@ -407,22 +383,11 @@ export default class SearchAutocomplete {
results = [];
for (i = 0, len = inputs.length; i < len; i += 1) {
input = inputs[i];
// _location isnt a input
if (input === '_location') {
break;
}
results.push(this.getElement("#" + input).val(''));
results.push(this.getElement('#' + input).val(''));
}
return results;
}
removeLocationBadge() {
this.locationBadgeEl.hide();
this.resetSearchState();
this.wrap.removeClass('has-location-badge');
return this.disableAutocomplete();
}
disableAutocomplete() {
if (!this.searchInput.hasClass('disabled') && this.dropdown.hasClass('show')) {
this.searchInput.addClass('disabled');
......@@ -440,19 +405,11 @@ export default class SearchAutocomplete {
onClick(item, $el, e) {
if (window.location.pathname.indexOf(item.url) !== -1) {
if (!e.metaKey) e.preventDefault();
if (!this.badgePresent) {
if (item.category === 'Projects') {
this.projectInputEl.val(item.id);
this.addLocationBadge({
value: 'This project',
});
}
if (item.category === 'Groups') {
this.groupInputEl.val(item.id);
this.addLocationBadge({
value: 'This group',
});
}
if (item.category === 'Projects') {
this.projectInputEl.val(item.id);
}
if (item.category === 'Groups') {
this.groupInputEl.val(item.id);
}
$el.removeClass('is-active');
this.disableAutocomplete();
......
......@@ -3,7 +3,6 @@
*/
@mixin gitlab-theme(
$location-badge-color,
$search-and-nav-links,
$active-tab-border,
$border-and-box-shadow,
......@@ -119,12 +118,6 @@
}
}
.location-badge {
color: $location-badge-color;
background-color: rgba($search-and-nav-links, 0.1);
border-right: 1px solid $sidebar-text;
}
.search-input::placeholder {
color: rgba($search-and-nav-links, 0.8);
}
......@@ -141,10 +134,6 @@
background-color: $white-light;
}
.location-badge {
color: $gl-text-color;
}
.search-input-wrap {
.search-icon {
fill: rgba($search-and-nav-links, 0.8);
......@@ -200,7 +189,6 @@
body {
&.ui-indigo {
@include gitlab-theme(
$indigo-100,
$indigo-200,
$indigo-500,
$indigo-700,
......@@ -212,7 +200,6 @@ body {
&.ui-light-indigo {
@include gitlab-theme(
$indigo-100,
$indigo-200,
$indigo-500,
$indigo-500,
......@@ -224,7 +211,6 @@ body {
&.ui-blue {
@include gitlab-theme(
$theme-blue-100,
$theme-blue-200,
$theme-blue-500,
$theme-blue-700,
......@@ -236,7 +222,6 @@ body {
&.ui-light-blue {
@include gitlab-theme(
$theme-light-blue-100,
$theme-light-blue-200,
$theme-light-blue-500,
$theme-light-blue-500,
......@@ -248,7 +233,6 @@ body {
&.ui-green {
@include gitlab-theme(
$theme-green-100,
$theme-green-200,
$theme-green-500,
$theme-green-700,
......@@ -260,7 +244,6 @@ body {
&.ui-light-green {
@include gitlab-theme(
$theme-green-100,
$theme-green-200,
$theme-green-500,
$theme-green-500,
......@@ -272,7 +255,6 @@ body {
&.ui-red {
@include gitlab-theme(
$theme-red-100,
$theme-red-200,
$theme-red-500,
$theme-red-700,
......@@ -284,7 +266,6 @@ body {
&.ui-light-red {
@include gitlab-theme(
$theme-light-red-100,
$theme-light-red-200,
$theme-light-red-500,
$theme-light-red-500,
......@@ -296,7 +277,6 @@ body {
&.ui-dark {
@include gitlab-theme(
$theme-gray-100,
$theme-gray-200,
$theme-gray-500,
$theme-gray-700,
......@@ -308,7 +288,6 @@ body {
&.ui-light {
@include gitlab-theme(
$theme-gray-900,
$theme-gray-700,
$theme-gray-800,
$theme-gray-700,
......@@ -357,10 +336,6 @@ body {
&:hover {
background-color: $white-light;
box-shadow: inset 0 0 0 1px $blue-200;
.location-badge {
box-shadow: inset 0 0 0 1px $blue-200;
}
}
}
......@@ -373,13 +348,6 @@ body {
color: $gl-text-color;
}
}
.location-badge {
color: $theme-gray-700;
box-shadow: inset 0 0 0 1px $border-color;
background-color: $nav-badge-bg;
border-right: 0;
}
}
.nav-sidebar li.active {
......
......@@ -467,8 +467,7 @@ $award-emoji-positive-add-lines: #bb9c13;
*/
$search-input-border-color: rgba($blue-400, 0.8);
$search-input-focus-shadow-color: $dropdown-input-focus-shadow;
$search-input-width: 220px;
$location-badge-active-bg: $blue-500;
$search-input-width: 240px;
$location-icon-color: #e7e9ed;
/*
......
......@@ -24,8 +24,9 @@
box-shadow: 0 0 4px lighten($search-input-focus-shadow-color, 20%);
}
input[type="checkbox"]:hover {
box-shadow: 0 0 2px 2px lighten($search-input-focus-shadow-color, 20%), 0 0 0 1px lighten($search-input-focus-shadow-color, 20%);
input[type='checkbox']:hover {
box-shadow: 0 0 2px 2px lighten($search-input-focus-shadow-color, 20%),
0 0 0 1px lighten($search-input-focus-shadow-color, 20%);
}
.search {
......@@ -40,24 +41,14 @@ input[type="checkbox"]:hover {
height: 32px;
border: 0;
border-radius: $border-radius-default;
transition: border-color ease-in-out $default-transition-duration, background-color ease-in-out $default-transition-duration;
transition: border-color ease-in-out $default-transition-duration,
background-color ease-in-out $default-transition-duration;
&:hover {
box-shadow: none;
}
}
.location-badge {
white-space: nowrap;
height: 32px;
font-size: 12px;
margin: -4px 4px -4px -4px;
line-height: 25px;
padding: 4px 8px;
border-radius: $border-radius-default 0 0 $border-radius-default;
transition: border-color ease-in-out $default-transition-duration;
}
.search-input {
border: 0;
font-size: 14px;
......@@ -141,12 +132,6 @@ input[type="checkbox"]:hover {
color: $gl-text-color-tertiary;
}
}
.location-badge {
transition: all $default-transition-duration;
background-color: $nav-badge-bg;
border-color: $border-color;
}
}
&.has-value {
......@@ -159,12 +144,6 @@ input[type="checkbox"]:hover {
display: block;
}
}
&.has-location-badge {
.search-input-wrap {
width: 68%;
}
}
}
.search-holder {
......
......@@ -6,21 +6,19 @@
- group_data_attrs = { group_path: j(@group.path), name: @group.name, issues_path: issues_group_path(j(@group.path)), mr_path: merge_requests_group_path(j(@group.path)) }
- if @project && @project.persisted?
- project_data_attrs = { project_path: j(@project.path), name: j(@project.name), issues_path: project_issues_path(@project), mr_path: project_merge_requests_path(@project), issues_disabled: !@project.issues_enabled? }
.search.search-form{ class: "#{'has-location-badge' if label.present?}" }
.search.search-form
= form_tag search_path, method: :get, class: 'form-inline' do |f|
.search-input-container
- if label.present?
.location-badge= label
.search-input-wrap
.dropdown{ data: { url: search_autocomplete_path } }
= search_field_tag 'search', nil, placeholder: _('Search'),
= search_field_tag 'search', nil, placeholder: _('Search or jump to…'),
class: 'search-input dropdown-menu-toggle no-outline js-search-dashboard-options',
spellcheck: false,
tabindex: '1',
autocomplete: 'off',
data: { issues_path: issues_dashboard_path,
mr_path: merge_requests_dashboard_path },
aria: { label: _('Search') }
aria: { label: _('Search or jump to…') }
%button.hidden.js-dropdown-search-toggle{ type: 'button', data: { toggle: 'dropdown' } }
.dropdown-menu.dropdown-select
= dropdown_content do
......
......@@ -4542,6 +4542,9 @@ msgstr ""
msgid "Search milestones"
msgstr ""
msgid "Search or jump to…"
msgstr ""
msgid "Search project"
msgstr ""
......
......@@ -62,10 +62,6 @@
end
end
it 'contains location badge' do
expect(page).to have_selector('.has-location-badge')
end
context 'when clicking the search field', :js do
before do
page.find('#search').click
......
.search.search-form.has-location-badge
.search.search-form
%form.navbar-form
.search-input-container
%div.location-badge
This project
.search-input-wrap
.dropdown
%input#search.search-input.dropdown-menu-toggle
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment