From 43de19f68598622a4d34ccb3a2b415c37a21ad44 Mon Sep 17 00:00:00 2001 From: iamsivin Date: Fri, 9 Feb 2024 15:40:12 +0530 Subject: [PATCH] chore: Inbox view enhancements --- .../conversation/ConversationHeader.vue | 2 +- .../dashboard/i18n/locale/en/inbox.json | 1 - .../dashboard/routes/dashboard/Dashboard.vue | 24 +++------ .../conversation/conversation.routes.js | 4 +- .../routes/dashboard/inbox/InboxList.vue | 26 ++++----- .../routes/dashboard/inbox/InboxView.vue | 54 +++++++++++-------- .../dashboard/inbox/components/InboxCard.vue | 8 +-- .../inbox/components/InboxListHeader.vue | 37 +++++++++---- .../shared/mixins/resizeListenerMixin.js | 25 +++++++++ 9 files changed, 107 insertions(+), 74 deletions(-) create mode 100644 app/javascript/shared/mixins/resizeListenerMixin.js diff --git a/app/javascript/dashboard/components/widgets/conversation/ConversationHeader.vue b/app/javascript/dashboard/components/widgets/conversation/ConversationHeader.vue index 42172eb23..fa22e6e5a 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ConversationHeader.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ConversationHeader.vue @@ -129,7 +129,7 @@ export default { name, } = this.$route; if (this.isInboxView) { - return frontendURL(`accounts/${accountId}/inbox`); + return frontendURL(`accounts/${accountId}/inbox-view`); } return conversationListPageURL({ accountId, diff --git a/app/javascript/dashboard/i18n/locale/en/inbox.json b/app/javascript/dashboard/i18n/locale/en/inbox.json index dcac5459f..9627b134f 100644 --- a/app/javascript/dashboard/i18n/locale/en/inbox.json +++ b/app/javascript/dashboard/i18n/locale/en/inbox.json @@ -4,7 +4,6 @@ "TITLE": "Inbox", "DISPLAY_DROPDOWN": "Display", "LOADING": "Fetching notifications", - "EOF": "All notifications loaded 🎉", "404": "There are no active notifications in this group.", "NO_NOTIFICATIONS": "No notifications", "NOTE": "Notifications from all subscribed inboxes", diff --git a/app/javascript/dashboard/routes/dashboard/Dashboard.vue b/app/javascript/dashboard/routes/dashboard/Dashboard.vue index 2602c9764..18b341ce8 100644 --- a/app/javascript/dashboard/routes/dashboard/Dashboard.vue +++ b/app/javascript/dashboard/routes/dashboard/Dashboard.vue @@ -50,6 +50,7 @@ import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel.v import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel.vue'; import uiSettingsMixin from 'dashboard/mixins/uiSettings'; import wootConstants from 'dashboard/constants/globals'; +import resizeListenerMixin from 'shared/mixins/resizeListenerMixin'; export default { components: { @@ -61,7 +62,7 @@ export default { AddLabelModal, NotificationPanel, }, - mixins: [uiSettingsMixin], + mixins: [uiSettingsMixin, resizeListenerMixin], data() { return { showAccountModal: false, @@ -109,33 +110,20 @@ export default { }, mounted() { this.handleResize(); - window.addEventListener('resize', this.handleResize); bus.$on(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar); }, beforeDestroy() { - window.removeEventListener('resize', this.handleResize); bus.$off(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar); }, methods: { handleResize() { const { SMALL_SCREEN_BREAKPOINT, LAYOUT_TYPES } = wootConstants; - let throttled = false; - const delay = 150; - - if (throttled) { - return; + if (window.innerWidth <= SMALL_SCREEN_BREAKPOINT) { + this.displayLayoutType = LAYOUT_TYPES.EXPANDED; + } else { + this.displayLayoutType = LAYOUT_TYPES.CONDENSED; } - throttled = true; - - setTimeout(() => { - throttled = false; - if (window.innerWidth <= SMALL_SCREEN_BREAKPOINT) { - this.displayLayoutType = LAYOUT_TYPES.EXPANDED; - } else { - this.displayLayoutType = LAYOUT_TYPES.CONDENSED; - } - }, delay); }, toggleSidebar() { this.updateUISettings({ diff --git a/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js b/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js index 63a32d72b..2411acdbf 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js +++ b/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js @@ -15,12 +15,12 @@ export default { }, }, { - path: frontendURL('accounts/:accountId/inbox-view/:conversation_id'), + path: frontendURL('accounts/:accountId/inbox-view/:notification_id'), name: 'inbox_view_conversation', roles: ['administrator', 'agent'], component: InboxView, props: route => { - return { inboxId: 0, conversationId: route.params.conversation_id }; + return { inboxId: 0, notificationId: route.params.notification_id }; }, }, { diff --git a/app/javascript/dashboard/routes/dashboard/inbox/InboxList.vue b/app/javascript/dashboard/routes/dashboard/inbox/InboxList.vue index bb0f2e7df..c4d5d87e9 100644 --- a/app/javascript/dashboard/routes/dashboard/inbox/InboxList.vue +++ b/app/javascript/dashboard/routes/dashboard/inbox/InboxList.vue @@ -3,7 +3,11 @@ class="flex flex-col h-full w-full ltr:border-r border-slate-50 dark:border-slate-800/50" :class="isOnExpandedLayout ? '' : 'min-w-[360px] max-w-[360px]'" > - +
@@ -25,12 +31,6 @@ > {{ $t('INBOX.LIST.NO_NOTIFICATIONS') }}

-

- {{ $t('INBOX.LIST.EOF') }} -

n.primary_actor.id === Number(this.conversationId) - ); + return this.notifications.find(n => n.id === Number(this.notificationId)); + }, + conversationId() { + return this.activeNotification?.primary_actor.id; }, isInboxViewEnabled() { return this.$store.getters['accounts/isFeatureEnabledGlobally']( @@ -93,14 +100,14 @@ export default { ); }, showConversationList() { - return this.isOnExpandedLayout ? !this.conversationId : true; + return this.isOnExpandedLayout ? !this.notificationId : true; }, isFetchingInitialData() { return this.uiFlags.isFetching && !this.notifications.length; }, showInboxMessageView() { return ( - Boolean(this.conversationId) && + Boolean(this.notificationId) && Boolean(this.currentChat.id) && !this.isFetchingInitialData ); @@ -109,20 +116,11 @@ export default { return this.notifications?.length ?? 0; }, activeNotificationIndex() { - const conversationId = Number(this.conversationId); const notificationIndex = this.notifications.findIndex( - n => n.primary_actor.id === conversationId + n => n.id === Number(this.notificationId) ); return notificationIndex >= 0 ? notificationIndex + 1 : 0; }, - isOnExpandedLayout() { - const { - LAYOUT_TYPES: { CONDENSED }, - } = wootConstants; - const { conversation_display_type: conversationDisplayType = CONDENSED } = - this.uiSettings; - return conversationDisplayType !== CONDENSED; - }, isContactPanelOpen() { if (this.currentChat.id) { const { is_contact_sidebar_open: isContactSidebarOpen } = @@ -149,10 +147,19 @@ export default { }); } this.$store.dispatch('agents/get'); + this.handleResize(); }, methods: { + handleResize() { + const { SMALL_SCREEN_BREAKPOINT } = wootConstants; + if (window.innerWidth <= SMALL_SCREEN_BREAKPOINT) { + this.isOnExpandedLayout = true; + } else { + this.isOnExpandedLayout = false; + } + }, async fetchConversationById() { - if (!this.conversationId) return; + if (!this.notificationId || !this.conversationId) return; const chat = this.findConversation(); if (!chat) { await this.$store.dispatch('getConversation', this.conversationId); @@ -169,8 +176,9 @@ export default { }); }, findConversation() { - const conversationId = Number(this.conversationId); - return this.allConversation.find(c => c.id === conversationId); + return this.allConversation.find( + c => c.id === Number(this.conversationId) + ); }, navigateToConversation(activeIndex, direction) { const indexOffset = direction === 'next' ? 0 : -2; @@ -180,7 +188,7 @@ export default { id, primary_actor_id: primaryActorId, primary_actor_type: primaryActorType, - primary_actor: { id: conversationId, meta: { unreadCount } = {} }, + primary_actor: { meta: { unreadCount } = {} }, notification_type: notificationType, } = targetNotification; @@ -197,7 +205,7 @@ export default { this.$router.push({ name: 'inbox_view_conversation', - params: { conversation_id: conversationId }, + params: { notification_id: id }, }); } }, diff --git a/app/javascript/dashboard/routes/dashboard/inbox/components/InboxCard.vue b/app/javascript/dashboard/routes/dashboard/inbox/components/InboxCard.vue index 8e100f7b5..f61e8680d 100644 --- a/app/javascript/dashboard/routes/dashboard/inbox/components/InboxCard.vue +++ b/app/javascript/dashboard/routes/dashboard/inbox/components/InboxCard.vue @@ -166,11 +166,11 @@ export default { id, primary_actor_id: primaryActorId, primary_actor_type: primaryActorType, - primary_actor: { id: conversationId, inbox_id: inboxId }, + primary_actor: { inbox_id: inboxId }, notification_type: notificationType, } = notification; - if (this.$route.params.conversation_id !== conversationId) { + if (this.$route.params.notification_id !== id) { this.$track(INBOX_EVENTS.OPEN_CONVERSATION_VIA_INBOX, { notificationType, }); @@ -184,13 +184,14 @@ export default { this.$router.push({ name: 'inbox_view_conversation', - params: { inboxId, conversation_id: conversationId }, + params: { inboxId, notification_id: id }, }); } }, closeContextMenu() { this.isContextMenuOpen = false; this.contextMenuPosition = { x: null, y: null }; + this.$emit('context-menu-close'); }, openContextMenu(e) { this.closeContextMenu(); @@ -200,6 +201,7 @@ export default { y: e.pageY || e.clientY, }; this.isContextMenuOpen = true; + this.$emit('context-menu-open'); }, handleAction(key) { switch (key) { diff --git a/app/javascript/dashboard/routes/dashboard/inbox/components/InboxListHeader.vue b/app/javascript/dashboard/routes/dashboard/inbox/components/InboxListHeader.vue index 3f5a594b7..d7be310de 100644 --- a/app/javascript/dashboard/routes/dashboard/inbox/components/InboxListHeader.vue +++ b/app/javascript/dashboard/routes/dashboard/inbox/components/InboxListHeader.vue @@ -69,12 +69,29 @@ export default { InboxDisplayMenu, }, mixins: [clickaway, alertMixin], + props: { + isContextMenuOpen: { + type: Boolean, + default: false, + }, + }, data() { return { showInboxDisplayMenu: false, showInboxOptionMenu: false, }; }, + watch: { + isContextMenuOpen: { + handler(val) { + if (val) { + this.showInboxDisplayMenu = false; + this.showInboxOptionMenu = false; + } + }, + immediate: true, + }, + }, methods: { markAllRead() { this.$track(INBOX_EVENTS.MARK_ALL_NOTIFICATIONS_AS_READ); @@ -100,21 +117,19 @@ export default { }, onInboxOptionMenuClick(key) { this.showInboxOptionMenu = false; - if (key === 'mark_all_read') { - this.markAllRead(); - } - if (key === 'delete_all') { - this.deleteAll(); - } - if (key === 'delete_all_read') { - this.deleteAllRead(); - } + const actions = { + mark_all_read: () => this.markAllRead(), + delete_all: () => this.deleteAll(), + delete_all_read: () => this.deleteAllRead(), + }; + const action = actions[key]; + if (action) action(); + this.$emit('redirect'); }, onFilterChange(option) { this.$emit('filter', option); this.showInboxDisplayMenu = false; - if (this.$route.name === 'inbox_view') return; - this.$router.push({ name: 'inbox_view' }); + this.$emit('redirect'); }, }, }; diff --git a/app/javascript/shared/mixins/resizeListenerMixin.js b/app/javascript/shared/mixins/resizeListenerMixin.js new file mode 100644 index 000000000..ea8569e0c --- /dev/null +++ b/app/javascript/shared/mixins/resizeListenerMixin.js @@ -0,0 +1,25 @@ +export default { + mounted() { + window.addEventListener('resize', this.handleResize); + }, + beforeDestroy() { + window.removeEventListener('resize', this.onResizeHandler); + }, + methods: { + // Resize event for layout changes + onResizeHandler() { + let throttled = false; + const delay = 150; + + if (throttled) { + return; + } + throttled = true; + + setTimeout(() => { + throttled = false; + this.handleResize(); + }, delay); + }, + }, +};