From 5c3de5e0957bf1447a98dd92906e582bc6246cee Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Wed, 11 Nov 2020 16:02:14 +0530 Subject: [PATCH] fix: Enhance CRM UI (#1397) * feat: Sort by name * feat: Fetch labels from sidebar * Remove unused language file * Add beta tag to contacts * Add timeMixin, reduce font-size * Remove unused methods * Remove unused prop * Disabled footer if no contacts or invalid page * Add keyup for input * Fix conversation not loading if there are no active conversations * return last_seen_at as unix time * Fix contact edit modal * Add loader for edit contact button * Fix review comments --- .../api/v1/accounts/contacts_controller.rb | 15 ++++++---- .../dashboard/components/layout/Sidebar.vue | 1 + .../dashboard/i18n/locale/en/contact.json | 3 +- .../i18n/locale/en/contactsPage.json | 21 -------------- .../dashboard/i18n/locale/en/settings.json | 2 +- .../contacts/components/ContactsTable.vue | 24 ++++++++------- .../contacts/components/ContactsView.vue | 29 +++++++------------ .../dashboard/contacts/components/Footer.vue | 25 ++++++++++------ .../dashboard/contacts/components/Header.vue | 1 + .../conversation/ConversationView.vue | 3 +- .../conversation/contact/ContactInfo.vue | 1 + .../conversation/contact/EditContact.vue | 14 ++++++++- .../api/v1/models/_contact.json.jbuilder | 2 +- 13 files changed, 72 insertions(+), 69 deletions(-) delete mode 100644 app/javascript/dashboard/i18n/locale/en/contactsPage.json diff --git a/app/controllers/api/v1/accounts/contacts_controller.rb b/app/controllers/api/v1/accounts/contacts_controller.rb index c1e90d957..d476c744c 100644 --- a/app/controllers/api/v1/accounts/contacts_controller.rb +++ b/app/controllers/api/v1/accounts/contacts_controller.rb @@ -7,16 +7,14 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController before_action :fetch_contact, only: [:show, :update] def index - contacts = Current.account.contacts.where.not(email: [nil, '']).or(Current.account.contacts.where.not(phone_number: [nil, ''])) - @contacts_count = contacts.count - @contacts = fetch_contact_last_seen_at(contacts) + @contacts_count = resolved_contacts.count + @contacts = fetch_contact_last_seen_at(resolved_contacts) end def search render json: { error: 'Specify search string with parameter q' }, status: :unprocessable_entity if params[:q].blank? && return - contacts = Current.account.contacts.where.not(email: [nil, '']).or(Current.account.contacts.where.not(phone_number: [nil, ''])) - .where('name LIKE :search OR email LIKE :search', search: "%#{params[:q]}%") + contacts = resolved_contacts.where('name LIKE :search OR email LIKE :search', search: "%#{params[:q]}%") @contacts_count = contacts.count @contacts = fetch_contact_last_seen_at(contacts) end @@ -53,6 +51,13 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController private + def resolved_contacts + @resolved_contacts ||= Current.account.contacts + .where.not(email: [nil, '']) + .or(Current.account.contacts.where.not(phone_number: [nil, ''])) + .order('LOWER(name)') + end + def set_current_page @current_page = params[:page] || 1 end diff --git a/app/javascript/dashboard/components/layout/Sidebar.vue b/app/javascript/dashboard/components/layout/Sidebar.vue index 77b12d9f8..1357ff104 100644 --- a/app/javascript/dashboard/components/layout/Sidebar.vue +++ b/app/javascript/dashboard/components/layout/Sidebar.vue @@ -286,6 +286,7 @@ export default { }, }, mounted() { + this.$store.dispatch('labels/get'); this.$store.dispatch('inboxes/get'); }, methods: { diff --git a/app/javascript/dashboard/i18n/locale/en/contact.json b/app/javascript/dashboard/i18n/locale/en/contact.json index 3dab6ac0b..684a56ee5 100644 --- a/app/javascript/dashboard/i18n/locale/en/contact.json +++ b/app/javascript/dashboard/i18n/locale/en/contact.json @@ -108,8 +108,7 @@ "Phone Number", "Conversations", "Last Contacted" - ], - "EDIT_BUTTON": "Edit" + ] } } } diff --git a/app/javascript/dashboard/i18n/locale/en/contactsPage.json b/app/javascript/dashboard/i18n/locale/en/contactsPage.json deleted file mode 100644 index e8345a3e2..000000000 --- a/app/javascript/dashboard/i18n/locale/en/contactsPage.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "CONTACTS_PAGE": { - "HEADER": "Contacts", - "SEARCH_BUTTON": "Search", - "SEARCH_INPUT_PLACEHOLDER": "Search for contacts", - "LIST": { - "404": "There are no canned responses available in this account.", - "TITLE": "Manage canned responses", - "DESC": "Canned Responses are predefined reply templates which can be used to quickly send out replies to tickets.", - "TABLE_HEADER": [ - "Name", - "Phone Number", - "Conversations", - "Last Contacted" - ], - "EDIT_BUTTON": "Edit", - "VIEW_BUTTON": "View" - - } - } -} diff --git a/app/javascript/dashboard/i18n/locale/en/settings.json b/app/javascript/dashboard/i18n/locale/en/settings.json index b1363f2aa..adab59092 100644 --- a/app/javascript/dashboard/i18n/locale/en/settings.json +++ b/app/javascript/dashboard/i18n/locale/en/settings.json @@ -121,7 +121,7 @@ "SIDEBAR": { "CONVERSATIONS": "Conversations", "REPORTS": "Reports", - "CONTACTS": "Contacts", + "CONTACTS": "Contacts (Beta)", "SETTINGS": "Settings", "HOME": "Home", "AGENTS": "Agents", diff --git a/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsTable.vue b/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsTable.vue index d34902d62..0579c2394 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsTable.vue +++ b/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsTable.vue @@ -29,17 +29,21 @@ {{ contactItem.name }}

- {{ contactItem.email || '--' }} + {{ contactItem.email || '---' }}

- {{ contactItem.phone_number || '--' }} + {{ contactItem.phone_number || '---' }} {{ contactItem.conversations_count }} - {{ contactItem.last_contacted_at || '--' }} + {{ + contactItem.last_seen_at + ? dynamicTime(contactItem.last_seen_at) + : '---' + }} @@ -60,6 +64,7 @@ import { mixin as clickaway } from 'vue-clickaway'; import Spinner from 'shared/components/Spinner.vue'; import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue'; import EmptyState from 'dashboard/components/widgets/EmptyState.vue'; +import timeMixin from 'dashboard/mixins/time'; export default { components: { @@ -67,7 +72,7 @@ export default { EmptyState, Spinner, }, - mixins: [clickaway], + mixins: [clickaway, timeMixin], props: { contacts: { type: Array, @@ -77,10 +82,6 @@ export default { type: Boolean, default: false, }, - openEditModal: { - type: Function, - default: () => {}, - }, onClickContact: { type: Function, default: () => {}, @@ -90,7 +91,7 @@ export default { default: false, }, activeContactId: { - type: String, + type: [String, Number], default: '', }, }, @@ -134,6 +135,8 @@ export default { } .contacts-table { + margin-top: -1px; + > thead { border-bottom: 1px solid var(--color-border); background: white; @@ -178,8 +181,9 @@ export default { } .user-name { - text-transform: capitalize; + font-size: var(--font-size-small); margin: 0; + text-transform: capitalize; } .user-email { diff --git a/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue b/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue index 0661c9d68..bd970ce06 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue +++ b/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue @@ -4,12 +4,12 @@ - import { mapGetters } from 'vuex'; -import EditContact from 'dashboard/routes/dashboard/conversation/contact/EditContact'; - import ContactsHeader from './Header'; import ContactsTable from './ContactsTable'; import ContactInfoPanel from './ContactInfoPanel'; @@ -48,7 +41,6 @@ export default { ContactsHeader, ContactsTable, ContactsFooter, - EditContact, ContactInfoPanel, }, data() { @@ -83,9 +75,15 @@ export default { wrapClas() { return this.showContactViewPane ? 'medium-9' : 'medium-12'; }, + pageParameter() { + const selectedPageNumber = Number(this.$route.query?.page); + return !Number.isNaN(selectedPageNumber) && selectedPageNumber >= 1 + ? selectedPageNumber + : 1; + }, }, mounted() { - this.$store.dispatch('contacts/get', { page: 1 }); + this.$store.dispatch('contacts/get', { page: this.pageParameter }); }, methods: { onInputSearch(event) { @@ -98,12 +96,15 @@ export default { this.searchQuery = event.target.value; }, onSearchSubmit() { + this.selectedContactId = ''; this.$store.dispatch('contacts/search', { search: this.searchQuery, page: 1, }); }, onPageChange(page) { + this.selectedContactId = ''; + window.history.pushState({}, null, `${this.$route.path}?page=${page}`); if (this.searchQuery) { this.$store.dispatch('contacts/search', { search: this.searchQuery, @@ -121,14 +122,6 @@ export default { this.selectedContactId = ''; this.showContactInfoPanelPane = false; }, - openEditModal(contactId) { - this.selectedContactId = contactId; - this.showEditModal = true; - }, - closeEditModal() { - this.selectedContactId = ''; - this.showEditModal = false; - }, }, }; diff --git a/app/javascript/dashboard/routes/dashboard/contacts/components/Footer.vue b/app/javascript/dashboard/routes/dashboard/contacts/components/Footer.vue index 70f27121a..9c2e5467b 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/components/Footer.vue +++ b/app/javascript/dashboard/routes/dashboard/contacts/components/Footer.vue @@ -1,5 +1,5 @@