feat: Link help center portal to an Inbox (#6903)
This commit is contained in:
@@ -114,10 +114,13 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController
|
||||
def inbox_attributes
|
||||
[:name, :avatar, :greeting_enabled, :greeting_message, :enable_email_collect, :csat_survey_enabled,
|
||||
:enable_auto_assignment, :working_hours_enabled, :out_of_office_message, :timezone, :allow_messages_after_resolved,
|
||||
:lock_to_single_conversation]
|
||||
:lock_to_single_conversation, :portal_id]
|
||||
end
|
||||
|
||||
def permitted_params(channel_attributes = [])
|
||||
# We will remove this line after fixing https://linear.app/chatwoot/issue/CW-1567/null-value-passed-as-null-string-to-backend
|
||||
params.each { |k, v| params[k] = params[k] == 'null' ? nil : v }
|
||||
|
||||
params.permit(
|
||||
*inbox_attributes,
|
||||
channel: [:type, *channel_attributes]
|
||||
|
||||
@@ -482,6 +482,13 @@
|
||||
"WHATSAPP_WEBHOOK_SUBHEADER": "This token is used to verify the authenticity of the webhook endpoint.",
|
||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
||||
},
|
||||
"HELP_CENTER": {
|
||||
"LABEL": "Help Center",
|
||||
"PLACEHOLDER": "Select Help Center",
|
||||
"SELECT_PLACEHOLDER": "Select Help Center",
|
||||
"REMOVE": "Remove Help Center",
|
||||
"SUB_TEXT": "Attach a Help Center with the inbox"
|
||||
},
|
||||
"AUTO_ASSIGNMENT": {
|
||||
"MAX_ASSIGNMENT_LIMIT": "Auto assignment limit",
|
||||
"MAX_ASSIGNMENT_LIMIT_RANGE_ERROR": "Please enter a value greater than 0",
|
||||
|
||||
@@ -258,7 +258,22 @@
|
||||
}}
|
||||
</p>
|
||||
</label>
|
||||
|
||||
<div class="medium-9 settings-item settings-item">
|
||||
<label>
|
||||
{{ $t('INBOX_MGMT.HELP_CENTER.LABEL') }}
|
||||
</label>
|
||||
<select v-model="selectedPortalSlug" class="filter__question">
|
||||
<option value="">
|
||||
{{ $t('INBOX_MGMT.HELP_CENTER.PLACEHOLDER') }}
|
||||
</option>
|
||||
<option v-for="p in portals" :key="p.slug" :value="p.slug">
|
||||
{{ p.name }}
|
||||
</option>
|
||||
</select>
|
||||
<p class="help-text">
|
||||
{{ $t('INBOX_MGMT.HELP_CENTER.SUB_TEXT') }}
|
||||
</p>
|
||||
</div>
|
||||
<label
|
||||
v-if="canLocktoSingleConversation"
|
||||
class="medium-9 columns settings-item"
|
||||
@@ -425,6 +440,7 @@ export default {
|
||||
selectedFeatureFlags: [],
|
||||
replyTime: '',
|
||||
selectedTabIndex: 0,
|
||||
selectedPortalSlug: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -432,6 +448,7 @@ export default {
|
||||
accountId: 'getCurrentAccountId',
|
||||
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
|
||||
uiFlags: 'inboxes/getUIFlags',
|
||||
portals: 'portals/allPortals',
|
||||
}),
|
||||
selectedTabKey() {
|
||||
return this.tabs[this.selectedTabIndex]?.key;
|
||||
@@ -519,6 +536,7 @@ export default {
|
||||
inbox() {
|
||||
return this.$store.getters['inboxes/getInbox'](this.currentInboxId);
|
||||
},
|
||||
|
||||
inboxName() {
|
||||
if (this.isATwilioSMSChannel || this.isATwilioWhatsAppChannel) {
|
||||
return `${this.inbox.name} (${this.inbox.messaging_service_sid ||
|
||||
@@ -566,8 +584,12 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.fetchInboxSettings();
|
||||
this.fetchPortals();
|
||||
},
|
||||
methods: {
|
||||
fetchPortals() {
|
||||
this.$store.dispatch('portals/index');
|
||||
},
|
||||
handleFeatureFlag(e) {
|
||||
this.selectedFeatureFlags = this.toggleInput(
|
||||
this.selectedFeatureFlags,
|
||||
@@ -607,6 +629,9 @@ export default {
|
||||
this.selectedFeatureFlags = this.inbox.selected_feature_flags || [];
|
||||
this.replyTime = this.inbox.reply_time;
|
||||
this.locktoSingleConversation = this.inbox.lock_to_single_conversation;
|
||||
this.selectedPortalSlug = this.inbox.help_center
|
||||
? this.inbox.help_center.slug
|
||||
: '';
|
||||
});
|
||||
},
|
||||
async updateInbox() {
|
||||
@@ -619,6 +644,11 @@ export default {
|
||||
allow_messages_after_resolved: this.allowMessagesAfterResolved,
|
||||
greeting_enabled: this.greetingEnabled,
|
||||
greeting_message: this.greetingMessage || '',
|
||||
portal_id: this.selectedPortalSlug
|
||||
? this.portals.find(
|
||||
portal => portal.slug === this.selectedPortalSlug
|
||||
).id
|
||||
: null,
|
||||
lock_to_single_conversation: this.locktoSingleConversation,
|
||||
channel: {
|
||||
widget_color: this.inbox.widget_color,
|
||||
|
||||
@@ -23,11 +23,17 @@
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer not null
|
||||
# channel_id :integer not null
|
||||
# portal_id :bigint
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_inboxes_on_account_id (account_id)
|
||||
# index_inboxes_on_channel_id_and_channel_type (channel_id,channel_type)
|
||||
# index_inboxes_on_portal_id (portal_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# fk_rails_... (portal_id => portals.id)
|
||||
#
|
||||
|
||||
class Inbox < ApplicationRecord
|
||||
@@ -45,6 +51,7 @@ class Inbox < ApplicationRecord
|
||||
validate :ensure_valid_max_assignment_limit
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :portal, optional: true
|
||||
|
||||
belongs_to :channel, polymorphic: true, dependent: :destroy
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class Portal < ApplicationRecord
|
||||
dependent: :nullify,
|
||||
source: :user
|
||||
has_one_attached :logo
|
||||
has_many :inboxes, dependent: :nullify
|
||||
|
||||
before_validation -> { normalize_empty_string_to_nil(%i[custom_domain homepage_link]) }
|
||||
validates :account_id, presence: true
|
||||
|
||||
@@ -17,6 +17,13 @@ json.callback_webhook_url resource.callback_webhook_url
|
||||
json.allow_messages_after_resolved resource.allow_messages_after_resolved
|
||||
json.lock_to_single_conversation resource.lock_to_single_conversation
|
||||
|
||||
if resource.portal.present?
|
||||
json.help_center do
|
||||
json.name resource.portal.name
|
||||
json.slug resource.portal.slug
|
||||
end
|
||||
end
|
||||
|
||||
## Channel specific settings
|
||||
## TODO : Clean up and move the attributes into channel sub section
|
||||
|
||||
|
||||
Reference in New Issue
Block a user