From b5db3c95126cf5e448e17eee1dc6a917ea15d15c Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 31 Mar 2026 14:58:26 +0530 Subject: [PATCH] Inline edit for phone, email, company --- .../dashboard/i18n/locale/en/contact.json | 1 + .../conversation/contact/ContactInfo.vue | 66 +++++++++++++++- .../conversation/contact/ContactInfoRow.vue | 78 ++++++++++++++++++- .../store/modules/contacts/actions.js | 6 +- 4 files changed, 147 insertions(+), 4 deletions(-) diff --git a/app/javascript/dashboard/i18n/locale/en/contact.json b/app/javascript/dashboard/i18n/locale/en/contact.json index 803cd66cb..9234071d1 100644 --- a/app/javascript/dashboard/i18n/locale/en/contact.json +++ b/app/javascript/dashboard/i18n/locale/en/contact.json @@ -20,6 +20,7 @@ "CALL": "Call", "CALL_INITIATED": "Calling the contact…", "CALL_FAILED": "Unable to start the call. Please try again.", + "CLICK_TO_EDIT": "Click to edit", "VOICE_INBOX_PICKER": { "TITLE": "Choose a voice inbox" }, diff --git a/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactInfo.vue b/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactInfo.vue index 3899d1ddf..36c4a7b41 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactInfo.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactInfo.vue @@ -52,6 +52,8 @@ export default { return { showEditModal: false, showDeleteModal: false, + isEditingName: false, + editName: '', }; }, computed: { @@ -173,6 +175,38 @@ export default { openMergeModal() { this.$refs.mergeModal?.open(); }, + startEditingName() { + this.editName = this.contact.name || ''; + this.isEditingName = true; + this.$nextTick(() => { + this.$refs.nameInput?.focus(); + }); + }, + saveNameEdit() { + if (!this.isEditingName) return; + this.isEditingName = false; + const trimmed = this.editName.trim(); + if (trimmed && trimmed !== this.contact.name) { + this.updateContactField({ name: trimmed }); + } + }, + cancelNameEdit() { + this.isEditingName = false; + }, + onFieldUpdate(field, value) { + this.updateContactField({ [field]: value }); + }, + async updateContactField(attrs) { + try { + await this.$store.dispatch('contacts/update', { + id: this.contact.id, + ...attrs, + }); + useAlert(this.$t('CONTACT_FORM.SUCCESS_MESSAGE')); + } catch (error) { + useAlert(error.message || this.$t('CONTACT_FORM.ERROR_MESSAGE')); + } + }, }, }; @@ -194,10 +228,26 @@ export default {
+

{{ contact.name }} +

{ + this.$refs.editInput?.focus(); + }); + }, + saveEdit() { + if (!this.isEditing) return; + this.isEditing = false; + const trimmed = this.editValue.trim(); + if (trimmed !== (this.value || '')) { + this.$emit('update', trimmed); + } + }, + cancelEdit() { + this.isEditing = false; + }, }, }; diff --git a/app/javascript/dashboard/store/modules/contacts/actions.js b/app/javascript/dashboard/store/modules/contacts/actions.js index d7f87b776..d0029207e 100644 --- a/app/javascript/dashboard/store/modules/contacts/actions.js +++ b/app/javascript/dashboard/store/modules/contacts/actions.js @@ -36,7 +36,11 @@ const buildContactFormData = contactParams => { export const handleContactOperationErrors = error => { if (error.response?.status === 422) { - throw new DuplicateContactException(error.response.data.attributes); + const exception = new DuplicateContactException( + error.response.data.attributes + ); + exception.message = error.response.data.message || exception.message; + throw exception; } else if (error.response?.data?.message) { throw new ExceptionWithMessage(error.response.data.message); } else {