BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
b0642299
Commit
b0642299
authored
May 19, 2017
by
Phil Hughes
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'user-avatar-vue-ce' into 'master'
Consolidate user avatar Vue logic Closes #31017 See merge request !10718
parents
01a7f333
55737682
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
449 additions
and
78 deletions
+449
-78
issue_card_inner.js
app/assets/javascripts/boards/components/issue_card_inner.js
+12
-15
stage_code_component.js
...cripts/cycle_analytics/components/stage_code_component.js
+6
-1
stage_issue_component.js
...ripts/cycle_analytics/components/stage_issue_component.js
+6
-2
stage_plan_component.js
...cripts/cycle_analytics/components/stage_plan_component.js
+6
-3
stage_production_component.js
.../cycle_analytics/components/stage_production_component.js
+6
-2
stage_review_component.js
...ipts/cycle_analytics/components/stage_review_component.js
+6
-2
stage_staging_component.js
...pts/cycle_analytics/components/stage_staging_component.js
+6
-1
diff_note_avatars.js
...ts/javascripts/diff_notes/components/diff_note_avatars.js
+17
-11
environment_item.vue
.../javascripts/environments/components/environment_item.vue
+9
-9
pipeline_url.js
app/assets/javascripts/pipelines/components/pipeline_url.js
+11
-11
commit.js
app/assets/javascripts/vue_shared/components/commit.js
+11
-9
user_avatar_image.vue
...s/vue_shared/components/user_avatar/user_avatar_image.vue
+80
-0
user_avatar_link.vue
...ts/vue_shared/components/user_avatar/user_avatar_link.vue
+80
-0
user_avatar_svg.vue
...pts/vue_shared/components/user_avatar/user_avatar_svg.vue
+45
-0
avatar.scss
app/assets/stylesheets/framework/avatar.scss
+2
-0
icons.scss
app/assets/stylesheets/framework/icons.scss
+4
-0
environments.scss
app/assets/stylesheets/pages/environments.scss
+0
-4
webpack.config.js
config/webpack.config.js
+3
-2
diff_notes_avatars_spec.rb
spec/features/merge_requests/diff_notes_avatars_spec.rb
+1
-1
issue_card_spec.js
spec/javascripts/boards/issue_card_spec.js
+1
-1
pipeline_url_spec.js
spec/javascripts/pipelines/pipeline_url_spec.js
+1
-1
commit_spec.js
spec/javascripts/vue_shared/components/commit_spec.js
+1
-1
pipelines_table_row_spec.js
...scripts/vue_shared/components/pipelines_table_row_spec.js
+2
-2
user_avatar_image_spec.js
...vascripts/vue_shared/components/user_avatar_image_spec.js
+54
-0
user_avatar_link_spec.js
...avascripts/vue_shared/components/user_avatar_link_spec.js
+50
-0
user_avatar_svg_spec.js
...javascripts/vue_shared/components/user_avatar_svg_spec.js
+29
-0
No files found.
app/assets/javascripts/boards/components/issue_card_inner.js
View file @
b0642299
import
Vue
from
'vue'
;
import
userAvatarLink
from
'../../vue_shared/components/user_avatar/user_avatar_link.vue'
;
import
eventHub
from
'../eventhub'
;
const
Store
=
gl
.
issueBoards
.
BoardsStore
;
...
...
@@ -38,6 +39,9 @@ gl.issueBoards.IssueCardInner = Vue.extend({
maxCounter
:
99
,
};
},
components
:
{
userAvatarLink
,
},
computed
:
{
numberOverLimit
()
{
return
this
.
issue
.
assignees
.
length
-
this
.
limitBeforeCounter
;
...
...
@@ -146,23 +150,16 @@ gl.issueBoards.IssueCardInner = Vue.extend({
</span>
</h4>
<div class="card-assignee">
<a
class="has-tooltip js-no-trigger"
:href="assigneeUrl(assignee)"
:title="assigneeUrlTitle(assignee)"
<user-avatar-link
v-for="(assignee, index) in issue.assignees"
v-if="shouldRenderAssignee(index)"
data-container="body"
data-placement="bottom"
>
<img
class="avatar avatar-inline s20"
:src="assignee.avatar"
width="20"
height="20"
:alt="avatarUrlTitle(assignee)"
/>
</a>
class="js-no-trigger"
:link-href="assigneeUrl(assignee)"
:img-alt="avatarUrlTitle(assignee)"
:img-src="assignee.avatar"
:tooltip-text="assigneeUrlTitle(assignee)"
tooltip-placement="bottom"
/>
<span
class="avatar-counter has-tooltip"
:title="assigneeCounterTooltip"
...
...
app/assets/javascripts/cycle_analytics/components/stage_code_component.js
View file @
b0642299
/* eslint-disable no-param-reassign */
import
Vue
from
'vue'
;
import
userAvatarImage
from
'../../vue_shared/components/user_avatar/user_avatar_image.vue'
;
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
global
.
cycleAnalytics
=
global
.
cycleAnalytics
||
{};
...
...
@@ -10,6 +11,9 @@ global.cycleAnalytics.StageCodeComponent = Vue.extend({
items
:
Array
,
stage
:
Object
,
},
components
:
{
userAvatarImage
,
},
template
:
`
<div>
<div class="events-description">
...
...
@@ -19,7 +23,8 @@ global.cycleAnalytics.StageCodeComponent = Vue.extend({
<ul class="stage-event-list">
<li v-for="mergeRequest in items" class="stage-event-item">
<div class="item-details">
<img class="avatar" :src="mergeRequest.author.avatarUrl">
<!-- FIXME: Pass an alt attribute here for accessibility -->
<user-avatar-image :img-src="mergeRequest.author.avatarUrl"/>
<h5 class="item-title merge-merquest-title">
<a :href="mergeRequest.url">
{{ mergeRequest.title }}
...
...
app/assets/javascripts/cycle_analytics/components/stage_issue_component.js
View file @
b0642299
/* eslint-disable no-param-reassign */
import
Vue
from
'vue'
;
import
userAvatarImage
from
'../../vue_shared/components/user_avatar/user_avatar_image.vue'
;
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
global
.
cycleAnalytics
=
global
.
cycleAnalytics
||
{};
...
...
@@ -10,6 +10,9 @@ global.cycleAnalytics.StageIssueComponent = Vue.extend({
items
:
Array
,
stage
:
Object
,
},
components
:
{
userAvatarImage
,
},
template
:
`
<div>
<div class="events-description">
...
...
@@ -19,7 +22,8 @@ global.cycleAnalytics.StageIssueComponent = Vue.extend({
<ul class="stage-event-list">
<li v-for="issue in items" class="stage-event-item">
<div class="item-details">
<img class="avatar" :src="issue.author.avatarUrl">
<!-- FIXME: Pass an alt attribute here for accessibility -->
<user-avatar-image :img-src="issue.author.avatarUrl"/>
<h5 class="item-title issue-title">
<a class="issue-title" :href="issue.url">
{{ issue.title }}
...
...
app/assets/javascripts/cycle_analytics/components/stage_plan_component.js
View file @
b0642299
/* eslint-disable no-param-reassign */
import
Vue
from
'vue'
;
import
userAvatarImage
from
'../../vue_shared/components/user_avatar/user_avatar_image.vue'
;
import
iconCommit
from
'../svg/icon_commit.svg'
;
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
...
...
@@ -10,11 +11,12 @@ global.cycleAnalytics.StagePlanComponent = Vue.extend({
items
:
Array
,
stage
:
Object
,
},
components
:
{
userAvatarImage
,
},
data
()
{
return
{
iconCommit
};
},
template
:
`
<div>
<div class="events-description">
...
...
@@ -24,7 +26,8 @@ global.cycleAnalytics.StagePlanComponent = Vue.extend({
<ul class="stage-event-list">
<li v-for="commit in items" class="stage-event-item">
<div class="item-details item-conmmit-component">
<img class="avatar" :src="commit.author.avatarUrl">
<!-- FIXME: Pass an alt attribute here for accessibility -->
<user-avatar-image :img-src="commit.author.avatarUrl"/>
<h5 class="item-title commit-title">
<a :href="commit.commitUrl">
{{ commit.title }}
...
...
app/assets/javascripts/cycle_analytics/components/stage_production_component.js
View file @
b0642299
/* eslint-disable no-param-reassign */
import
Vue
from
'vue'
;
import
userAvatarImage
from
'../../vue_shared/components/user_avatar/user_avatar_image.vue'
;
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
global
.
cycleAnalytics
=
global
.
cycleAnalytics
||
{};
...
...
@@ -10,6 +10,9 @@ global.cycleAnalytics.StageProductionComponent = Vue.extend({
items
:
Array
,
stage
:
Object
,
},
components
:
{
userAvatarImage
,
},
template
:
`
<div>
<div class="events-description">
...
...
@@ -19,7 +22,8 @@ global.cycleAnalytics.StageProductionComponent = Vue.extend({
<ul class="stage-event-list">
<li v-for="issue in items" class="stage-event-item">
<div class="item-details">
<img class="avatar" :src="issue.author.avatarUrl">
<!-- FIXME: Pass an alt attribute here for accessibility -->
<user-avatar-image :img-src="issue.author.avatarUrl"/>
<h5 class="item-title issue-title">
<a class="issue-title" :href="issue.url">
{{ issue.title }}
...
...
app/assets/javascripts/cycle_analytics/components/stage_review_component.js
View file @
b0642299
/* eslint-disable no-param-reassign */
import
Vue
from
'vue'
;
import
userAvatarImage
from
'../../vue_shared/components/user_avatar/user_avatar_image.vue'
;
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
global
.
cycleAnalytics
=
global
.
cycleAnalytics
||
{};
...
...
@@ -10,6 +10,9 @@ global.cycleAnalytics.StageReviewComponent = Vue.extend({
items
:
Array
,
stage
:
Object
,
},
components
:
{
userAvatarImage
,
},
template
:
`
<div>
<div class="events-description">
...
...
@@ -19,7 +22,8 @@ global.cycleAnalytics.StageReviewComponent = Vue.extend({
<ul class="stage-event-list">
<li v-for="mergeRequest in items" class="stage-event-item">
<div class="item-details">
<img class="avatar" :src="mergeRequest.author.avatarUrl">
<!-- FIXME: Pass an alt attribute here for accessibility -->
<user-avatar-image :img-src="mergeRequest.author.avatarUrl"/>
<h5 class="item-title merge-merquest-title">
<a :href="mergeRequest.url">
{{ mergeRequest.title }}
...
...
app/assets/javascripts/cycle_analytics/components/stage_staging_component.js
View file @
b0642299
/* eslint-disable no-param-reassign */
import
Vue
from
'vue'
;
import
userAvatarImage
from
'../../vue_shared/components/user_avatar/user_avatar_image.vue'
;
import
iconBranch
from
'../svg/icon_branch.svg'
;
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
...
...
@@ -13,6 +14,9 @@ global.cycleAnalytics.StageStagingComponent = Vue.extend({
data
()
{
return
{
iconBranch
};
},
components
:
{
userAvatarImage
,
},
template
:
`
<div>
<div class="events-description">
...
...
@@ -22,7 +26,8 @@ global.cycleAnalytics.StageStagingComponent = Vue.extend({
<ul class="stage-event-list">
<li v-for="build in items" class="stage-event-item item-build-component">
<div class="item-details">
<img class="avatar" :src="build.author.avatarUrl">
<!-- FIXME: Pass an alt attribute here for accessibility -->
<user-avatar-image :img-src="build.author.avatarUrl"/>
<h5 class="item-title">
<a :href="build.url" class="pipeline-id">#{{ build.id }}</a>
<i class="fa fa-code-fork"></i>
...
...
app/assets/javascripts/diff_notes/components/diff_note_avatars.js
View file @
b0642299
...
...
@@ -3,6 +3,7 @@
import
Vue
from
'vue'
;
import
collapseIcon
from
'../icons/collapse_icon.svg'
;
import
userAvatarImage
from
'../../vue_shared/components/user_avatar/user_avatar_image.vue'
;
const
DiffNoteAvatars
=
Vue
.
extend
({
props
:
[
'discussionId'
],
...
...
@@ -15,22 +16,24 @@ const DiffNoteAvatars = Vue.extend({
collapseIcon
,
};
},
components
:
{
userAvatarImage
,
},
template
:
`
<div class="diff-comment-avatar-holders"
v-show="notesCount !== 0">
<div v-if="!isVisible">
<img v-for="note in notesSubset"
class="avatar diff-comment-avatar has-tooltip js-diff-comment-avatar"
width="19"
height="19"
role="button"
data-container="body"
data-placement="top"
data-html="true"
<!-- FIXME: Pass an alt attribute here for accessibility -->
<user-avatar-image
v-for="note in notesSubset"
class="diff-comment-avatar js-diff-comment-avatar"
@click.native="clickedAvatar($event)"
:img-src="note.authorAvatar"
:tooltip-text="getTooltipText(note)"
:data-line-type="lineType"
:
title="note.authorName + ': ' + note.noteTruncated
"
:src="note.authorAvatar
"
@click="clickedAvatar($event)"
/>
:
size="19
"
data-html="true
"
/>
<span v-if="notesCount > shownAvatars"
class="diff-comments-more-count has-tooltip js-diff-comment-avatar"
data-container="body"
...
...
@@ -150,6 +153,9 @@ const DiffNoteAvatars = Vue.extend({
setDiscussionVisible
()
{
this
.
isVisible
=
$
(
`.diffs .notes[data-discussion-id="
${
this
.
discussion
.
id
}
"]`
).
is
(
':visible'
);
},
getTooltipText
(
note
)
{
return
`
${
note
.
authorName
}
:
${
note
.
noteTruncated
}
`
;
},
},
});
...
...
app/assets/javascripts/environments/components/environment_item.vue
View file @
b0642299
<
script
>
import
Timeago
from
'timeago.js'
;
import
_
from
'underscore'
;
import
userAvatarLink
from
'../../vue_shared/components/user_avatar/user_avatar_link.vue'
;
import
'../../lib/utils/text_utility'
;
import
ActionsComponent
from
'./environment_actions.vue'
;
import
ExternalUrlComponent
from
'./environment_external_url.vue'
;
...
...
@@ -20,6 +21,7 @@ const timeagoInstance = new Timeago();
export
default
{
components
:
{
userAvatarLink
,
'commit-component'
:
CommitComponent
,
'actions-component'
:
ActionsComponent
,
'external-url-component'
:
ExternalUrlComponent
,
...
...
@@ -468,15 +470,13 @@ export default {
<span
v-if=
"!model.isFolder && deploymentHasUser"
>
by
<a
:href=
"deploymentUser.web_url"
class=
"js-deploy-user-container"
>
<img
class=
"avatar has-tooltip s20"
:src=
"deploymentUser.avatar_url"
:alt=
"userImageAltDescription"
:title=
"deploymentUser.username"
/>
</a>
<user-avatar-link
class=
"js-deploy-user-container"
:link-href=
"deploymentUser.web_url"
:img-src=
"deploymentUser.avatar_url"
:img-alt=
"userImageAltDescription"
:tooltip-text=
"deploymentUser.username"
/>
</span>
</td>
...
...
app/assets/javascripts/pipelines/components/pipeline_url.js
View file @
b0642299
import
userAvatarLink
from
'../../vue_shared/components/user_avatar/user_avatar_link.vue'
;
export
default
{
props
:
[
'pipeline'
,
...
...
@@ -7,6 +9,9 @@ export default {
return
!!
this
.
pipeline
.
user
;
},
},
components
:
{
userAvatarLink
,
},
template
:
`
<td>
<a
...
...
@@ -15,18 +20,13 @@ export default {
<span class="pipeline-id">#{{pipeline.id}}</span>
</a>
<span>by</span>
<a
class="js-pipeline-url-user"
<user-avatar-link
v-if="user"
:href="pipeline.user.web_url">
<img
v-if="user"
class="avatar has-tooltip s20 "
:title="pipeline.user.name"
data-container="body"
:src="pipeline.user.avatar_url"
>
</a>
class="js-pipeline-url-user"
:link-href="pipeline.user.web_url"
:img-src="pipeline.user.avatar_url"
:tooltip-text="pipeline.user.name"
/>
<span
v-if="!user"
class="js-pipeline-url-api api">
...
...
app/assets/javascripts/vue_shared/components/commit.js
View file @
b0642299
import
commitIconSvg
from
'icons/_icon_commit.svg'
;
import
userAvatarLink
from
'./user_avatar/user_avatar_link.vue'
;
export
default
{
props
:
{
...
...
@@ -110,6 +111,9 @@ export default {
return
{
commitIconSvg
};
},
components
:
{
userAvatarLink
,
},
template
:
`
<div class="branch-commit">
...
...
@@ -133,16 +137,14 @@ export default {
<p class="commit-title">
<span v-if="title">
<a v-if="hasAuthor"
<user-avatar-link
v-if="hasAuthor"
class="avatar-image-container"
:href="author.web_url">
<img
class="avatar has-tooltip s20"
:src="author.avatar_url"
:alt="userImageAltDescription"
:title="author.username" />
</a>
:link-href="author.web_url"
:img-src="author.avatar_url"
:img-alt="userImageAltDescription"
:tooltip-text="author.username"
/>
<a class="commit-row-message"
:href="commitUrl">
{{title}}
...
...
app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue
0 → 100644
View file @
b0642299
<
script
>
/* This is a re-usable vue component for rendering a user avatar that
does not need to link to the user's profile. The image and an optional
tooltip can be configured by props passed to this component.
Sample configuration:
<user-avatar-image
:img-src="userAvatarSrc"
:img-alt="tooltipText"
:tooltip-text="tooltipText"
tooltip-placement="top"
/>
*/
import
defaultAvatarUrl
from
'images/no_avatar.png'
;
import
TooltipMixin
from
'../../mixins/tooltip'
;
export
default
{
name
:
'UserAvatarImage'
,
mixins
:
[
TooltipMixin
],
props
:
{
imgSrc
:
{
type
:
String
,
required
:
false
,
default
:
defaultAvatarUrl
,
},
cssClasses
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
imgAlt
:
{
type
:
String
,
required
:
false
,
default
:
'user avatar'
,
},
size
:
{
type
:
Number
,
required
:
false
,
default
:
20
,
},
tooltipText
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
tooltipPlacement
:
{
type
:
String
,
required
:
false
,
default
:
'top'
,
},
},
computed
:
{
tooltipContainer
()
{
return
this
.
tooltipText
?
'body'
:
null
;
},
avatarSizeClass
()
{
return
`s
${
this
.
size
}
`
;
},
},
};
</
script
>
<
template
>
<img
class=
"avatar"
:class=
"[avatarSizeClass, cssClasses]"
:src=
"imgSrc"
:width=
"size"
:height=
"size"
:alt=
"imgAlt"
:data-container=
"tooltipContainer"
:data-placement=
"tooltipPlacement"
:title=
"tooltipText"
ref=
"tooltip"
/>
</
template
>
app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
0 → 100644
View file @
b0642299
<
script
>
/* This is a re-usable vue component for rendering a user avatar wrapped in
a clickable link (likely to the user's profile). The link, image, and
tooltip can be configured by props passed to this component.
Sample configuration:
<user-avatar-link
:link-href="userProfileUrl"
:img-src="userAvatarSrc"
:img-alt="tooltipText"
:img-size="20"
:tooltip-text="tooltipText"
tooltip-placement="top"
/>
*/
import
userAvatarImage
from
'./user_avatar_image.vue'
;
export
default
{
name
:
'UserAvatarLink'
,
components
:
{
userAvatarImage
,
},
props
:
{
linkHref
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
imgSrc
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
imgAlt
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
imgCssClasses
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
imgSize
:
{
type
:
Number
,
required
:
false
,
default
:
20
,
},
tooltipText
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
tooltipPlacement
:
{
type
:
String
,
required
:
false
,
default
:
'top'
,
},
},
};
</
script
>
<
template
>
<a
class=
"user-avatar-link"
:href=
"linkHref"
>
<user-avatar-image
:img-src=
"imgSrc"
:img-alt=
"imgAlt"
:css-classes=
"imgCssClasses"
:size=
"imgSize"
:tooltip-text=
"tooltipText"
:tooltip-placement=
"tooltipPlacement"
/>
</a>
</
template
>
app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_svg.vue
0 → 100644
View file @
b0642299
<
script
>
/* This is a re-usable vue component for rendering a user avatar svg (typically
for a blank state). It will receive styles comparable to the user avatar,
but no image is loaded, it isn't wrapped in a link, and tooltips aren't supported.
The svg and avatar size can be configured by props passed to this component.
Sample configuration:
<user-avatar-svg
:svg="potentialApproverSvg"
:size="20"
/>
*/
export
default
{
props
:
{
svg
:
{
type
:
String
,
required
:
true
,
},
size
:
{
type
:
Number
,
required
:
false
,
default
:
20
,
},
},
computed
:
{
avatarSizeClass
()
{
return
`s
${
this
.
size
}
`
;
},
},
};
</
script
>
<
template
>
<svg
:class=
"avatarSizeClass"
:height=
"size"
:width=
"size"
v-html=
"svg"
>
</svg>
</
template
>
app/assets/stylesheets/framework/avatar.scss
View file @
b0642299
...
...
@@ -10,6 +10,8 @@
border-radius
:
$avatar_radius
;
border
:
1px
solid
$avatar-border
;
&
.s16
{
@include
avatar-size
(
16px
,
6px
);
}
&
.s18
{
@include
avatar-size
(
18px
,
6px
);
}
&
.s19
{
@include
avatar-size
(
19px
,
6px
);
}
&
.s20
{
@include
avatar-size
(
20px
,
7px
);
}
&
.s24
{
@include
avatar-size
(
24px
,
8px
);
}
&
.s26
{
@include
avatar-size
(
26px
,
8px
);
}
...
...
app/assets/stylesheets/framework/icons.scss
View file @
b0642299
...
...
@@ -65,3 +65,7 @@
text-decoration
:
none
;
}
}
.user-avatar-link
{
text-decoration
:
none
;
}
app/assets/stylesheets/pages/environments.scss
View file @
b0642299
...
...
@@ -68,10 +68,6 @@
margin
:
0
;
}
.avatar-image-container
{
text-decoration
:
none
;
}
.icon-play
{
height
:
13px
;
width
:
12px
;
...
...
config/webpack.config.js
View file @
b0642299
...
...
@@ -90,9 +90,9 @@ var config = {
loader
:
'raw-loader'
,
},
{
test
:
/
\.
gif
$/
,
test
:
/
\.
(
gif|png
)
$/
,
loader
:
'url-loader'
,
query
:
{
mimetype
:
'image/gif'
},
options
:
{
limit
:
2048
},
},
{
test
:
/
\.(
worker
\.
js|pdf|bmpr
)
$/
,
...
...
@@ -190,6 +190,7 @@ var config = {
'emojis'
:
path
.
join
(
ROOT_PATH
,
'fixtures/emojis'
),
'empty_states'
:
path
.
join
(
ROOT_PATH
,
'app/views/shared/empty_states'
),
'icons'
:
path
.
join
(
ROOT_PATH
,
'app/views/shared/icons'
),
'images'
:
path
.
join
(
ROOT_PATH
,
'app/assets/images'
),
'vendor'
:
path
.
join
(
ROOT_PATH
,
'vendor/assets/javascripts'
),
'vue$'
:
'vue/dist/vue.esm.js'
,
}
...
...
spec/features/merge_requests/diff_notes_avatars_spec.rb
View file @
b0642299
...
...
@@ -91,7 +91,7 @@ feature 'Diff note avatars', feature: true, js: true do
page
.
within
find
(
"[id='
#{
position
.
line_code
(
project
.
repository
)
}
']"
)
do
find
(
'.diff-notes-collapse'
).
click
expect
(
first
(
'img.js-diff-comment-avatar'
)[
"title"
]).
to
eq
(
"
#{
note
.
author
.
name
}
:
#{
note
.
note
.
truncate
(
17
)
}
"
)
expect
(
first
(
'img.js-diff-comment-avatar'
)[
"
data-original-
title"
]).
to
eq
(
"
#{
note
.
author
.
name
}
:
#{
note
.
note
.
truncate
(
17
)
}
"
)
end
end
...
...
spec/javascripts/boards/issue_card_spec.js
View file @
b0642299
...
...
@@ -129,7 +129,7 @@ describe('Issue card component', () => {
it
(
'sets title'
,
()
=>
{
expect
(
component
.
$el
.
querySelector
(
'.card-assignee
a'
).
getAttribute
(
'
title'
),
component
.
$el
.
querySelector
(
'.card-assignee
img'
).
getAttribute
(
'data-original-
title'
),
).
toContain
(
`Assigned to
${
user
.
name
}
`
);
});
...
...
spec/javascripts/pipelines/pipeline_url_spec.js
View file @
b0642299
...
...
@@ -60,7 +60,7 @@ describe('Pipeline Url Component', () => {
expect
(
component
.
$el
.
querySelector
(
'.js-pipeline-url-user'
).
getAttribute
(
'href'
),
).
toEqual
(
mockData
.
pipeline
.
user
.
web_url
);
expect
(
image
.
getAttribute
(
'title'
)).
toEqual
(
mockData
.
pipeline
.
user
.
name
);
expect
(
image
.
getAttribute
(
'
data-original-
title'
)).
toEqual
(
mockData
.
pipeline
.
user
.
name
);
expect
(
image
.
getAttribute
(
'src'
)).
toEqual
(
mockData
.
pipeline
.
user
.
avatar_url
);
});
...
...
spec/javascripts/vue_shared/components/commit_spec.js
View file @
b0642299
...
...
@@ -86,7 +86,7 @@ describe('Commit component', () => {
it
(
'Should render the author avatar with title and alt attributes'
,
()
=>
{
expect
(
component
.
$el
.
querySelector
(
'.commit-title .avatar-image-container img'
).
getAttribute
(
'title'
),
component
.
$el
.
querySelector
(
'.commit-title .avatar-image-container img'
).
getAttribute
(
'
data-original-
title'
),
).
toContain
(
props
.
author
.
username
);
expect
(
component
.
$el
.
querySelector
(
'.commit-title .avatar-image-container img'
).
getAttribute
(
'alt'
),
...
...
spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
View file @
b0642299
...
...
@@ -79,7 +79,7 @@ describe('Pipelines Table Row', () => {
).
toEqual
(
pipeline
.
user
.
web_url
);
expect
(
component
.
$el
.
querySelector
(
'td:nth-child(2) img'
).
getAttribute
(
'title'
),
component
.
$el
.
querySelector
(
'td:nth-child(2) img'
).
getAttribute
(
'
data-original-
title'
),
).
toEqual
(
pipeline
.
user
.
name
);
});
});
...
...
@@ -102,7 +102,7 @@ describe('Pipelines Table Row', () => {
}
const
commitAuthorLink
=
commitAuthorElement
.
getAttribute
(
'href'
);
const
commitAuthorName
=
commitAuthorElement
.
querySelector
(
'img.avatar'
).
getAttribute
(
'title'
);
const
commitAuthorName
=
commitAuthorElement
.
querySelector
(
'img.avatar'
).
getAttribute
(
'
data-original-
title'
);
return
{
commitAuthorElement
,
commitAuthorLink
,
commitAuthorName
};
};
...
...
spec/javascripts/vue_shared/components/user_avatar_image_spec.js
0 → 100644
View file @
b0642299
import
Vue
from
'vue'
;
import
UserAvatarImage
from
'~/vue_shared/components/user_avatar/user_avatar_image.vue'
;
const
UserAvatarImageComponent
=
Vue
.
extend
(
UserAvatarImage
);
describe
(
'User Avatar Image Component'
,
function
()
{
describe
(
'Initialization'
,
function
()
{
beforeEach
(
function
()
{
this
.
propsData
=
{
size
:
99
,
imgSrc
:
'myavatarurl.com'
,
imgAlt
:
'mydisplayname'
,
cssClasses
:
'myextraavatarclass'
,
tooltipText
:
'tooltip text'
,
tooltipPlacement
:
'bottom'
,
};
this
.
userAvatarImage
=
new
UserAvatarImageComponent
({
propsData
:
this
.
propsData
,
}).
$mount
();
});
it
(
'should return a defined Vue component'
,
function
()
{
expect
(
this
.
userAvatarImage
).
toBeDefined
();
});
it
(
'should have <img> as a child element'
,
function
()
{
expect
(
this
.
userAvatarImage
.
$el
.
tagName
).
toBe
(
'IMG'
);
});
it
(
'should properly compute tooltipContainer'
,
function
()
{
expect
(
this
.
userAvatarImage
.
tooltipContainer
).
toBe
(
'body'
);
});
it
(
'should properly render tooltipContainer'
,
function
()
{
expect
(
this
.
userAvatarImage
.
$el
.
getAttribute
(
'data-container'
)).
toBe
(
'body'
);
});
it
(
'should properly compute avatarSizeClass'
,
function
()
{
expect
(
this
.
userAvatarImage
.
avatarSizeClass
).
toBe
(
's99'
);
});
it
(
'should properly render img css'
,
function
()
{
const
classList
=
this
.
userAvatarImage
.
$el
.
classList
;
const
containsAvatar
=
classList
.
contains
(
'avatar'
);
const
containsSizeClass
=
classList
.
contains
(
's99'
);
const
containsCustomClass
=
classList
.
contains
(
'myextraavatarclass'
);
expect
(
containsAvatar
).
toBe
(
true
);
expect
(
containsSizeClass
).
toBe
(
true
);
expect
(
containsCustomClass
).
toBe
(
true
);
});
});
});
spec/javascripts/vue_shared/components/user_avatar_link_spec.js
0 → 100644
View file @
b0642299
import
Vue
from
'vue'
;
import
UserAvatarLink
from
'~/vue_shared/components/user_avatar/user_avatar_link.vue'
;
describe
(
'User Avatar Link Component'
,
function
()
{
beforeEach
(
function
()
{
this
.
propsData
=
{
linkHref
:
'myavatarurl.com'
,
imgSize
:
99
,
imgSrc
:
'myavatarurl.com'
,
imgAlt
:
'mydisplayname'
,
imgCssClasses
:
'myextraavatarclass'
,
tooltipText
:
'tooltip text'
,
tooltipPlacement
:
'bottom'
,
};
const
UserAvatarLinkComponent
=
Vue
.
extend
(
UserAvatarLink
);
this
.
userAvatarLink
=
new
UserAvatarLinkComponent
({
propsData
:
this
.
propsData
,
}).
$mount
();
this
.
userAvatarImage
=
this
.
userAvatarLink
.
$children
[
0
];
});
it
(
'should return a defined Vue component'
,
function
()
{
expect
(
this
.
userAvatarLink
).
toBeDefined
();
});
it
(
'should have user-avatar-image registered as child component'
,
function
()
{
expect
(
this
.
userAvatarLink
.
$options
.
components
.
userAvatarImage
).
toBeDefined
();
});
it
(
'user-avatar-link should have user-avatar-image as child component'
,
function
()
{
expect
(
this
.
userAvatarImage
).
toBeDefined
();
});
it
(
'should render <a> as a child element'
,
function
()
{
expect
(
this
.
userAvatarLink
.
$el
.
tagName
).
toBe
(
'A'
);
});
it
(
'should have <img> as a child element'
,
function
()
{
expect
(
this
.
userAvatarLink
.
$el
.
querySelector
(
'img'
)).
not
.
toBeNull
();
});
it
(
'should return neccessary props as defined'
,
function
()
{
_
.
each
(
this
.
propsData
,
(
val
,
key
)
=>
{
expect
(
this
.
userAvatarLink
[
key
]).
toBeDefined
();
});
});
});
spec/javascripts/vue_shared/components/user_avatar_svg_spec.js
0 → 100644
View file @
b0642299
import
Vue
from
'vue'
;
import
UserAvatarSvg
from
'~/vue_shared/components/user_avatar/user_avatar_svg.vue'
;
import
avatarSvg
from
'icons/_icon_random.svg'
;
const
UserAvatarSvgComponent
=
Vue
.
extend
(
UserAvatarSvg
);
describe
(
'User Avatar Svg Component'
,
function
()
{
describe
(
'Initialization'
,
function
()
{
beforeEach
(
function
()
{
this
.
propsData
=
{
size
:
99
,
svg
:
avatarSvg
,
};
this
.
userAvatarSvg
=
new
UserAvatarSvgComponent
({
propsData
:
this
.
propsData
,
}).
$mount
();
});
it
(
'should return a defined Vue component'
,
function
()
{
expect
(
this
.
userAvatarSvg
).
toBeDefined
();
});
it
(
'should have <svg> as a child element'
,
function
()
{
expect
(
this
.
userAvatarSvg
.
$el
.
tagName
).
toEqual
(
'svg'
);
expect
(
this
.
userAvatarSvg
.
$el
.
innerHTML
).
toContain
(
'<path'
);
});
});
});
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