Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
386e7775
Commit
386e7775
authored
Mar 09, 2020
by
Florie Guibert
Committed by
Kushal Pandya
Mar 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update labels in Vue with GlLabel component
- Epic sidebar - Issue boards - Group Issues list
parent
f61daee3
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
158 additions
and
368 deletions
+158
-368
app/assets/javascripts/boards/components/issue_card_inner.vue
...assets/javascripts/boards/components/issue_card_inner.vue
+9
-27
app/assets/javascripts/boards/components/issue_card_inner_scoped_label.vue
...ripts/boards/components/issue_card_inner_scoped_label.vue
+0
-45
app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value.vue
...hared/components/sidebar/labels_select/dropdown_value.vue
+8
-23
app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_regular_label.vue
...ts/sidebar/labels_select/dropdown_value_regular_label.vue
+0
-39
app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_scoped_label.vue
...nts/sidebar/labels_select/dropdown_value_scoped_label.vue
+0
-52
app/assets/stylesheets/pages/boards.scss
app/assets/stylesheets/pages/boards.scss
+3
-14
app/assets/stylesheets/pages/issuable.scss
app/assets/stylesheets/pages/issuable.scss
+4
-0
changelogs/unreleased/38143-replace-labels-in-vue-with-gitlab-ui-component.yml
.../38143-replace-labels-in-vue-with-gitlab-ui-component.yml
+5
-0
ee/app/assets/javascripts/boards/components/board_settings_sidebar.vue
.../javascripts/boards/components/board_settings_sidebar.vue
+8
-1
ee/app/assets/javascripts/epic/components/sidebar_items/sidebar_labels.vue
...ascripts/epic/components/sidebar_items/sidebar_labels.vue
+1
-1
ee/spec/features/boards/sidebar_spec.rb
ee/spec/features/boards/sidebar_spec.rb
+47
-9
ee/spec/features/labels_hierarchy_spec.rb
ee/spec/features/labels_hierarchy_spec.rb
+1
-1
ee/spec/frontend/boards/components/board_settings_sidebar_spec.js
...frontend/boards/components/board_settings_sidebar_spec.js
+4
-0
ee/spec/frontend/boards/issue_card_spec.js
ee/spec/frontend/boards/issue_card_spec.js
+8
-6
ee/spec/frontend/epic/components/sidebar_items/sidebar_labels_spec.js
...tend/epic/components/sidebar_items/sidebar_labels_spec.js
+31
-27
locale/gitlab.pot
locale/gitlab.pot
+0
-3
spec/features/boards/boards_spec.rb
spec/features/boards/boards_spec.rb
+2
-2
spec/features/boards/sidebar_spec.rb
spec/features/boards/sidebar_spec.rb
+2
-2
spec/frontend/boards/components/issue_card_inner_scoped_label_spec.js
...d/boards/components/issue_card_inner_scoped_label_spec.js
+0
-40
spec/frontend/boards/issue_card_spec.js
spec/frontend/boards/issue_card_spec.js
+11
-21
spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js
...d/components/sidebar/labels_select/dropdown_value_spec.js
+13
-48
spec/javascripts/boards/board_card_spec.js
spec/javascripts/boards/board_card_spec.js
+1
-7
No files found.
app/assets/javascripts/boards/components/issue_card_inner.vue
View file @
386e7775
<
script
>
import
_
from
'
underscore
'
;
import
{
mapState
}
from
'
vuex
'
;
import
{
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
Gl
Label
,
Gl
TooltipDirective
}
from
'
@gitlab/ui
'
;
import
issueCardInner
from
'
ee_else_ce/boards/mixins/issue_card_inner
'
;
import
{
sprintf
,
__
}
from
'
~/locale
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
...
...
@@ -10,18 +10,17 @@ import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_
import
IssueDueDate
from
'
./issue_due_date.vue
'
;
import
IssueTimeEstimate
from
'
./issue_time_estimate.vue
'
;
import
boardsStore
from
'
../stores/boards_store
'
;
import
IssueCardInnerScopedLabel
from
'
./issue_card_inner_scoped_label.vue
'
;
import
{
isScopedLabel
}
from
'
~/lib/utils/common_utils
'
;
export
default
{
components
:
{
GlLabel
,
Icon
,
UserAvatarLink
,
TooltipOnTruncate
,
IssueDueDate
,
IssueTimeEstimate
,
IssueCardWeight
:
()
=>
import
(
'
ee_component/boards/components/issue_card_weight.vue
'
),
IssueCardInnerScopedLabel
,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
...
...
@@ -145,12 +144,6 @@ export default {
boardsStore
.
toggleFilter
(
filter
);
},
labelStyle
(
label
)
{
return
{
backgroundColor
:
label
.
color
,
color
:
label
.
textColor
,
};
},
showScopedLabel
(
label
)
{
return
boardsStore
.
scopedLabels
.
enabled
&&
isScopedLabel
(
label
);
},
...
...
@@ -184,27 +177,16 @@ export default {
</div>
<div
v-if=
"showLabelFooter"
class=
"board-card-labels prepend-top-4 d-flex flex-wrap"
>
<template
v-for=
"label in orderedLabels"
>
<issue-card-inner-scoped-label
v-if=
"showScopedLabel(label)"
<gl-label
:key=
"label.id"
:label=
"label"
:label-style=
"labelStyle(label)"
:background-color=
"label.color"
:title=
"label.title"
:description=
"label.description"
size=
"sm"
:scoped=
"showScopedLabel(label)"
:scoped-labels-documentation-link=
"helpLink"
@
scoped-label-click=
"filterByLabel($event)"
/>
<button
v-else
:key=
"label.id"
v-gl-tooltip
:style=
"labelStyle(label)"
:title=
"label.description"
class=
"badge color-label append-right-4 prepend-top-4"
type=
"button"
@
click=
"filterByLabel(label)"
>
{{
label
.
title
}}
</button>
/>
</
template
>
</div>
<div
class=
"board-card-footer d-flex justify-content-between align-items-end"
>
...
...
app/assets/javascripts/boards/components/issue_card_inner_scoped_label.vue
deleted
100644 → 0
View file @
f61daee3
<
script
>
import
{
GlLink
,
GlTooltip
}
from
'
@gitlab/ui
'
;
export
default
{
components
:
{
GlTooltip
,
GlLink
,
},
props
:
{
label
:
{
type
:
Object
,
required
:
true
,
},
labelStyle
:
{
type
:
Object
,
required
:
true
,
},
scopedLabelsDocumentationLink
:
{
type
:
String
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<span
class=
"d-inline-block position-relative scoped-label-wrapper append-right-4 prepend-top-4 board-label"
>
<a
@
click=
"$emit('scoped-label-click', label)"
>
<span
:ref=
"'labelTitleRef'"
:style=
"labelStyle"
class=
"badge label color-label"
>
{{
label
.
title
}}
</span>
<gl-tooltip
:target=
"() => $refs.labelTitleRef"
placement=
"top"
boundary=
"viewport"
>
<span
class=
"font-weight-bold scoped-label-tooltip-title"
>
{{
__
(
'
Scoped label
'
)
}}
</span
><br
/>
{{
label
.
description
}}
</gl-tooltip>
</a>
<gl-link
:href=
"scopedLabelsDocumentationLink"
target=
"_blank"
class=
"label scoped-label"
><i
class=
"fa fa-question-circle"
:style=
"labelStyle"
></i
></gl-link>
</span>
</
template
>
app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value.vue
View file @
386e7775
<
script
>
import
DropdownValueScopedLabel
from
'
./dropdown_value_scoped_label.vue
'
;
import
DropdownValueRegularLabel
from
'
./dropdown_value_regular_label.vue
'
;
import
{
GlLabel
}
from
'
@gitlab/ui
'
;
import
{
isScopedLabel
}
from
'
~/lib/utils/common_utils
'
;
export
default
{
components
:
{
DropdownValueScopedLabel
,
DropdownValueRegularLabel
,
GlLabel
,
},
props
:
{
labels
:
{
...
...
@@ -37,12 +35,6 @@ export default {
labelFilterUrl
(
label
)
{
return
`
${
this
.
labelFilterBasePath
}
?label_name[]=
${
encodeURIComponent
(
label
.
title
)}
`
;
},
labelStyle
(
label
)
{
return
{
color
:
label
.
textColor
,
backgroundColor
:
label
.
color
,
};
},
scopedLabelsDescription
({
description
=
''
})
{
return
`<span class="font-weight-bold scoped-label-tooltip-title">Scoped label</span><br />
${
description
}
`
;
},
...
...
@@ -65,22 +57,15 @@ export default {
</span>
<template
v-for=
"label in labels"
v-else
>
<dropdown-value-scoped-label
v-if=
"showScopedLabels(label)"
<gl-label
:key=
"label.id"
:label=
"label"
:label-filter-url=
"labelFilterUrl(label)"
:label-style=
"labelStyle(label)"
:target=
"labelFilterUrl(label)"
:background-color=
"label.color"
:title=
"label.title"
:description=
"label.description"
:scoped=
"showScopedLabels(label)"
:scoped-labels-documentation-link=
"scopedLabelsDocumentationLink"
/>
<dropdown-value-regular-label
v-else
:key=
"label.id"
:label=
"label"
:label-filter-url=
"labelFilterUrl(label)"
:label-style=
"labelStyle(label)"
/>
</
template
>
</div>
</template>
app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_regular_label.vue
deleted
100644 → 0
View file @
f61daee3
<
script
>
import
{
GlTooltip
}
from
'
@gitlab/ui
'
;
export
default
{
components
:
{
GlTooltip
,
},
props
:
{
label
:
{
type
:
Object
,
required
:
true
,
},
labelStyle
:
{
type
:
Object
,
required
:
true
,
},
labelFilterUrl
:
{
type
:
String
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<a
ref=
"regularLabelRef"
:href=
"labelFilterUrl"
>
<span
:style=
"labelStyle"
class=
"badge color-label"
>
{{
label
.
title
}}
</span>
<gl-tooltip
v-if=
"label.description"
:target=
"() => $refs.regularLabelRef"
placement=
"top"
boundary=
"viewport"
>
{{
label
.
description
}}
</gl-tooltip>
</a>
</
template
>
app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_scoped_label.vue
deleted
100644 → 0
View file @
f61daee3
<
script
>
import
{
GlLink
,
GlTooltip
}
from
'
@gitlab/ui
'
;
export
default
{
components
:
{
GlTooltip
,
GlLink
,
},
props
:
{
label
:
{
type
:
Object
,
required
:
true
,
},
labelStyle
:
{
type
:
Object
,
required
:
true
,
},
scopedLabelsDocumentationLink
:
{
type
:
String
,
required
:
true
,
},
labelFilterUrl
:
{
type
:
String
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<span
class=
"d-inline-block position-relative scoped-label-wrapper"
>
<a
:href=
"labelFilterUrl"
>
<span
:ref=
"`labelTitleRef`"
:style=
"labelStyle"
class=
"badge color-label label"
>
{{
label
.
title
}}
</span>
<gl-tooltip
v-if=
"label.description"
:target=
"() => $refs.labelTitleRef"
placement=
"top"
boundary=
"viewport"
>
<span
class=
"font-weight-bold scoped-label-tooltip-title"
>
{{
__
(
'
Scoped label
'
)
}}
</span
><br
/>
{{
label
.
description
}}
</gl-tooltip>
</a>
<gl-link
:href=
"scopedLabelsDocumentationLink"
target=
"_blank"
class=
"label scoped-label"
><i
class=
"fa fa-question-circle"
:style=
"labelStyle"
></i
></gl-link>
</span>
</
template
>
app/assets/stylesheets/pages/boards.scss
View file @
386e7775
...
...
@@ -266,20 +266,9 @@
background-color
:
$blue-50
;
}
.badge
{
border
:
0
;
outline
:
0
;
&
:hover
{
text-decoration
:
underline
;
}
@include
media-breakpoint-down
(
lg
)
{
font-size
:
$gl-font-size-xs
;
padding-left
:
$gl-padding-4
;
padding-right
:
$gl-padding-4
;
font-weight
:
$gl-font-weight-bold
;
}
.gl-label
{
margin-top
:
4px
;
margin-right
:
4px
;
}
.confidential-icon
{
...
...
app/assets/stylesheets/pages/issuable.scss
View file @
386e7775
...
...
@@ -158,6 +158,10 @@
a
:not
(
.btn
)
{
color
:
inherit
;
.gl-label-text
:hover
{
color
:
inherit
;
}
&
:hover
{
color
:
$blue-800
;
...
...
changelogs/unreleased/38143-replace-labels-in-vue-with-gitlab-ui-component.yml
0 → 100644
View file @
386e7775
---
title
:
Update labels in Vue with GlLabel component
merge_request
:
21465
author
:
type
:
changed
ee/app/assets/javascripts/boards/components/board_settings_sidebar.vue
View file @
386e7775
...
...
@@ -13,6 +13,7 @@ import { __, n__ } from '~/locale';
import
autofocusonshow
from
'
~/vue_shared/directives/autofocusonshow
'
;
import
boardsStoreEE
from
'
../stores/boards_store_ee
'
;
import
flash
from
'
~/flash
'
;
import
{
isScopedLabel
}
from
'
~/lib/utils/common_utils
'
;
// NOTE: need to revisit how we handle headerHeight, because we have so many different header and footer options.
export
default
{
...
...
@@ -157,6 +158,12 @@ export default {
onEnter
()
{
this
.
offFocus
();
},
showScopedLabels
(
label
)
{
return
boardsStoreEE
.
store
.
scopedLabels
.
enabled
&&
isScopedLabel
(
label
);
},
helpLink
()
{
return
boardsStoreEE
.
store
.
scopedLabels
.
helpLink
;
},
},
};
</
script
>
...
...
@@ -176,7 +183,7 @@ export default {
<gl-label
:title=
"activeListLabel.title"
:background-color=
"activeListLabel.color"
color=
"light
"
:scoped=
"showScopedLabels(activeListLabel)
"
/>
</
template
>
<
template
v-else-if=
"boardListType === $options.assignee"
>
...
...
ee/app/assets/javascripts/epic/components/sidebar_items/sidebar_labels.vue
View file @
386e7775
...
...
@@ -90,7 +90,7 @@ export default {
new
ListLabel
({
id
:
label
.
id
,
title
:
label
.
title
,
color
:
label
.
color
[
0
]
,
color
:
label
.
color
,
textColor
:
label
.
text_color
,
}),
);
...
...
ee/spec/features/boards/sidebar_spec.rb
View file @
386e7775
...
...
@@ -14,6 +14,8 @@ describe 'Issue Boards', :js do
let!
(
:stretch
)
{
create
(
:label
,
project:
project
,
name:
'Stretch'
)
}
let!
(
:issue1
)
{
create
(
:labeled_issue
,
project:
project
,
assignees:
[
user
],
milestone:
milestone
,
labels:
[
development
],
weight:
3
,
relative_position:
2
)
}
let!
(
:issue2
)
{
create
(
:labeled_issue
,
project:
project
,
labels:
[
development
,
stretch
],
relative_position:
1
)
}
let!
(
:scoped_label_1
)
{
create
(
:label
,
project:
project
,
name:
'Scoped1::Label1'
)
}
let!
(
:scoped_label_2
)
{
create
(
:label
,
project:
project
,
name:
'Scoped2::Label2'
)
}
let
(
:board
)
{
create
(
:board
,
project:
project
)
}
let!
(
:list
)
{
create
(
:list
,
board:
board
,
label:
development
,
position:
0
)
}
let
(
:card1
)
{
find
(
'.board:nth-child(2)'
).
find
(
'.board-card:nth-child(2)'
)
}
...
...
@@ -252,9 +254,6 @@ describe 'Issue Boards', :js do
end
context
'scoped labels'
do
let!
(
:scoped_label_1
)
{
create
(
:label
,
project:
project
,
name:
'Scoped::Label1'
)
}
let!
(
:scoped_label_2
)
{
create
(
:label
,
project:
project
,
name:
'Scoped::Label2'
)
}
before
do
stub_licensed_features
(
scoped_labels:
true
)
...
...
@@ -262,7 +261,7 @@ describe 'Issue Boards', :js do
wait_for_requests
end
it
'
removes existing scoped label
'
do
it
'
adds multiple scoped labels
'
do
click_card
(
card1
)
page
.
within
(
'.labels'
)
do
...
...
@@ -280,6 +279,42 @@ describe 'Issue Boards', :js do
find
(
'.dropdown-menu-close-icon'
).
click
page
.
within
(
'.value'
)
do
expect
(
page
).
to
have_selector
(
'.gl-label-scoped'
,
count:
2
)
expect
(
page
).
to
have_content
(
scoped_label_1
.
scoped_label_key
)
expect
(
page
).
to
have_content
(
scoped_label_1
.
scoped_label_value
)
expect
(
page
).
to
have_content
(
scoped_label_2
.
scoped_label_key
)
expect
(
page
).
to
have_content
(
scoped_label_2
.
scoped_label_value
)
end
end
end
context
'with scoped label assigned'
do
let!
(
:issue3
)
{
create
(
:labeled_issue
,
project:
project
,
labels:
[
development
,
scoped_label_1
,
scoped_label_2
],
relative_position:
3
)
}
let
(
:board
)
{
create
(
:board
,
project:
project
)
}
let
(
:card3
)
{
find
(
'.board:nth-child(2)'
).
find
(
'.board-card:nth-child(1)'
)
}
before
do
stub_licensed_features
(
scoped_labels:
true
)
visit
project_board_path
(
project
,
board
)
wait_for_requests
end
it
'removes existing scoped label'
do
click_card
(
card3
)
page
.
within
(
'.labels'
)
do
click_link
'Edit'
wait_for_requests
click_link
scoped_label_2
.
title
wait_for_requests
find
(
'.dropdown-menu-close-icon'
).
click
page
.
within
(
'.value'
)
do
expect
(
page
).
to
have_selector
(
'.gl-label-scoped'
,
count:
1
)
expect
(
page
).
not_to
have_content
(
scoped_label_1
.
scoped_label_value
)
...
...
@@ -288,9 +323,12 @@ describe 'Issue Boards', :js do
end
end
expect
(
card1
).
to
have_selector
(
'.scoped-label-wrapper'
,
count:
1
)
expect
(
card1
).
not_to
have_content
(
scoped_label_1
.
title
)
expect
(
card1
).
to
have_content
(
scoped_label_2
.
title
)
expect
(
card3
).
to
have_selector
(
'.gl-label-scoped'
,
count:
1
)
expect
(
card3
).
not_to
have_content
(
scoped_label_1
.
scoped_label_key
)
expect
(
card3
).
not_to
have_content
(
scoped_label_1
.
scoped_label_value
)
expect
(
card3
).
to
have_content
(
scoped_label_2
.
scoped_label_key
)
expect
(
card3
).
to
have_content
(
scoped_label_2
.
scoped_label_value
)
end
end
end
end
ee/spec/features/labels_hierarchy_spec.rb
View file @
386e7775
...
...
@@ -51,7 +51,7 @@ describe 'Labels Hierarchy', :js do
expect
(
page
).
to
have_selector
(
'a'
,
text:
issue
.
title
)
end
expect
(
page
).
to
have_selector
(
'.
badge
'
,
text:
label
.
title
)
expect
(
page
).
to
have_selector
(
'.
gl-label
'
,
text:
label
.
title
)
end
end
end
...
...
ee/spec/frontend/boards/components/board_settings_sidebar_spec.js
View file @
386e7775
...
...
@@ -64,6 +64,10 @@ describe('BoardSettingsSideBar', () => {
findList
:
bs
.
findList
,
addList
:
bs
.
addList
,
removeList
:
bs
.
removeList
,
scopedLabels
:
{
enabled
:
false
,
scopedLabelsDocumentationLink
:
''
,
},
};
boardsStore
.
initEESpecific
(
storeMock
);
...
...
ee/spec/frontend/boards/issue_card_spec.js
View file @
386e7775
import
{
m
ount
}
from
'
@vue/test-utils
'
;
import
{
shallowM
ount
}
from
'
@vue/test-utils
'
;
import
IssueCardWeight
from
'
ee/boards/components/issue_card_weight.vue
'
;
import
ListIssueEE
from
'
ee/boards/models/issue
'
;
import
ListLabel
from
'
~/boards/models/label
'
;
import
IssueCardInner
from
'
~/boards/components/issue_card_inner.vue
'
;
import
defaultStore
from
'
~/boards/stores
'
;
import
{
GlLabel
}
from
'
@gitlab/ui
'
;
describe
(
'
Issue card component
'
,
()
=>
{
let
wrapper
;
...
...
@@ -11,7 +12,7 @@ describe('Issue card component', () => {
let
list
;
const
createComponent
=
(
props
=
{},
store
=
defaultStore
)
=>
{
wrapper
=
m
ount
(
IssueCardInner
,
{
wrapper
=
shallowM
ount
(
IssueCardInner
,
{
store
,
propsData
:
{
list
,
...
...
@@ -33,7 +34,7 @@ describe('Issue card component', () => {
label
:
{
id
:
5000
,
title
:
'
Testing
'
,
color
:
'
red
'
,
color
:
'
#ff0000
'
,
description
:
'
testing;
'
,
textColor
:
'
white
'
,
},
...
...
@@ -62,7 +63,7 @@ describe('Issue card component', () => {
const
label1
=
new
ListLabel
({
id
:
3
,
title
:
'
testing 123
'
,
color
:
'
blue
'
,
color
:
'
#000cff
'
,
text_color
:
'
white
'
,
description
:
'
test
'
,
});
...
...
@@ -80,13 +81,14 @@ describe('Issue card component', () => {
id
:
9001
,
type
,
title
,
color
:
'
#000000
'
,
}),
);
createComponent
({
groupId
:
1
});
expect
(
wrapper
.
findAll
(
'
.badge
'
).
length
).
toBe
(
3
);
expect
(
wrapper
.
text
(
)).
toContain
(
title
);
expect
(
wrapper
.
findAll
(
GlLabel
).
length
).
toBe
(
3
);
expect
(
wrapper
.
find
(
GlLabel
).
props
(
'
title
'
)).
toContain
(
title
);
});
it
(
'
shows no labels when the isShowingLabels state is false
'
,
()
=>
{
...
...
ee/spec/frontend/epic/components/sidebar_items/sidebar_labels_spec.js
View file @
386e7775
import
Vue
from
'
vue
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
SidebarLabels
from
'
ee/epic/components/sidebar_items/sidebar_labels.vue
'
;
import
createStore
from
'
ee/epic/store
'
;
import
{
mountComponentWithStore
}
from
'
helpers/vue_mount_component_helper
'
;
import
{
mockEpicMeta
,
mockEpicData
,
mockLabels
}
from
'
../../mock_data
'
;
describe
(
'
SidebarLabelsComponent
'
,
()
=>
{
let
vm
;
let
wrapper
;
let
store
;
beforeEach
(()
=>
{
...
...
@@ -16,26 +16,30 @@ describe('SidebarLabelsComponent', () => {
store
.
dispatch
(
'
setEpicMeta
'
,
mockEpicMeta
);
store
.
dispatch
(
'
setEpicData
'
,
mockEpicData
);
vm
=
mountComponentWithStore
(
Component
,
{
wrapper
=
mount
(
Component
,
{
propsData
:
{
canUpdate
:
false
,
sidebarCollapsed
:
false
},
store
,
props
:
{
canUpdate
:
false
,
sidebarCollapsed
:
false
},
stubs
:
{
GlLabel
:
true
,
},
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
wrapper
.
destroy
();
wrapper
=
null
;
});
describe
(
'
data
'
,
()
=>
{
it
(
'
returns default data props
'
,
()
=>
{
expect
(
vm
.
sidebarExpandedOnClick
).
toBe
(
false
);
expect
(
wrapper
.
vm
.
sidebarExpandedOnClick
).
toBe
(
false
);
});
});
describe
(
'
computed
'
,
()
=>
{
describe
(
'
epicContext
'
,
()
=>
{
it
(
'
returns object containing `this.labels` as a child prop
'
,
()
=>
{
expect
(
vm
.
epicContext
.
labels
).
toBe
(
vm
.
labels
);
expect
(
wrapper
.
vm
.
epicContext
.
labels
).
toBe
(
wrapper
.
vm
.
labels
);
});
});
});
...
...
@@ -43,11 +47,11 @@ describe('SidebarLabelsComponent', () => {
describe
(
'
methods
'
,
()
=>
{
describe
(
'
toggleSidebarRevealLabelsDropdown
'
,
()
=>
{
it
(
'
calls `toggleSidebar` action with param `sidebarCollapse`
'
,
()
=>
{
jest
.
spyOn
(
vm
,
'
toggleSidebar
'
);
jest
.
spyOn
(
wrapper
.
vm
,
'
toggleSidebar
'
);
vm
.
toggleSidebarRevealLabelsDropdown
();
wrapper
.
vm
.
toggleSidebarRevealLabelsDropdown
();
expect
(
vm
.
toggleSidebar
).
toHaveBeenCalledWith
(
expect
(
wrapper
.
vm
.
toggleSidebar
).
toHaveBeenCalledWith
(
jasmine
.
objectContaining
({
sidebarCollapsed
:
false
,
}),
...
...
@@ -57,14 +61,14 @@ describe('SidebarLabelsComponent', () => {
describe
(
'
handleDropdownClose
'
,
()
=>
{
it
(
'
calls `toggleSidebar` action only when `sidebarExpandedOnClick` prop is true
'
,
()
=>
{
jest
.
spyOn
(
vm
,
'
toggleSidebar
'
);
jest
.
spyOn
(
wrapper
.
vm
,
'
toggleSidebar
'
);
vm
.
sidebarExpandedOnClick
=
true
;
wrapper
.
vm
.
sidebarExpandedOnClick
=
true
;
vm
.
handleDropdownClose
();
wrapper
.
vm
.
handleDropdownClose
();
expect
(
vm
.
sidebarExpandedOnClick
).
toBe
(
false
);
expect
(
vm
.
toggleSidebar
).
toHaveBeenCalledWith
(
expect
(
wrapper
.
vm
.
sidebarExpandedOnClick
).
toBe
(
false
);
expect
(
wrapper
.
vm
.
toggleSidebar
).
toHaveBeenCalledWith
(
jasmine
.
objectContaining
({
sidebarCollapsed
:
false
,
}),
...
...
@@ -86,34 +90,34 @@ describe('SidebarLabelsComponent', () => {
it
(
'
initializes `epicContext.labels` as empty array when `label.isAny` is `true`
'
,
()
=>
{
const
labelIsAny
=
{
isAny
:
true
};
vm
.
handleLabelClick
(
labelIsAny
);
wrapper
.
vm
.
handleLabelClick
(
labelIsAny
);
expect
(
Array
.
isArray
(
vm
.
epicContext
.
labels
)).
toBe
(
true
);
expect
(
vm
.
epicContext
.
labels
.
length
).
toBe
(
0
);
expect
(
Array
.
isArray
(
wrapper
.
vm
.
epicContext
.
labels
)).
toBe
(
true
);
expect
(
wrapper
.
vm
.
epicContext
.
labels
.
length
).
toBe
(
0
);
});
it
(
'
adds provided `label` to epicContext.labels
'
,
()
=>
{
vm
.
handleLabelClick
(
label
);
wrapper
.
vm
.
handleLabelClick
(
label
);
// epicContext.labels gets initialized with initialLabels, hence
// newly insert label will be at second position (index `1`)
expect
(
vm
.
epicContext
.
labels
.
length
).
toBe
(
2
);
expect
(
vm
.
epicContext
.
labels
[
1
].
id
).
toBe
(
label
.
id
);
vm
.
handleLabelClick
(
label
);
expect
(
wrapper
.
vm
.
epicContext
.
labels
.
length
).
toBe
(
2
);
expect
(
wrapper
.
vm
.
epicContext
.
labels
[
1
].
id
).
toBe
(
label
.
id
);
wrapper
.
vm
.
handleLabelClick
(
label
);
});
it
(
'
filters epicContext.labels to exclude provided `label` if it is already present in `epicContext.labels`
'
,
()
=>
{
vm
.
handleLabelClick
(
label
);
// Select
vm
.
handleLabelClick
(
label
);
// Un-select
wrapper
.
vm
.
handleLabelClick
(
label
);
// Select
wrapper
.
vm
.
handleLabelClick
(
label
);
// Un-select
expect
(
vm
.
epicContext
.
labels
.
length
).
toBe
(
1
);
expect
(
vm
.
epicContext
.
labels
[
0
].
id
).
toBe
(
mockLabels
[
0
].
id
);
expect
(
wrapper
.
vm
.
epicContext
.
labels
.
length
).
toBe
(
1
);
expect
(
wrapper
.
vm
.
epicContext
.
labels
[
0
].
id
).
toBe
(
mockLabels
[
0
].
id
);
});
});
});
describe
(
'
template
'
,
()
=>
{
it
(
'
renders labels select element container
'
,
()
=>
{
expect
(
vm
.
$el
.
classList
.
contains
(
'
js-labels-block
'
)).
toBe
(
true
);
expect
(
wrapper
.
vm
.
$el
.
classList
.
contains
(
'
js-labels-block
'
)).
toBe
(
true
);
});
});
});
locale/gitlab.pot
View file @
386e7775
...
...
@@ -16983,9 +16983,6 @@ msgstr ""
msgid "Scoped issue boards"
msgstr ""
msgid "Scoped label"
msgstr ""
msgid "Scopes"
msgstr ""
...
...
spec/features/boards/boards_spec.rb
View file @
386e7775
...
...
@@ -519,7 +519,7 @@ describe 'Issue Boards', :js do
page
.
within
(
find
(
'.board:nth-child(2)'
))
do
expect
(
page
).
to
have_selector
(
'.board-card'
,
count:
8
)
expect
(
find
(
'.board-card'
,
match: :first
)).
to
have_content
(
bug
.
title
)
click_
button
(
bug
.
title
)
click_
link
(
bug
.
title
)
wait_for_requests
end
...
...
@@ -536,7 +536,7 @@ describe 'Issue Boards', :js do
it
'removes label filter by clicking label button on issue'
do
page
.
within
(
find
(
'.board:nth-child(2)'
))
do
page
.
within
(
find
(
'.board-card'
,
match: :first
))
do
click_
button
(
bug
.
title
)
click_
link
(
bug
.
title
)
end
wait_for_requests
...
...
spec/features/boards/sidebar_spec.rb
View file @
386e7775
...
...
@@ -305,7 +305,7 @@ describe 'Issue Boards', :js do
end
# 'Development' label does not show since the card is in a 'Development' list label
expect
(
card
).
to
have_selector
(
'.
badge
'
,
count:
2
)
expect
(
card
).
to
have_selector
(
'.
gl-label
'
,
count:
2
)
expect
(
card
).
to
have_content
(
bug
.
title
)
end
...
...
@@ -335,7 +335,7 @@ describe 'Issue Boards', :js do
end
# 'Development' label does not show since the card is in a 'Development' list label
expect
(
card
).
to
have_selector
(
'.
badge
'
,
count:
3
)
expect
(
card
).
to
have_selector
(
'.
gl-label
'
,
count:
3
)
expect
(
card
).
to
have_content
(
bug
.
title
)
expect
(
card
).
to
have_content
(
regression
.
title
)
end
...
...
spec/frontend/boards/components/issue_card_inner_scoped_label_spec.js
deleted
100644 → 0
View file @
f61daee3
import
{
GlLink
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
IssueCardInnerScopedLabel
from
'
~/boards/components/issue_card_inner_scoped_label.vue
'
;
describe
(
'
IssueCardInnerScopedLabel Component
'
,
()
=>
{
let
wrapper
;
beforeEach
(()
=>
{
wrapper
=
shallowMount
(
IssueCardInnerScopedLabel
,
{
propsData
:
{
label
:
{
title
:
'
Foo::Bar
'
,
description
:
'
Some Random Description
'
},
labelStyle
:
{
background
:
'
white
'
,
color
:
'
black
'
},
scopedLabelsDocumentationLink
:
'
/docs-link
'
,
},
});
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
it
(
'
should render label title
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
.color-label
'
).
text
()).
toBe
(
'
Foo::Bar
'
);
});
it
(
'
should render question mark symbol
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
.fa-question-circle
'
).
exists
()).
toBe
(
true
);
});
it
(
'
should render label style provided
'
,
()
=>
{
const
label
=
wrapper
.
find
(
'
.color-label
'
);
expect
(
label
.
attributes
(
'
style
'
)).
toContain
(
'
background: white;
'
);
expect
(
label
.
attributes
(
'
style
'
)).
toContain
(
'
color: black;
'
);
});
it
(
'
should render the docs link
'
,
()
=>
{
expect
(
wrapper
.
find
(
GlLink
).
attributes
(
'
href
'
)).
toBe
(
'
/docs-link
'
);
});
});
spec/frontend/boards/issue_card_spec.js
View file @
386e7775
...
...
@@ -8,6 +8,7 @@ import '~/boards/models/list';
import
IssueCardInner
from
'
~/boards/components/issue_card_inner.vue
'
;
import
{
listObj
}
from
'
../../javascripts/boards/mock_data
'
;
import
store
from
'
~/boards/stores
'
;
import
{
GlLabel
}
from
'
@gitlab/ui
'
;
describe
(
'
Issue card component
'
,
()
=>
{
const
user
=
new
ListAssignee
({
...
...
@@ -20,7 +21,7 @@ describe('Issue card component', () => {
const
label1
=
new
ListLabel
({
id
:
3
,
title
:
'
testing 123
'
,
color
:
'
blue
'
,
color
:
'
#000CFF
'
,
text_color
:
'
white
'
,
description
:
'
test
'
,
});
...
...
@@ -50,6 +51,9 @@ describe('Issue card component', () => {
rootPath
:
'
/
'
,
},
store
,
stubs
:
{
GlLabel
:
true
,
},
});
});
...
...
@@ -290,25 +294,11 @@ describe('Issue card component', () => {
});
it
(
'
does not render list label but renders all other labels
'
,
()
=>
{
expect
(
wrapper
.
findAll
(
'
.badge
'
).
length
).
toBe
(
1
);
});
it
(
'
renders label
'
,
()
=>
{
const
nodes
=
wrapper
.
findAll
(
'
.badge
'
).
wrappers
.
map
(
label
=>
label
.
attributes
(
'
title
'
));
expect
(
nodes
.
includes
(
label1
.
description
)).
toBe
(
true
);
});
it
(
'
sets label description as title
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
.badge
'
).
attributes
(
'
title
'
)).
toContain
(
label1
.
description
);
});
it
(
'
sets background color of button
'
,
()
=>
{
const
nodes
=
wrapper
.
findAll
(
'
.badge
'
)
.
wrappers
.
map
(
label
=>
label
.
element
.
style
.
backgroundColor
);
expect
(
nodes
.
includes
(
label1
.
color
)).
toBe
(
true
);
expect
(
wrapper
.
findAll
(
GlLabel
).
length
).
toBe
(
1
);
const
label
=
wrapper
.
find
(
GlLabel
);
expect
(
label
.
props
(
'
title
'
)).
toEqual
(
label1
.
title
);
expect
(
label
.
props
(
'
description
'
)).
toEqual
(
label1
.
description
);
expect
(
label
.
props
(
'
backgroundColor
'
)).
toEqual
(
label1
.
color
);
});
it
(
'
does not render label if label does not have an ID
'
,
done
=>
{
...
...
@@ -321,7 +311,7 @@ describe('Issue card component', () => {
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
expect
(
wrapper
.
findAll
(
'
.badge
'
).
length
).
toBe
(
1
);
expect
(
wrapper
.
findAll
(
GlLabel
).
length
).
toBe
(
1
);
expect
(
wrapper
.
text
()).
not
.
toContain
(
'
closed
'
);
done
();
})
...
...
spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js
View file @
386e7775
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
hexToRgb
}
from
'
~/lib/utils/color_utils
'
;
import
DropdownValueComponent
from
'
~/vue_shared/components/sidebar/labels_select/dropdown_value.vue
'
;
import
DropdownValueScopedLabel
from
'
~/vue_shared/components/sidebar/labels_select/dropdown_value_scoped_label.vue
'
;
import
{
GlLabel
}
from
'
@gitlab/ui
'
;
import
{
mockConfig
,
mockLabels
,
}
from
'
../../../../../javascripts/vue_shared/components/sidebar/labels_select/mock_data
'
;
const
labelStyles
=
{
textColor
:
'
#FFFFFF
'
,
color
:
'
#BADA55
'
,
};
const
createComponent
=
(
labels
=
mockLabels
,
labelFilterBasePath
=
mockConfig
.
labelFilterBasePath
,
)
=>
{
labels
.
forEach
(
label
=>
Object
.
assign
(
label
,
labelStyles
));
return
mount
(
DropdownValueComponent
,
{
)
=>
mount
(
DropdownValueComponent
,
{
propsData
:
{
labels
,
labelFilterBasePath
,
enableScopedLabels
:
true
,
},
stubs
:
{
GlLabel
:
true
,
},
});
};
describe
(
'
DropdownValueComponent
'
,
()
=>
{
let
vm
;
...
...
@@ -56,24 +51,17 @@ describe('DropdownValueComponent', () => {
describe
(
'
methods
'
,
()
=>
{
describe
(
'
labelFilterUrl
'
,
()
=>
{
it
(
'
returns URL string starting with labelFilterBasePath and encoded label.title
'
,
()
=>
{
expect
(
vm
.
find
(
DropdownValueScopedLabel
).
props
(
'
labelFilterUrl
'
)).
toBe
(
'
/gitlab-org/my-project/issues?label_name[]=Foo%
3A%3ABar
'
,
expect
(
vm
.
find
(
GlLabel
).
props
(
'
target
'
)).
toBe
(
'
/gitlab-org/my-project/issues?label_name[]=Foo%
20Label
'
,
);
});
});
describe
(
'
labelStyle
'
,
()
=>
{
it
(
'
returns object with `color` & `backgroundColor` properties from label.textColor & label.color
'
,
()
=>
{
expect
(
vm
.
find
(
DropdownValueScopedLabel
).
props
(
'
labelStyle
'
)).
toEqual
({
color
:
labelStyles
.
textColor
,
backgroundColor
:
labelStyles
.
color
,
});
});
});
describe
(
'
showScopedLabels
'
,
()
=>
{
it
(
'
returns true if the label is scoped label
'
,
()
=>
{
expect
(
vm
.
findAll
(
DropdownValueScopedLabel
).
length
).
toEqual
(
1
);
const
labels
=
vm
.
findAll
(
GlLabel
);
expect
(
labels
.
length
).
toEqual
(
2
);
expect
(
labels
.
at
(
1
).
props
(
'
scoped
'
)).
toBe
(
true
);
});
});
});
...
...
@@ -95,33 +83,10 @@ describe('DropdownValueComponent', () => {
vmEmptyLabels
.
destroy
();
});
it
(
'
renders label element with filter URL
'
,
()
=>
{
expect
(
vm
.
find
(
'
a
'
).
attributes
(
'
href
'
)).
toBe
(
'
/gitlab-org/my-project/issues?label_name[]=Foo%20Label
'
,
);
});
it
(
'
renders label element and styles based on label details
'
,
()
=>
{
const
labelEl
=
vm
.
find
(
'
a span.badge.color-label
'
);
it
(
'
renders DropdownValueComponent element
'
,
()
=>
{
const
labelEl
=
vm
.
find
(
GlLabel
);
expect
(
labelEl
.
exists
()).
toBe
(
true
);
expect
(
labelEl
.
attributes
(
'
style
'
)).
toContain
(
`background-color: rgb(
${
hexToRgb
(
labelStyles
.
color
).
join
(
'
,
'
)}
);`
,
);
expect
(
labelEl
.
text
().
trim
()).
toBe
(
mockLabels
[
0
].
title
);
});
describe
(
'
label is of scoped-label type
'
,
()
=>
{
it
(
'
renders a scoped-label-wrapper span to incorporate 2 anchors
'
,
()
=>
{
expect
(
vm
.
find
(
'
span.scoped-label-wrapper
'
).
exists
()).
toBe
(
true
);
});
it
(
'
renders anchor tag containing question icon
'
,
()
=>
{
const
anchor
=
vm
.
find
(
'
.scoped-label-wrapper a.scoped-label
'
);
expect
(
anchor
.
exists
()).
toBe
(
true
);
expect
(
anchor
.
find
(
'
i.fa-question-circle
'
).
exists
()).
toBe
(
true
);
});
});
});
});
spec/javascripts/boards/board_card_spec.js
View file @
386e7775
...
...
@@ -32,7 +32,7 @@ describe('Board card', () => {
const
label1
=
new
ListLabel
({
id
:
3
,
title
:
'
testing 123
'
,
color
:
'
blue
'
,
color
:
'
#000cff
'
,
text_color
:
'
white
'
,
description
:
'
test
'
,
});
...
...
@@ -155,12 +155,6 @@ describe('Board card', () => {
expect
(
boardsStore
.
detail
.
issue
).
toEqual
({});
});
it
(
'
does not set detail issue if button is clicked
'
,
()
=>
{
triggerEvent
(
'
mouseup
'
,
vm
.
$el
.
querySelector
(
'
button
'
));
expect
(
boardsStore
.
detail
.
issue
).
toEqual
({});
});
it
(
'
does not set detail issue if img is clicked
'
,
done
=>
{
vm
.
issue
.
assignees
=
[
new
ListAssignee
({
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment