Commit 41a3d9a2 authored by Phil Hughes's avatar Phil Hughes

Merge branch '2182-merge-vue-shared' into 'master'

Moves link to member component into vue shared folder

Closes #2182

See merge request !1660
parents c2ad90aa 5bc7c26d
import Vue from 'vue';
require('../approvals_store');
require('../../../vue_common_component/link_to_member_avatar');
import '../approvals_store';
import linkToMemberAvatar from '../../../vue_shared/components/link_to_member_avatar';
Vue.component('approvals-footer', {
name: 'approvals-footer',
......@@ -35,6 +34,9 @@ Vue.component('approvals-footer', {
required: true,
},
},
components: {
'link-to-member-avatar': linkToMemberAvatar,
},
data() {
return {
unapproving: false,
......@@ -57,32 +59,34 @@ Vue.component('approvals-footer', {
gl.ApprovalsStore.initStoreOnce();
},
template: `
<div class='mr-widget-footer approved-by-users approvals-footer clearfix mr-approvals-footer'>
<span class='approvers-prefix'> Approved by </span>
<span v-for='approver in approvedBy'>
<div class="mr-widget-footer approved-by-users approvals-footer clearfix mr-approvals-footer">
<span class="approvers-prefix"> Approved by </span>
<span v-for="approver in approvedBy">
<link-to-member-avatar
extra-link-class='approver-avatar'
:avatar-url='approver.user.avatar_url'
:display-name='approver.user.name'
:profile-url='approver.user.web_url'
:avatar-html='checkmarkSvg'
:show-tooltip='true'>
</link-to-member-avatar>
extra-link-class="approver-avatar"
:avatar-url="approver.user.avatar_url"
:display-name="approver.user.name"
:profile-url="approver.user.web_url"
:avatar-html="checkmarkSvg"
:show-tooltip="true" />
</span>
<span v-for='n in approvalsLeft'>
<span v-for="n in approvalsLeft">
<link-to-member-avatar
:clickable='false'
:avatar-html='pendingAvatarSvg'
:show-tooltip='false'
extra-link-class='hide-asset'>
</link-to-member-avatar>
:clickable="false"
:avatar-html="pendingAvatarSvg"
:show-tooltip="false"
extra-link-class="hide-asset" />
</span>
<span class='unapprove-btn-wrap' v-if='showUnapproveButton'>
<span
class="unapprove-btn-wrap"
v-if="showUnapproveButton">
<button
:disabled='unapproving'
@click='unapproveMergeRequest'
class='btn btn-link unapprove-btn'>
<i class='fa fa-close'></i>
:disabled="unapproving"
@click="unapproveMergeRequest"
class="btn btn-link unapprove-btn">
<i
class="fa fa-close"
aria-hidden="true"/>
Remove your approval
</button>
</span>
......
import Vue from 'vue';
// Analogue of link_to_member_avatar in app/helpers/projects_helper.rb
(() => {
Vue.component('link-to-member-avatar', {
props: {
avatarUrl: {
type: String,
required: false,
default: '/assets/no_avatar.png',
},
profileUrl: {
type: String,
required: false,
default: '',
},
displayName: {
type: String,
required: false,
},
extraAvatarClass: {
type: String,
default: '',
required: false,
},
extraLinkClass: {
type: String,
default: '',
required: false,
},
showTooltip: {
type: Boolean,
required: false,
default: true,
},
clickable: {
type: Boolean,
default: true,
required: false,
},
tooltipContainer: {
type: String,
required: false,
},
avatarHtml: {
type: String,
required: false,
},
avatarSize: {
type: Number,
required: false,
default: 32,
},
},
data() {
return {
avatarBaseClass: 'avatar avatar-inline',
};
},
computed: {
avatarSizeClass() {
return `s${this.avatarSize}`;
},
avatarHtmlClass() {
return `${this.avatarSizeClass} ${this.avatarBaseClass}`;
},
tooltipClass() {
return this.showTooltip ? 'has-tooltip' : '';
},
avatarClass() {
return `${this.avatarBaseClass} ${this.avatarSizeClass} ${this.extraAvatarClass}`;
},
disabledClass() {
return !this.clickable ? 'disabled' : '';
},
linkClass() {
return `author_link ${this.tooltipClass} ${this.extraLinkClass} ${this.disabledClass}`;
},
tooltipContainerAttr() {
return this.tooltipContainer || 'body';
},
},
template: `
<div class='link-to-member-avatar'>
<a :href='profileUrl' :class='linkClass' :data-original-title='displayName' :data-container='tooltipContainerAttr'>
<svg v-if='avatarHtml' v-html='avatarHtml' :class='avatarHtmlClass' :width='avatarSize' :height='avatarSize' :alt='displayName'></svg>
<img :class='avatarClass' :src='avatarUrl' :width='avatarSize' :height='avatarSize' :alt='displayName'/>
</a>
</div>
`,
});
})();
// Analogue of link_to_member_avatar in app/helpers/projects_helper.rb
export default {
props: {
avatarUrl: {
type: String,
required: false,
default: '/assets/no_avatar.png',
},
profileUrl: {
type: String,
required: false,
default: '',
},
displayName: {
type: String,
required: false,
},
extraAvatarClass: {
type: String,
default: '',
required: false,
},
extraLinkClass: {
type: String,
default: '',
required: false,
},
showTooltip: {
type: Boolean,
required: false,
default: true,
},
clickable: {
type: Boolean,
default: true,
required: false,
},
tooltipContainer: {
type: String,
required: false,
},
avatarHtml: {
type: String,
required: false,
},
avatarSize: {
type: Number,
required: false,
default: 32,
},
},
data() {
return {
avatarBaseClass: 'avatar avatar-inline',
};
},
computed: {
avatarSizeClass() {
return `s${this.avatarSize}`;
},
avatarHtmlClass() {
return `${this.avatarSizeClass} ${this.avatarBaseClass}`;
},
tooltipClass() {
return this.showTooltip ? 'has-tooltip' : '';
},
avatarClass() {
return `${this.avatarBaseClass} ${this.avatarSizeClass} ${this.extraAvatarClass}`;
},
disabledClass() {
return !this.clickable ? 'disabled' : '';
},
linkClass() {
return `author_link ${this.tooltipClass} ${this.extraLinkClass} ${this.disabledClass}`;
},
tooltipContainerAttr() {
return this.tooltipContainer || 'body';
},
},
template: `
<div class="link-to-member-avatar">
<a
:href="profileUrl"
:class="linkClass"
:title="displayName"
:data-container="tooltipContainerAttr">
<svg
v-if="avatarHtml"
v-html="avatarHtml"
:class="avatarHtmlClass"
:width="avatarSize"
:height="avatarSize"
:alt="displayName">
</svg>
<img
:class="avatarClass"
:src="avatarUrl"
:width="avatarSize"
:height="avatarSize"
:alt="displayName"/>
</a>
</div>
`,
};
/* eslint-disable guard-for-in, no-restricted-syntax */
/* eslint-disable no-restricted-syntax */
import Vue from 'vue';
require('~/vue_common_component/link_to_member_avatar');
import linkToMemberAvatar from '~/vue_shared/components/link_to_member_avatar';
(() => {
function initComponent(propsData = {}) {
......@@ -12,7 +11,7 @@ require('~/vue_common_component/link_to_member_avatar');
</div>
`);
const LinkToMembersComponent = Vue.component('link-to-member-avatar');
const LinkToMembersComponent = Vue.extend(linkToMemberAvatar);
this.component = new LinkToMembersComponent({
el: '#mock-container',
......@@ -63,9 +62,11 @@ require('~/vue_common_component/link_to_member_avatar');
Vue.nextTick(() => {
for (const computedKey in correctVals) {
const expectedVal = correctVals[computedKey];
const actualComputed = this.component[computedKey];
expect(actualComputed).toBe(expectedVal);
if (Object.prototype.hasOwnProperty.call(correctVals, computedKey)) {
const expectedVal = correctVals[computedKey];
const actualComputed = this.component[computedKey];
expect(actualComputed).toBe(expectedVal);
}
}
done();
});
......
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