Merge Author+RelatedUser into User component

This commit is contained in:
Robert Schäfer 2019-03-15 16:45:17 +01:00
parent fc244cd098
commit 3fad432858
7 changed files with 145 additions and 99 deletions

View File

@ -4,7 +4,7 @@
<ds-space
margin-bottom="x-small"
>
<hc-author :post="comment" />
<hc-user :user="author" />
</ds-space>
<no-ssr>
<content-menu
@ -36,12 +36,12 @@
<script>
import { mapGetters } from 'vuex'
import HcAuthor from '~/components/Author.vue'
import HcUser from '~/components/User.vue'
import ContentMenu from '~/components/ContentMenu'
export default {
components: {
HcAuthor,
HcUser,
ContentMenu
},
props: {

View File

@ -26,10 +26,10 @@
>
<!-- TODO: find better solution for rendering errors -->
<no-ssr>
<hc-author
:post="post"
<hc-user
:user="post.author"
:trunc="35"
:show-author-popover="showAuthorPopover"
:show-user-popover="showUserPopover"
/>
</no-ssr>
</ds-space>
@ -64,14 +64,14 @@
</template>
<script>
import HcAuthor from '~/components/Author.vue'
import HcUser from '~/components/User.vue'
import ContentMenu from '~/components/ContentMenu'
import { randomBytes } from 'crypto'
export default {
name: 'HcPostCard',
components: {
HcAuthor,
HcUser,
ContentMenu
},
props: {
@ -79,7 +79,7 @@ export default {
type: Object,
required: true
},
showAuthorPopover: {
showUserPopover: {
type: Boolean,
default: true
}

View File

@ -1,23 +0,0 @@
<script>
import HcAuthor from '~/components/Author.vue'
let mouseEnterTimer = null
let mouseLeaveTimer = null
export default {
name: 'HcRelatedUser',
extends: HcAuthor,
computed: {
author() {
return this.hasAuthor
? this.post
: {
name: 'Anonymus'
}
},
hasAuthor() {
return Boolean(this.post)
}
}
}
</script>

78
components/User.spec.js Normal file
View File

@ -0,0 +1,78 @@
import { config, mount, createLocalVue } from '@vue/test-utils'
import User from './User.vue'
import Vue from 'vue'
import Vuex from 'vuex'
import VTooltip from 'v-tooltip'
import Styleguide from '@human-connection/styleguide'
const localVue = createLocalVue()
const filter = jest.fn(str => str)
localVue.use(Vuex)
localVue.use(VTooltip)
localVue.use(Styleguide)
localVue.filter('truncate', filter)
describe('User.vue', () => {
let wrapper
let Wrapper
let propsData
let mocks
let stubs
let getters
let user
beforeEach(() => {
propsData = {}
mocks = {
$t: jest.fn()
}
stubs = ['router-link', 'router-view']
getters = {
'auth/user': () => {
return {}
},
'auth/isModerator': () => false
}
})
describe('mount', () => {
const Wrapper = () => {
const store = new Vuex.Store({
getters
})
return mount(User, { store, propsData, mocks, stubs, localVue })
}
it('renders anonymous user', () => {
const wrapper = Wrapper()
expect(wrapper.text()).not.toMatch('Tilda Swinton')
expect(wrapper.text()).toMatch('Anonymus')
})
describe('given an user', () => {
beforeEach(() => {
propsData.user = {
name: 'Tilda Swinton',
slug: 'tilda-swinton'
}
})
it('renders user name', () => {
const wrapper = Wrapper()
expect(wrapper.text()).not.toMatch('Anonymous')
expect(wrapper.text()).toMatch('Tilda Swinton')
})
describe('user is disabled', () => {
beforeEach(() => {
propsData.user.disabled = true
})
})
})
})
})

View File

@ -1,6 +1,6 @@
<template>
<dropdown
:disabled="!hasAuthor || !showAuthorPopover"
:disabled="disabled || !showUserPopover"
placement="top-start"
offset="0"
>
@ -8,62 +8,55 @@
slot="default"
slot-scope="{openMenu, closeMenu, isOpen}"
>
<a
v-router-link
:href="author.slug ? $router.resolve({ name: 'profile-slug', params: { slug: author.slug } }).href : null"
:class="['author', isOpen && 'active']"
<div
@mouseover="openMenu(true)"
@mouseleave="closeMenu(true)"
>
<div style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;">
<ds-avatar
:image="author.avatar"
:name="author.name"
style="display: inline-block; vertical-align: middle;"
size="32px"
/>
</div>
<div style="display: inline-block; height: 100%; vertical-align: middle;">
<b
class="username"
style="vertical-align: middle;"
>
{{ author.name | truncate(trunc, 18) }}
</b>
<template v-if="post.createdAt">
<br>
<ds-text
size="small"
color="soft"
<nuxt-link
:to="userLink"
:class="['user', isOpen && 'active']"
>
<div style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;">
<ds-avatar
:image="user.avatar"
:name="user.name"
style="display: inline-block; vertical-align: middle;"
size="32px"
/>
</div>
<div style="display: inline-block; height: 100%; vertical-align: middle;">
<b
class="username"
style="vertical-align: middle;"
>
{{ post.createdAt | dateTime('dd. MMMM yyyy HH:mm') }}
</ds-text>
</template>
</div>
</a>
{{ user.name | truncate(trunc, 18) }}
</b>
</div>
</nuxt-link>
</div>
</template>
<template
slot="popover"
>
<div style="min-width: 250px">
<!--<ds-avatar
:image="author.avatar"
:name="author.name || 'Anonymus'"
:image="user.avatar"
:name="user.name || 'Anonymus'"
class="profile-avatar"
size="90px" />-->
<hc-badges
v-if="author.badges && author.badges.length"
:badges="author.badges"
v-if="user.badges && user.badges.length"
:badges="user.badges"
/>
<ds-text
v-if="author.location"
v-if="user.location"
align="center"
color="soft"
size="small"
style="margin-top: 5px"
bold
>
<ds-icon name="map-marker" /> {{ author.location.name }}
<ds-icon name="map-marker" /> {{ user.location.name }}
</ds-text>
<ds-flex
style="margin-top: -10px"
@ -80,16 +73,16 @@
<ds-flex-item class="ds-tab-nav-item ds-tab-nav-item-active">
<ds-space margin="small">
<ds-number
:count="author.contributionsCount"
:label="$t('common.post', null, author.contributionsCount)"
:count="user.contributionsCount"
:label="$t('common.post', null, user.contributionsCount)"
/>
</ds-space>
</ds-flex-item>
<ds-flex-item class="ds-tab-nav-item">
<ds-space margin="small">
<ds-number
:count="author.commentsCount"
:label="$t('common.comment', null, author.commentsCount)"
:count="user.commentsCount"
:label="$t('common.comment', null, user.commentsCount)"
/>
</ds-space>
</ds-flex-item>
@ -106,10 +99,10 @@
>
<ds-flex-item :width="{base: 3}">
<hc-follow-button
:follow-id="author.id"
:is-followed="author.followedByCurrentUser"
@optimistic="follow => author.followedByCurrentUser = follow"
@update="follow => author.followedByCurrentUser = follow"
:follow-id="user.id"
:is-followed="user.followedByCurrentUser"
@optimistic="follow => user.followedByCurrentUser = follow"
@update="follow => user.followedByCurrentUser = follow"
/>
</ds-flex-item>
<ds-flex-item :width="{base: 1}">
@ -130,34 +123,32 @@ import HcBadges from '~/components/Badges.vue'
import Dropdown from '~/components/Dropdown'
export default {
name: 'HcAuthor',
name: 'HcUser',
components: {
HcFollowButton,
HcBadges,
Dropdown
},
props: {
post: { type: Object, default: null },
user: { type: Object, default: null },
trunc: { type: Number, default: null },
showAuthorPopover: { type: Boolean, default: true }
showUserPopover: { type: Boolean, default: true }
},
computed: {
itsMe() {
return this.author.slug === this.$store.getters['auth/user'].slug
return this.user.slug === this.$store.getters['auth/user'].slug
},
fanCount() {
let count = Number(this.author.followedByCount) || 0
let count = Number(this.user.followedByCount) || 0
return count
},
author() {
return this.hasAuthor
? this.post.author
: {
name: 'Anonymus'
}
disabled() {
return this.user && this.user.disabled
},
hasAuthor() {
return Boolean(this.post && this.post.author)
userLink() {
const { slug } = this.user
if (!slug) return ''
return { name: 'profile-slug', params: { slug } }
}
}
}
@ -170,7 +161,7 @@ export default {
margin-top: -45px;
border: #fff 5px solid;
}
.author {
.user {
white-space: nowrap;
position: relative;
display: flex;

View File

@ -9,7 +9,7 @@
:header="post.title"
:class="{'post-card': true, 'disabled-content': post.disabled}"
>
<hc-author :post="post" />
<hc-user :user="post.author" />
<no-ssr>
<content-menu
placement="bottom-end"
@ -107,7 +107,7 @@
<script>
import gql from 'graphql-tag'
import ContentMenu from '~/components/ContentMenu'
import HcAuthor from '~/components/Author.vue'
import HcUser from '~/components/User.vue'
import HcShoutButton from '~/components/ShoutButton.vue'
import HcEmpty from '~/components/Empty.vue'
import Comment from '~/components/Comment.vue'
@ -118,7 +118,7 @@ export default {
mode: 'out-in'
},
components: {
HcAuthor,
HcUser,
HcShoutButton,
HcEmpty,
Comment,

View File

@ -137,8 +137,8 @@
>
<!-- TODO: find better solution for rendering errors -->
<no-ssr>
<hc-related-user
:post="follow"
<user
:user="follow"
:trunc="15"
/>
</no-ssr>
@ -182,8 +182,8 @@
>
<!-- TODO: find better solution for rendering errors -->
<no-ssr>
<hc-related-user
:post="follow"
<user
:user="follow"
:trunc="15"
/>
</no-ssr>
@ -302,7 +302,7 @@
<script>
import uniqBy from 'lodash/uniqBy'
import HcRelatedUser from '~/components/RelatedUser.vue'
import User from '~/components/User.vue'
import HcPostCard from '~/components/PostCard.vue'
import HcFollowButton from '~/components/FollowButton.vue'
import HcCountTo from '~/components/CountTo.vue'
@ -313,7 +313,7 @@ import ContentMenu from '~/components/ContentMenu'
export default {
components: {
HcRelatedUser,
User,
HcPostCard,
HcFollowButton,
HcCountTo,