Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
李少辉-开发者
gitlab-foss
提交
51c19616
G
gitlab-foss
项目概览
李少辉-开发者
/
gitlab-foss
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gitlab-foss
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
51c19616
编写于
6月 02, 2017
作者:
T
Tim Zallmann
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'winh-styled-people-search-bar' into 'master'
Style people in issuable search bar Closes #30468 See merge request !11402
上级
b1f86081
0583916d
变更
12
展开全部
隐藏空白更改
内联
并排
Showing
12 changed file
with
414 addition
and
143 deletion
+414
-143
app/assets/javascripts/filtered_search/dropdown_utils.js
app/assets/javascripts/filtered_search/dropdown_utils.js
+4
-1
app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
...ascripts/filtered_search/filtered_search_visual_tokens.js
+60
-12
app/assets/stylesheets/framework/filters.scss
app/assets/stylesheets/framework/filters.scss
+2
-1
app/views/shared/issuable/_search_bar.html.haml
app/views/shared/issuable/_search_bar.html.haml
+2
-2
changelogs/unreleased/winh-styled-people-search-bar.yml
changelogs/unreleased/winh-styled-people-search-bar.yml
+4
-0
spec/features/boards/modal_filter_spec.rb
spec/features/boards/modal_filter_spec.rb
+2
-2
spec/features/issues/filtered_search/filter_issues_spec.rb
spec/features/issues/filtered_search/filter_issues_spec.rb
+1
-1
spec/features/issues/filtered_search/visual_tokens_spec.rb
spec/features/issues/filtered_search/visual_tokens_spec.rb
+3
-1
spec/javascripts/filtered_search/dropdown_utils_spec.js
spec/javascripts/filtered_search/dropdown_utils_spec.js
+29
-0
spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
...pts/filtered_search/filtered_search_visual_tokens_spec.js
+288
-118
spec/javascripts/fixtures/issues.rb
spec/javascripts/fixtures/issues.rb
+11
-0
spec/javascripts/helpers/filtered_search_spec_helper.js
spec/javascripts/helpers/filtered_search_spec_helper.js
+8
-5
未找到文件。
app/assets/javascripts/filtered_search/dropdown_utils.js
浏览文件 @
51c19616
...
...
@@ -102,10 +102,13 @@ class DropdownUtils {
if
(
token
.
classList
.
contains
(
'
js-visual-token
'
))
{
const
name
=
token
.
querySelector
(
'
.name
'
);
const
value
=
token
.
querySelector
(
'
.value
'
);
const
valueContainer
=
token
.
querySelector
(
'
.value-container
'
);
const
symbol
=
value
&&
value
.
dataset
.
symbol
?
value
.
dataset
.
symbol
:
''
;
let
valueText
=
''
;
if
(
value
&&
value
.
innerText
)
{
if
(
valueContainer
&&
valueContainer
.
dataset
.
originalValue
)
{
valueText
=
valueContainer
.
dataset
.
originalValue
;
}
else
if
(
value
&&
value
.
innerText
)
{
valueText
=
value
.
innerText
;
}
...
...
app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
浏览文件 @
51c19616
import
AjaxCache
from
'
~
/lib/utils/ajax_cache
'
;
import
'
~
/flash
'
;
/* global Flash */
import
AjaxCache
from
'
..
/lib/utils/ajax_cache
'
;
import
'
..
/flash
'
;
/* global Flash */
import
FilteredSearchContainer
from
'
./container
'
;
import
UsersCache
from
'
../lib/utils/users_cache
'
;
class
FilteredSearchVisualTokens
{
static
getLastVisualTokenBeforeInput
()
{
...
...
@@ -82,12 +83,42 @@ class FilteredSearchVisualTokens {
.
catch
(()
=>
new
Flash
(
'
An error occurred while fetching label colors.
'
));
}
static
updateUserTokenAppearance
(
tokenValueContainer
,
tokenValueElement
,
tokenValue
)
{
if
(
tokenValue
===
'
none
'
)
{
return
Promise
.
resolve
();
}
const
username
=
tokenValue
.
replace
(
/^@/
,
''
);
return
UsersCache
.
retrieve
(
username
)
.
then
((
user
)
=>
{
if
(
!
user
)
{
return
;
}
/* eslint-disable no-param-reassign */
tokenValueContainer
.
dataset
.
originalValue
=
tokenValue
;
tokenValueElement
.
innerHTML
=
`
<img class="avatar s20" src="
${
user
.
avatar_url
}
" alt="
${
user
.
name
}
's avatar">
${
user
.
name
}
`
;
/* eslint-enable no-param-reassign */
})
// ignore error and leave username in the search bar
.
catch
(()
=>
{
});
}
static
renderVisualTokenValue
(
parentElement
,
tokenName
,
tokenValue
)
{
const
tokenValueContainer
=
parentElement
.
querySelector
(
'
.value-container
'
);
tokenValueContainer
.
querySelector
(
'
.value
'
).
innerText
=
tokenValue
;
const
tokenValueElement
=
tokenValueContainer
.
querySelector
(
'
.value
'
);
tokenValueElement
.
innerText
=
tokenValue
;
if
(
tokenName
.
toLowerCase
()
===
'
label
'
)
{
const
tokenType
=
tokenName
.
toLowerCase
();
if
(
tokenType
===
'
label
'
)
{
FilteredSearchVisualTokens
.
updateLabelTokenColor
(
tokenValueContainer
,
tokenValue
);
}
else
if
((
tokenType
===
'
author
'
)
||
(
tokenType
===
'
assignee
'
))
{
FilteredSearchVisualTokens
.
updateUserTokenAppearance
(
tokenValueContainer
,
tokenValueElement
,
tokenValue
,
);
}
}
...
...
@@ -153,6 +184,12 @@ class FilteredSearchVisualTokens {
if
(
!
lastVisualToken
)
return
''
;
const
valueContainer
=
lastVisualToken
.
querySelector
(
'
.value-container
'
);
const
originalValue
=
valueContainer
&&
valueContainer
.
dataset
.
originalValue
;
if
(
originalValue
)
{
return
originalValue
;
}
const
value
=
lastVisualToken
.
querySelector
(
'
.value
'
);
const
name
=
lastVisualToken
.
querySelector
(
'
.name
'
);
...
...
@@ -205,17 +242,28 @@ class FilteredSearchVisualTokens {
const
inputLi
=
input
.
parentElement
;
tokenContainer
.
replaceChild
(
inputLi
,
token
);
const
name
=
token
.
querySelector
(
'
.name
'
);
const
value
=
token
.
querySelector
(
'
.value
'
)
;
const
name
Element
=
token
.
querySelector
(
'
.name
'
);
let
value
;
if
(
token
.
classList
.
contains
(
'
filtered-search-token
'
)
&&
value
)
{
FilteredSearchVisualTokens
.
addFilterVisualToken
(
name
.
innerText
);
input
.
value
=
value
.
innerText
;
}
else
{
// token is a search term
input
.
value
=
name
.
innerText
;
if
(
token
.
classList
.
contains
(
'
filtered-search-token
'
))
{
FilteredSearchVisualTokens
.
addFilterVisualToken
(
nameElement
.
innerText
);
const
valueContainerElement
=
token
.
querySelector
(
'
.value-container
'
);
value
=
valueContainerElement
.
dataset
.
originalValue
;
if
(
!
value
)
{
const
valueElement
=
valueContainerElement
.
querySelector
(
'
.value
'
);
value
=
valueElement
.
innerText
;
}
}
// token is a search term
if
(
!
value
)
{
value
=
nameElement
.
innerText
;
}
input
.
value
=
value
;
// Opens dropdown
const
inputEvent
=
new
Event
(
'
input
'
);
input
.
dispatchEvent
(
inputEvent
);
...
...
app/assets/stylesheets/framework/filters.scss
浏览文件 @
51c19616
...
...
@@ -90,6 +90,7 @@
.filtered-search-term
{
display
:
-
webkit-flex
;
display
:
flex
;
flex-shrink
:
0
;
margin-top
:
5px
;
margin-bottom
:
5px
;
...
...
@@ -239,7 +240,7 @@
width
:
35px
;
background-color
:
$white-light
;
border
:
none
;
position
:
absolute
;
position
:
static
;
right
:
0
;
height
:
100%
;
outline
:
none
;
...
...
app/views/shared/issuable/_search_bar.html.haml
浏览文件 @
51c19616
...
...
@@ -26,8 +26,6 @@
%li
.input-token
%input
.form-control.filtered-search
{
id:
"filtered-search-#{type.to_s}"
,
placeholder:
'Search or filter results...'
,
data:
{
'project-id'
=>
@project
.
id
,
'username-params'
=>
@users
.
to_json
(
only:
[
:id
,
:username
]),
'base-endpoint'
=>
namespace_project_path
(
@project
.
namespace
,
@project
)
}
}
=
icon
(
'filter'
)
%button
.clear-search.hidden
{
type:
'button'
}
=
icon
(
'times'
)
#js-dropdown-hint
.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown
%ul
{
data:
{
dropdown:
true
}
}
%li
.filter-dropdown-item
{
data:
{
action:
'submit'
}
}
...
...
@@ -95,6 +93,8 @@
%span
.dropdown-label-box
{
style:
'
background:
{{
color
}}
'
}
%span
.label-title.js-data-value
{{title}}
%button
.clear-search.hidden
{
type:
'button'
}
=
icon
(
'times'
)
.filter-dropdown-container
-
if
type
==
:boards
-
if
can?
(
current_user
,
:admin_list
,
@project
)
...
...
changelogs/unreleased/winh-styled-people-search-bar.yml
0 → 100644
浏览文件 @
51c19616
---
title
:
Style people in issuable search bar
merge_request
:
11402
author
:
spec/features/boards/modal_filter_spec.rb
浏览文件 @
51c19616
...
...
@@ -89,7 +89,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do
page
.
within
(
'.add-issues-modal'
)
do
wait_for_requests
expect
(
page
).
to
have_selector
(
'.js-visual-token'
,
text:
user2
.
user
name
)
expect
(
page
).
to
have_selector
(
'.js-visual-token'
,
text:
user2
.
name
)
expect
(
page
).
to
have_selector
(
'.card'
,
count:
1
)
end
end
...
...
@@ -125,7 +125,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do
page
.
within
(
'.add-issues-modal'
)
do
wait_for_requests
expect
(
page
).
to
have_selector
(
'.js-visual-token'
,
text:
user2
.
user
name
)
expect
(
page
).
to
have_selector
(
'.js-visual-token'
,
text:
user2
.
name
)
expect
(
page
).
to
have_selector
(
'.card'
,
count:
1
)
end
end
...
...
spec/features/issues/filtered_search/filter_issues_spec.rb
浏览文件 @
51c19616
...
...
@@ -6,7 +6,7 @@ describe 'Filter issues', js: true, feature: true do
let!
(
:group
)
{
create
(
:group
)
}
let!
(
:project
)
{
create
(
:project
,
group:
group
)
}
let!
(
:user
)
{
create
(
:user
,
username:
'joe'
)
}
let!
(
:user
)
{
create
(
:user
,
username:
'joe'
,
name:
'Joe'
)
}
let!
(
:user2
)
{
create
(
:user
,
username:
'jane'
)
}
let!
(
:label
)
{
create
(
:label
,
project:
project
)
}
let!
(
:wontfix
)
{
create
(
:label
,
project:
project
,
title:
"Won't fix"
)
}
...
...
spec/features/issues/filtered_search/visual_tokens_spec.rb
浏览文件 @
51c19616
...
...
@@ -2,6 +2,7 @@ require 'rails_helper'
describe
'Visual tokens'
,
js:
true
,
feature:
true
do
include
FilteredSearchHelpers
include
WaitForRequests
let!
(
:project
)
{
create
(
:empty_project
)
}
let!
(
:user
)
{
create
(
:user
,
name:
'administrator'
,
username:
'root'
)
}
...
...
@@ -70,7 +71,8 @@ describe 'Visual tokens', js: true, feature: true do
end
it
'changes value in visual token'
do
expect
(
first
(
'.tokens-container .filtered-search-token .value'
).
text
).
to
eq
(
"@
#{
user_rock
.
username
}
"
)
wait_for_requests
expect
(
first
(
'.tokens-container .filtered-search-token .value'
).
text
).
to
eq
(
"
#{
user_rock
.
name
}
"
)
end
it
'moves input to the right'
do
...
...
spec/javascripts/filtered_search/dropdown_utils_spec.js
浏览文件 @
51c19616
...
...
@@ -2,8 +2,12 @@ import '~/extensions/array';
import
'
~/filtered_search/dropdown_utils
'
;
import
'
~/filtered_search/filtered_search_tokenizer
'
;
import
'
~/filtered_search/filtered_search_dropdown_manager
'
;
import
FilteredSearchSpecHelper
from
'
../helpers/filtered_search_spec_helper
'
;
describe
(
'
Dropdown Utils
'
,
()
=>
{
const
issueListFixture
=
'
issues/issue_list.html.raw
'
;
preloadFixtures
(
issueListFixture
);
describe
(
'
getEscapedText
'
,
()
=>
{
it
(
'
should return same word when it has no space
'
,
()
=>
{
const
escaped
=
gl
.
DropdownUtils
.
getEscapedText
(
'
textWithoutSpace
'
);
...
...
@@ -314,4 +318,29 @@ describe('Dropdown Utils', () => {
});
});
});
describe
(
'
getSearchQuery
'
,
()
=>
{
let
authorToken
;
beforeEach
(()
=>
{
loadFixtures
(
issueListFixture
);
authorToken
=
FilteredSearchSpecHelper
.
createFilterVisualToken
(
'
author
'
,
'
@user
'
);
const
searchTermToken
=
FilteredSearchSpecHelper
.
createSearchVisualToken
(
'
search term
'
);
const
tokensContainer
=
document
.
querySelector
(
'
.tokens-container
'
);
tokensContainer
.
appendChild
(
searchTermToken
);
tokensContainer
.
appendChild
(
authorToken
);
});
it
(
'
uses original value if present
'
,
()
=>
{
const
originalValue
=
'
original dance
'
;
const
valueContainer
=
authorToken
.
querySelector
(
'
.value-container
'
);
valueContainer
.
dataset
.
originalValue
=
originalValue
;
const
searchQuery
=
gl
.
DropdownUtils
.
getSearchQuery
();
expect
(
searchQuery
).
toBe
(
'
search term author:original dance
'
);
});
});
});
spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
浏览文件 @
51c19616
此差异已折叠。
点击以展开。
spec/javascripts/fixtures/issues.rb
浏览文件 @
51c19616
...
...
@@ -36,6 +36,17 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller
render_issue
(
example
.
description
,
issue
)
end
it
'issues/issue_list.html.raw'
do
|
example
|
create
(
:issue
,
project:
project
)
get
:index
,
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
expect
(
response
).
to
be_success
store_frontend_fixture
(
response
,
example
.
description
)
end
private
def
render_issue
(
fixture_file_name
,
issue
)
...
...
spec/javascripts/helpers/filtered_search_spec_helper.js
浏览文件 @
51c19616
...
...
@@ -30,12 +30,15 @@ export default class FilteredSearchSpecHelper {
`
;
}
static
createSearchVisualToken
(
name
)
{
const
li
=
document
.
createElement
(
'
li
'
);
li
.
classList
.
add
(
'
js-visual-token
'
,
'
filtered-search-term
'
);
li
.
innerHTML
=
`<div class="name">
${
name
}
</div>`
;
return
li
;
}
static
createSearchVisualTokenHTML
(
name
)
{
return
`
<li class="js-visual-token filtered-search-term">
<div class="name">
${
name
}
</div>
</li>
`
;
return
FilteredSearchSpecHelper
.
createSearchVisualToken
(
name
).
outerHTML
;
}
static
createInputHTML
(
placeholder
=
''
,
value
=
''
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录