mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge Author+RelatedUser into User component
This commit is contained in:
parent
fc244cd098
commit
3fad432858
@ -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: {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
78
components/User.spec.js
Normal 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
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -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;
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user