Commit ee367580 authored by Fatih Acet's avatar Fatih Acet

Merge branch '2491-approval-align' into 'master'

MR approval placeholders same size as images

Closes #2491

See merge request !2007
parents d11a4e13 4e6f1d54
/* global Flash */ /* global Flash */
import pendingAvatarSvg from 'icons/_icon_dotted_circle.svg';
import LinkToMemberAvatar from '~/vue_shared/components/link_to_member_avatar'; import LinkToMemberAvatar from '~/vue_shared/components/link_to_member_avatar';
import eventHub from '../../../event_hub'; import eventHub from '../../../event_hub';
...@@ -38,7 +37,6 @@ export default { ...@@ -38,7 +37,6 @@ export default {
data() { data() {
return { return {
unapproving: false, unapproving: false,
pendingAvatarSvg,
}; };
}, },
components: { components: {
...@@ -68,23 +66,22 @@ export default { ...@@ -68,23 +66,22 @@ export default {
template: ` template: `
<div v-if="approvedBy.length" class="approved-by-users approvals-footer clearfix mr-info-list"> <div v-if="approvedBy.length" class="approved-by-users approvals-footer clearfix mr-info-list">
<div class="legend"></div> <div class="legend"></div>
<div> <div class="approvers-prefix">
<p class="approvers-prefix">Approved by</p> <p>Approved by</p>
<div class="approvers-list"> <div class="approvers-list">
<span v-for="approver in approvedBy"> <span v-for="approver in approvedBy">
<link-to-member-avatar <link-to-member-avatar
:avatarSize="20"
extra-link-class="approver-avatar" extra-link-class="approver-avatar"
:avatar-url="approver.user.avatar_url"
:display-name="approver.user.name" :display-name="approver.user.name"
:profile-url="approver.user.web_url" :profile-url="approver.user.web_url"
:show-tooltip="true" /> :show-tooltip="true" />
</span> </span>
<span class="potential-approvers-list" v-for="n in approvalsLeft"> <span class="potential-approvers-list" v-for="n in approvalsLeft">
<link-to-member-avatar <link-to-member-avatar
:avatarSize="20"
:clickable="false" :clickable="false"
:avatar-html="pendingAvatarSvg" :show-tooltip="false" />
:show-tooltip="false"
extra-link-class="hide-asset" />
</span> </span>
</div> </div>
<span class="unapprove-btn-wrap" v-if="showUnapproveButton"> <span class="unapprove-btn-wrap" v-if="showUnapproveButton">
......
// Analogue of link_to_member_avatar in app/helpers/projects_helper.rb // Analogue of link_to_member_avatar in app/helpers/projects_helper.rb
import pendingAvatarSvg from 'icons/_icon_dotted_circle.svg';
export default { export default {
props: { props: {
...@@ -52,6 +53,7 @@ export default { ...@@ -52,6 +53,7 @@ export default {
data() { data() {
return { return {
avatarBaseClass: 'avatar avatar-inline', avatarBaseClass: 'avatar avatar-inline',
pendingAvatarSvg,
}; };
}, },
computed: { computed: {
...@@ -59,7 +61,7 @@ export default { ...@@ -59,7 +61,7 @@ export default {
return `s${this.avatarSize}`; return `s${this.avatarSize}`;
}, },
avatarHtmlClass() { avatarHtmlClass() {
return `${this.avatarSizeClass} ${this.avatarBaseClass}`; return `${this.avatarSizeClass} ${this.avatarBaseClass} avatar-placeholder`;
}, },
tooltipClass() { tooltipClass() {
return this.showTooltip ? 'has-tooltip' : ''; return this.showTooltip ? 'has-tooltip' : '';
...@@ -84,21 +86,23 @@ export default { ...@@ -84,21 +86,23 @@ export default {
:class="linkClass" :class="linkClass"
:title="displayName" :title="displayName"
:data-container="tooltipContainerAttr"> :data-container="tooltipContainerAttr">
<img
v-if="avatarUrl"
:class="avatarClass"
:src="avatarUrl"
:width="avatarSize"
:height="avatarSize"
:alt="displayName"/>
<svg <svg
v-if="avatarHtml" v-else
v-html="avatarHtml" v-html="pendingAvatarSvg"
:class="avatarHtmlClass" :class="avatarHtmlClass"
:width="avatarSize" :width="avatarSize"
:height="avatarSize" :height="avatarSize"
:alt="displayName"> :alt="displayName">
</svg> </svg>
<img
:class="avatarClass"
:src="avatarUrl"
:width="avatarSize"
:height="avatarSize"
:alt="displayName"/>
</a> </a>
</div> </div>
`, `,
......
...@@ -59,6 +59,10 @@ ...@@ -59,6 +59,10 @@
border: none; border: none;
} }
&.avatar-placeholder {
border: none;
}
&:not([href]):hover { &:not([href]):hover {
border-color: rgba($avatar-border, .2); border-color: rgba($avatar-border, .2);
} }
......
...@@ -817,32 +817,11 @@ ...@@ -817,32 +817,11 @@
top: 10px; top: 10px;
} }
// vertically centers all children
> span {
align-self: center;
}
.hide-asset {
img {
display: none;
}
svg {
margin-bottom: -7px; // makes up for border removed
border: none;
}
}
.approvers-prefix, .approvers-prefix,
.approvers-list { .approvers-list {
display: flex;
align-items: center;
margin-right: 5px; margin-right: 5px;
float: left;
}
.approvers-list img {
width: 18px;
height: 18px;
margin-top: 3px;
} }
.unapprove-btn { .unapprove-btn {
...@@ -860,18 +839,8 @@ ...@@ -860,18 +839,8 @@
} }
} }
// styles for approver avatar checkmark
.approver-avatar { .approver-avatar {
position: relative; position: relative;
display: inline-block;
svg.avatar {
position: absolute;
top: 12%;
right: 4%;
height: 45%;
width: 45%;
}
} }
} }
...@@ -882,8 +851,9 @@ ...@@ -882,8 +851,9 @@
} }
.avatar { .avatar {
margin-bottom: -2px; margin-bottom: 0;
margin-right: 3px; margin-left: 7px;
display: block;
} }
} }
......
...@@ -20,6 +20,7 @@ import linkToMemberAvatar from '~/vue_shared/components/link_to_member_avatar'; ...@@ -20,6 +20,7 @@ import linkToMemberAvatar from '~/vue_shared/components/link_to_member_avatar';
this.$document = $(document); this.$document = $(document);
} }
describe('Link To Members Components', function () { describe('Link To Members Components', function () {
describe('Initialization', function () { describe('Initialization', function () {
beforeEach(function () { beforeEach(function () {
...@@ -41,19 +42,19 @@ import linkToMemberAvatar from '~/vue_shared/components/link_to_member_avatar'; ...@@ -41,19 +42,19 @@ import linkToMemberAvatar from '~/vue_shared/components/link_to_member_avatar';
expect(this.component.$data).toBeDefined(); expect(this.component.$data).toBeDefined();
}); });
it('should have <a> and <img> children', function () { it('should have <a> and <svg> children', function () {
const componentLink = this.component.$el.querySelector('a'); const componentLink = this.component.$el.querySelector('a');
const componentImg = componentLink.querySelector('img'); const componentPlaceholder = componentLink.querySelector('svg');
expect(componentLink).not.toBeNull(); expect(componentLink).not.toBeNull();
expect(componentImg).not.toBeNull(); expect(componentPlaceholder).not.toBeNull();
}); });
it('should correctly compute computed values', function (done) { it('should correctly compute computed values', function (done) {
const correctVals = { const correctVals = {
disabledClass: '', disabledClass: '',
avatarSizeClass: 's32', avatarSizeClass: 's32',
avatarHtmlClass: 's32 avatar avatar-inline', avatarHtmlClass: 's32 avatar avatar-inline avatar-placeholder',
avatarClass: 'avatar avatar-inline s32 ', avatarClass: 'avatar avatar-inline s32 ',
tooltipClass: 'has-tooltip', tooltipClass: 'has-tooltip',
linkClass: 'author_link has-tooltip ', linkClass: 'author_link has-tooltip ',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment