diff --git a/app/controllers/api/v1/accounts/conversations/participants_controller.rb b/app/controllers/api/v1/accounts/conversations/participants_controller.rb index 609490e2f..ebd02380f 100644 --- a/app/controllers/api/v1/accounts/conversations/participants_controller.rb +++ b/app/controllers/api/v1/accounts/conversations/participants_controller.rb @@ -9,6 +9,15 @@ class Api::V1::Accounts::Conversations::ParticipantsController < Api::V1::Accoun end end + def update + ActiveRecord::Base.transaction do + participants_to_be_added_ids.each { |user_id| @conversation.conversation_participants.find_or_create_by(user_id: user_id) } + participants_to_be_removed_ids.each { |user_id| @conversation.conversation_participants.find_by(user_id: user_id)&.destroy } + end + @participants = @conversation.conversation_participants + render action: 'show' + end + def destroy ActiveRecord::Base.transaction do params[:user_ids].map { |user_id| @conversation.conversation_participants.find_by(user_id: user_id)&.destroy } diff --git a/app/javascript/dashboard/api/inbox/conversation.js b/app/javascript/dashboard/api/inbox/conversation.js index 9f6b8baf1..77dc47208 100644 --- a/app/javascript/dashboard/api/inbox/conversation.js +++ b/app/javascript/dashboard/api/inbox/conversation.js @@ -105,6 +105,22 @@ class ConversationApi extends ApiClient { custom_attributes: customAttributes, }); } + + fecthParticipants(id) { + return axios.get(`${this.url}/${id}/participants`); + } + + createParticipants(object) { + return axios.post(`${this.url}/${object.conversationId}/participants`, { + user_ids: object.user_ids, + }); + } + + updateParticipants(object) { + return axios.patch(`${this.url}/${object.conversationId}/participants`, { + user_ids: object.user_ids, + }); + } } export default new ConversationApi(); diff --git a/app/javascript/dashboard/helper/URLHelper.js b/app/javascript/dashboard/helper/URLHelper.js index 335bf07b7..d8bcd8d21 100644 --- a/app/javascript/dashboard/helper/URLHelper.js +++ b/app/javascript/dashboard/helper/URLHelper.js @@ -37,8 +37,7 @@ export const conversationUrl = ({ url = `accounts/${accountId}/custom_view/${foldersId}/conversations/${id}`; } else if (conversationType === 'mention') { url = `accounts/${accountId}/mentions/conversations/${id}`; - } - else if (conversationType === 'participating') { + } else if (conversationType === 'participating') { url = `accounts/${accountId}/participating/conversations/${id}`; } return url; diff --git a/app/javascript/dashboard/mixins/uiSettings.js b/app/javascript/dashboard/mixins/uiSettings.js index e265975e1..d2bcf53f1 100644 --- a/app/javascript/dashboard/mixins/uiSettings.js +++ b/app/javascript/dashboard/mixins/uiSettings.js @@ -1,6 +1,7 @@ import { mapGetters } from 'vuex'; export const DEFAULT_CONVERSATION_SIDEBAR_ITEMS_ORDER = [ { name: 'conversation_actions' }, + { name: 'conversation_participants' }, { name: 'conversation_info' }, { name: 'contact_attributes' }, { name: 'previous_conversation' }, diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue b/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue index 294f2b6ba..2aed87ab2 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue @@ -38,6 +38,24 @@ /> +
+ + + +
+
+ + + +
+ + + + diff --git a/app/javascript/dashboard/store/modules/conversations/actions.js b/app/javascript/dashboard/store/modules/conversations/actions.js index ca42dfae0..6b65e4d05 100644 --- a/app/javascript/dashboard/store/modules/conversations/actions.js +++ b/app/javascript/dashboard/store/modules/conversations/actions.js @@ -330,6 +330,43 @@ const actions = { clearConversationFilters({ commit }) { commit(types.CLEAR_CONVERSATION_FILTERS); }, + + fetchConversationParticipants: async ({ commit }, id) => { + try { + const response = await ConversationApi.fecthParticipants(id); + commit(types.SET_CONVERSATION_PARTICIPANTS, response.data); + } catch (error) { + // Handle error + } + }, + + createConversationParticipants: async ( + { commit }, + conversationId, + user_ids + ) => { + const response = await ConversationApi.createParticipants( + conversationId, + user_ids + ); + commit(types.SET_CONVERSATION_PARTICIPANTS, response.data); + }, + + updateConversationParticipants: async ( + { commit }, + conversationId, + user_ids + ) => { + const response = await ConversationApi.updateParticipants( + conversationId, + user_ids + ); + commit(types.SET_CONVERSATION_PARTICIPANTS, response.data); + }, + + clearConversationParticipants({ commit }) { + commit(types.CLEAR_CONVERSATION_PARTICIPANTS); + }, }; export default actions; diff --git a/app/javascript/dashboard/store/modules/conversations/getters.js b/app/javascript/dashboard/store/modules/conversations/getters.js index 60ca0d590..a5bed4a3e 100644 --- a/app/javascript/dashboard/store/modules/conversations/getters.js +++ b/app/javascript/dashboard/store/modules/conversations/getters.js @@ -92,6 +92,9 @@ const getters = { value => value.id === Number(conversationId) ); }, + getConversationParticipants: _state => { + return _state.conversationParticipants; + }, }; export default getters; diff --git a/app/javascript/dashboard/store/modules/conversations/index.js b/app/javascript/dashboard/store/modules/conversations/index.js index c8519c253..c3a344273 100644 --- a/app/javascript/dashboard/store/modules/conversations/index.js +++ b/app/javascript/dashboard/store/modules/conversations/index.js @@ -12,6 +12,7 @@ const state = { currentInbox: null, selectedChatId: null, appliedFilters: [], + conversationParticipants: [], }; // mutations @@ -194,6 +195,14 @@ export const mutations = { [types.CLEAR_CONVERSATION_FILTERS](_state) { _state.appliedFilters = []; }, + + [types.SET_CONVERSATION_PARTICIPANTS](_state, data) { + _state.conversationParticipants = data; + }, + + [types.CLEAR_CONVERSATION_PARTICIPANTS](_state) { + _state.conversationParticipants = []; + }, }; export default { diff --git a/app/javascript/dashboard/store/mutation-types.js b/app/javascript/dashboard/store/mutation-types.js index 734e0b5e5..44d53b653 100755 --- a/app/javascript/dashboard/store/mutation-types.js +++ b/app/javascript/dashboard/store/mutation-types.js @@ -21,6 +21,8 @@ export default { CLEAR_CONTACT_CONVERSATIONS: 'CLEAR_CONTACT_CONVERSATIONS', SET_CONVERSATION_FILTERS: 'SET_CONVERSATION_FILTERS', CLEAR_CONVERSATION_FILTERS: 'CLEAR_CONVERSATION_FILTERS', + SET_CONVERSATION_PARTICIPANTS: 'SET_CONVERSATION_PARTICIPANTS', + CLEAR_CONVERSATION_PARTICIPANTS: 'CLEAR_CONVERSATION_PARTICIPANTS', SET_CURRENT_CHAT_WINDOW: 'SET_CURRENT_CHAT_WINDOW', CLEAR_CURRENT_CHAT_WINDOW: 'CLEAR_CURRENT_CHAT_WINDOW', diff --git a/app/models/conversation.rb b/app/models/conversation.rb index 51a0713a4..18cc62e5e 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -77,7 +77,6 @@ class Conversation < ApplicationRecord has_many :conversation_participants, dependent: :destroy_async has_many :notifications, as: :primary_actor, dependent: :destroy - before_save :ensure_snooze_until_reset before_create :mark_conversation_pending_if_bot diff --git a/app/models/conversation_participant.rb b/app/models/conversation_participant.rb index 9c4d89b50..4ce3a1f02 100644 --- a/app/models/conversation_participant.rb +++ b/app/models/conversation_participant.rb @@ -33,7 +33,7 @@ class ConversationParticipant < ApplicationRecord before_validation :ensure_account_id private - + def ensure_account_id self.account_id = conversation&.account_id end diff --git a/app/views/api/v1/accounts/conversations/participants/create.json.jbuilder b/app/views/api/v1/accounts/conversations/participants/create.json.jbuilder index b7a9b9375..cce70781c 100644 --- a/app/views/api/v1/accounts/conversations/participants/create.json.jbuilder +++ b/app/views/api/v1/accounts/conversations/participants/create.json.jbuilder @@ -1,3 +1,3 @@ json.array! @participants do |participant| json.partial! 'api/v1/models/agent.json.jbuilder', resource: participant.user -end \ No newline at end of file +end diff --git a/app/views/api/v1/accounts/conversations/participants/show.json.jbuilder b/app/views/api/v1/accounts/conversations/participants/show.json.jbuilder index b7a9b9375..cce70781c 100644 --- a/app/views/api/v1/accounts/conversations/participants/show.json.jbuilder +++ b/app/views/api/v1/accounts/conversations/participants/show.json.jbuilder @@ -1,3 +1,3 @@ json.array! @participants do |participant| json.partial! 'api/v1/models/agent.json.jbuilder', resource: participant.user -end \ No newline at end of file +end diff --git a/config/routes.rb b/config/routes.rb index cb444abfc..5a37a1b17 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -71,7 +71,7 @@ Rails.application.routes.draw do resources :messages, only: [:index, :create, :destroy] resources :assignments, only: [:create] resources :labels, only: [:create, :index] - resource :participants, only: [:show, :create, :destroy] + resource :participants, only: [:show, :create, :update, :destroy] end member do post :mute diff --git a/db/migrate/20220308193420_add_conversation_participants.rb b/db/migrate/20220308193420_add_conversation_participants.rb index 5fdeb170d..8a2708c8b 100644 --- a/db/migrate/20220308193420_add_conversation_participants.rb +++ b/db/migrate/20220308193420_add_conversation_participants.rb @@ -4,8 +4,8 @@ class AddConversationParticipants < ActiveRecord::Migration[6.1] t.references :account, null: false, foreign_key: { on_delete: :cascade } t.references :user, null: false, foreign_key: { on_delete: :cascade } t.references :conversation, null: false, foreign_key: { on_delete: :cascade } - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime 'created_at', precision: 6, null: false + t.datetime 'updated_at', precision: 6, null: false end end end