From cd6c9a8fe9592f2f0a47184f38f8b535d8f9ffbb Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Thu, 27 Jan 2022 08:26:12 +0530 Subject: [PATCH] enhancement: Custom views (#3838) * enhancement: Custom views * Review fixes --- .../dashboard/components/ChatList.vue | 130 ++++++++------ .../layout/config/sidebarItems/contacts.js | 2 +- .../config/sidebarItems/conversations.js | 4 +- .../layout/sidebarComponents/Secondary.vue | 14 +- .../widgets/conversation/ConversationCard.vue | 4 +- app/javascript/dashboard/helper/URLHelper.js | 6 +- .../i18n/locale/en/advancedFilters.json | 20 ++- .../contacts/components/ContactsView.vue | 164 ++++++++++++------ .../dashboard/contacts/components/Header.vue | 22 ++- .../routes/dashboard/contacts/routes.js | 4 +- .../conversation/ConversationView.vue | 4 +- .../conversation/conversation.routes.js | 8 +- .../dashboard/customviews/AddCustomViews.vue | 16 +- .../customviews/DeleteCustomViews.vue | 22 ++- 14 files changed, 251 insertions(+), 169 deletions(-) diff --git a/app/javascript/dashboard/components/ChatList.vue b/app/javascript/dashboard/components/ChatList.vue index 03e5b68bc..4b951a705 100644 --- a/app/javascript/dashboard/components/ChatList.vue +++ b/app/javascript/dashboard/components/ChatList.vue @@ -3,7 +3,7 @@

{{ pageTitle }} @@ -11,17 +11,17 @@
-
+
-
+
@@ -59,21 +59,23 @@
view.id === Number(this.customViewsId) + activeFolder() { + if (this.foldersId) { + const activeView = this.folders.filter( + view => view.id === Number(this.foldersId) ); const [firstValue] = activeView; return firstValue; @@ -349,8 +349,10 @@ export default { conversationType() { this.resetAndFetchData(); }, - activeCustomView() { - this.resetAndFetchData(); + activeFolder() { + if (!this.hasAppliedFilters) { + this.resetAndFetchData(); + } }, }, mounted() { @@ -366,22 +368,22 @@ export default { if (this.$route.name !== 'home') { this.$router.push({ name: 'home' }); } - this.customViewsQuery = { payload: payload }; + this.foldersQuery = { payload: payload }; this.$store.dispatch('conversationPage/reset'); this.$store.dispatch('emptyAllConversations'); this.fetchFilteredConversations(payload); }, - onClickOpenAddCustomViewsModal() { - this.showAddCustomViewsModal = true; + onClickOpenAddFoldersModal() { + this.showAddFoldersModal = true; }, - onCloseAddCustomViewsModal() { - this.showAddCustomViewsModal = false; + onCloseAddFoldersModal() { + this.showAddFoldersModal = false; }, - onClickOpenDeleteCustomViewsModal() { - this.showDeleteCustomViewsModal = true; + onClickOpenDeleteFoldersModal() { + this.showDeleteFoldersModal = true; }, - onCloseDeleteCustomViewsModal() { - this.showDeleteCustomViewsModal = false; + onCloseDeleteFoldersModal() { + this.showDeleteFoldersModal = false; }, onToggleAdvanceFiltersModal() { this.showAdvancedFilters = !this.showAdvancedFilters; @@ -434,11 +436,11 @@ export default { this.$store.dispatch('conversationPage/reset'); this.$store.dispatch('emptyAllConversations'); this.$store.dispatch('clearConversationFilters'); - if (this.hasActiveCustomViews) { - const payload = this.activeCustomView.query; + if (this.hasActiveFolders) { + const payload = this.activeFolder.query; this.fetchSavedFilteredConversations(payload); } - if (this.customViewsId) { + if (this.foldersId) { return; } this.fetchConversations(); @@ -449,11 +451,11 @@ export default { .then(() => this.$emit('conversation-load')); }, loadMoreConversations() { - if (!this.hasAppliedFiltersOrActiveCustomViews) { + if (!this.hasAppliedFiltersOrActiveFolders) { this.fetchConversations(); } - if (this.hasActiveCustomViews) { - const payload = this.activeCustomView.query; + if (this.hasActiveFolders) { + const payload = this.activeFolder.query; this.fetchSavedFilteredConversations(payload); } else { this.fetchFilteredConversations(this.appliedFilters); @@ -493,6 +495,22 @@ export default { this.resetAndFetchData(); } }, + openLastSavedItemInFolder() { + const lastItemOfFolder = this.folders[this.folders.length - 1]; + const lastItemId = lastItemOfFolder.id; + this.$router.push({ + name: 'folder_conversations', + params: { id: lastItemId }, + }); + }, + openLastItemAfterDeleteInFolder() { + if (this.folders.length > 0) { + this.openLastSavedItemInFolder(); + } else { + this.$router.push({ name: 'home' }); + this.fetchConversations(); + } + }, }, }; diff --git a/app/javascript/dashboard/components/layout/config/sidebarItems/contacts.js b/app/javascript/dashboard/components/layout/config/sidebarItems/contacts.js index 723b3fbdf..d615bd15c 100644 --- a/app/javascript/dashboard/components/layout/config/sidebarItems/contacts.js +++ b/app/javascript/dashboard/components/layout/config/sidebarItems/contacts.js @@ -5,7 +5,7 @@ const contacts = accountId => ({ routes: [ 'contacts_dashboard', 'contact_profile_dashboard', - 'contacts_through_custom_view', + 'contacts_segments_dashboard', 'contacts_labels_dashboard', ], menuItems: [ diff --git a/app/javascript/dashboard/components/layout/config/sidebarItems/conversations.js b/app/javascript/dashboard/components/layout/config/sidebarItems/conversations.js index c19cc1846..596fdd8d1 100644 --- a/app/javascript/dashboard/components/layout/config/sidebarItems/conversations.js +++ b/app/javascript/dashboard/components/layout/config/sidebarItems/conversations.js @@ -14,8 +14,8 @@ const conversations = accountId => ({ 'conversations_through_team', 'conversation_mentions', 'conversation_through_mentions', - 'custom_view_conversations', - 'conversations_through_custom_view', + 'folder_conversations', + 'conversations_through_folders', ], menuItems: [ { diff --git a/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue b/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue index 9c41f9946..da14cf295 100644 --- a/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue +++ b/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue @@ -157,7 +157,7 @@ export default { })), }; }, - customViewsSection() { + foldersSection() { return { icon: 'folder', label: 'CUSTOM_VIEWS_FOLDER', @@ -175,7 +175,7 @@ export default { })), }; }, - contactCustomViewsSection() { + contactSegmentsSection() { return { icon: 'folder', label: 'CUSTOM_VIEWS_SEGMENTS', @@ -200,16 +200,10 @@ export default { conversationMenuItems = [this.teamSection, ...conversationMenuItems]; } if (this.customViews.length) { - conversationMenuItems = [ - this.customViewsSection, - ...conversationMenuItems, - ]; + conversationMenuItems = [this.foldersSection, ...conversationMenuItems]; } if (this.contactCustomViews.length) { - contactMenuItems = [ - this.contactCustomViewsSection, - ...contactMenuItems, - ]; + contactMenuItems = [this.contactSegmentsSection, ...contactMenuItems]; } return { conversations: conversationMenuItems, diff --git a/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue b/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue index 3e509eb9f..dc8cae554 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue @@ -130,7 +130,7 @@ export default { type: [String, Number], default: 0, }, - customViewsId: { + foldersId: { type: [String, Number], default: 0, }, @@ -252,7 +252,7 @@ export default { id: chat.id, label: this.activeLabel, teamId: this.teamId, - customViewsId: this.customViewsId, + foldersId: this.foldersId, conversationType: this.conversationType, }); router.push({ path: frontendURL(path) }); diff --git a/app/javascript/dashboard/helper/URLHelper.js b/app/javascript/dashboard/helper/URLHelper.js index 120d6f2de..503b98f8e 100644 --- a/app/javascript/dashboard/helper/URLHelper.js +++ b/app/javascript/dashboard/helper/URLHelper.js @@ -12,7 +12,7 @@ export const conversationUrl = ({ label, teamId, conversationType = '', - customViewsId, + foldersId, }) => { let url = `accounts/${accountId}/conversations/${id}`; if (activeInbox) { @@ -21,8 +21,8 @@ export const conversationUrl = ({ url = `accounts/${accountId}/label/${label}/conversations/${id}`; } else if (teamId) { url = `accounts/${accountId}/team/${teamId}/conversations/${id}`; - } else if (customViewsId && customViewsId !== 0) { - url = `accounts/${accountId}/custom_view/${customViewsId}/conversations/${id}`; + } else if (foldersId && foldersId !== 0) { + url = `accounts/${accountId}/custom_view/${foldersId}/conversations/${id}`; } else if (conversationType === 'mention') { url = `accounts/${accountId}/mentions/conversations/${id}`; } diff --git a/app/javascript/dashboard/i18n/locale/en/advancedFilters.json b/app/javascript/dashboard/i18n/locale/en/advancedFilters.json index 492c27620..5ab31027a 100644 --- a/app/javascript/dashboard/i18n/locale/en/advancedFilters.json +++ b/app/javascript/dashboard/i18n/locale/en/advancedFilters.json @@ -41,9 +41,13 @@ "ERROR_MESSAGE": "Name is required", "SAVE_BUTTON": "Save filter", "CANCEL_BUTTON": "Cancel", - "API": { - "SUCCESS_MESSAGE": "Custom view created successfully", - "ERROR_MESSAGE": "Error while creating custom view" + "API_FOLDERS": { + "SUCCESS_MESSAGE": "Folder created successfully", + "ERROR_MESSAGE": "Error while creating folder" + }, + "API_SEGMENTS": { + "SUCCESS_MESSAGE": "Segment created successfully", + "ERROR_MESSAGE": "Error while creating segment" } }, "DELETE": { @@ -56,9 +60,13 @@ "NO": "No, Keep it" } }, - "API": { - "SUCCESS_MESSAGE": "Custom view deleted successfully", - "ERROR_MESSAGE": "Error while deleting custom view" + "API_FOLDERS": { + "SUCCESS_MESSAGE": "Folder deleted successfully", + "ERROR_MESSAGE": "Error while deleting folder" + }, + "API_SEGMENTS": { + "SUCCESS_MESSAGE": "Segment deleted successfully", + "ERROR_MESSAGE": "Error while deleting segment" } } } diff --git a/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue b/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue index 39bc16b08..b0801935f 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue +++ b/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue @@ -3,7 +3,7 @@
view.id === Number(this.customViewsId) + activeSegment() { + if (this.segmentsId) { + const [firstValue] = this.segments.filter( + view => view.id === Number(this.segmentsId) ); return firstValue; } @@ -189,11 +197,17 @@ export default { watch: { label() { this.fetchContacts(DEFAULT_PAGE); + if (this.hasAppliedFilters) { + this.clearFilters(); + } }, - activeCustomView() { - if (this.hasActiveCustomViews) { - const payload = this.activeCustomView.query; - this.fetchSavedFilteredContact(payload); + activeSegment() { + if (this.hasActiveSegments) { + const payload = this.activeSegment.query; + this.fetchSavedFilteredContact(payload, DEFAULT_PAGE); + } + if (this.hasAppliedFilters && this.$route.name === 'contacts_dashboard') { + this.fetchFilteredContacts(DEFAULT_PAGE); } else { this.fetchContacts(DEFAULT_PAGE); } @@ -222,35 +236,49 @@ export default { return sortAttr; }, fetchContacts(page) { - this.updatePageParam(page); - let value = ''; - if (this.searchQuery.charAt(0) === '+') { - value = this.searchQuery.substring(1); - } else { - value = this.searchQuery; + if (this.isContactAndLabelDashboard) { + this.updatePageParam(page); + let value = ''; + if (this.searchQuery.charAt(0) === '+') { + value = this.searchQuery.substring(1); + } else { + value = this.searchQuery; + } + const requestParams = { + page, + sortAttr: this.getSortAttribute(), + label: this.label, + }; + if (!value) { + this.$store.dispatch('contacts/get', requestParams); + } else { + this.$store.dispatch('contacts/search', { + search: value, + ...requestParams, + }); + } } - const requestParams = { - page, - sortAttr: this.getSortAttribute(), - label: this.label, - }; - if (!value) { - this.$store.dispatch('contacts/get', requestParams); - } else { - this.$store.dispatch('contacts/search', { - search: value, - ...requestParams, + }, + fetchSavedFilteredContact(payload, page) { + if (this.hasActiveSegments) { + this.updatePageParam(page); + this.$store.dispatch('contacts/filter', { + queryPayload: payload, + page, }); } }, - fetchSavedFilteredContact(payload) { + fetchFilteredContacts(page) { if (this.hasAppliedFilters) { - this.clearFilters(); + const payload = this.segmentsQuery; + this.updatePageParam(page); + this.$store.dispatch('contacts/filter', { + queryPayload: payload, + page, + }); } - this.$store.dispatch('contacts/filter', { - queryPayload: payload, - }); }, + onInputSearch(event) { const newQuery = event.target.value; const refetchAllContacts = !!this.searchQuery && newQuery === ''; @@ -267,7 +295,15 @@ export default { }, onPageChange(page) { this.selectedContactId = ''; - this.fetchContacts(page); + if (this.segmentsId !== 0) { + const payload = this.activeSegment.query; + this.fetchSavedFilteredContact(payload, page); + } + if (this.hasAppliedFilters) { + this.fetchFilteredContacts(page); + } else { + this.fetchContacts(page); + } }, openContactInfoPanel(contactId) { this.selectedContactId = contactId; @@ -281,16 +317,16 @@ export default { this.showCreateModal = !this.showCreateModal; }, onToggleSaveFilters() { - this.showAddCustomViewsModal = true; + this.showAddSegmentsModal = true; }, - onCloseAddCustomViewsModal() { - this.showAddCustomViewsModal = false; + onCloseAddSegmentsModal() { + this.showAddSegmentsModal = false; }, onToggleDeleteFilters() { - this.showDeleteCustomViewsModal = true; + this.showDeleteSegmentsModal = true; }, - onCloseDeleteCustomViewsModal() { - this.showDeleteCustomViewsModal = false; + onCloseDeleteSegmentsModal() { + this.showDeleteSegmentsModal = false; }, onToggleImport() { this.showImportModal = !this.showImportModal; @@ -304,7 +340,7 @@ export default { }, onApplyFilter(payload) { this.closeContactInfoPanel(); - this.customViewsQuery = { payload }; + this.segmentsQuery = { payload }; this.$store.dispatch('contacts/filter', { queryPayload: filterQueryGenerator(payload), }); @@ -314,6 +350,22 @@ export default { this.$store.dispatch('contacts/clearContactFilters'); this.fetchContacts(this.pageParameter); }, + openSavedItemInSegment() { + const lastItemInSegments = this.segments[this.segments.length - 1]; + const lastItemId = lastItemInSegments.id; + this.$router.push({ + name: 'contacts_segments_dashboard', + params: { id: lastItemId }, + }); + }, + openLastItemAfterDeleteInSegment() { + if (this.segments.length > 0) { + this.openSavedItemInSegment(); + } else { + this.$router.push({ name: 'contacts_dashboard' }); + this.fetchContacts(DEFAULT_PAGE); + } + }, }, }; diff --git a/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue b/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue index 3006f43ca..9a9e670b1 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue +++ b/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue @@ -26,18 +26,16 @@ {{ $t('CONTACTS_PAGE.SEARCH_BUTTON') }}
- {{ $t('CONTACTS_PAGE.FILTER_CONTACTS_DELETE') }} - -
+
{{ $t('CONTACTS_PAGE.FILTER_CONTACTS_SAVE') }} @@ -96,7 +94,7 @@ export default { type: String, default: '', }, - customViewsId: { + segmentsId: { type: [String, Number], default: 0, }, @@ -137,15 +135,15 @@ export default { hasAppliedFilters() { return this.getAppliedContactFilters.length; }, - hasActiveCustomViews() { - return this.customViewsId !== 0; + hasActiveSegments() { + return this.segmentsId !== 0; }, }, methods: { - onToggleCustomViewsModal() { + onToggleSegmentsModal() { this.$emit('on-toggle-save-filter'); }, - onToggleDeleteCustomViewsModal() { + onToggleDeleteSegmentsModal() { this.$emit('on-toggle-delete-filter'); }, }, diff --git a/app/javascript/dashboard/routes/dashboard/contacts/routes.js b/app/javascript/dashboard/routes/dashboard/contacts/routes.js index 0901489bf..9734c88e2 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/routes.js +++ b/app/javascript/dashboard/routes/dashboard/contacts/routes.js @@ -12,11 +12,11 @@ export const routes = [ }, { path: frontendURL('accounts/:accountId/contacts/custom_view/:id'), - name: 'contacts_through_custom_view', + name: 'contacts_segments_dashboard', roles: ['administrator', 'agent'], component: ContactsView, props: route => { - return { customViewsId: route.params.id }; + return { segmentsId: route.params.id }; }, }, { diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue b/app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue index b1a88223d..7c34b4fb1 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue @@ -5,7 +5,7 @@ :label="label" :team-id="teamId" :conversation-type="conversationType" - :custom-views-id="customViewsId" + :folders-id="foldersId" @conversation-load="onConversationLoad" > @@ -55,7 +55,7 @@ export default { type: String, default: '', }, - customViewsId: { + foldersId: { type: [String, Number], default: 0, }, diff --git a/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js b/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js index 45e05b489..ebd219a2f 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js +++ b/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js @@ -85,21 +85,21 @@ export default { }, { path: frontendURL('accounts/:accountId/custom_view/:id'), - name: 'custom_view_conversations', + name: 'folder_conversations', roles: ['administrator', 'agent'], component: ConversationView, - props: route => ({ customViewsId: route.params.id }), + props: route => ({ foldersId: route.params.id }), }, { path: frontendURL( 'accounts/:accountId/custom_view/:id/conversations/:conversation_id' ), - name: 'conversations_through_custom_view', + name: 'conversations_through_folders', roles: ['administrator', 'agent'], component: ConversationView, props: route => ({ conversationId: route.params.conversation_id, - customViewsId: route.params.id, + foldersId: route.params.id, }), }, { diff --git a/app/javascript/dashboard/routes/dashboard/customviews/AddCustomViews.vue b/app/javascript/dashboard/routes/dashboard/customviews/AddCustomViews.vue index 319dbab24..37e532e02 100644 --- a/app/javascript/dashboard/routes/dashboard/customviews/AddCustomViews.vue +++ b/app/javascript/dashboard/routes/dashboard/customviews/AddCustomViews.vue @@ -43,6 +43,10 @@ export default { type: Object, default: () => {}, }, + openLastSavedItem: { + type: Function, + default: () => {}, + }, }, data() { @@ -80,17 +84,21 @@ export default { filter_type: this.filterType, query: this.customViewsQuery, }); - this.alertMessage = this.$t( - 'FILTER.CUSTOM_VIEWS.ADD.API.SUCCESS_MESSAGE' - ); + this.alertMessage = + this.filterType === 0 + ? this.$t('FILTER.CUSTOM_VIEWS.ADD.API_FOLDERS.SUCCESS_MESSAGE') + : this.$t('FILTER.CUSTOM_VIEWS.ADD.API_SEGMENTS.SUCCESS_MESSAGE'); this.onClose(); } catch (error) { const errorMessage = error?.message; this.alertMessage = - errorMessage || this.$t('FILTER.CUSTOM_VIEWS.ADD.API.ERROR_MESSAGE'); + errorMessage || this.filterType === 0 + ? this.$t('FILTER.CUSTOM_VIEWS.ADD.API_FOLDERS.ERROR_MESSAGE') + : this.$t('FILTER.CUSTOM_VIEWS.ADD.API_SEGMENTS.ERROR_MESSAGE'); } finally { this.showAlert(this.alertMessage); } + this.openLastSavedItem(); }, }, }; diff --git a/app/javascript/dashboard/routes/dashboard/customviews/DeleteCustomViews.vue b/app/javascript/dashboard/routes/dashboard/customviews/DeleteCustomViews.vue index 6d01e387c..547cdddf4 100644 --- a/app/javascript/dashboard/routes/dashboard/customviews/DeleteCustomViews.vue +++ b/app/javascript/dashboard/routes/dashboard/customviews/DeleteCustomViews.vue @@ -34,6 +34,10 @@ export default { type: Number, default: 0, }, + openLastItemAfterDelete: { + type: Function, + default: () => {}, + }, }, computed: { @@ -75,20 +79,20 @@ export default { await this.$store.dispatch('customViews/delete', { id, filterType }); this.closeDeletePopup(); this.showAlert( - this.$t('FILTER.CUSTOM_VIEWS.DELETE.API.SUCCESS_MESSAGE') + this.activeFilterType === 0 + ? this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_FOLDERS.SUCCESS_MESSAGE') + : this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_SEGMENTS.SUCCESS_MESSAGE') ); } catch (error) { const errorMessage = - error?.response?.message || - this.$t('FILTER.CUSTOM_VIEWS.DELETE.API.ERROR_MESSAGE'); + error?.response?.message || this.activeFilterType === 0 + ? this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_FOLDERS.SUCCESS_MESSAGE') + : this.$t( + 'FILTER.CUSTOM_VIEWS.DELETE.API_SEGMENTS.SUCCESS_MESSAGE' + ); this.showAlert(errorMessage); } - if (this.isFolderSection) { - this.$router.push({ name: 'home' }); - } - if (this.isSegmentSection) { - this.$router.push({ name: 'contacts_dashboard' }); - } + this.openLastItemAfterDelete(); }, closeDeletePopup() { this.$emit('close');