From 0bffede0214b9cdbfad843f6221631dbed34dd6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adem=C3=ADlson=20F=2E=20Tonato?= Date: Sat, 24 Oct 2020 11:29:02 +0100 Subject: [PATCH 01/36] feat: add mutation for new functionality (mark-all-as-read) - Add mutation for markAllAsRead (notifications) - Add method to the schema that returns a list of all notifications - Add permissions rules to invoke this method (isAuthenticated) See #2660 --- .../src/middleware/permissionsMiddleware.js | 1 + backend/src/schema/resolvers/notifications.js | 29 +++++++++++++++ backend/src/schema/types/type/NOTIFIED.gql | 1 + webapp/graphql/User.js | 36 +++++++++++++++++++ 4 files changed, 67 insertions(+) diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 2c8d7ff63..d3aa7ce9a 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -143,6 +143,7 @@ export default shield( blockUser: isAuthenticated, unblockUser: isAuthenticated, markAsRead: isAuthenticated, + markAllAsRead: isAuthenticated, AddEmailAddress: isAuthenticated, VerifyEmailAddress: isAuthenticated, pinPost: isAdmin, diff --git a/backend/src/schema/resolvers/notifications.js b/backend/src/schema/resolvers/notifications.js index 3c01ddb97..a96181a50 100644 --- a/backend/src/schema/resolvers/notifications.js +++ b/backend/src/schema/resolvers/notifications.js @@ -99,6 +99,35 @@ export default { session.close() } }, + markAllAsRead: async (parent, args, context, resolveInfo) => { + const { user: currentUser } = context + const session = context.driver.session() + const writeTxResultPromise = session.writeTransaction(async (transaction) => { + const markAllNotificationAsReadTransactionResponse = await transaction.run( + ` + MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED {read: FALSE}]->(user:User {id:$id}) + SET notification.read = TRUE + WITH user, notification, resource, + [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts + WITH resource, user, notification, authors, posts, + resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} AS finalResource + RETURN notification {.*, from: finalResource, to: properties(user)} + `, + { id: currentUser.id }, + ) + log(markAllNotificationAsReadTransactionResponse) + return markAllNotificationAsReadTransactionResponse.records.map((record) => + record.get('notification'), + ) + }) + try { + const notifications = await writeTxResultPromise + return notifications + } finally { + session.close() + } + }, }, NOTIFIED: { id: async (parent) => { diff --git a/backend/src/schema/types/type/NOTIFIED.gql b/backend/src/schema/types/type/NOTIFIED.gql index 88ecd3882..864cdea4d 100644 --- a/backend/src/schema/types/type/NOTIFIED.gql +++ b/backend/src/schema/types/type/NOTIFIED.gql @@ -29,6 +29,7 @@ type Query { type Mutation { markAsRead(id: ID!): NOTIFIED + markAllAsRead: [NOTIFIED] } type Subscription { diff --git a/webapp/graphql/User.js b/webapp/graphql/User.js index 3b015dacc..8a0494402 100644 --- a/webapp/graphql/User.js +++ b/webapp/graphql/User.js @@ -136,6 +136,42 @@ export const markAsReadMutation = (i18n) => { ` } +export const markAllAsReadMutation = (i18n) => { + return gql` + ${userFragment} + ${commentFragment} + ${postFragment} + + mutation { + markAllAsRead { + id + read + reason + createdAt + updatedAt + from { + __typename + ... on Post { + ...post + author { + ...user + } + } + ... on Comment { + ...comment + post { + ...post + author { + ...user + } + } + } + } + } + } + ` +} + export const notificationAdded = () => { return gql` ${userFragment} From e37fb535dce43cd5629ee0a900568be5409608be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adem=C3=ADlson=20F=2E=20Tonato?= Date: Sat, 24 Oct 2020 11:54:52 +0100 Subject: [PATCH 02/36] feat: add translations for notifications label (mark all as read) --- webapp/locales/de.json | 1 + webapp/locales/en.json | 1 + webapp/locales/es.json | 1 + webapp/locales/fr.json | 1 + webapp/locales/it.json | 1 + webapp/locales/nl.json | 20 ++++++++++++++++++++ webapp/locales/pt.json | 1 + webapp/locales/ru.json | 1 + 8 files changed, 27 insertions(+) diff --git a/webapp/locales/de.json b/webapp/locales/de.json index adee8921c..8de89bd5c 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -456,6 +456,7 @@ "unread": "Ungelesen" }, "pageLink": "Alle Benachrichtigungen", + "markAllAsRead": "Markiere alle als gelesen", "post": "Beitrag", "reason": { "commented_on_post": "Hat Deinen Beitrag kommentiert …", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 8959e3830..f9e7a43e6 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -456,6 +456,7 @@ "unread": "Unread" }, "pageLink": "All notifications", + "markAllAsRead": "Mark all as read", "post": "Post", "reason": { "commented_on_post": "Commented on your post …", diff --git a/webapp/locales/es.json b/webapp/locales/es.json index 0925687fc..8dc91ac52 100644 --- a/webapp/locales/es.json +++ b/webapp/locales/es.json @@ -449,6 +449,7 @@ "unread": "No leído" }, "pageLink": "Todas las notificaciones", + "markAllAsRead": "Marcar todas como leido", "post": "Contribución", "reason": { "commented_on_post": "Comentó su contribución ...", diff --git a/webapp/locales/fr.json b/webapp/locales/fr.json index e0bcf14e1..0bab5e73d 100644 --- a/webapp/locales/fr.json +++ b/webapp/locales/fr.json @@ -438,6 +438,7 @@ "unread": "Non lu" }, "pageLink": "Toutes les notifications", + "markAllAsRead": "Tout marquer comme lu", "post": "Post", "reason": { "commented_on_post": "Commenté sur votre post…", diff --git a/webapp/locales/it.json b/webapp/locales/it.json index b53b863cc..898a80d63 100644 --- a/webapp/locales/it.json +++ b/webapp/locales/it.json @@ -388,6 +388,7 @@ "unread": "" }, "pageLink": "", + "markAllAsRead": "Segna tutti come letti", "post": "", "reason": { "commented_on_post": "", diff --git a/webapp/locales/nl.json b/webapp/locales/nl.json index 64643133c..35e31591f 100644 --- a/webapp/locales/nl.json +++ b/webapp/locales/nl.json @@ -172,5 +172,25 @@ "taxident": "Identificatienummer voor de belasting over de toegevoegde waarde overeenkomstig § 27 a Wet op de belasting over de toegevoegde waarde (Duitsland).", "termsAc": "Gebruiksvoorwaarden", "tribunal": "registerrechtbank" + }, + "notifications": { + "comment": "", + "content": "", + "empty": "", + "filterLabel": { + "all": "", + "read": "", + "unread": "" + }, + "pageLink": "", + "markAllAsRead": "Markeer alles als gelezen", + "post": "", + "reason": { + "commented_on_post": "", + "mentioned_in_comment": "", + "mentioned_in_post": "" + }, + "title": "", + "user": "" } } diff --git a/webapp/locales/pt.json b/webapp/locales/pt.json index 1a3efeb44..96be89f8e 100644 --- a/webapp/locales/pt.json +++ b/webapp/locales/pt.json @@ -377,6 +377,7 @@ "unread": "Não lido" }, "pageLink": "Todas as notificações", + "markAllAsRead": "Marcar todas como lidas", "post": "Post", "reason": { "commented_on_post": "Comentou no seu post …", diff --git a/webapp/locales/ru.json b/webapp/locales/ru.json index 59928a2c5..bb66aa862 100644 --- a/webapp/locales/ru.json +++ b/webapp/locales/ru.json @@ -449,6 +449,7 @@ "unread": "Непрочитанные" }, "pageLink": "Все уведомления", + "markAllAsRead": "Отметить все как прочитанное", "post": "Пост", "reason": { "commented_on_post": "Комментарий к посту...", From 1df69c90fdd5233d4ab1059a3afb0b95f85db134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adem=C3=ADlson=20F=2E=20Tonato?= Date: Sat, 24 Oct 2020 19:38:45 +0100 Subject: [PATCH 03/36] feat: add tests for mark all as read (backend) --- .../schema/resolvers/notifications.spec.js | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/backend/src/schema/resolvers/notifications.spec.js b/backend/src/schema/resolvers/notifications.spec.js index 9d7795dd4..d4805bfc9 100644 --- a/backend/src/schema/resolvers/notifications.spec.js +++ b/backend/src/schema/resolvers/notifications.spec.js @@ -393,4 +393,51 @@ describe('given some notifications', () => { }) }) }) + describe('markAllAsRead', () => { + const markAllAsReadMutation = gql` + mutation { + markAllAsRead { + from { + __typename + ... on Post { + content + } + ... on Comment { + content + } + } + read + createdAt + } + } + ` + describe('unauthenticated', () => { + it('throws authorization error', async () => { + const result = await mutate({ + mutation: markAllAsReadMutation, + }) + expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!') + }) + }) + + describe('authenticated', () => { + beforeEach(async () => { + authenticatedUser = await user.toJson() + }) + + describe('not being notified at all', () => { + beforeEach(async () => { + variables = { + ...variables, + } + }) + + it('returns undefined', async () => { + const response = await mutate({ mutation: markAllAsReadMutation, variables }) + expect(response.data.markAsRead).toEqual(undefined) + expect(response.errors).toBeUndefined() + }) + }) + }) + }) }) From bfe66adaacc9a6bc19976ea7e616f62ac061bb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adem=C3=ADlson=20F=2E=20Tonato?= Date: Sat, 24 Oct 2020 19:40:05 +0100 Subject: [PATCH 04/36] feat: add button to mark all notifications as read on notification menu --- .../NotificationMenu/NotificationMenu.vue | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/webapp/components/NotificationMenu/NotificationMenu.vue b/webapp/components/NotificationMenu/NotificationMenu.vue index ec991f0ef..c53545b91 100644 --- a/webapp/components/NotificationMenu/NotificationMenu.vue +++ b/webapp/components/NotificationMenu/NotificationMenu.vue @@ -16,11 +16,24 @@
- + + + + {{ $t('notifications.pageLink') }} + + + + + {{ $t('notifications.markAllAsRead') }} + + + @@ -28,7 +41,12 @@