diff --git a/app/actions/contact_identify_action.rb b/app/actions/contact_identify_action.rb index 75af71a1f..ff8efd3b5 100644 --- a/app/actions/contact_identify_action.rb +++ b/app/actions/contact_identify_action.rb @@ -33,7 +33,8 @@ class ContactIdentifyAction end def update_contact - @contact.update!(params.slice(:name, :email, :identifier)) + custom_attributes = params[:custom_attributes] ? @contact.custom_attributes.merge(params[:custom_attributes]) : @contact.custom_attributes + @contact.update!(params.slice(:name, :email, :identifier).merge({ custom_attributes: custom_attributes })) ContactAvatarJob.perform_later(@contact, params[:avatar_url]) if params[:avatar_url].present? end diff --git a/app/controllers/api/v1/accounts/contacts_controller.rb b/app/controllers/api/v1/accounts/contacts_controller.rb index eef50ef11..580ba799d 100644 --- a/app/controllers/api/v1/accounts/contacts_controller.rb +++ b/app/controllers/api/v1/accounts/contacts_controller.rb @@ -12,14 +12,14 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController def create ActiveRecord::Base.transaction do - @contact = Current.account.contacts.new(contact_create_params) + @contact = Current.account.contacts.new(contact_params) @contact.save! @contact_inbox = build_contact_inbox end end def update - @contact.update!(contact_params) + @contact.update!(contact_update_params) end def search @@ -43,14 +43,21 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController end def contact_params - params.require(:contact).permit(:name, :email, :phone_number) + params.require(:contact).permit(:name, :email, :phone_number, custom_attributes: {}) + end + + def contact_custom_attributes + return @contact.custom_attributes.merge(contact_params[:custom_attributes]) if contact_params[:custom_attributes] + + @contact.custom_attributes + end + + def contact_update_params + # we want the merged custom attributes not the original one + contact_params.except(:custom_attributes).merge({ custom_attributes: contact_custom_attributes }) end def fetch_contact @contact = Current.account.contacts.find(params[:id]) end - - def contact_create_params - params.require(:contact).permit(:name, :email, :phone_number) - end end diff --git a/app/controllers/api/v1/widget/contacts_controller.rb b/app/controllers/api/v1/widget/contacts_controller.rb index 2a2b184fb..b58d26373 100644 --- a/app/controllers/api/v1/widget/contacts_controller.rb +++ b/app/controllers/api/v1/widget/contacts_controller.rb @@ -10,6 +10,6 @@ class Api::V1::Widget::ContactsController < Api::V1::Widget::BaseController private def permitted_params - params.permit(:website_token, :identifier, :email, :name, :avatar_url) + params.permit(:website_token, :identifier, :email, :name, :avatar_url, custom_attributes: {}) end end diff --git a/app/javascript/dashboard/i18n/locale/en/contact.json b/app/javascript/dashboard/i18n/locale/en/contact.json index 87c9256c2..d13ade2be 100644 --- a/app/javascript/dashboard/i18n/locale/en/contact.json +++ b/app/javascript/dashboard/i18n/locale/en/contact.json @@ -9,6 +9,9 @@ "NO_RECORDS_FOUND": "There are no previous conversations associated to this contact.", "TITLE": "Previous Conversations" }, + "CUSTOM_ATTRIBUTES": { + "TITLE": "Custom Attributes" + }, "LABELS": { "TITLE": "Conversation Labels", "MODAL": { diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ContactCustomAttributes.vue b/app/javascript/dashboard/routes/dashboard/conversation/ContactCustomAttributes.vue new file mode 100644 index 000000000..98c1775e8 --- /dev/null +++ b/app/javascript/dashboard/routes/dashboard/conversation/ContactCustomAttributes.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ContactDetailsItem.vue b/app/javascript/dashboard/routes/dashboard/conversation/ContactDetailsItem.vue index fda504c35..75bf0c018 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ContactDetailsItem.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ContactDetailsItem.vue @@ -36,7 +36,7 @@ export default { @import '~dashboard/assets/scss/mixins'; .conv-details--item { - padding-bottom: $space-normal; + padding-bottom: var(--space-slab); &:last-child { padding-bottom: 0; diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue b/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue index e59d80a49..52e6dc2b2 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue @@ -84,6 +84,10 @@ icon="ion-clock" /> + { } }, + setCustomAttributes(customAttributes = {}) { + if (!customAttributes || !Object.keys(customAttributes).length) { + throw new Error('Custom attributes should have atleast one key'); + } else { + IFrameHelper.sendMessage('set-custom-attributes', { customAttributes }); + } + }, + + deleteCustomAttribute(customAttribute = '') { + if (!customAttribute) { + throw new Error('Custom attribute is required'); + } else { + IFrameHelper.sendMessage('delete-custom-attribute', { + customAttribute, + }); + } + }, + setLabel(label = '') { IFrameHelper.sendMessage('set-label', { label }); }, diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue index 45b45fb48..fb865d03e 100755 --- a/app/javascript/widget/App.vue +++ b/app/javascript/widget/App.vue @@ -15,8 +15,6 @@