From 7cdc12f4b9943062e15a874dd39f8a50142b6c61 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Mon, 21 Oct 2019 19:48:02 +0200 Subject: [PATCH 01/38] Add notifications page with Notifications in table - At the moment, the notifications are displayed in a table, and have the same functionality as the NotificationMenu where you can click on the title of the Post and visit the Post - Unsure about the styling, it would kind of be nice to have a more condensed list to see more notifications per page, but still be able to click on a row and visit the Post --- .../Notification/Notification.vue | 70 ++++--- .../NotificationMenu/NotificationMenu.vue | 3 + webapp/graphql/User.js | 2 +- webapp/locales/en.json | 8 +- webapp/pages/notifications/index.vue | 197 ++++++++++++++++++ 5 files changed, 244 insertions(+), 36 deletions(-) create mode 100644 webapp/pages/notifications/index.vue diff --git a/webapp/components/notifications/Notification/Notification.vue b/webapp/components/notifications/Notification/Notification.vue index dc9383c85..9649b0d7e 100644 --- a/webapp/components/notifications/Notification/Notification.vue +++ b/webapp/components/notifications/Notification/Notification.vue @@ -1,37 +1,39 @@ - From b79770469fd7773d5c9816ab5a4325cd6010ebfa Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Tue, 22 Oct 2019 14:40:10 +0200 Subject: [PATCH 02/38] Update notifications page - display more notifications by simplifying the table - get sorting working --- .../Notification/Notification.spec.js | 0 .../Notification/Notification.vue | 0 .../NotificationList/NotificationList.spec.js | 0 .../NotificationList/NotificationList.vue | 0 .../NotificationMenu/NotificationMenu.spec.js | 0 .../NotificationMenu/NotificationMenu.vue | 20 ++- webapp/graphql/User.js | 4 +- webapp/locales/en.json | 2 +- webapp/pages/notifications/index.vue | 135 +++++++----------- 9 files changed, 71 insertions(+), 90 deletions(-) rename webapp/components/{notifications => }/Notification/Notification.spec.js (100%) rename webapp/components/{notifications => }/Notification/Notification.vue (100%) rename webapp/components/{notifications => }/NotificationList/NotificationList.spec.js (100%) rename webapp/components/{notifications => }/NotificationList/NotificationList.vue (100%) rename webapp/components/{notifications => }/NotificationMenu/NotificationMenu.spec.js (100%) rename webapp/components/{notifications => }/NotificationMenu/NotificationMenu.vue (87%) diff --git a/webapp/components/notifications/Notification/Notification.spec.js b/webapp/components/Notification/Notification.spec.js similarity index 100% rename from webapp/components/notifications/Notification/Notification.spec.js rename to webapp/components/Notification/Notification.spec.js diff --git a/webapp/components/notifications/Notification/Notification.vue b/webapp/components/Notification/Notification.vue similarity index 100% rename from webapp/components/notifications/Notification/Notification.vue rename to webapp/components/Notification/Notification.vue diff --git a/webapp/components/notifications/NotificationList/NotificationList.spec.js b/webapp/components/NotificationList/NotificationList.spec.js similarity index 100% rename from webapp/components/notifications/NotificationList/NotificationList.spec.js rename to webapp/components/NotificationList/NotificationList.spec.js diff --git a/webapp/components/notifications/NotificationList/NotificationList.vue b/webapp/components/NotificationList/NotificationList.vue similarity index 100% rename from webapp/components/notifications/NotificationList/NotificationList.vue rename to webapp/components/NotificationList/NotificationList.vue diff --git a/webapp/components/notifications/NotificationMenu/NotificationMenu.spec.js b/webapp/components/NotificationMenu/NotificationMenu.spec.js similarity index 100% rename from webapp/components/notifications/NotificationMenu/NotificationMenu.spec.js rename to webapp/components/NotificationMenu/NotificationMenu.spec.js diff --git a/webapp/components/notifications/NotificationMenu/NotificationMenu.vue b/webapp/components/NotificationMenu/NotificationMenu.vue similarity index 87% rename from webapp/components/notifications/NotificationMenu/NotificationMenu.vue rename to webapp/components/NotificationMenu/NotificationMenu.vue index 255101139..4ab3dedca 100644 --- a/webapp/components/notifications/NotificationMenu/NotificationMenu.vue +++ b/webapp/components/NotificationMenu/NotificationMenu.vue @@ -13,7 +13,9 @@ - {{ $t('notifications.page') }} + + {{ $t('notifications.page') }} + @@ -35,6 +37,7 @@ export default { return { displayedNotifications: [], notifications: [], + nofiticationRead: null, } }, props: { @@ -75,15 +78,24 @@ export default { } return countUnread }, + updateNotifications() { + return this.notificationRead + }, }, apollo: { notifications: { query() { return notificationQuery(this.$i18n) }, + variables() { + return { + read: false, + orderBy: 'updatedAt_desc', + } + }, pollInterval: NOTIFICATIONS_POLL_INTERVAL, - update(data) { - const newNotifications = data.notifications.filter(newN => { + update({ notifications }) { + const newNotifications = notifications.filter(newN => { return !this.displayedNotifications.find(oldN => this.equalNotification(newN, oldN)) }) this.displayedNotifications = newNotifications @@ -91,7 +103,7 @@ export default { .sort((a, b) => { return new Date(b.createdAt) - new Date(a.createdAt) }) - return data.notifications + return notifications }, error(error) { this.$toast.error(error.message) diff --git a/webapp/graphql/User.js b/webapp/graphql/User.js index 54d5889e2..5a4b18b6a 100644 --- a/webapp/graphql/User.js +++ b/webapp/graphql/User.js @@ -51,8 +51,8 @@ export const notificationQuery = i18n => { ${commentFragment(lang)} ${postFragment(lang)} - query { - notifications(orderBy: updatedAt_desc) { + query($read: Boolean, $orderBy: NotificationOrdering) { + notifications(read: $read, orderBy: $orderBy) { read reason createdAt diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 59b8a9390..c978a35a7 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -182,7 +182,7 @@ "createdAt": "Notification created at", "type": "Type", "user": "User", - "action": "Action" + "content": "Content" }, "search": { "placeholder": "Search", diff --git a/webapp/pages/notifications/index.vue b/webapp/pages/notifications/index.vue index fcbebd1c2..118ca0d45 100644 --- a/webapp/pages/notifications/index.vue +++ b/webapp/pages/notifications/index.vue @@ -14,7 +14,7 @@ @click.prevent="toggleMenu()" > - {{ 'All' }} + {{ selected }} - {{ item.route.option }} + {{ item.route.label }} @@ -39,51 +39,12 @@ - - + + @@ -136,23 +98,29 @@ export default { }, data() { return { - notifications: [], - sortingOptions: ['All', 'Read', 'Unread'], + selectedNotifications: [], + selected: 'All', + sortingOptions: [ + { label: 'All', value: null }, + { label: 'Read', value: true }, + { label: 'Unread', value: false }, + ], nofiticationRead: null, } }, computed: { fields() { return { - notifications: null, - // user: this.$t('notifications.user'), - // type: this.$t('notifications.type'), + user: this.$t('notifications.user'), + post: this.$t('notifications.type'), + content: this.$t('notifications.content'), } }, routes() { let routes = this.sortingOptions.map(option => { return { - option, + label: option.label, + value: option.value, } }) return routes @@ -160,24 +128,25 @@ export default { }, methods: { sortNotifications(option, toggleMenu) { - if (option === 'Read') { - this.notificationRead = true - } else if (option === 'Unread') { - this.notificationRead = false - } else { - this.notificationRead = null - } - this.$apollo.queries.notificationsPage.refetch() + this.notificationRead = option.value + this.selected = option.label + this.$apollo.queries.notifications.refresh() toggleMenu() }, }, apollo: { - notificationsPage: { + notifications: { query() { return notificationQuery(this.$i18n) }, + variables() { + return { + read: this.notificationRead, + orderBy: 'updatedAt_desc', + } + }, update({ notifications }) { - this.notifications = notifications + this.selectedNotifications = notifications }, fetchPolicy: 'cache-and-network', error(error) { @@ -191,7 +160,7 @@ export default { .sorting-dropdown { float: right; } -#notifications-table thead { - display: none; +.notifications-table td { + width: 500px; } From cf8124fb2d96c04c44c35f3542d1a6eaac10fe47 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Thu, 24 Oct 2019 09:11:49 +0200 Subject: [PATCH 03/38] Clean up/add german translations --- .../components/Notification/Notification.vue | 68 +++++++++---------- webapp/locales/de.json | 11 ++- webapp/locales/en.json | 11 +-- webapp/pages/notifications/index.vue | 10 +-- 4 files changed, 55 insertions(+), 45 deletions(-) diff --git a/webapp/components/Notification/Notification.vue b/webapp/components/Notification/Notification.vue index 9649b0d7e..321d1df39 100644 --- a/webapp/components/Notification/Notification.vue +++ b/webapp/components/Notification/Notification.vue @@ -1,39 +1,37 @@ - diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 25ce3742f..534ef819f 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -185,7 +185,8 @@ "all": "Alle", "read": "Lesen ", "unread": "Ungelesen" - } + }, + "empty": "Sorry, du hast im Moment keine Benachrichtigungen." }, "search": { "placeholder": "Suchen", @@ -684,7 +685,7 @@ "terms-of-service": { "title": "Nutzungsbedingungen", "description": "Die folgenden Nutzungsbedingungen sind Basis für die Nutzung unseres Netzwerkes. Beim Registrieren musst Du sie anerkennen und wir werden Dich auch später über ggf. stattfindende Änderungen informieren. Das Human Connection Netzwerk wird in Deutschland betrieben und unterliegt daher deutschem Recht. Gerichtsstand ist Kirchheim / Teck. Zu Details schau in unser Impressum: https://human-connection.org/impressum " - }, + }, "use-and-license" : { "title": "Nutzung und Lizenz", "description": "Sind Inhalte, die Du bei uns einstellst, durch Rechte am geistigen Eigentum geschützt, erteilst Du uns eine nicht-exklusive, übertragbare, unterlizenzierbare und weltweite Lizenz für die Nutzung dieser Inhalte für die Bereitstellung in unserem Netzwerk. Diese Lizenz endet, sobald Du Deine Inhalte oder Deinen ganzen Account löscht. Bedenke, dass andere Deine Inhalte weiter teilen können und wir diese nicht löschen können." @@ -712,6 +713,6 @@ "addition" : { "title": "Zusätzliche machen wir regelmäßig Veranstaltungen, wo Du auch Eindrücke wiedergeben und Fragen stellen kannst. Du findest eine aktuelle Übersicht hier:", "description": " https://human-connection.org/veranstaltungen/ " - } + } } } diff --git a/webapp/locales/en.json b/webapp/locales/en.json index b77922b74..775132eab 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -186,7 +186,8 @@ "all": "All", "read": "Read", "unread": "Unread" - } + }, + "empty": "Sorry, you don't have any notifications at the moment." }, "search": { "placeholder": "Search", @@ -685,7 +686,7 @@ "terms-of-service": { "title": "Terms of Service", "description": "The following terms of use form the basis for the use of our network. When you register, you must accept them and we will inform you later about any changes that may take place. The Human Connection Network is operated in Germany and is therefore subject to German law. Place of jurisdiction is Kirchheim / Teck. For details see our imprint: https://human-connection.org/imprint " - }, + }, "use-and-license" : { "title": "Use and License", "description": "If any content you post to us is protected by intellectual property rights, you grant us a non-exclusive, transferable, sublicensable, worldwide license to use such content for posting to our network. This license expires when you delete your content or your entire account. Remember that others may share your content and we cannot delete it." @@ -713,10 +714,10 @@ "addition" : { "title": "In addition, we regularly hold events where you can also share your impressions and ask questions. You can find a current overview here:", "description": " https://human-connection.org/events/ " - } + } } } - - - + + + diff --git a/webapp/pages/notifications/index.vue b/webapp/pages/notifications/index.vue index 0ed768dfc..2ff6fe2d5 100644 --- a/webapp/pages/notifications/index.vue +++ b/webapp/pages/notifications/index.vue @@ -44,19 +44,35 @@ :fields="fields" class="notifications-table" > + - + @@ -88,7 +106,7 @@ import HcUser from '~/components/User/User' import HcEmpty from '~/components/Empty.vue' import Dropdown from '~/components/Dropdown' -import { notificationQuery } from '~/graphql/User' +import { notificationQuery, markAsReadMutation } from '~/graphql/User' export default { components: { @@ -111,7 +129,14 @@ export default { computed: { fields() { return { - user: this.$t('notifications.user'), + icon: { + label: ' ', + width: '60px', + }, + user: { + label: this.$t('notifications.user'), + width: '350px', + }, post: this.$t('notifications.post'), content: this.$t('notifications.content'), } @@ -133,6 +158,16 @@ export default { this.$apollo.queries.notifications.refresh() toggleMenu() }, + async markNotificationAsRead(notificationSourceId) { + try { + await this.$apollo.mutate({ + mutation: markAsReadMutation(this.$i18n), + variables: { id: notificationSourceId }, + }) + } catch (error) { + this.$toast.error(error.message) + } + }, }, apollo: { notifications: { @@ -160,7 +195,8 @@ export default { .sorting-dropdown { float: right; } -.notifications-table td { - width: 500px; +.notification-status { + opacity: 0.6; /* Real browsers */ + filter: alpha(opacity = 60); /* MSIE */ } From 994a0b049d1803784d9c06383872f1c9e33095a0 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Fri, 25 Oct 2019 13:12:55 +0200 Subject: [PATCH 06/38] Extract AvatarMenu into its own component --- webapp/components/AvatarMenu/AvatarMenu.vue | 162 ++++++++++++++++++++ webapp/layouts/default.vue | 138 +---------------- 2 files changed, 165 insertions(+), 135 deletions(-) create mode 100644 webapp/components/AvatarMenu/AvatarMenu.vue diff --git a/webapp/components/AvatarMenu/AvatarMenu.vue b/webapp/components/AvatarMenu/AvatarMenu.vue new file mode 100644 index 000000000..96d26f210 --- /dev/null +++ b/webapp/components/AvatarMenu/AvatarMenu.vue @@ -0,0 +1,162 @@ + + + diff --git a/webapp/layouts/default.vue b/webapp/layouts/default.vue index 35af4d25f..091bfb7c8 100644 --- a/webapp/layouts/default.vue +++ b/webapp/layouts/default.vue @@ -71,52 +71,7 @@ - - - - + @@ -144,21 +99,19 @@ import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch' import SearchInput from '~/components/SearchInput.vue' import Modal from '~/components/Modal' import NotificationMenu from '~/components/notifications/NotificationMenu/NotificationMenu' -import Dropdown from '~/components/Dropdown' -import HcAvatar from '~/components/Avatar/Avatar.vue' import seo from '~/mixins/seo' import FilterPosts from '~/components/FilterPosts/FilterPosts.vue' import CategoryQuery from '~/graphql/CategoryQuery.js' import PageFooter from '~/components/PageFooter/PageFooter' +import AvatarMenu from '~/components/AvatarMenu/AvatarMenu' export default { components: { - Dropdown, LocaleSwitch, SearchInput, Modal, NotificationMenu, - HcAvatar, + AvatarMenu, FilterPosts, PageFooter, }, @@ -172,49 +125,10 @@ export default { }, computed: { ...mapGetters({ - user: 'auth/user', isLoggedIn: 'auth/isLoggedIn', - isModerator: 'auth/isModerator', - isAdmin: 'auth/isAdmin', quickSearchResults: 'search/quickResults', quickSearchPending: 'search/quickPending', }), - userName() { - const { name } = this.user || {} - return name || this.$t('profile.userAnonym') - }, - routes() { - if (!this.user.slug) { - return [] - } - let routes = [ - { - name: this.$t('profile.name'), - path: `/profile/${this.user.slug}`, - icon: 'user', - }, - { - name: this.$t('settings.name'), - path: `/settings`, - icon: 'cogs', - }, - ] - if (this.isModerator) { - routes.push({ - name: this.$t('moderation.name'), - path: `/moderation`, - icon: 'balance-scale', - }) - } - if (this.isAdmin) { - routes.push({ - name: this.$t('admin.name'), - path: `/admin`, - icon: 'shield', - }) - } - return routes - }, showFilterPostsDropdown() { const [firstRoute] = this.$route.matched return firstRoute && firstRoute.name === 'index' @@ -239,13 +153,6 @@ export default { }) }) }, - matcher(url, route) { - if (url.indexOf('/profile') === 0) { - // do only match own profile - return this.$route.path === url - } - return this.$route.path.indexOf(url) === 0 - }, toggleMobileMenuView() { this.toggleMobileMenu = !this.toggleMobileMenu }, @@ -289,45 +196,6 @@ export default { .main-navigation-right .desktop-view { float: right; } -.avatar-menu { - margin: 2px 0px 0px 5px; -} -.avatar-menu-trigger { - user-select: none; - display: flex; - align-items: center; - padding-left: $space-xx-small; -} -.avatar-menu-popover { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - hr { - color: $color-neutral-90; - background-color: $color-neutral-90; - } - .logout-link { - margin-left: -$space-small; - margin-right: -$space-small; - margin-top: -$space-xxx-small; - margin-bottom: -$space-x-small; - padding: $space-x-small $space-small; - // subtract menu border with from padding - padding-left: $space-small - 2; - color: $text-color-base; - &:hover { - color: $text-color-link-active; - } - } - nav { - margin-left: -$space-small; - margin-right: -$space-small; - margin-top: -$space-xx-small; - margin-bottom: -$space-xx-small; - a { - padding-left: 12px; - } - } -} @media only screen and (min-width: 960px) { .mobile-hamburger-menu { display: none; From d83a42451318cdc1fe85c58dfea0d6b21fa56b77 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Mon, 28 Oct 2019 17:29:01 +0100 Subject: [PATCH 07/38] Add styling - to link in NotificationMenu - make table more mobile responsive - remove unneccessary props Co-authored-by: Alina Beck --- webapp/components/AvatarMenu/AvatarMenu.vue | 5 ++-- .../NotificationMenu/NotificationMenu.vue | 28 ++++++++++--------- webapp/layouts/default.vue | 2 +- webapp/pages/notifications/index.vue | 2 +- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/webapp/components/AvatarMenu/AvatarMenu.vue b/webapp/components/AvatarMenu/AvatarMenu.vue index 96d26f210..18865f457 100644 --- a/webapp/components/AvatarMenu/AvatarMenu.vue +++ b/webapp/components/AvatarMenu/AvatarMenu.vue @@ -1,5 +1,5 @@ diff --git a/webapp/pages/notifications/index.vue b/webapp/pages/notifications/index.vue index 2ff6fe2d5..95d30df1a 100644 --- a/webapp/pages/notifications/index.vue +++ b/webapp/pages/notifications/index.vue @@ -135,7 +135,7 @@ export default { }, user: { label: this.$t('notifications.user'), - width: '350px', + width: '33.333%', }, post: this.$t('notifications.post'), content: this.$t('notifications.content'), From 4448c12f2e153d2eec04e7734c39992e7b04f408 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Mon, 28 Oct 2019 17:30:28 +0100 Subject: [PATCH 08/38] Add componenet test for AvatarMenu Co-authored-by: mindcodemediator Co-authored-by: Mike Aono --- .../components/AvatarMenu/AvatarMenu.spec.js | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 webapp/components/AvatarMenu/AvatarMenu.spec.js diff --git a/webapp/components/AvatarMenu/AvatarMenu.spec.js b/webapp/components/AvatarMenu/AvatarMenu.spec.js new file mode 100644 index 000000000..17237d37e --- /dev/null +++ b/webapp/components/AvatarMenu/AvatarMenu.spec.js @@ -0,0 +1,148 @@ +import { config, mount, createLocalVue } from '@vue/test-utils' +import Vuex from 'vuex' +import VTooltip from 'v-tooltip' +import Styleguide from '@human-connection/styleguide' +import AvatarMenu from './AvatarMenu.vue' +import Filters from '~/plugins/vue-filters' + +const localVue = createLocalVue() +localVue.use(Styleguide) +localVue.use(Vuex) +localVue.use(Filters) +localVue.use(VTooltip) + +config.stubs['nuxt-link'] = '' +config.stubs['router-link'] = '' + +describe('AvatarMenu.vue', () => { + let propsData, getters, wrapper, mocks + + beforeEach(() => { + propsData = {} + mocks = { + $route: { + path: '', + }, + $router: { + resolve: jest.fn(() => { + return { href: '/profile/u343/matt' } + }), + }, + $t: jest.fn(a => a), + } + getters = { + 'auth/user': () => { + return { id: 'u343', name: 'Matt' } + }, + } + }) + + const Wrapper = () => { + const store = new Vuex.Store({ + getters, + }) + return mount(AvatarMenu, { propsData, localVue, store, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the HcAvatar component', () => { + wrapper.find('.avatar-menu-trigger').trigger('click') + expect(wrapper.find('.ds-avatar').exists()).toBe(true) + }) + + describe('given a userName', () => { + it('displays the userName', () => { + expect(wrapper.find('b').text()).toEqual('Matt') + }) + }) + + describe('no userName', () => { + beforeEach(() => { + getters = { + 'auth/user': () => { + return { id: 'u343' } + }, + } + wrapper = Wrapper() + wrapper.find('.avatar-menu-trigger').trigger('click') + }) + + it('displays anonymous user', () => { + expect(wrapper.find('b').text()).toEqual('profile.userAnonym') + }) + }) + + describe('routes', () => { + beforeEach(() => { + getters = { + 'auth/user': () => { + return { id: 'u343', slug: 'matt' } + }, + 'auth/isModerator': () => false, + 'auth/isAdmin': () => false, + } + wrapper = Wrapper() + wrapper.find('.avatar-menu-trigger').trigger('click') + }) + + describe('role user', () => { + it('displays a link to user profile', () => { + const profileLink = wrapper.findAll('.ds-menu-item span').at(0) + expect(profileLink.attributes().to).toEqual('/profile/u343/matt') + }) + + it('displays a link to the notifications page', () => { + const notificationsLink = wrapper.findAll('.ds-menu-item span').at(2) + expect(notificationsLink.attributes().to).toEqual('/notifications') + }) + + it('displays a link to the settings page', () => { + const settingsLink = wrapper.findAll('.ds-menu-item span').at(4) + expect(settingsLink.attributes().to).toEqual('/settings') + }) + }) + + describe('role moderator', () => { + beforeEach(() => { + getters = { + 'auth/user': () => { + return { id: 'u343', slug: 'matt' } + }, + 'auth/isModerator': () => true, + 'auth/isAdmin': () => false, + } + wrapper = Wrapper() + wrapper.find('.avatar-menu-trigger').trigger('click') + }) + + it('displays a link to moderation page', () => { + const moderationLink = wrapper.findAll('.ds-menu-item span').at(6) + expect(moderationLink.attributes().to).toEqual('/moderation') + }) + }) + + describe('role admin', () => { + beforeEach(() => { + getters = { + 'auth/user': () => { + return { id: 'u343', slug: 'matt' } + }, + 'auth/isModerator': () => true, + 'auth/isAdmin': () => true, + } + wrapper = Wrapper() + wrapper.find('.avatar-menu-trigger').trigger('click') + }) + + it('displays a link to admin page', () => { + const adminLink = wrapper.findAll('.ds-menu-item span').at(8) + expect(adminLink.attributes().to).toEqual('/admin') + }) + }) + }) + }) +}) From f34c8f44e0b5fa816fd79a11dfc310c443a7aefe Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Tue, 29 Oct 2019 18:02:49 +0100 Subject: [PATCH 09/38] Update resolver for paginated notifications --- backend/src/schema/resolvers/notifications.js | 9 +++++---- backend/src/schema/types/type/NOTIFIED.gql | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/src/schema/resolvers/notifications.js b/backend/src/schema/resolvers/notifications.js index 4cab1ffc4..8fe45bde3 100644 --- a/backend/src/schema/resolvers/notifications.js +++ b/backend/src/schema/resolvers/notifications.js @@ -18,9 +18,8 @@ export default { notifications: async (_parent, args, context, _resolveInfo) => { const { user: currentUser } = context const session = context.driver.session() - let notifications - let whereClause - let orderByClause + let notifications, whereClause, orderByClause + switch (args.read) { case true: whereClause = 'WHERE notification.read = TRUE' @@ -41,13 +40,15 @@ export default { default: orderByClause = '' } - + const offset = args.offset ? `SKIP ${args.offset}` : '' + const limit = args.first ? `LIMIT ${args.first}` : '' try { const cypher = ` MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED]->(user:User {id:$id}) ${whereClause} RETURN resource, notification, user ${orderByClause} + ${offset} ${limit} ` const result = await session.run(cypher, { id: currentUser.id }) notifications = await result.records.map(transformReturnType) diff --git a/backend/src/schema/types/type/NOTIFIED.gql b/backend/src/schema/types/type/NOTIFIED.gql index 5082b5f7f..42da6a39b 100644 --- a/backend/src/schema/types/type/NOTIFIED.gql +++ b/backend/src/schema/types/type/NOTIFIED.gql @@ -23,7 +23,7 @@ enum NotificationReason { } type Query { - notifications(read: Boolean, orderBy: NotificationOrdering): [NOTIFIED] + notifications(read: Boolean, orderBy: NotificationOrdering, first: Int, offset: Int): [NOTIFIED] } type Mutation { From 084388a21ec669607bdb6245963dc011c523e142 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Tue, 29 Oct 2019 18:04:51 +0100 Subject: [PATCH 10/38] Follow new file structure - avoid nested directories --- webapp/components/{ => Empty}/Empty.vue | 0 webapp/layouts/default.vue | 2 +- webapp/pages/admin/notifications.vue | 2 +- webapp/pages/admin/organizations.vue | 2 +- webapp/pages/admin/pages.vue | 2 +- webapp/pages/admin/settings.vue | 2 +- webapp/pages/index.vue | 2 +- webapp/pages/moderation/index.vue | 2 +- webapp/pages/post/_id/_slug/more-info.vue | 2 +- webapp/pages/post/_id/_slug/take-action.vue | 2 +- webapp/pages/profile/_id/_slug.vue | 2 +- webapp/pages/registration/signup.vue | 2 +- webapp/pages/settings/data-download.vue | 2 +- webapp/pages/settings/invites.vue | 2 +- webapp/pages/settings/languages.vue | 2 +- webapp/pages/settings/my-organizations.vue | 2 +- 16 files changed, 15 insertions(+), 15 deletions(-) rename webapp/components/{ => Empty}/Empty.vue (100%) diff --git a/webapp/components/Empty.vue b/webapp/components/Empty/Empty.vue similarity index 100% rename from webapp/components/Empty.vue rename to webapp/components/Empty/Empty.vue diff --git a/webapp/layouts/default.vue b/webapp/layouts/default.vue index 7a95ada76..a39e0a148 100644 --- a/webapp/layouts/default.vue +++ b/webapp/layouts/default.vue @@ -98,7 +98,7 @@ import { mapGetters, mapActions } from 'vuex' import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch' import SearchInput from '~/components/SearchInput.vue' import Modal from '~/components/Modal' -import NotificationMenu from '~/components/notifications/NotificationMenu/NotificationMenu' +import NotificationMenu from '~/components/NotificationMenu/NotificationMenu' import seo from '~/mixins/seo' import FilterPosts from '~/components/FilterPosts/FilterPosts.vue' import CategoryQuery from '~/graphql/CategoryQuery.js' diff --git a/webapp/pages/admin/notifications.vue b/webapp/pages/admin/notifications.vue index 0d348633f..faad87a46 100644 --- a/webapp/pages/admin/notifications.vue +++ b/webapp/pages/admin/notifications.vue @@ -5,7 +5,7 @@ diff --git a/webapp/graphql/User.js b/webapp/graphql/User.js index 5a4b18b6a..7b2a012a4 100644 --- a/webapp/graphql/User.js +++ b/webapp/graphql/User.js @@ -51,8 +51,8 @@ export const notificationQuery = i18n => { ${commentFragment(lang)} ${postFragment(lang)} - query($read: Boolean, $orderBy: NotificationOrdering) { - notifications(read: $read, orderBy: $orderBy) { + query($read: Boolean, $orderBy: NotificationOrdering, $first: Int, $offset: Int) { + notifications(read: $read, orderBy: $orderBy, first: $first, offset: $offset) { read reason createdAt diff --git a/webapp/pages/notifications/index.vue b/webapp/pages/notifications/index.vue index 95d30df1a..5d22aa0b4 100644 --- a/webapp/pages/notifications/index.vue +++ b/webapp/pages/notifications/index.vue @@ -5,158 +5,52 @@ {{ $t('notifications.title') }} - - - - {{ selected }} - - - - - {{ item.route.label }} - - - + + + - - - - - - - + + diff --git a/webapp/components/NotificationsTable/NotificationsTable.vue b/webapp/components/NotificationsTable/NotificationsTable.vue new file mode 100644 index 000000000..8366ea5c5 --- /dev/null +++ b/webapp/components/NotificationsTable/NotificationsTable.vue @@ -0,0 +1,105 @@ + + + diff --git a/webapp/pages/notifications/index.vue b/webapp/pages/notifications/index.vue index 5d22aa0b4..9e2346061 100644 --- a/webapp/pages/notifications/index.vue +++ b/webapp/pages/notifications/index.vue @@ -103,8 +103,4 @@ export default { .sorting-dropdown { float: right; } -.notification-status { - opacity: 0.6; /* Real browsers */ - filter: alpha(opacity = 60); /* MSIE */ -} From b916c9fe8308d58b0998993e13bd47008a6c024d Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Wed, 30 Oct 2019 12:26:05 +0100 Subject: [PATCH 13/38] Add portuguese translations Co-authored-by: ppelegrin <56610168+ppelegrin@users.noreply.github.com> --- webapp/locales/pt.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/webapp/locales/pt.json b/webapp/locales/pt.json index 0765ff465..8ff168b72 100644 --- a/webapp/locales/pt.json +++ b/webapp/locales/pt.json @@ -182,6 +182,25 @@ "hint": "O que você está pesquisando??", "failed": "Nada foi encontrado" }, + "notifications": { + "reason": { + "mentioned_in_post": "Mencinou você em um post …", + "mentioned_in_comment": "Mentionou você em um comentário …", + "commented_on_post": "Comentou no seu post …" + }, + "comment": "Comentário", + "title": "Notificações", + "pageLink": "Todas as notificações", + "post": "Post", + "user": "Usuário", + "content": "Conteúdo", + "sortingLabel": { + "all": "Todos", + "read": "Lido", + "unread": "Não lido" + }, + "empty": "Desculpe, não tem nenhuma notificação neste momento." + }, "settings": { "name": "Configurações", "data": { From aabaa2e637db5eb815c1476f0ae2ddb94c13368b Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Wed, 30 Oct 2019 13:37:30 +0100 Subject: [PATCH 14/38] Fix typo Co-authored-by: Alina Beck --- webapp/components/Paginate/Paginate.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webapp/components/Paginate/Paginate.spec.js b/webapp/components/Paginate/Paginate.spec.js index 36e22d1b4..034d33301 100644 --- a/webapp/components/Paginate/Paginate.spec.js +++ b/webapp/components/Paginate/Paginate.spec.js @@ -20,6 +20,7 @@ describe('Paginate.vue', () => { beforeEach(() => { wrapper = Wrapper() }) + describe('next button', () => { beforeEach(() => { propsData.hasNext = true @@ -38,7 +39,7 @@ describe('Paginate.vue', () => { expect(nextButton.attributes().disabled).toBeUndefined() }) - it('emits back when clicked', async () => { + it('emits next when clicked', async () => { await nextButton.trigger('click') expect(wrapper.emitted().next).toHaveLength(1) }) From a1af4f5037f0d5445328385946a4f59d1e73a39f Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Wed, 30 Oct 2019 13:38:17 +0100 Subject: [PATCH 15/38] Add storybook notes Co-authored-by: @alina-beck --- webapp/package.json | 1 + webapp/storybook/addons.js | 1 + webapp/yarn.lock | 140 +++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) diff --git a/webapp/package.json b/webapp/package.json index 4e63bb3d6..649788ac7 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -97,6 +97,7 @@ "@babel/preset-env": "~7.7.1", "@storybook/addon-a11y": "^5.2.5", "@storybook/addon-actions": "^5.2.5", + "@storybook/addon-notes": "^5.2.5", "@storybook/vue": "~5.2.5", "@vue/cli-shared-utils": "~4.0.5", "@vue/eslint-config-prettier": "~5.0.0", diff --git a/webapp/storybook/addons.js b/webapp/storybook/addons.js index 44a5acb23..47c4cbd22 100644 --- a/webapp/storybook/addons.js +++ b/webapp/storybook/addons.js @@ -1,4 +1,5 @@ import '@storybook/addon-actions/register' import '@storybook/addon-a11y/register' import 'storybook-design-token/register' +import '@storybook/addon-notes/register-panel' // import '@storybook/addon-links/register' diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 712696431..ef0decedc 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -2113,6 +2113,25 @@ react-inspector "^3.0.2" uuid "^3.3.2" +"@storybook/addon-notes@^5.2.5": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/addon-notes/-/addon-notes-5.2.6.tgz#bf74ff4f8018e315a4c07c3d5e90cd9154ce6e8e" + integrity sha512-CfWOkoPFI1ZAWQYnwFVqGmeCeXnVQGoFyDSVc3NcIFF1lsk2aagGV+ifJMJuDTXIKu0FClKpvMcENWt+bBpA+w== + dependencies: + "@storybook/addons" "5.2.6" + "@storybook/api" "5.2.6" + "@storybook/client-logger" "5.2.6" + "@storybook/components" "5.2.6" + "@storybook/core-events" "5.2.6" + "@storybook/router" "5.2.6" + "@storybook/theming" "5.2.6" + core-js "^3.0.1" + global "^4.3.2" + markdown-to-jsx "^6.10.3" + memoizerific "^1.11.3" + prop-types "^15.7.2" + util-deprecate "^1.0.2" + "@storybook/addons@5.1.9": version "5.1.9" resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.1.9.tgz#ecf218d08508b97ca5e6e0f1ed361081385bd3ff" @@ -2138,6 +2157,19 @@ global "^4.3.2" util-deprecate "^1.0.2" +"@storybook/addons@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.2.6.tgz#c1278137acb3502e068b0b0d07a8371c607e9c02" + integrity sha512-5MF64lsAhIEMxTbVpYROz5Wez595iwSw45yXyP8gWt12d+EmFO5tdy7cYJCxcMuVhDfaCI78tFqS9orr1atVyA== + dependencies: + "@storybook/api" "5.2.6" + "@storybook/channels" "5.2.6" + "@storybook/client-logger" "5.2.6" + "@storybook/core-events" "5.2.6" + core-js "^3.0.1" + global "^4.3.2" + util-deprecate "^1.0.2" + "@storybook/api@5.1.9": version "5.1.9" resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.1.9.tgz#eec5b2f775392ce0803930104c6ce14fa4931e8b" @@ -2184,6 +2216,29 @@ telejson "^3.0.2" util-deprecate "^1.0.2" +"@storybook/api@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.2.6.tgz#43d3c20b90e585e6c94b36e29845d39704ae2135" + integrity sha512-X/di44/SAL68mD6RHTX2qdWwhjRW6BgcfPtu0dMd38ErB3AfsfP4BITXs6kFOeSM8kWiaQoyuw0pOBzA8vlYug== + dependencies: + "@storybook/channels" "5.2.6" + "@storybook/client-logger" "5.2.6" + "@storybook/core-events" "5.2.6" + "@storybook/router" "5.2.6" + "@storybook/theming" "5.2.6" + core-js "^3.0.1" + fast-deep-equal "^2.0.1" + global "^4.3.2" + lodash "^4.17.15" + memoizerific "^1.11.3" + prop-types "^15.6.2" + react "^16.8.3" + semver "^6.0.0" + shallow-equal "^1.1.0" + store2 "^2.7.1" + telejson "^3.0.2" + util-deprecate "^1.0.2" + "@storybook/channel-postmessage@5.2.5": version "5.2.5" resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.2.5.tgz#47397e543a87ea525cbe93f7d85bd8533edc9127" @@ -2209,6 +2264,13 @@ dependencies: core-js "^3.0.1" +"@storybook/channels@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.2.6.tgz#e2837508864dc4d5b5e03f078886f0ce113762ea" + integrity sha512-/UsktYsXuvb1efjVPCEivhh5ywRhm7hl73pQnpJLJHRqyLMM2I5nGPFELTTNuU9yWy7sP9QL5gRqBBPe1sqjZQ== + dependencies: + core-js "^3.0.1" + "@storybook/client-api@5.2.5": version "5.2.5" resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.2.5.tgz#53151a236b6ffc2088acc4535a08e010013e3278" @@ -2244,6 +2306,13 @@ dependencies: core-js "^3.0.1" +"@storybook/client-logger@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.2.6.tgz#cfc4536e9b724b086f7509c2bb34c221016713c9" + integrity sha512-hJvPD267cCwLIRMOISjDH8h9wbwOcXIJip29UlJbU9iMtZtgE+YelmlpmZJvqcDfUiXWWrOh7tP76mj8EAfwIQ== + dependencies: + core-js "^3.0.1" + "@storybook/components@5.1.9": version "5.1.9" resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.1.9.tgz#2a5258780fff07172d103287759946dbb4b13e2d" @@ -2293,6 +2362,31 @@ react-textarea-autosize "^7.1.0" simplebar-react "^1.0.0-alpha.6" +"@storybook/components@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.2.6.tgz#cddb60227720aea7cae34fe782d0370bcdbd4005" + integrity sha512-C7OS90bZ1ZvxlWUZ3B2MPFFggqAtUo7X8DqqS3IwsuDUiK9dD/KS0MwPgOuFDnOTW1R5XqmQd/ylt53w3s/U5g== + dependencies: + "@storybook/client-logger" "5.2.6" + "@storybook/theming" "5.2.6" + "@types/react-syntax-highlighter" "10.1.0" + "@types/react-textarea-autosize" "^4.3.3" + core-js "^3.0.1" + global "^4.3.2" + markdown-to-jsx "^6.9.1" + memoizerific "^1.11.3" + polished "^3.3.1" + popper.js "^1.14.7" + prop-types "^15.7.2" + react "^16.8.3" + react-dom "^16.8.3" + react-focus-lock "^1.18.3" + react-helmet-async "^1.0.2" + react-popper-tooltip "^2.8.3" + react-syntax-highlighter "^8.0.1" + react-textarea-autosize "^7.1.0" + simplebar-react "^1.0.0-alpha.6" + "@storybook/core-events@5.1.9": version "5.1.9" resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.1.9.tgz#441a6297e2ccfa743e15d1db1f4ac445b91f40d8" @@ -2307,6 +2401,13 @@ dependencies: core-js "^3.0.1" +"@storybook/core-events@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.2.6.tgz#34c9aae256e7e5f4a565b81f1e77dda8bccc6752" + integrity sha512-W8kLJ7tc0aAxs11CPUxUOCReocKL4MYGyjTg8qwk0USLzPUb/FUQWmhcm2ilFz6Nz8dXLcKrXdRVYTmiMsgAeg== + dependencies: + core-js "^3.0.1" + "@storybook/core@5.2.5": version "5.2.5" resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.2.5.tgz#cc04313480a1847aa6881420c675517cc400dc2e" @@ -2416,6 +2517,19 @@ memoizerific "^1.11.3" qs "^6.6.0" +"@storybook/router@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.2.6.tgz#5180d3785501699283c6c3717986c877f84fead5" + integrity sha512-/FZd3fYg5s2QzOqSIP8UMOSnCIFFIlli/jKlOxvm3WpcpxgwQOY4lfHsLO+r9ThCLs2UvVg2R/HqGrOHqDFU7A== + dependencies: + "@reach/router" "^1.2.1" + "@types/reach__router" "^1.2.3" + core-js "^3.0.1" + global "^4.3.2" + lodash "^4.17.15" + memoizerific "^1.11.3" + qs "^6.6.0" + "@storybook/theming@5.1.9": version "5.1.9" resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.1.9.tgz#c425f5867fae0db79e01112853b1808332a5f1a2" @@ -2452,6 +2566,24 @@ prop-types "^15.7.2" resolve-from "^5.0.0" +"@storybook/theming@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.2.6.tgz#e04170b3e53dcfc791b2381c8a39192ae88cd291" + integrity sha512-Xa9R/H8DDgmvxsCHloJUJ2d9ZQl80AeqHrL+c/AKNpx05s9lV74DcinusCf0kz72YGUO/Xt1bAjuOvLnAaS8Gw== + dependencies: + "@emotion/core" "^10.0.14" + "@emotion/styled" "^10.0.14" + "@storybook/client-logger" "5.2.6" + common-tags "^1.8.0" + core-js "^3.0.1" + deep-object-diff "^1.1.0" + emotion-theming "^10.0.14" + global "^4.3.2" + memoizerific "^1.11.3" + polished "^3.3.1" + prop-types "^15.7.2" + resolve-from "^5.0.0" + "@storybook/ui@5.2.5": version "5.2.5" resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.2.5.tgz#0c2c67216e4c808e39cdb48301cafde81b77d074" @@ -10713,6 +10845,14 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +markdown-to-jsx@^6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.10.3.tgz#7f0946684acd321125ff2de7fd258a9b9c7c40b7" + integrity sha512-PSoUyLnW/xoW6RsxZrquSSz5eGEOTwa15H5eqp3enmrp8esmgDJmhzd6zmQ9tgAA9TxJzx1Hmf3incYU/IamoQ== + dependencies: + prop-types "^15.6.2" + unquote "^1.1.0" + markdown-to-jsx@^6.9.1, markdown-to-jsx@^6.9.3: version "6.10.2" resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.10.2.tgz#644f602b81d088f10aef1c3674874876146cf38b" From 3ae71544d6cd6912bf35ea692e0ff65d0ef251a8 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Wed, 30 Oct 2019 13:39:02 +0100 Subject: [PATCH 16/38] Add story for Empty component Co-authored-by: @alina-beck --- webapp/components/Empty/Empty.story.js | 24 ++++++++++++++++++++++++ webapp/components/Empty/Empty.vue | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 webapp/components/Empty/Empty.story.js diff --git a/webapp/components/Empty/Empty.story.js b/webapp/components/Empty/Empty.story.js new file mode 100644 index 000000000..44d241df7 --- /dev/null +++ b/webapp/components/Empty/Empty.story.js @@ -0,0 +1,24 @@ +import { storiesOf } from '@storybook/vue' +import { withA11y } from '@storybook/addon-a11y' +import HcEmpty from '~/components/Empty/Empty' +import helpers from '~/storybook/helpers' + +helpers.init() + +storiesOf('Empty', module) + .addDecorator(withA11y) + .addDecorator(helpers.layout) + .add( + 'tasks icon with message', + () => ({ + components: { HcEmpty }, + template: '', + }), + { + notes: "Possible icons include 'messages', 'events', 'alert', 'tasks', 'docs', and 'file'", + }, + ) + .add('default icon, no message', () => ({ + components: { HcEmpty }, + template: '', + })) diff --git a/webapp/components/Empty/Empty.vue b/webapp/components/Empty/Empty.vue index 8760a6e6f..ea99702b5 100644 --- a/webapp/components/Empty/Empty.vue +++ b/webapp/components/Empty/Empty.vue @@ -26,7 +26,7 @@ export default { */ icon: { type: String, - required: true, + default: 'alert', validator: value => { return value.match(/(messages|events|alert|tasks|docs|file)/) }, From 542647f4186780595a0d831158f20144526a8727 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Wed, 30 Oct 2019 14:40:02 +0100 Subject: [PATCH 17/38] Add NotificationsDropdownFilter story, refactor - rename incorrectly named varaibles - use filterOptions to remove unneccessary computed routes Co-authored-by: @alina-beck --- .../NotificationsDropdownFilter.story.js | 18 ++++++++++ .../NotificationsDropdownFilter.vue | 33 +++++++------------ webapp/locales/de.json | 2 +- webapp/locales/en.json | 2 +- webapp/locales/pt.json | 2 +- webapp/pages/notifications/index.vue | 6 ++-- 6 files changed, 35 insertions(+), 28 deletions(-) create mode 100644 webapp/components/NotificationsDropdownFilter/NotificationsDropdownFilter.story.js diff --git a/webapp/components/NotificationsDropdownFilter/NotificationsDropdownFilter.story.js b/webapp/components/NotificationsDropdownFilter/NotificationsDropdownFilter.story.js new file mode 100644 index 000000000..35724fe7e --- /dev/null +++ b/webapp/components/NotificationsDropdownFilter/NotificationsDropdownFilter.story.js @@ -0,0 +1,18 @@ +import { storiesOf } from '@storybook/vue' +import { withA11y } from '@storybook/addon-a11y' +import { action } from '@storybook/addon-actions' +import NotificationsDropdownFilter from '~/components/NotificationsDropdownFilter/NotificationsDropdownFilter' +import helpers from '~/storybook/helpers' + +helpers.init() + +storiesOf('NotificationsDropdownFilter', module) + .addDecorator(withA11y) + .addDecorator(helpers.layout) + .add('filter dropdown', () => ({ + components: { NotificationsDropdownFilter }, + methods: { + filterNotifications: action('filterNotifications'), + }, + template: '', + })) diff --git a/webapp/components/NotificationsDropdownFilter/NotificationsDropdownFilter.vue b/webapp/components/NotificationsDropdownFilter/NotificationsDropdownFilter.vue index b0d1deb7d..7c5e0a42a 100644 --- a/webapp/components/NotificationsDropdownFilter/NotificationsDropdownFilter.vue +++ b/webapp/components/NotificationsDropdownFilter/NotificationsDropdownFilter.vue @@ -1,5 +1,5 @@