mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 03:57:52 +00:00
feat: Add the ability to block/unblock contact via contact details page (#10899)
This commit is contained in:
@@ -8,17 +8,17 @@ import Breadcrumb from 'dashboard/components-next/breadcrumb/Breadcrumb.vue';
|
||||
import ComposeConversation from 'dashboard/components-next/NewConversation/ComposeConversation.vue';
|
||||
|
||||
const props = defineProps({
|
||||
buttonLabel: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
selectedContact: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
isUpdating: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['goToContactsList']);
|
||||
const emit = defineEmits(['goToContactsList', 'toggleBlock']);
|
||||
|
||||
const { t } = useI18n();
|
||||
const slots = useSlots();
|
||||
@@ -45,9 +45,17 @@ const breadcrumbItems = computed(() => {
|
||||
return items;
|
||||
});
|
||||
|
||||
const isContactBlocked = computed(() => {
|
||||
return props.selectedContact?.blocked;
|
||||
});
|
||||
|
||||
const handleBreadcrumbClick = () => {
|
||||
emit('goToContactsList');
|
||||
};
|
||||
|
||||
const toggleBlock = () => {
|
||||
emit('toggleBlock', isContactBlocked.value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -64,11 +72,29 @@ const handleBreadcrumbClick = () => {
|
||||
:items="breadcrumbItems"
|
||||
@click="handleBreadcrumbClick"
|
||||
/>
|
||||
<ComposeConversation :contact-id="contactId">
|
||||
<template #trigger="{ toggle }">
|
||||
<Button :label="buttonLabel" size="sm" @click="toggle" />
|
||||
</template>
|
||||
</ComposeConversation>
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
:label="
|
||||
!isContactBlocked
|
||||
? $t('CONTACTS_LAYOUT.HEADER.BLOCK_CONTACT')
|
||||
: $t('CONTACTS_LAYOUT.HEADER.UNBLOCK_CONTACT')
|
||||
"
|
||||
size="sm"
|
||||
slate
|
||||
:is-loading="isUpdating"
|
||||
:disabled="isUpdating"
|
||||
@click="toggleBlock"
|
||||
/>
|
||||
<ComposeConversation :contact-id="contactId">
|
||||
<template #trigger="{ toggle }">
|
||||
<Button
|
||||
:label="$t('CONTACTS_LAYOUT.HEADER.SEND_MESSAGE')"
|
||||
size="sm"
|
||||
@click="toggle"
|
||||
/>
|
||||
</template>
|
||||
</ComposeConversation>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -289,6 +289,8 @@
|
||||
"SEARCH_PLACEHOLDER": "Search...",
|
||||
"MESSAGE_BUTTON": "Message",
|
||||
"SEND_MESSAGE": "Send message",
|
||||
"BLOCK_CONTACT": "Block contact",
|
||||
"UNBLOCK_CONTACT": "Unblock contact",
|
||||
"BREADCRUMB": {
|
||||
"CONTACTS": "Contacts"
|
||||
},
|
||||
@@ -303,6 +305,10 @@
|
||||
"SUCCESS_MESSAGE": "Contact saved successfully",
|
||||
"ERROR_MESSAGE": "Unable to save contact. Please try again later."
|
||||
},
|
||||
"BLOCK_SUCCESS_MESSAGE": "This contact is blocked successfully",
|
||||
"BLOCK_ERROR_MESSAGE": "Unable to block contact. Please try again later.",
|
||||
"UNBLOCK_SUCCESS_MESSAGE": "This contact is unblocked successfully",
|
||||
"UNBLOCK_ERROR_MESSAGE": "Unable to unblock contact. Please try again later.",
|
||||
"IMPORT_CONTACT": {
|
||||
"TITLE": "Import contacts",
|
||||
"DESCRIPTION": "Import contacts through a CSV file.",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup>
|
||||
import { onMounted, computed, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import { useStore, useMapGetter } from 'dashboard/composables/store';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
@@ -25,6 +26,7 @@ const contactMergeRef = ref(null);
|
||||
|
||||
const isFetchingItem = computed(() => uiFlags.value.isFetchingItem);
|
||||
const isMergingContact = computed(() => uiFlags.value.isMerging);
|
||||
const isUpdatingContact = computed(() => uiFlags.value.isUpdating);
|
||||
|
||||
const selectedContact = computed(() => contact.value(route.params.contactId));
|
||||
|
||||
@@ -88,6 +90,33 @@ const fetchAttributes = () => {
|
||||
store.dispatch('attributes/get');
|
||||
};
|
||||
|
||||
const toggleContactBlock = async isBlocked => {
|
||||
const ALERT_MESSAGES = {
|
||||
success: {
|
||||
block: t('CONTACTS_LAYOUT.HEADER.ACTIONS.BLOCK_SUCCESS_MESSAGE'),
|
||||
unblock: t('CONTACTS_LAYOUT.HEADER.ACTIONS.UNBLOCK_SUCCESS_MESSAGE'),
|
||||
},
|
||||
error: {
|
||||
block: t('CONTACTS_LAYOUT.HEADER.ACTIONS.BLOCK_ERROR_MESSAGE'),
|
||||
unblock: t('CONTACTS_LAYOUT.HEADER.ACTIONS.UNBLOCK_ERROR_MESSAGE'),
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
await store.dispatch(`contacts/update`, {
|
||||
...selectedContact.value,
|
||||
blocked: !isBlocked,
|
||||
});
|
||||
useAlert(
|
||||
isBlocked ? ALERT_MESSAGES.success.unblock : ALERT_MESSAGES.success.block
|
||||
);
|
||||
} catch (error) {
|
||||
useAlert(
|
||||
isBlocked ? ALERT_MESSAGES.error.unblock : ALERT_MESSAGES.error.block
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchActiveContact();
|
||||
fetchContactNotes();
|
||||
@@ -105,7 +134,9 @@ onMounted(() => {
|
||||
:selected-contact="selectedContact"
|
||||
is-detail-view
|
||||
:show-pagination-footer="false"
|
||||
:is-updating="isUpdatingContact"
|
||||
@go-to-contacts-list="goToContactsList"
|
||||
@toggle-block="toggleContactBlock"
|
||||
>
|
||||
<div
|
||||
v-if="showSpinner"
|
||||
|
||||
Reference in New Issue
Block a user