feat(inboxes): add inbox disable toggle

This commit is contained in:
Muhsin
2026-06-09 21:07:05 +04:00
parent 8a3b129292
commit cbd24dbdb2
49 changed files with 239 additions and 19 deletions
@@ -10,10 +10,16 @@ defineProps({
</script>
<template>
<div :title="inbox.name" class="flex items-center gap-0.5 min-w-0">
<div :title="inbox.name" class="flex items-center gap-1 min-w-0">
<ChannelIcon :inbox="inbox" class="size-4 flex-shrink-0 text-n-slate-11" />
<span class="truncate text-body-main text-n-slate-11">
{{ inbox.name }}
</span>
<span
v-if="inbox.active === false"
class="shrink-0 rounded-md bg-n-ruby-3 px-1 py-0.5 text-xs font-medium text-n-ruby-11"
>
{{ $t('INBOX_MGMT.DISABLED') }}
</span>
</div>
</template>
@@ -27,6 +27,10 @@ const props = defineProps({
const reauthorizationRequired = computed(() => {
return props.inbox.reauthorization_required;
});
const inboxDisabled = computed(() => {
return props.inbox.active === false;
});
</script>
<template>
@@ -34,6 +38,13 @@ const reauthorizationRequired = computed(() => {
<ChannelIcon :inbox="inbox" class="size-4" />
</span>
<div class="flex-1 truncate min-w-0">{{ label }}</div>
<div
v-if="inboxDisabled"
v-tooltip.top-end="$t('INBOX_MGMT.DISABLED')"
class="grid place-content-center size-5 bg-n-ruby-3 rounded-full"
>
<Icon icon="i-woot-alert" class="size-3 text-n-ruby-9" />
</div>
<SidebarUnreadBadge :count="badgeCount" />
<div
v-if="reauthorizationRequired"
@@ -10,10 +10,16 @@ defineProps({
</script>
<template>
<div :title="inbox.name" class="flex items-center gap-0.5 min-w-0">
<div :title="inbox.name" class="flex items-center gap-1 min-w-0">
<ChannelIcon :inbox="inbox" class="size-4 flex-shrink-0 text-n-slate-11" />
<span class="truncate text-label-small text-n-slate-11">
{{ inbox.name }}
</span>
<span
v-if="inbox.active === false"
class="shrink-0 rounded-md bg-n-ruby-3 px-1 py-0.5 text-xs font-medium text-n-ruby-11"
>
{{ $t('INBOX_MGMT.DISABLED') }}
</span>
</div>
</template>
@@ -170,8 +170,14 @@ export default {
instagramInbox
);
},
isInboxDisabled() {
return this.inbox.active === false;
},
replyWindowBannerMessage() {
if (this.isInboxDisabled) {
return this.$t('CONVERSATION.INBOX_DISABLED');
}
if (this.isAWhatsAppChannel) {
return this.$t('CONVERSATION.TWILIO_WHATSAPP_CAN_REPLY');
}
@@ -194,6 +200,9 @@ export default {
return this.$t('CONVERSATION.CANNOT_REPLY');
},
replyWindowLink() {
if (this.isInboxDisabled) {
return '';
}
if (this.isAFacebookInbox || this.isAnInstagramChannel) {
return REPLY_POLICY.FACEBOOK;
}
@@ -209,6 +218,9 @@ export default {
return '';
},
replyWindowLinkText() {
if (this.isInboxDisabled) {
return '';
}
if (
this.isAWhatsAppChannel ||
this.isAFacebookInbox ||
@@ -455,7 +467,7 @@ export default {
>
<div ref="topBannerRef">
<Banner
v-if="!currentChat.can_reply"
v-if="isInboxDisabled || !currentChat.can_reply"
color-scheme="alert"
class="mx-2 mt-2 overflow-hidden rounded-lg"
:banner-message="replyWindowBannerMessage"
@@ -208,6 +208,9 @@ export default {
},
messagePlaceHolder() {
if (this.isEditorDisabled) {
if (this.inbox.active === false) {
return this.$t('CONVERSATION.FOOTER.MESSAGING_RESTRICTED_INBOX');
}
if (this.isAWhatsAppChannel) {
return this.$t('CONVERSATION.FOOTER.MESSAGING_RESTRICTED_WHATSAPP');
}
@@ -438,6 +441,10 @@ export default {
return !this.showAudioRecorderEditor && !this.copilot.isActive.value;
},
isEditorDisabled() {
if (this.inbox.active === false) {
return true;
}
return (
(this.isAWhatsAppChannel || this.isAPIInbox) &&
!this.isOnPrivateNote &&
@@ -31,6 +31,7 @@
"LOADING_INBOXES": "Loading inboxes",
"LOADING_CONVERSATIONS": "Loading Conversations",
"CANNOT_REPLY": "You cannot reply due to",
"INBOX_DISABLED": "This inbox is disabled. You cannot send messages.",
"24_HOURS_WINDOW": "24 hour message window restriction",
"48_HOURS_WINDOW": "48 hour message window restriction",
"API_HOURS_WINDOW": "You can only reply to this conversation within {hours} hours",
@@ -211,6 +212,7 @@
"MSG_INPUT": "Shift + enter for new line. Start with '/' to select a Canned Response.",
"PRIVATE_MSG_INPUT": "Shift + enter for new line. This will be visible only to Agents",
"MESSAGING_RESTRICTED": "You cannot reply to this conversation",
"MESSAGING_RESTRICTED_INBOX": "This inbox is disabled. You cannot send messages.",
"MESSAGING_RESTRICTED_WHATSAPP": "You can only reply using a template message due to 24-hour message window restriction",
"MESSAGING_RESTRICTED_API": "You can only reply using a template message due to message window restriction",
"MESSAGE_SIGNATURE_NOT_CONFIGURED": "Message signature is not configured, please configure it in profile settings.",
@@ -743,6 +743,7 @@
}
},
"SETTINGS": "Settings",
"DISABLED": "Disabled",
"FEATURES": {
"LABEL": "Features",
"DISPLAY_FILE_PICKER": "Display file picker on the widget",
@@ -772,6 +773,10 @@
},
"INBOX_AGENTS": "Agents",
"INBOX_AGENTS_SUB_TEXT": "Add or remove agents from this inbox",
"INBOX_ACTIVE": {
"TITLE": "Enable inbox",
"DESCRIPTION": "When disabled, this inbox stays visible but stops new conversations, incoming messages, replies, private notes, automations, and bot processing."
},
"AGENT_ASSIGNMENT": "Conversation Assignment",
"AGENT_ASSIGNMENT_SUB_TEXT": "Update conversation assignment settings",
"UPDATE": "Update",
@@ -139,9 +139,19 @@ const openDelete = inbox => {
<ChannelIcon class="size-6 text-n-slate-10" :inbox="inbox" />
</div>
<div class="flex flex-col items-start gap-1">
<span class="block text-heading-3 text-n-slate-12 capitalize">
{{ inbox.name }}
</span>
<div class="flex items-center gap-2 min-w-0">
<span
class="block text-heading-3 text-n-slate-12 capitalize truncate"
>
{{ inbox.name }}
</span>
<span
v-if="inbox.active === false"
class="shrink-0 rounded-md bg-n-ruby-3 px-1.5 py-0.5 text-xs font-medium text-n-ruby-11"
>
{{ $t('INBOX_MGMT.DISABLED') }}
</span>
</div>
<ChannelName
:channel-type="inbox.channel_type"
:medium="inbox.medium"
@@ -91,6 +91,7 @@ export default {
senderNameType: 'friendly',
businessName: '',
locktoSingleConversation: false,
inboxActive: true,
allowMessagesAfterResolved: true,
continuityViaEmail: true,
selectedInboxName: '',
@@ -470,6 +471,7 @@ export default {
this.businessName = this.inbox.business_name;
this.allowMessagesAfterResolved =
this.inbox.allow_messages_after_resolved;
this.inboxActive = this.inbox.active !== false;
this.continuityViaEmail = this.inbox.continuity_via_email;
this.channelWebsiteUrl = this.inbox.website_url;
this.channelWelcomeTitle = this.inbox.welcome_title;
@@ -581,6 +583,7 @@ export default {
const payload = {
id: this.currentInboxId,
name: this.selectedInboxName?.trim(),
active: this.inboxActive,
enable_email_collect: this.emailCollectEnabled,
allow_messages_after_resolved: this.allowMessagesAfterResolved,
greeting_enabled: this.greetingEnabled,
@@ -819,6 +822,15 @@ export default {
/>
</SettingsFieldSection>
<SettingsToggleSection
v-model="inboxActive"
:header="$t('INBOX_MGMT.SETTINGS_POPUP.INBOX_ACTIVE.TITLE')"
:description="
$t('INBOX_MGMT.SETTINGS_POPUP.INBOX_ACTIVE.DESCRIPTION')
"
class="mb-4"
/>
<SettingsFieldSection
v-if="isAWebWidgetInbox"
:label="$t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_DOMAIN.LABEL')"