mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
fix(webapp): notifications - UI Improvements (#8559)
* Notifications view: - restructured broken layout - joined several columns for mobile view - moved button from footer to header - set alternating colors for the table rows UserTeaser - added injectedText - added injectedDate - fixed padding * fixed race-condition with default behavior of browser * - fixed: jumping menu / menu should get closed by click on notification - fixed: NotificationList replaced by NotificationTable * - fixed: menu gets closed when cursor leaves content area, but it is still within popup * - fixed: menu top buttons should be next to each other * - fixed: popup background overlay remains after NotificationMenu disappeared after viewport change to mobile * - fixed lint errors * - fixed tests + snapshots * - fixed e2e test * fix lint error Co-authored-by: Sebastian Stein <sebastian@codepassion.de> * Fix locale identifier to have single quotes 'notifications.reason.on_date' --------- Co-authored-by: Sebastian Stein <sebastian@codepassion.de> Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com> Co-authored-by: Ulf Gebhardt <ulf.gebhardt@webcraft-media.de>
This commit is contained in:
parent
18ae2a04ab
commit
a69006873d
@ -4,7 +4,7 @@ defineStep('open the notification menu and click on the first item', () => {
|
||||
cy.get('.notifications-menu')
|
||||
.invoke('show')
|
||||
.click() // 'invoke('show')' because of the delay for show the menu
|
||||
cy.get('.notification .link')
|
||||
cy.get('.notification-content a')
|
||||
.first()
|
||||
.click({force: true})
|
||||
})
|
||||
|
||||
@ -1,200 +0,0 @@
|
||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||
import Notification from './Notification.vue'
|
||||
|
||||
import Vuex from 'vuex'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('Notification', () => {
|
||||
let stubs
|
||||
let getters
|
||||
let mocks
|
||||
let propsData
|
||||
let wrapper
|
||||
beforeEach(() => {
|
||||
propsData = {}
|
||||
mocks = {
|
||||
$t: (key) => key,
|
||||
}
|
||||
stubs = {
|
||||
NuxtLink: RouterLinkStub,
|
||||
'client-only': true,
|
||||
}
|
||||
getters = {
|
||||
'auth/user': () => {
|
||||
return {}
|
||||
},
|
||||
'auth/isModerator': () => false,
|
||||
}
|
||||
})
|
||||
|
||||
const Wrapper = () => {
|
||||
const store = new Vuex.Store({
|
||||
getters,
|
||||
})
|
||||
return mount(Notification, {
|
||||
stubs,
|
||||
store,
|
||||
mocks,
|
||||
propsData,
|
||||
localVue,
|
||||
})
|
||||
}
|
||||
|
||||
describe('given a notification about a comment on a post', () => {
|
||||
beforeEach(() => {
|
||||
propsData.notification = {
|
||||
reason: 'commented_on_post',
|
||||
from: {
|
||||
__typename: 'Comment',
|
||||
id: 'comment-1',
|
||||
contentExcerpt:
|
||||
'<a href="/profile/u123" target="_blank">@dagobert-duck</a> is the best on this comment.',
|
||||
post: {
|
||||
title: "It's a post title",
|
||||
id: 'post-1',
|
||||
slug: 'its-a-title',
|
||||
contentExcerpt: 'Post content.',
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
it('renders reason', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.find('.notification > .description').text()).toEqual(
|
||||
'notifications.reason.commented_on_post',
|
||||
)
|
||||
})
|
||||
it('renders title', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain("It's a post title")
|
||||
})
|
||||
it('renders the identifier "notifications.comment"', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain('notifications.comment')
|
||||
})
|
||||
it('renders the contentExcerpt', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain('@dagobert-duck is the best on this comment.')
|
||||
})
|
||||
it('has no class "--read"', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.classes()).not.toContain('--read')
|
||||
})
|
||||
|
||||
describe('that is read', () => {
|
||||
beforeEach(() => {
|
||||
propsData.notification.read = true
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has class "--read"', () => {
|
||||
expect(wrapper.classes()).toContain('--read')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('given a notification about a mention in a post', () => {
|
||||
beforeEach(() => {
|
||||
propsData.notification = {
|
||||
reason: 'mentioned_in_post',
|
||||
from: {
|
||||
__typename: 'Post',
|
||||
title: "It's a post title",
|
||||
id: 'post-1',
|
||||
slug: 'its-a-title',
|
||||
contentExcerpt:
|
||||
'<a href="/profile/u3" target="_blank">@jenny-rostock</a> is the best on this post.',
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
it('renders reason', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.find('.notification > .description').text()).toEqual(
|
||||
'notifications.reason.mentioned_in_post',
|
||||
)
|
||||
})
|
||||
it('renders title', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain("It's a post title")
|
||||
})
|
||||
it('renders the contentExcerpt', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain('@jenny-rostock is the best on this post.')
|
||||
})
|
||||
it('has no class "--read"', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.classes()).not.toContain('--read')
|
||||
})
|
||||
|
||||
describe('that is read', () => {
|
||||
beforeEach(() => {
|
||||
propsData.notification.read = true
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has class "--read"', () => {
|
||||
expect(wrapper.classes()).toContain('--read')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('given a notification about a mention in a comment', () => {
|
||||
beforeEach(() => {
|
||||
propsData.notification = {
|
||||
reason: 'mentioned_in_comment',
|
||||
from: {
|
||||
__typename: 'Comment',
|
||||
id: 'comment-1',
|
||||
contentExcerpt:
|
||||
'<a href="/profile/u123" target="_blank">@dagobert-duck</a> is the best on this comment.',
|
||||
post: {
|
||||
title: "It's a post title",
|
||||
id: 'post-1',
|
||||
slug: 'its-a-title',
|
||||
contentExcerpt: 'Post content.',
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
it('renders reason', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.find('.notification > .description').text()).toEqual(
|
||||
'notifications.reason.mentioned_in_comment',
|
||||
)
|
||||
})
|
||||
it('renders title', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain("It's a post title")
|
||||
})
|
||||
|
||||
it('renders the identifier "notifications.comment"', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain('notifications.comment')
|
||||
})
|
||||
|
||||
it('renders the contentExcerpt', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain('@dagobert-duck is the best on this comment.')
|
||||
})
|
||||
|
||||
it('has no class "--read"', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.classes()).not.toContain('--read')
|
||||
})
|
||||
|
||||
describe('that is read', () => {
|
||||
beforeEach(() => {
|
||||
propsData.notification.read = true
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has class "--read"', () => {
|
||||
expect(wrapper.classes()).toContain('--read')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,100 +0,0 @@
|
||||
<template>
|
||||
<article :class="{ '--read': notification.read, notification: true }">
|
||||
<client-only>
|
||||
<user-teaser
|
||||
:user="isGroup ? notification.relatedUser : from.author"
|
||||
:date-time="from.createdAt"
|
||||
:show-popover="false"
|
||||
/>
|
||||
</client-only>
|
||||
<p class="description">{{ $t(`notifications.reason.${notification.reason}`) }}</p>
|
||||
<nuxt-link
|
||||
class="link"
|
||||
:to="{ name: isGroup ? 'groups-id-slug' : 'post-id-slug', params, ...hashParam }"
|
||||
@click.native="$emit('read')"
|
||||
>
|
||||
<base-card wideContent>
|
||||
<h2 class="title">{{ from.title || from.groupName || from.post.title }}</h2>
|
||||
<p>
|
||||
<strong v-if="isComment" class="comment">{{ $t(`notifications.comment`) }}:</strong>
|
||||
{{ from.contentExcerpt | removeHtml }}
|
||||
<strong v-if="isGroup" class="comment">{{ $t(`notifications.group`) }}:</strong>
|
||||
{{ from.descriptionExcerpt | removeHtml }}
|
||||
</p>
|
||||
</base-card>
|
||||
</nuxt-link>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserTeaser from '~/components/UserTeaser/UserTeaser'
|
||||
|
||||
export default {
|
||||
name: 'Notification',
|
||||
components: {
|
||||
UserTeaser,
|
||||
},
|
||||
props: {
|
||||
notification: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
from() {
|
||||
return this.notification.from
|
||||
},
|
||||
isComment() {
|
||||
return this.from.__typename === 'Comment'
|
||||
},
|
||||
isGroup() {
|
||||
return this.from.__typename === 'Group'
|
||||
},
|
||||
params() {
|
||||
const target = this.isComment ? this.from.post : this.from
|
||||
return {
|
||||
id: target.id,
|
||||
slug: target.slug,
|
||||
}
|
||||
},
|
||||
hashParam() {
|
||||
return this.isComment ? { hash: `#commentId-${this.from.id}` } : {}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.notification {
|
||||
margin-bottom: $space-base;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: $space-x-small;
|
||||
}
|
||||
|
||||
&.--read {
|
||||
opacity: $opacity-disabled;
|
||||
}
|
||||
|
||||
> .description {
|
||||
margin-bottom: $space-x-small;
|
||||
}
|
||||
|
||||
> .link {
|
||||
display: block;
|
||||
color: $text-color-base;
|
||||
|
||||
&:hover {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.user-teaser {
|
||||
margin-bottom: $space-x-small;
|
||||
}
|
||||
|
||||
.comment {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,103 +0,0 @@
|
||||
import { shallowMount, mount, RouterLinkStub } from '@vue/test-utils'
|
||||
import NotificationList from './NotificationList'
|
||||
import Notification from '../Notification/Notification'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
import { notifications } from '~/components/utils/Notifications'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
localVue.filter('truncate', (string) => string)
|
||||
|
||||
describe('NotificationList.vue', () => {
|
||||
let wrapper
|
||||
let mocks
|
||||
let stubs
|
||||
let store
|
||||
let propsData
|
||||
|
||||
beforeEach(() => {
|
||||
store = new Vuex.Store({
|
||||
getters: {
|
||||
'auth/isModerator': () => false,
|
||||
'auth/user': () => {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
})
|
||||
mocks = {
|
||||
$t: jest.fn(),
|
||||
}
|
||||
stubs = {
|
||||
NuxtLink: RouterLinkStub,
|
||||
'client-only': true,
|
||||
'v-popover': true,
|
||||
}
|
||||
propsData = { notifications }
|
||||
})
|
||||
|
||||
describe('shallowMount', () => {
|
||||
const Wrapper = () => {
|
||||
return shallowMount(NotificationList, {
|
||||
propsData,
|
||||
mocks,
|
||||
store,
|
||||
localVue,
|
||||
stubs,
|
||||
})
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('renders Notification.vue for each notification of the user', () => {
|
||||
expect(wrapper.findAllComponents(Notification)).toHaveLength(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('mount', () => {
|
||||
const Wrapper = () => {
|
||||
return mount(NotificationList, {
|
||||
propsData,
|
||||
mocks,
|
||||
stubs,
|
||||
store,
|
||||
localVue,
|
||||
})
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
describe('click on a notification', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find('.notification > .link').trigger('click')
|
||||
})
|
||||
|
||||
it("emits 'markAsRead' with the id of the notification source", () => {
|
||||
expect(wrapper.emitted('markAsRead')[0]).toEqual(['post-1'])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('shallowMount with no notifications', () => {
|
||||
const Wrapper = () => {
|
||||
return shallowMount(NotificationList, {
|
||||
propsData: {},
|
||||
mocks,
|
||||
store,
|
||||
localVue,
|
||||
})
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('renders Notification.vue zero times', () => {
|
||||
expect(wrapper.findAllComponents(Notification)).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,32 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<notification
|
||||
v-for="notification in notifications"
|
||||
:key="notification.id"
|
||||
:notification="notification"
|
||||
@read="markAsRead(notification.from.id)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Notification from '../Notification/Notification'
|
||||
|
||||
export default {
|
||||
name: 'NotificationList',
|
||||
components: {
|
||||
Notification,
|
||||
},
|
||||
props: {
|
||||
notifications: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
markAsRead(notificationSourceId) {
|
||||
this.$emit('markAsRead', notificationSourceId)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -26,7 +26,14 @@
|
||||
<counter-icon icon="bell" :count="unreadNotificationsCount" danger />
|
||||
</base-button>
|
||||
</nuxt-link>
|
||||
<dropdown v-else class="notifications-menu" offset="8" :placement="placement">
|
||||
<dropdown
|
||||
v-else
|
||||
class="notifications-menu"
|
||||
offset="8"
|
||||
:placement="placement"
|
||||
noMouseLeaveClosing
|
||||
ref="dropdown"
|
||||
>
|
||||
<template #default="{ toggleMenu }">
|
||||
<base-button
|
||||
ghost
|
||||
@ -42,14 +49,12 @@
|
||||
</template>
|
||||
<template #popover="{ closeMenu }">
|
||||
<ds-flex class="notifications-link-container">
|
||||
<ds-flex-item class="notifications-link-container-item" :width="{ base: '100%' }" centered>
|
||||
<ds-flex-item>
|
||||
<nuxt-link :to="{ name: 'notifications' }">
|
||||
<base-button ghost primary>
|
||||
{{ $t('notifications.pageLink') }}
|
||||
</base-button>
|
||||
</nuxt-link>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item class="notifications-link-container-item" :width="{ base: '100%' }" centered>
|
||||
<base-button
|
||||
ghost
|
||||
primary
|
||||
@ -61,7 +66,11 @@
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<div class="notifications-menu-popover">
|
||||
<notification-list :notifications="notifications" @markAsRead="markAsRead" />
|
||||
<notifications-table
|
||||
@markNotificationAsRead="markAsReadAndCloseMenu($event, closeMenu)"
|
||||
:notifications="notifications"
|
||||
:show-popover="false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</dropdown>
|
||||
@ -78,14 +87,14 @@ import {
|
||||
} from '~/graphql/User'
|
||||
import CounterIcon from '~/components/_new/generic/CounterIcon/CounterIcon'
|
||||
import Dropdown from '~/components/Dropdown'
|
||||
import NotificationList from '../NotificationList/NotificationList'
|
||||
import NotificationsTable from '../NotificationsTable/NotificationsTable.vue'
|
||||
|
||||
export default {
|
||||
name: 'NotificationMenu',
|
||||
components: {
|
||||
NotificationsTable,
|
||||
CounterIcon,
|
||||
Dropdown,
|
||||
NotificationList,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -96,14 +105,25 @@ export default {
|
||||
placement: { type: String },
|
||||
noMenu: { type: Boolean, default: false },
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
},
|
||||
methods: {
|
||||
async markAsRead(notificationSourceId) {
|
||||
const variables = { id: notificationSourceId }
|
||||
handleResize() {
|
||||
// When the viewport get resized close menu
|
||||
this.$refs?.dropdown?.closeMenu?.()
|
||||
},
|
||||
async markAsReadAndCloseMenu(notificationSourceId, closeMenu) {
|
||||
try {
|
||||
await this.$apollo.mutate({
|
||||
mutation: markAsReadMutation(this.$i18n),
|
||||
variables,
|
||||
variables: { id: notificationSourceId },
|
||||
})
|
||||
|
||||
closeMenu?.()
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message)
|
||||
}
|
||||
@ -113,7 +133,7 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
closeMenu()
|
||||
closeMenu?.()
|
||||
try {
|
||||
await this.$apollo.mutate({
|
||||
mutation: markAllAsReadMutation(this.$i18n),
|
||||
@ -178,12 +198,8 @@ export default {
|
||||
}
|
||||
.notifications-link-container {
|
||||
background-color: $background-color-softer-active;
|
||||
justify-content: center;
|
||||
padding: $space-x-small;
|
||||
text-align: right;
|
||||
padding: $space-x-small 0;
|
||||
flex-direction: row;
|
||||
}
|
||||
.notifications-link-container-item {
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -63,11 +63,7 @@ describe('NotificationsTable.vue', () => {
|
||||
expect(wrapper.find('.notification-grid').exists()).toBe(true)
|
||||
})
|
||||
|
||||
describe('renders 4 columns', () => {
|
||||
it('for icon', () => {
|
||||
expect(wrapper.vm.fields.icon).toBeTruthy()
|
||||
})
|
||||
|
||||
describe('renders 2 columns', () => {
|
||||
it('for user', () => {
|
||||
expect(wrapper.vm.fields.user).toBeTruthy()
|
||||
})
|
||||
@ -75,10 +71,6 @@ describe('NotificationsTable.vue', () => {
|
||||
it('for post', () => {
|
||||
expect(wrapper.vm.fields.post).toBeTruthy()
|
||||
})
|
||||
|
||||
it('for content', () => {
|
||||
expect(wrapper.vm.fields.content).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Post', () => {
|
||||
@ -93,9 +85,9 @@ describe('NotificationsTable.vue', () => {
|
||||
})
|
||||
|
||||
it('renders the reason for the notification', () => {
|
||||
const dsTexts = firstRowNotification.findAll('.ds-text')
|
||||
const reason = dsTexts.filter(
|
||||
(element) => element.text() === 'notifications.reason.mentioned_in_post',
|
||||
const dsTexts = firstRowNotification.findAll('.info span')
|
||||
const reason = dsTexts.filter((element) =>
|
||||
element.text().startsWith('notifications.reason.mentioned_in_post'),
|
||||
)
|
||||
expect(reason.exists()).toBe(true)
|
||||
})
|
||||
@ -106,7 +98,7 @@ describe('NotificationsTable.vue', () => {
|
||||
})
|
||||
|
||||
it("renders the Post's content", () => {
|
||||
const boldTags = firstRowNotification.findAll('b')
|
||||
const boldTags = firstRowNotification.findAll('p')
|
||||
const content = boldTags.filter(
|
||||
(element) => element.text() === postNotification.from.contentExcerpt,
|
||||
)
|
||||
@ -126,9 +118,9 @@ describe('NotificationsTable.vue', () => {
|
||||
})
|
||||
|
||||
it('renders the reason for the notification', () => {
|
||||
const dsTexts = secondRowNotification.findAll('.ds-text')
|
||||
const reason = dsTexts.filter(
|
||||
(element) => element.text() === 'notifications.reason.mentioned_in_comment',
|
||||
const dsTexts = secondRowNotification.findAll('.info span')
|
||||
const reason = dsTexts.filter((element) =>
|
||||
element.text().startsWith('notifications.reason.mentioned_in_comment'),
|
||||
)
|
||||
expect(reason.exists()).toBe(true)
|
||||
})
|
||||
@ -139,7 +131,7 @@ describe('NotificationsTable.vue', () => {
|
||||
})
|
||||
|
||||
it("renders the Post's content", () => {
|
||||
const boldTags = secondRowNotification.findAll('b')
|
||||
const boldTags = secondRowNotification.findAll('p')
|
||||
const content = boldTags.filter(
|
||||
(element) => element.text() === commentNotification.from.contentExcerpt,
|
||||
)
|
||||
|
||||
@ -17,9 +17,31 @@
|
||||
<ds-grid>
|
||||
<ds-grid-item>
|
||||
<ds-flex class="user-section">
|
||||
<ds-flex-item :width="{ base: '20%' }">
|
||||
<div>
|
||||
<ds-flex-item>
|
||||
<base-card :wide-content="true">
|
||||
<client-only>
|
||||
<user-teaser
|
||||
:user="
|
||||
isGroup(notification.from)
|
||||
? notification.relatedUser
|
||||
: notification.from.author
|
||||
"
|
||||
:class="{ 'notification-status': notification.read }"
|
||||
:date-time="notification.from.createdAt"
|
||||
:injected-text="$t(`notifications.reason.${notification.reason}`)"
|
||||
:injected-date="true"
|
||||
:show-popover="showPopover"
|
||||
/>
|
||||
</client-only>
|
||||
</base-card>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</ds-grid-item>
|
||||
<ds-grid-item>
|
||||
<base-card :wide-content="true">
|
||||
<div class="notification-container">
|
||||
<!-- Icon with responsive sizing -->
|
||||
<div class="notification-icon">
|
||||
<base-icon
|
||||
v-if="notification.from.post"
|
||||
name="comment"
|
||||
@ -30,37 +52,10 @@
|
||||
name="bookmark"
|
||||
v-tooltip="{ content: $t('notifications.post'), placement: 'right' }"
|
||||
/>
|
||||
</base-card>
|
||||
</div>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item>
|
||||
<div>
|
||||
<base-card :wide-content="true">
|
||||
<ds-space margin-bottom="base">
|
||||
<client-only>
|
||||
<user-teaser
|
||||
:user="
|
||||
isGroup(notification.from)
|
||||
? notification.relatedUser
|
||||
: notification.from.author
|
||||
"
|
||||
:date-time="notification.from.createdAt"
|
||||
:class="{ 'notification-status': notification.read }"
|
||||
/>
|
||||
</client-only>
|
||||
</ds-space>
|
||||
<ds-text :class="{ 'notification-status': notification.read, reason: true }">
|
||||
{{ $t(`notifications.reason.${notification.reason}`) }}
|
||||
</ds-text>
|
||||
</base-card>
|
||||
</div>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</ds-grid-item>
|
||||
<ds-grid-item>
|
||||
<ds-flex class="content-section" :direction="{ base: 'column', xs: 'row' }">
|
||||
<ds-flex-item>
|
||||
<base-card :wide-content="true">
|
||||
|
||||
<!-- Content section with title and description -->
|
||||
<div class="notification-content">
|
||||
<nuxt-link
|
||||
class="notification-mention-post"
|
||||
:class="{ 'notification-status': notification.read }"
|
||||
@ -69,7 +64,7 @@
|
||||
params: params(notification.from),
|
||||
hash: hashParam(notification.from),
|
||||
}"
|
||||
@click.native="markNotificationAsRead(notification.from.id)"
|
||||
@click.native.prevent="handleNotificationClick(notification)"
|
||||
>
|
||||
<b>
|
||||
{{
|
||||
@ -79,19 +74,18 @@
|
||||
}}
|
||||
</b>
|
||||
</nuxt-link>
|
||||
</base-card>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item>
|
||||
<base-card :wide-content="true">
|
||||
<b :class="{ 'notification-status': notification.read }">
|
||||
<p
|
||||
class="notification-description"
|
||||
:class="{ 'notification-status': notification.read }"
|
||||
>
|
||||
{{
|
||||
notification.from.contentExcerpt ||
|
||||
notification.from.descriptionExcerpt | removeHtml
|
||||
}}
|
||||
</b>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</base-card>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</ds-grid-item>
|
||||
</ds-grid>
|
||||
</ds-grid-item>
|
||||
@ -116,25 +110,18 @@ export default {
|
||||
mixins: [mobile(maxMobileWidth)],
|
||||
props: {
|
||||
notifications: { type: Array, default: () => [] },
|
||||
showPopover: { type: Boolean, default: true },
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
return {
|
||||
icon: {
|
||||
label: ' ',
|
||||
width: '5',
|
||||
},
|
||||
user: {
|
||||
label: this.$t('notifications.user'),
|
||||
width: '45%',
|
||||
width: '50%',
|
||||
},
|
||||
post: {
|
||||
label: this.$t('notifications.post'),
|
||||
width: '25%',
|
||||
},
|
||||
content: {
|
||||
label: this.$t('notifications.content'),
|
||||
width: '25%',
|
||||
width: '50%',
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -159,7 +146,23 @@ export default {
|
||||
return this.isComment(notificationSource) ? `#commentId-${notificationSource.id}` : ''
|
||||
},
|
||||
markNotificationAsRead(notificationSourceId) {
|
||||
return new Promise((resolve) => {
|
||||
this.$emit('markNotificationAsRead', notificationSourceId)
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
async handleNotificationClick(notification) {
|
||||
const route = {
|
||||
name: this.isGroup(notification.from) ? 'groups-id-slug' : 'post-id-slug',
|
||||
params: this.params(notification.from),
|
||||
hash: this.hashParam(notification.from),
|
||||
}
|
||||
|
||||
await this.markNotificationAsRead(notification.from.id)
|
||||
|
||||
setTimeout(() => {
|
||||
this.$router.push(route)
|
||||
}, 10)
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -172,12 +175,6 @@ export default {
|
||||
.notification-grid .content-section {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.notification-grid .ds-grid.header-grid {
|
||||
grid-template-columns: 1fr 4fr 3fr 3fr !important;
|
||||
}
|
||||
.notification-grid-row {
|
||||
border-top: 1px dotted #e5e3e8;
|
||||
}
|
||||
.notification-grid .base-card {
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
@ -190,6 +187,19 @@ export default {
|
||||
grid-template-rows: 1fr;
|
||||
gap: 0px !important;
|
||||
}
|
||||
.notification-grid-row {
|
||||
padding: 10px;
|
||||
border-bottom: 1px dotted #e5e3e8;
|
||||
background-color: white;
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: $color-neutral-90;
|
||||
}
|
||||
.base-card {
|
||||
padding: 8px 0;
|
||||
background-color: unset !important;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 768px) {
|
||||
.notification-grid .ds-grid {
|
||||
grid-template-columns: 1fr !important;
|
||||
@ -197,10 +207,47 @@ export default {
|
||||
.notification-grid .content-section {
|
||||
border-top: 1px dotted #e5e3e8;
|
||||
}
|
||||
.notification-grid-row {
|
||||
box-shadow: 0px 12px 26px -4px rgb(0 0 0 / 10%);
|
||||
margin-top: 5px;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.notification-description {
|
||||
margin-top: 4px;
|
||||
}
|
||||
.notification-container {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
|
||||
.notification-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop icon size */
|
||||
@media (min-width: 768px) {
|
||||
.notification-icon {
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
.notification-icon :deep(svg) {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile icon size */
|
||||
@media (max-width: 767px) {
|
||||
.notification-icon {
|
||||
width: 34px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.notification-icon :deep(svg) {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.notification-content {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
:show-avatar="showAvatar"
|
||||
:date-time="dateTime"
|
||||
:show-popover="showPopover"
|
||||
:injectedText="injectedText"
|
||||
:injectedDate="injectedDate"
|
||||
@close="closeMenu"
|
||||
/>
|
||||
</client-only>
|
||||
@ -41,6 +43,8 @@ export default {
|
||||
showAvatar: { type: Boolean, default: true },
|
||||
dateTime: { type: [Date, String], default: null },
|
||||
showPopover: { type: Boolean, default: true },
|
||||
injectedText: { type: String, default: null },
|
||||
injectedDate: { type: Boolean, default: false },
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
@ -76,10 +80,10 @@ export default {
|
||||
}
|
||||
|
||||
.info {
|
||||
padding-left: $space-xx-small;
|
||||
padding-left: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
white-space: break-spaces;
|
||||
|
||||
&.anonymous {
|
||||
font-size: $font-size-base;
|
||||
|
||||
@ -36,8 +36,10 @@
|
||||
</span>
|
||||
</nuxt-link>
|
||||
</span>
|
||||
<!-- eslint-disable-next-line prettier/prettier -->
|
||||
<span>{{ injectedText }}<span v-if="injectedText && injectedDate && !userOnly && dateTime"> {{$t('notifications.reason.on_date')}} <date-time :date-time="dateTime" /></span></span>
|
||||
</div>
|
||||
<span v-if="!userOnly && dateTime" class="text">
|
||||
<span v-if="!userOnly && !injectedDate && dateTime" class="text">
|
||||
<base-icon name="clock" />
|
||||
<date-time :date-time="dateTime" />
|
||||
<slot name="dateTime"></slot>
|
||||
@ -81,6 +83,8 @@ export default {
|
||||
showAvatar: { type: Boolean, default: true },
|
||||
dateTime: { type: [Date, String], default: null },
|
||||
showPopover: { type: Boolean, default: true },
|
||||
injectedText: { type: String, default: null },
|
||||
injectedDate: { type: Boolean, default: false },
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
|
||||
@ -51,6 +51,11 @@ exports[`UserTeaser given an user avatar is disabled does not render the avatar
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -199,6 +204,11 @@ exports[`UserTeaser given an user user is disabled current user is a moderator r
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -315,6 +325,11 @@ exports[`UserTeaser given an user with linkToProfile, on desktop renders 1`] = `
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -400,6 +415,11 @@ exports[`UserTeaser given an user with linkToProfile, on desktop when hovering t
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -489,6 +509,11 @@ exports[`UserTeaser given an user with linkToProfile, on touch screen renders 1`
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -574,6 +599,11 @@ exports[`UserTeaser given an user with linkToProfile, on touch screen when click
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -663,6 +693,11 @@ exports[`UserTeaser given an user without linkToProfile, on desktop renders 1`]
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -748,6 +783,11 @@ exports[`UserTeaser given an user without linkToProfile, on desktop when hoverin
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -837,6 +877,11 @@ exports[`UserTeaser given an user without linkToProfile, on desktop when hoverin
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -925,6 +970,11 @@ exports[`UserTeaser given an user without linkToProfile, on touch screen renders
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -1010,6 +1060,11 @@ exports[`UserTeaser given an user without linkToProfile, on touch screen when cl
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -1099,6 +1154,11 @@ exports[`UserTeaser given an user without linkToProfile, on touch screen when cl
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
|
||||
@ -804,15 +804,16 @@
|
||||
"pageLink": "Alle Benachrichtigungen",
|
||||
"post": "Beitrag oder Gruppe",
|
||||
"reason": {
|
||||
"changed_group_member_role": "Hat deine Rolle in der Gruppe geändert …",
|
||||
"commented_on_post": "Hat einen Beitrag den du beobachtest kommentiert …",
|
||||
"followed_user_posted": "Hat einen neuen Betrag geschrieben …",
|
||||
"mentioned_in_comment": "Hat dich in einem Kommentar erwähnt …",
|
||||
"mentioned_in_post": "Hat dich in einem Beitrag erwähnt …",
|
||||
"post_in_group": "Hat einen Beitrag in der Gruppe geschrieben …",
|
||||
"removed_user_from_group": "Hat dich aus der Gruppe entfernt …",
|
||||
"user_joined_group": "Ist deiner Gruppe beigetreten …",
|
||||
"user_left_group": "Hat deine Gruppe verlassen …"
|
||||
"changed_group_member_role": "Hat deine Rolle in der Gruppe geändert",
|
||||
"commented_on_post": "Hat einen Beitrag den du beobachtest kommentiert",
|
||||
"followed_user_posted": "Hat einen neuen Betrag geschrieben",
|
||||
"mentioned_in_comment": "Hat dich in einem Kommentar erwähnt",
|
||||
"mentioned_in_post": "Hat dich in einem Beitrag erwähnt",
|
||||
"on_date": "am",
|
||||
"post_in_group": "Hat einen Beitrag in der Gruppe geschrieben",
|
||||
"removed_user_from_group": "Hat dich aus der Gruppe entfernt",
|
||||
"user_joined_group": "Ist deiner Gruppe beigetreten",
|
||||
"user_left_group": "Hat deine Gruppe verlassen"
|
||||
},
|
||||
"title": "Benachrichtigungen",
|
||||
"user": "Nutzer"
|
||||
|
||||
@ -804,15 +804,16 @@
|
||||
"pageLink": "All notifications",
|
||||
"post": "Post or Group",
|
||||
"reason": {
|
||||
"changed_group_member_role": "Changed your role in group …",
|
||||
"commented_on_post": "Commented on a post you observe …",
|
||||
"followed_user_posted": "Wrote a new post …",
|
||||
"mentioned_in_comment": "Mentioned you in a comment …",
|
||||
"mentioned_in_post": "Mentioned you in a post …",
|
||||
"post_in_group": "Posted in a group …",
|
||||
"removed_user_from_group": "Removed you from group …",
|
||||
"user_joined_group": "Joined your group …",
|
||||
"user_left_group": "Left your group …"
|
||||
"changed_group_member_role": "Changed your role in group",
|
||||
"commented_on_post": "Commented on a post you observe",
|
||||
"followed_user_posted": "Wrote a new post",
|
||||
"mentioned_in_comment": "Mentioned you in a comment",
|
||||
"mentioned_in_post": "Mentioned you in a post",
|
||||
"on_date": "on",
|
||||
"post_in_group": "Posted in a group",
|
||||
"removed_user_from_group": "Removed you from group",
|
||||
"user_joined_group": "Joined your group",
|
||||
"user_left_group": "Left your group"
|
||||
},
|
||||
"title": "Notifications",
|
||||
"user": "User"
|
||||
|
||||
@ -805,10 +805,11 @@
|
||||
"post": "Contribución",
|
||||
"reason": {
|
||||
"changed_group_member_role": null,
|
||||
"commented_on_post": "Comentó su contribución ...",
|
||||
"commented_on_post": "Comentó su contribución",
|
||||
"followed_user_posted": null,
|
||||
"mentioned_in_comment": "Le mencionó en un comentario …",
|
||||
"mentioned_in_post": "Le mencionó en una contribución …",
|
||||
"mentioned_in_comment": "Le mencionó en un comentario",
|
||||
"mentioned_in_post": "Le mencionó en una contribución",
|
||||
"on_date": "de",
|
||||
"post_in_group": null,
|
||||
"removed_user_from_group": null,
|
||||
"user_joined_group": null,
|
||||
|
||||
@ -809,6 +809,7 @@
|
||||
"followed_user_posted": null,
|
||||
"mentioned_in_comment": "Vous a mentionné dans un commentaire…",
|
||||
"mentioned_in_post": "Vous a mentionné dans un post…",
|
||||
"on_date": null,
|
||||
"post_in_group": null,
|
||||
"removed_user_from_group": null,
|
||||
"user_joined_group": null,
|
||||
|
||||
@ -809,6 +809,7 @@
|
||||
"followed_user_posted": null,
|
||||
"mentioned_in_comment": null,
|
||||
"mentioned_in_post": null,
|
||||
"on_date": null,
|
||||
"post_in_group": null,
|
||||
"removed_user_from_group": null,
|
||||
"user_joined_group": null,
|
||||
|
||||
@ -809,6 +809,7 @@
|
||||
"followed_user_posted": null,
|
||||
"mentioned_in_comment": null,
|
||||
"mentioned_in_post": null,
|
||||
"on_date": null,
|
||||
"post_in_group": null,
|
||||
"removed_user_from_group": null,
|
||||
"user_joined_group": null,
|
||||
|
||||
@ -809,6 +809,7 @@
|
||||
"followed_user_posted": null,
|
||||
"mentioned_in_comment": "Mentionou você em um comentário …",
|
||||
"mentioned_in_post": "Mencinou você em um post …",
|
||||
"on_date": null,
|
||||
"post_in_group": null,
|
||||
"removed_user_from_group": null,
|
||||
"user_joined_group": null,
|
||||
|
||||
@ -809,6 +809,7 @@
|
||||
"followed_user_posted": null,
|
||||
"mentioned_in_comment": "Упоминание в комментарии....",
|
||||
"mentioned_in_post": "Упоминание в посте....",
|
||||
"on_date": null,
|
||||
"post_in_group": null,
|
||||
"removed_user_from_group": null,
|
||||
"user_joined_group": null,
|
||||
|
||||
@ -579,6 +579,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a close
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -660,6 +665,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a close
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -741,6 +751,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a close
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -822,6 +837,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a close
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -2455,6 +2475,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a close
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -2536,6 +2561,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a close
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -2617,6 +2647,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a close
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -2698,6 +2733,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a close
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -3434,6 +3474,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -3515,6 +3560,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -3596,6 +3646,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -3677,6 +3732,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -4257,6 +4317,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -4338,6 +4403,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -4419,6 +4489,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -4500,6 +4575,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -5078,6 +5158,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -5159,6 +5244,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -5240,6 +5330,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -5321,6 +5416,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -5969,6 +6069,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -6050,6 +6155,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -6131,6 +6241,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -6212,6 +6327,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a curre
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -6995,6 +7115,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a hidde
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -7076,6 +7201,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a hidde
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -7157,6 +7287,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a hidde
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -7238,6 +7373,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a hidde
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -7974,6 +8114,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a hidde
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -8055,6 +8200,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a hidde
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -8136,6 +8286,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a hidde
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
@ -8217,6 +8372,11 @@ exports[`GroupProfileSlug given a puplic group – "yoga-practice" given a hidde
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!---->
|
||||
|
||||
@ -11,6 +11,17 @@
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<ds-space />
|
||||
<ds-flex-item class="notifications-header-button" :width="{ base: 'auto' }" centered>
|
||||
<base-button
|
||||
primary
|
||||
:disabled="unreadNotificationsCount === 0"
|
||||
@click="markAllAsRead"
|
||||
data-test="markAllAsRead-button"
|
||||
>
|
||||
{{ $t('notifications.markAllAsRead') }}
|
||||
</base-button>
|
||||
</ds-flex-item>
|
||||
<ds-space />
|
||||
<notifications-table
|
||||
@markNotificationAsRead="markNotificationAsRead"
|
||||
:notifications="notifications"
|
||||
@ -25,16 +36,6 @@
|
||||
@next="next"
|
||||
/>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item class="notifications-footer-button" :width="{ base: 'auto' }" centered>
|
||||
<base-button
|
||||
primary
|
||||
:disabled="unreadNotificationsCount === 0"
|
||||
@click="markAllAsRead"
|
||||
data-test="markAllAsRead-button"
|
||||
>
|
||||
{{ $t('notifications.markAllAsRead') }}
|
||||
</base-button>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</base-card>
|
||||
</template>
|
||||
@ -153,10 +154,15 @@ export default {
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.notifications-page-flex {
|
||||
padding: 8px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.notifications-header-button {
|
||||
text-align: right;
|
||||
}
|
||||
.notifications-footer {
|
||||
margin-top: 1.5rem;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user