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
d92bdee7
Commit
d92bdee7
authored
Nov 18, 2020
by
Evan Read
Committed by
Scott Hampton
Nov 18, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate awards list buttons to GLButton
Fix tests affected by changes
parent
825d5232
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
286 additions
and
89 deletions
+286
-89
app/assets/javascripts/vue_shared/components/awards_list.vue
app/assets/javascripts/vue_shared/components/awards_list.vue
+17
-18
app/assets/stylesheets/framework/awards.scss
app/assets/stylesheets/framework/awards.scss
+108
-0
changelogs/unreleased/eread-migrate-awards-list-buttons.yml
changelogs/unreleased/eread-migrate-awards-list-buttons.yml
+5
-0
spec/frontend/vue_shared/components/__snapshots__/awards_list_spec.js.snap
..._shared/components/__snapshots__/awards_list_spec.js.snap
+137
-54
spec/frontend/vue_shared/components/awards_list_spec.js
spec/frontend/vue_shared/components/awards_list_spec.js
+19
-17
No files found.
app/assets/javascripts/vue_shared/components/awards_list.vue
View file @
d92bdee7
<
script
>
/* eslint-disable vue/no-v-html */
import
{
groupBy
}
from
'
lodash
'
;
import
{
GlIcon
,
Gl
LoadingIc
on
,
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
GlIcon
,
Gl
Butt
on
,
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
glEmojiTag
}
from
'
../../emoji
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
...
...
@@ -10,8 +10,8 @@ const NO_USER_ID = -1;
export
default
{
components
:
{
GlButton
,
GlIcon
,
GlLoadingIcon
,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
...
...
@@ -64,7 +64,7 @@ export default {
methods
:
{
getAwardClassBindings
(
awardList
)
{
return
{
active
:
this
.
hasReactionByCurrentUser
(
awardList
),
selected
:
this
.
hasReactionByCurrentUser
(
awardList
),
disabled
:
this
.
currentUserId
===
NO_USER_ID
,
};
},
...
...
@@ -150,40 +150,39 @@ export default {
<
template
>
<div
class=
"awards js-awards-block"
>
<button
<
gl-
button
v-for=
"awardList in groupedAwards"
:key=
"awardList.name"
v-gl-tooltip
.
viewport
class=
"gl-mr-3"
:class=
"awardList.classes"
:title=
"awardList.title"
data-testid=
"award-button"
class=
"btn award-control"
type=
"button"
@
click=
"handleAward(awardList.name)"
>
<span
data-testid=
"award-html"
v-html=
"awardList.html"
></span>
<span
class=
"award-control-text js-counter"
>
{{
awardList
.
list
.
length
}}
</span>
</button>
<template
#emoji
>
<span
class=
"award-emoji-block"
data-testid=
"award-html"
v-html=
"awardList.html"
></span>
</
template
>
<span
class=
"js-counter"
>
{{ awardList.list.length }}
</span>
</gl-button>
<div
v-if=
"canAwardEmoji"
class=
"award-menu-holder"
>
<button
<
gl-
button
v-gl-tooltip
.
viewport
:class=
"addButtonClass"
class=
"a
ward-control bt
n js-add-award"
class=
"a
dd-reaction-butto
n js-add-award"
title=
"Add reaction"
:aria-label=
"__('Add reaction')"
type=
"button"
>
<span
class=
"
award-control-icon award
-control-icon-neutral"
>
<span
class=
"
reaction-control-icon reaction
-control-icon-neutral"
>
<gl-icon
aria-hidden=
"true"
name=
"slight-smile"
/>
</span>
<span
class=
"
award-control-icon award
-control-icon-positive"
>
<span
class=
"
reaction-control-icon reaction
-control-icon-positive"
>
<gl-icon
aria-hidden=
"true"
name=
"smiley"
/>
</span>
<span
class=
"
award-control-icon award
-control-icon-super-positive"
>
<gl-icon
aria-hidden=
"true"
name=
"smile
y
"
/>
<span
class=
"
reaction-control-icon reaction
-control-icon-super-positive"
>
<gl-icon
aria-hidden=
"true"
name=
"smile"
/>
</span>
<gl-loading-icon
size=
"md"
color=
"dark"
class=
"award-control-icon-loading"
/>
</button>
</gl-button>
</div>
</div>
</template>
app/assets/stylesheets/framework/awards.scss
View file @
d92bdee7
...
...
@@ -253,3 +253,111 @@
vertical-align
:
middle
;
}
}
// The following encompasses the "add reaction" button redesign to
// align properly within GitLab UI's gl-button. The implementation
// above will be deprecated once all instances of "award emoji" are
// migrated to Vue.
.gl-button
.award-emoji-block
gl-emoji
{
top
:
-1px
;
margin-top
:
-1px
;
margin-bottom
:
-1px
;
}
.add-reaction-button
{
position
:
relative
;
// This forces the height and width of the inner content to match
// other gl-buttons despite all child elements being set to
// `position:absolute`
&
:
:
after
{
content
:
'\a0'
;
width
:
1em
;
}
.reaction-control-icon
{
position
:
absolute
;
top
:
0
;
left
:
0
;
height
:
100%
;
width
:
100%
;
// center the icon vertically and horizontally within the button
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
@include
transition
(
opacity
,
transform
);
.gl-icon
{
height
:
$default-icon-size
;
width
:
$default-icon-size
;
}
}
.reaction-control-icon-neutral
{
opacity
:
1
;
}
.reaction-control-icon-positive
,
.reaction-control-icon-super-positive
{
opacity
:
0
;
}
&
:hover
,
&
.active
,
&
:active
,
&
.is-active
{
// extra specificty added to override another selector
.reaction-control-icon
.gl-icon
{
color
:
$blue-500
;
transform
:
scale
(
1
.15
);
}
.reaction-control-icon-neutral
{
opacity
:
0
;
}
}
&
:hover
{
.reaction-control-icon-positive
{
opacity
:
1
;
}
}
&
.active
,
&
:active
,
&
.is-active
{
.reaction-control-icon-positive
{
opacity
:
0
;
}
.reaction-control-icon-super-positive
{
opacity
:
1
;
}
}
&
.disabled
{
cursor
:
default
;
&
:hover
,
&
:focus
,
&
:active
{
.reaction-control-icon
.gl-icon
{
color
:
inherit
;
transform
:
scale
(
1
);
}
.reaction-control-icon-neutral
{
opacity
:
1
;
}
.reaction-control-icon-positive
,
.reaction-control-icon-super-positive
{
opacity
:
0
;
}
}
}
}
changelogs/unreleased/eread-migrate-awards-list-buttons.yml
0 → 100644
View file @
d92bdee7
---
title
:
Migrate awards list buttons to new buttons
merge_request
:
43061
author
:
type
:
other
spec/frontend/vue_shared/components/__snapshots__/awards_list_spec.js.snap
View file @
d92bdee7
...
...
@@ -5,12 +5,17 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
class="awards js-awards-block"
>
<button
class="btn
award-control
"
class="btn
gl-mr-3 btn-default btn-md gl-button
"
data-testid="award-button"
title="Ada, Leonardo, and Marie"
type="button"
>
<!---->
<!---->
<span
class="award-emoji-block"
data-testid="award-html"
>
...
...
@@ -23,18 +28,28 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
</span>
<span
class="
award-control-text js-counter
"
class="
gl-button-text
"
>
3
<span
class="js-counter"
>
3
</span>
</span>
</button>
<button
class="btn
award-control active
"
class="btn
gl-mr-3 btn-default btn-md gl-button selected
"
data-testid="award-button"
title="You, Ada, and Marie"
type="button"
>
<!---->
<!---->
<span
class="award-emoji-block"
data-testid="award-html"
>
...
...
@@ -47,18 +62,28 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
</span>
<span
class="
award-control-text js-counter
"
class="
gl-button-text
"
>
3
<span
class="js-counter"
>
3
</span>
</span>
</button>
<button
class="btn
award-control
"
class="btn
gl-mr-3 btn-default btn-md gl-button
"
data-testid="award-button"
title="Ada and Jane"
type="button"
>
<!---->
<!---->
<span
class="award-emoji-block"
data-testid="award-html"
>
...
...
@@ -71,18 +96,28 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
</span>
<span
class="
award-control-text js-counter
"
class="
gl-button-text
"
>
2
<span
class="js-counter"
>
2
</span>
</span>
</button>
<button
class="btn
award-control active
"
class="btn
gl-mr-3 btn-default btn-md gl-button selected
"
data-testid="award-button"
title="You, Ada, Jane, and Leonardo"
type="button"
>
<!---->
<!---->
<span
class="award-emoji-block"
data-testid="award-html"
>
...
...
@@ -95,18 +130,28 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
</span>
<span
class="
award-control-text js-counter
"
class="
gl-button-text
"
>
4
<span
class="js-counter"
>
4
</span>
</span>
</button>
<button
class="btn
award-control active
"
class="btn
gl-mr-3 btn-default btn-md gl-button selected
"
data-testid="award-button"
title="You"
type="button"
>
<!---->
<!---->
<span
class="award-emoji-block"
data-testid="award-html"
>
...
...
@@ -119,18 +164,28 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
</span>
<span
class="
award-control-text js-counter
"
class="
gl-button-text
"
>
1
<span
class="js-counter"
>
1
</span>
</span>
</button>
<button
class="btn
award-control
"
class="btn
gl-mr-3 btn-default btn-md gl-button
"
data-testid="award-button"
title="Marie"
type="button"
>
<!---->
<!---->
<span
class="award-emoji-block"
data-testid="award-html"
>
...
...
@@ -143,18 +198,28 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
</span>
<span
class="
award-control-text js-counter
"
class="
gl-button-text
"
>
1
<span
class="js-counter"
>
1
</span>
</span>
</button>
<button
class="btn
award-control active
"
class="btn
gl-mr-3 btn-default btn-md gl-button selected
"
data-testid="award-button"
title="You"
type="button"
>
<!---->
<!---->
<span
class="award-emoji-block"
data-testid="award-html"
>
...
...
@@ -167,9 +232,14 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
</span>
<span
class="
award-control-text js-counter
"
class="
gl-button-text
"
>
1
<span
class="js-counter"
>
1
</span>
</span>
</button>
...
...
@@ -178,46 +248,59 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
>
<button
aria-label="Add reaction"
class="
award-control btn js-add-award
js-test-add-button-class"
class="
btn add-reaction-button js-add-award btn-default btn-md gl-button
js-test-add-button-class"
title="Add reaction"
type="button"
>
<span
class="award-control-icon award-control-icon-neutral"
>
<gl-icon-stub
aria-hidden="true"
name="slight-smile"
size="16"
/>
</span>
<!---->
<!---->
<span
class="
award-control-icon award-control-icon-positive
"
class="
gl-button-text
"
>
<gl-icon-stub
aria-hidden="true"
name="smiley"
size="16"
/>
<span
class="reaction-control-icon reaction-control-icon-neutral"
>
<svg
aria-hidden="true"
class="gl-icon s16"
data-testid="slight-smile-icon"
>
<use
href="#slight-smile"
/>
</svg>
</span>
<span
class="reaction-control-icon reaction-control-icon-positive"
>
<svg
aria-hidden="true"
class="gl-icon s16"
data-testid="smiley-icon"
>
<use
href="#smiley"
/>
</svg>
</span>
<span
class="reaction-control-icon reaction-control-icon-super-positive"
>
<svg
aria-hidden="true"
class="gl-icon s16"
data-testid="smile-icon"
>
<use
href="#smile"
/>
</svg>
</span>
</span>
<span
class="award-control-icon award-control-icon-super-positive"
>
<gl-icon-stub
aria-hidden="true"
name="smiley"
size="16"
/>
</span>
<gl-loading-icon-stub
class="award-control-icon-loading"
color="dark"
label="Loading"
size="md"
/>
</button>
</div>
</div>
...
...
spec/frontend/vue_shared/components/awards_list_spec.js
View file @
d92bdee7
import
{
shallowM
ount
}
from
'
@vue/test-utils
'
;
import
{
m
ount
}
from
'
@vue/test-utils
'
;
import
AwardsList
from
'
~/vue_shared/components/awards_list.vue
'
;
const
createUser
=
(
id
,
name
)
=>
({
id
,
name
});
...
...
@@ -41,6 +41,8 @@ const TEST_AWARDS = [
];
const
TEST_ADD_BUTTON_CLASS
=
'
js-test-add-button-class
'
;
const
REACTION_CONTROL_CLASSES
=
[
'
btn
'
,
'
gl-mr-3
'
,
'
btn-default
'
,
'
btn-md
'
,
'
gl-button
'
];
describe
(
'
vue_shared/components/awards_list
'
,
()
=>
{
let
wrapper
;
...
...
@@ -54,16 +56,16 @@ describe('vue_shared/components/awards_list', () => {
throw
new
Error
(
'
There should only be one wrapper created per test
'
);
}
wrapper
=
shallowM
ount
(
AwardsList
,
{
propsData
:
props
});
wrapper
=
m
ount
(
AwardsList
,
{
propsData
:
props
});
};
const
matchingEmojiTag
=
name
=>
expect
.
stringMatching
(
`gl-emoji data-name="
${
name
}
"`
);
const
findAwardButtons
=
()
=>
wrapper
.
findAll
(
'
[data-testid="award-button"
'
);
const
findAwardButtons
=
()
=>
wrapper
.
findAll
(
'
[data-testid="award-button"
]
'
);
const
findAwardsData
=
()
=>
findAwardButtons
().
wrappers
.
map
(
x
=>
{
return
{
classes
:
x
.
classes
(),
title
:
x
.
attributes
(
'
title
'
),
html
:
x
.
find
(
'
[data-testid="award-html"]
'
).
element
.
innerHTML
,
html
:
x
.
find
(
'
[data-testid="award-html"]
'
).
html
()
,
count
:
Number
(
x
.
find
(
'
.js-counter
'
).
text
()),
};
});
...
...
@@ -86,43 +88,43 @@ describe('vue_shared/components/awards_list', () => {
it
(
'
shows awards in correct order
'
,
()
=>
{
expect
(
findAwardsData
()).
toEqual
([
{
classes
:
[
'
btn
'
,
'
award-control
'
]
,
classes
:
REACTION_CONTROL_CLASSES
,
count
:
3
,
html
:
matchingEmojiTag
(
EMOJI_THUMBSUP
),
title
:
'
Ada, Leonardo, and Marie
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
,
'
active
'
],
classes
:
[
...
REACTION_CONTROL_CLASSES
,
'
selected
'
],
count
:
3
,
html
:
matchingEmojiTag
(
EMOJI_THUMBSDOWN
),
title
:
'
You, Ada, and Marie
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
]
,
classes
:
REACTION_CONTROL_CLASSES
,
count
:
2
,
html
:
matchingEmojiTag
(
EMOJI_SMILE
),
title
:
'
Ada and Jane
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
,
'
active
'
],
classes
:
[
...
REACTION_CONTROL_CLASSES
,
'
selected
'
],
count
:
4
,
html
:
matchingEmojiTag
(
EMOJI_OK
),
title
:
'
You, Ada, Jane, and Leonardo
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
,
'
active
'
],
classes
:
[
...
REACTION_CONTROL_CLASSES
,
'
selected
'
],
count
:
1
,
html
:
matchingEmojiTag
(
EMOJI_CACTUS
),
title
:
'
You
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
]
,
classes
:
REACTION_CONTROL_CLASSES
,
count
:
1
,
html
:
matchingEmojiTag
(
EMOJI_A
),
title
:
'
Marie
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
,
'
active
'
],
classes
:
[
...
REACTION_CONTROL_CLASSES
,
'
selected
'
],
count
:
1
,
html
:
matchingEmojiTag
(
EMOJI_B
),
title
:
'
You
'
,
...
...
@@ -135,7 +137,7 @@ describe('vue_shared/components/awards_list', () => {
findAwardButtons
()
.
at
(
2
)
.
trigger
(
'
click
'
);
.
vm
.
$emit
(
'
click
'
);
expect
(
wrapper
.
emitted
().
award
).
toEqual
([[
EMOJI_SMILE
]]);
});
...
...
@@ -162,7 +164,7 @@ describe('vue_shared/components/awards_list', () => {
findAwardButtons
()
.
at
(
0
)
.
trigger
(
'
click
'
);
.
vm
.
$emit
(
'
click
'
);
expect
(
wrapper
.
emitted
().
award
).
toEqual
([[
Number
(
EMOJI_100
)]]);
});
...
...
@@ -225,26 +227,26 @@ describe('vue_shared/components/awards_list', () => {
it
(
'
shows awards in correct order
'
,
()
=>
{
expect
(
findAwardsData
()).
toEqual
([
{
classes
:
[
'
btn
'
,
'
award-control
'
]
,
classes
:
REACTION_CONTROL_CLASSES
,
count
:
0
,
html
:
matchingEmojiTag
(
EMOJI_THUMBSUP
),
title
:
''
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
]
,
classes
:
REACTION_CONTROL_CLASSES
,
count
:
0
,
html
:
matchingEmojiTag
(
EMOJI_THUMBSDOWN
),
title
:
''
,
},
// We expect the EMOJI_100 before the EMOJI_SMILE because it was given as a defaultAward
{
classes
:
[
'
btn
'
,
'
award-control
'
]
,
classes
:
REACTION_CONTROL_CLASSES
,
count
:
1
,
html
:
matchingEmojiTag
(
EMOJI_100
),
title
:
'
Marie
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
]
,
classes
:
REACTION_CONTROL_CLASSES
,
count
:
1
,
html
:
matchingEmojiTag
(
EMOJI_SMILE
),
title
:
'
Marie
'
,
...
...
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