Fix notification queries in webapp

This commit is contained in:
roschaefer 2019-08-30 01:24:15 +02:00
parent bf6e7a8131
commit c585b23d7a
8 changed files with 138 additions and 219 deletions

View File

@ -2,13 +2,7 @@
<ds-space :class="[{ read: notification.read }, notification]" margin-bottom="x-small">
<client-only>
<ds-space margin-bottom="x-small">
<hc-user
v-if="resourceType == 'Post'"
:user="post.author"
:date-time="post.createdAt"
:trunc="35"
/>
<hc-user v-else :user="comment.author" :date-time="comment.createdAt" :trunc="35" />
<hc-user :user="from.author" :date-time="from.createdAt" :trunc="35" />
</ds-space>
<ds-text class="reason-text-for-test" color="soft">
{{ $t(`notifications.menu.${notification.reason}`) }}
@ -22,16 +16,15 @@
>
<ds-space margin-bottom="x-small">
<ds-card
:header="post.title || comment.post.title"
:header="from.title || from.post.title"
hover
space="x-small"
class="notifications-card"
>
<ds-space margin-bottom="x-small" />
<div v-if="resourceType == 'Post'">{{ post.contentExcerpt | removeHtml }}</div>
<div v-else>
<span class="comment-notification-header">Comment:</span>
{{ comment.contentExcerpt | removeHtml }}
<div>
<span v-if="isComment" class="comment-notification-header">Comment:</span>
{{ from.contentExcerpt | removeHtml }}
</div>
</ds-card>
</ds-space>
@ -54,23 +47,21 @@ export default {
},
},
computed: {
resourceType() {
return this.post.id ? 'Post' : 'Comment'
from() {
return this.notification.from
},
post() {
return this.notification.post || {}
},
comment() {
return this.notification.comment || {}
isComment() {
return this.from.__typename === 'Comment'
},
params() {
const post = this.isComment ? this.from.post : this.from
return {
id: this.post.id || this.comment.post.id,
slug: this.post.slug || this.comment.post.slug,
id: post.id,
slug: post.slug,
}
},
hashParam() {
return this.post.id ? {} : { hash: `#commentId-${this.comment.id}` }
return this.isComment ? { hash: `#commentId-${this.from.id}` } : {}
},
},
}

View File

@ -4,7 +4,7 @@
v-for="notification in notifications"
:key="notification.id"
:notification="notification"
@read="markAsRead(notification.id)"
@read="markAsRead(notification.from.id)"
/>
</div>
</template>
@ -24,8 +24,8 @@ export default {
},
},
methods: {
markAsRead(notificationId) {
this.$emit('markAsRead', notificationId)
async markAsRead(notificationSourceId) {
this.$emit('markAsRead', notificationSourceId)
},
},
}

View File

@ -18,7 +18,7 @@
<script>
import Dropdown from '~/components/Dropdown'
import { currentUserNotificationsQuery, updateNotificationMutation } from '~/graphql/User'
import { notificationQuery, markAsReadMutation } from '~/graphql/User'
import NotificationList from '../NotificationList/NotificationList'
export default {
@ -27,36 +27,41 @@ export default {
NotificationList,
Dropdown,
},
data() {
return {
notifications: [],
}
},
props: {
placement: { type: String },
},
computed: {
totalNotifications() {
return (this.notifications || []).length
},
},
methods: {
async markAsRead(notificationId) {
const variables = { id: notificationId, read: true }
async markAsRead(notificationSourceId) {
const variables = { id: notificationSourceId }
try {
await this.$apollo.mutate({
mutation: updateNotificationMutation(),
const {
data: { markAsRead },
} = await this.$apollo.mutate({
mutation: markAsReadMutation(),
variables,
})
if (!(markAsRead && markAsRead.read === true)) return
this.notifications = this.notifications.filter(n => {
return n.from.id !== markAsRead.from.id
})
} catch (err) {
throw new Error(err)
}
},
},
computed: {
totalNotifications() {
return this.notifications.length
},
},
apollo: {
notifications: {
query: currentUserNotificationsQuery(),
update: data => {
const {
currentUser: { notifications },
} = data
return notifications
},
query: notificationQuery(),
},
},
}

View File

@ -1,5 +1,58 @@
import gql from 'graphql-tag'
const fragments = gql`
fragment post on Post {
id
createdAt
disabled
deleted
title
contentExcerpt
slug
author {
id
slug
name
disabled
deleted
avatar
}
}
fragment comment on Comment {
id
createdAt
disabled
deleted
contentExcerpt
author {
id
slug
name
disabled
deleted
avatar
}
post {
id
createdAt
disabled
deleted
title
contentExcerpt
slug
author {
id
slug
name
disabled
deleted
avatar
}
}
}
`
export default i18n => {
const lang = i18n.locale().toUpperCase()
return gql`
@ -76,77 +129,37 @@ export default i18n => {
`
}
export const currentUserNotificationsQuery = () => {
export const notificationQuery = () => {
return gql`
${fragments}
query {
currentUser {
id
notifications(read: false, orderBy: createdAt_desc) {
id
read
reason
createdAt
post {
id
createdAt
disabled
deleted
title
contentExcerpt
slug
author {
id
slug
name
disabled
deleted
avatar
}
}
comment {
id
createdAt
disabled
deleted
contentExcerpt
author {
id
slug
name
disabled
deleted
avatar
}
post {
id
createdAt
disabled
deleted
title
contentExcerpt
slug
author {
id
slug
name
disabled
deleted
avatar
}
}
}
notifications(read: false, orderBy: createdAt_desc) {
read
reason
createdAt
from {
__typename
...post
...comment
}
}
}
`
}
export const updateNotificationMutation = () => {
export const markAsReadMutation = () => {
return gql`
mutation($id: ID!, $read: Boolean!) {
UpdateNotification(id: $id, read: $read) {
id
${fragments}
mutation($id: ID!) {
markAsRead(id: $id) {
read
reason
createdAt
from {
__typename
...post
...comment
}
}
}
`

View File

@ -1,3 +1,10 @@
import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'
import introspectionQueryResultData from './apollo-config/fragmentTypes.json'
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData,
})
export default ({ app }) => {
const backendUrl = process.env.GRAPHQL_URI || 'http://localhost:4000'
@ -10,5 +17,6 @@ export default ({ app }) => {
tokenName: 'human-connection-token',
persisting: false,
websocketsOnly: false,
cache: new InMemoryCache({ fragmentMatcher }),
}
}

View File

@ -0,0 +1,18 @@
{
"__schema": {
"types": [
{
"kind": "UNION",
"name": "NotificationSource",
"possibleTypes": [
{
"name": "Post"
},
{
"name": "Comment"
}
]
}
]
}
}

View File

@ -86,23 +86,6 @@ export const actions = {
id
url
}
notifications(read: false, orderBy: createdAt_desc) {
id
read
createdAt
post {
author {
id
slug
name
disabled
deleted
}
title
contentExcerpt
slug
}
}
}
}
`,

View File

@ -1,99 +0,0 @@
import gql from 'graphql-tag'
export const state = () => {
return {
notifications: null,
pending: false,
}
}
export const mutations = {
SET_NOTIFICATIONS(state, notifications) {
state.notifications = notifications
},
SET_PENDING(state, pending) {
state.pending = pending
},
UPDATE_NOTIFICATIONS(state, notification) {
const notifications = state.notifications
const toBeUpdated = notifications.find(n => {
return n.id === notification.id
})
state.notifications = {
...toBeUpdated,
...notification,
}
},
}
export const getters = {
notifications(state) {
return !!state.notifications
},
}
export const actions = {
async init({ getters, commit }) {
if (getters.notifications) return
commit('SET_PENDING', true)
const client = this.app.apolloProvider.defaultClient
let notifications
try {
const {
data: { currentUser },
} = await client.query({
query: gql`
{
currentUser {
id
notifications(orderBy: createdAt_desc) {
id
read
createdAt
post {
author {
id
slug
name
disabled
deleted
}
title
contentExcerpt
slug
}
}
}
}
`,
})
notifications = currentUser.notifications
commit('SET_NOTIFICATIONS', notifications)
} finally {
commit('SET_PENDING', false)
}
return notifications
},
async markAsRead({ commit, rootGetters }, notificationId) {
const client = this.app.apolloProvider.defaultClient
const mutation = gql`
mutation($id: ID!, $read: Boolean!) {
UpdateNotification(id: $id, read: $read) {
id
read
}
}
`
const variables = {
id: notificationId,
read: true,
}
const {
data: { UpdateNotification },
} = await client.mutate({
mutation,
variables,
})
commit('UPDATE_NOTIFICATIONS', UpdateNotification)
},
}