chore: Review fixes
This commit is contained in:
+91
-72
@@ -1,11 +1,13 @@
|
||||
<script setup>
|
||||
import { computed, useTemplateRef } from 'vue';
|
||||
import { getLastMessage } from 'dashboard/helper/conversationHelper';
|
||||
import CardMetaSection from './CardMetaSection.vue';
|
||||
import Icon from 'dashboard/components-next/Icon/Icon.vue';
|
||||
import TimeAgo from 'dashboard/components/ui/TimeAgo.vue';
|
||||
import InboxName from 'dashboard/components-next/Conversation/InboxName.vue';
|
||||
import CardAvatar from './CardAvatar.vue';
|
||||
import CardHeader from './CardHeader.vue';
|
||||
import CardContent from './CardContent.vue';
|
||||
import CardLabels from './CardLabels.vue';
|
||||
import CardPriorityIcon from './CardPriorityIcon.vue';
|
||||
import SLACardLabel from 'dashboard/components-next/Conversation/Sla/SLACardLabel.vue';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -20,7 +22,6 @@ const props = defineProps({
|
||||
showInboxName: { type: Boolean, default: false },
|
||||
hideThumbnail: { type: Boolean, default: false },
|
||||
enableSelection: { type: Boolean, default: true },
|
||||
isInboxView: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const emit = defineEmits(['selectConversation', 'click', 'contextmenu']);
|
||||
@@ -28,10 +29,6 @@ const emit = defineEmits(['selectConversation', 'click', 'contextmenu']);
|
||||
const slaCardLabel = useTemplateRef('slaCardLabel');
|
||||
|
||||
const lastMessageInChat = computed(() => getLastMessage(props.chat));
|
||||
const showLabelsSection = computed(() => props.chat.labels?.length > 0);
|
||||
const showExpandedPreview = computed(
|
||||
() => props.compact && !showLabelsSection.value
|
||||
);
|
||||
|
||||
const voiceCallData = computed(() => ({
|
||||
status: props.chat.additional_attributes?.call_status,
|
||||
@@ -39,11 +36,23 @@ const voiceCallData = computed(() => ({
|
||||
}));
|
||||
|
||||
const unreadCount = computed(() => props.chat?.unread_count);
|
||||
const hasUnread = computed(() => unreadCount.value > 0);
|
||||
|
||||
const hasSlaPolicyId = computed(
|
||||
() => props.chat?.sla_policy_id || slaCardLabel.value?.hasSlaThreshold
|
||||
);
|
||||
|
||||
const showLabelsSection = computed(
|
||||
() => props.chat.labels?.length > 0 || hasSlaPolicyId.value
|
||||
);
|
||||
|
||||
const showMetaSection = computed(
|
||||
() =>
|
||||
props.showInboxName ||
|
||||
(props.showAssignee && props.assignee?.name) ||
|
||||
props.chat.priority
|
||||
);
|
||||
|
||||
const onSelectConversation = checked => {
|
||||
emit('selectConversation', checked);
|
||||
};
|
||||
@@ -51,85 +60,95 @@ const onSelectConversation = checked => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="relative flex items-start flex-grow-0 flex-shrink-0 w-auto max-w-full cursor-pointer group transition-colors duration-150"
|
||||
class="relative flex items-start max-w-full cursor-pointer group transition-colors duration-150 hover:bg-n-alpha-1 dark:hover:bg-n-alpha-3"
|
||||
:class="{
|
||||
'active animate-card-select bg-n-alpha-1 dark:bg-n-alpha-3': isActiveChat,
|
||||
'selected bg-n-slate-2 dark:bg-n-slate-3': selected,
|
||||
'px-0 py-3': compact,
|
||||
'px-2 pt-2.5 pb-3 hover:bg-n-alpha-1 rounded-lg': !compact,
|
||||
'active animate-card-select bg-n-background border-n-weak': isActiveChat,
|
||||
'bg-n-slate-2': selected,
|
||||
'px-0': compact,
|
||||
'px-2 rounded-lg': !compact,
|
||||
}"
|
||||
@click="$emit('click', $event)"
|
||||
@contextmenu="$emit('contextmenu', $event)"
|
||||
>
|
||||
<div class="min-w-0 w-full">
|
||||
<CardMetaSection
|
||||
v-if="!isInboxView"
|
||||
:chat="chat"
|
||||
:inbox="inbox"
|
||||
:show-inbox-name="showInboxName"
|
||||
:show-assignee="showAssignee"
|
||||
:assignee="assignee"
|
||||
<div class="relative">
|
||||
<CardAvatar
|
||||
v-if="!compact && !hideThumbnail"
|
||||
:contact="currentContact"
|
||||
:selected="selected"
|
||||
:enable-selection="enableSelection"
|
||||
:hide-thumbnail="hideThumbnail"
|
||||
:class="showMetaSection ? 'mt-8' : 'mt-4'"
|
||||
@select-conversation="onSelectConversation"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="px-0 py-3 border-b group-hover:border-transparent flex-1 border-n-slate-3 min-w-0"
|
||||
>
|
||||
<div
|
||||
class="grid gap-2.5 items-start"
|
||||
v-if="showMetaSection"
|
||||
class="flex items-center min-w-0 gap-1"
|
||||
:class="{
|
||||
'mt-0.5 grid-cols-1': compact,
|
||||
'grid-cols-[auto,1fr]': !compact,
|
||||
'ltr:ml-2 rtl:mr-2': !compact,
|
||||
'mx-2': compact,
|
||||
}"
|
||||
>
|
||||
<CardAvatar
|
||||
v-if="!compact"
|
||||
:contact="currentContact"
|
||||
:selected="selected"
|
||||
:enable-selection="enableSelection"
|
||||
:hide-thumbnail="hideThumbnail"
|
||||
class="mt-0.5"
|
||||
@select-conversation="onSelectConversation"
|
||||
/>
|
||||
|
||||
<div class="min-w-0 flex flex-col gap-1.5">
|
||||
<div class="min-w-0 flex flex-col gap-px">
|
||||
<CardHeader
|
||||
v-if="!compact"
|
||||
:contact-name="currentContact.name"
|
||||
:timestamp="chat.timestamp"
|
||||
:created-at="chat.created_at"
|
||||
/>
|
||||
|
||||
<CardContent
|
||||
:last-message="lastMessageInChat"
|
||||
:voice-call-status="voiceCallData.status"
|
||||
:voice-call-direction="voiceCallData.direction"
|
||||
:unread-count="unreadCount"
|
||||
:show-expanded-preview="showExpandedPreview"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CardLabels
|
||||
v-if="showLabelsSection || isInboxView"
|
||||
:labels="chat.labels"
|
||||
<InboxName v-if="showInboxName" :inbox="inbox" class="flex-1 min-w-0" />
|
||||
<div
|
||||
class="flex items-center gap-2 flex-shrink-0 h-4"
|
||||
:class="{
|
||||
'flex-1 justify-between': !showInboxName,
|
||||
}"
|
||||
>
|
||||
<span
|
||||
v-if="showAssignee && assignee.name"
|
||||
class="text-n-slate-11 text-label-small px-0 inline-flex items-center truncate gap-0.5 max-w-36"
|
||||
>
|
||||
<template #before>
|
||||
<CardMetaSection
|
||||
v-if="isInboxView"
|
||||
:chat="chat"
|
||||
:inbox="inbox"
|
||||
:show-assignee="showAssignee"
|
||||
:assignee="assignee"
|
||||
:is-labels-empty="chat.labels.length === 0"
|
||||
inline
|
||||
/>
|
||||
<SLACardLabel
|
||||
v-else-if="hasSlaPolicyId"
|
||||
ref="slaCardLabel"
|
||||
data-before-slot
|
||||
:chat="chat"
|
||||
/>
|
||||
</template>
|
||||
</CardLabels>
|
||||
<Icon icon="i-lucide-user-round" class="text-n-slate-11 size-3" />
|
||||
{{ assignee.name }}
|
||||
</span>
|
||||
<CardPriorityIcon
|
||||
v-if="chat.priority"
|
||||
:priority="chat.priority"
|
||||
class="flex-shrink-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inline-flex items-center justify-between w-full">
|
||||
<h4
|
||||
class="text-heading-3 mx-2 capitalize pt-0.5 truncate flex-1 min-w-0 text-n-slate-12"
|
||||
:class="hasUnread ? 'font-semibold' : ''"
|
||||
>
|
||||
{{ currentContact.name }}
|
||||
</h4>
|
||||
|
||||
<span class="text-label-small text-n-slate-11">
|
||||
<TimeAgo
|
||||
:last-activity-timestamp="chat.timestamp"
|
||||
:created-at-timestamp="chat.created_at"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mx-2 leading-6 h-6 min-w-0">
|
||||
<CardContent
|
||||
:last-message="lastMessageInChat"
|
||||
:voice-call-status="voiceCallData.status"
|
||||
:voice-call-direction="voiceCallData.direction"
|
||||
:unread-count="unreadCount"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CardLabels
|
||||
v-if="showLabelsSection"
|
||||
:labels="chat.labels"
|
||||
class="mt-0.5 mx-2"
|
||||
>
|
||||
<template v-if="hasSlaPolicyId" #before>
|
||||
<SLACardLabel ref="slaCardLabel" :chat="chat" data-before-slot />
|
||||
</template>
|
||||
</CardLabels>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
+2
-50
@@ -6,8 +6,8 @@ import { frontendURL, conversationUrl } from 'dashboard/helper/URLHelper';
|
||||
import ContextMenu from 'dashboard/components/ui/ContextMenu.vue';
|
||||
import ConversationContextMenu from 'dashboard/components/widgets/conversation/contextMenu/Index.vue';
|
||||
import ConversationCardExpanded from './ConversationCardExpanded.vue';
|
||||
// import ConversationCardCompact from './ConversationCardCompact.vue';
|
||||
import ConversationCard from 'dashboard/components/widgets/conversation/ConversationCard.vue';
|
||||
import ConversationCardCompact from './ConversationCardCompact.vue';
|
||||
// import ConversationCard from 'dashboard/components/widgets/conversation/ConversationCard.vue';
|
||||
|
||||
const props = defineProps({
|
||||
activeLabel: { type: String, default: '' },
|
||||
@@ -197,53 +197,6 @@ const deleteConversation = () => {
|
||||
/>
|
||||
|
||||
<!-- Compact: All other cases (mobile OR isExpandedLayout=false) - Using older ConversationCard -->
|
||||
<ConversationCard
|
||||
v-else
|
||||
:active-label="activeLabel"
|
||||
:team-id="teamId"
|
||||
:folders-id="foldersId"
|
||||
:chat="chat"
|
||||
:conversation-type="conversationType"
|
||||
:selected="selected"
|
||||
:show-assignee="showAssignee"
|
||||
:hide-thumbnail="hideThumbnail"
|
||||
:compact="compact"
|
||||
:enable-context-menu="enableContextMenu"
|
||||
:allowed-context-menu-options="allowedContextMenuOptions"
|
||||
@select-conversation="
|
||||
(chatId, inboxId) => emit('selectConversation', chatId, inboxId)
|
||||
"
|
||||
@de-select-conversation="
|
||||
(chatId, inboxId) => emit('deSelectConversation', chatId, inboxId)
|
||||
"
|
||||
@assign-agent="
|
||||
(agent, conversationIds) => emit('assignAgent', agent, conversationIds)
|
||||
"
|
||||
@assign-label="
|
||||
(labels, conversationIds) => emit('assignLabel', labels, conversationIds)
|
||||
"
|
||||
@remove-label="
|
||||
(labels, conversationIds) => emit('removeLabel', labels, conversationIds)
|
||||
"
|
||||
@assign-team="
|
||||
(team, conversationId) => emit('assignTeam', team, conversationId)
|
||||
"
|
||||
@mark-as-unread="conversationId => emit('markAsUnread', conversationId)"
|
||||
@mark-as-read="conversationId => emit('markAsRead', conversationId)"
|
||||
@assign-priority="
|
||||
(priority, conversationId) =>
|
||||
emit('assignPriority', priority, conversationId)
|
||||
"
|
||||
@update-conversation-status="
|
||||
(conversationId, status, snoozedUntil) =>
|
||||
emit('updateConversationStatus', conversationId, status, snoozedUntil)
|
||||
"
|
||||
@delete-conversation="
|
||||
conversationId => emit('deleteConversation', conversationId)
|
||||
"
|
||||
@context-menu-toggle="state => emit('contextMenuToggle', state)"
|
||||
/>
|
||||
<!-- New ConversationCardCompact
|
||||
<ConversationCardCompact
|
||||
v-else
|
||||
:chat="chat"
|
||||
@@ -262,7 +215,6 @@ const deleteConversation = () => {
|
||||
@click="onCardClick"
|
||||
@contextmenu="openContextMenu"
|
||||
/>
|
||||
-->
|
||||
|
||||
<ContextMenu
|
||||
v-if="showContextMenu"
|
||||
|
||||
@@ -143,10 +143,10 @@ async function assignPriority(priority, conversationId = null) {
|
||||
|
||||
async function markAsUnread(conversationId) {
|
||||
try {
|
||||
emit('redirectToList');
|
||||
await store.dispatch('markMessagesUnread', {
|
||||
id: conversationId,
|
||||
});
|
||||
emit('redirectToList');
|
||||
} catch (error) {
|
||||
// Ignore error
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { provide, useTemplateRef, shallowRef, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStore } from 'vuex';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { Virtualizer } from 'virtua/vue';
|
||||
import { useInfiniteScroll, useBreakpoints } from '@vueuse/core';
|
||||
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
||||
@@ -13,6 +13,11 @@ import Icon from 'dashboard/components-next/icon/Icon.vue';
|
||||
import Dialog from 'dashboard/components-next/dialog/Dialog.vue';
|
||||
import ConversationResolveAttributesModal from 'dashboard/components-next/ConversationWorkflow/ConversationResolveAttributesModal.vue';
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import {
|
||||
isOnMentionsView,
|
||||
isOnUnattendedView,
|
||||
} from 'dashboard/store/modules/conversations/helpers/actionHelpers';
|
||||
import { conversationListPageURL } from 'dashboard/helper/URLHelper';
|
||||
|
||||
const props = defineProps({
|
||||
items: { type: Array, default: () => [] },
|
||||
@@ -31,6 +36,7 @@ const emit = defineEmits(['loadMore']);
|
||||
const { t } = useI18n();
|
||||
const store = useStore();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const parentRef = useTemplateRef('parentRef');
|
||||
const virtualizerRef = shallowRef(null);
|
||||
@@ -112,27 +118,27 @@ function handleDeleteConversation(conversationId) {
|
||||
}
|
||||
|
||||
function redirectToConversationList() {
|
||||
const accountId = store.getters.getCurrentAccountId;
|
||||
const conversationType = props.conversationType || '';
|
||||
const inboxId = store.getters.getSelectedInbox?.id;
|
||||
const {
|
||||
params: { accountId, inbox_id: inboxId, label, teamId },
|
||||
name,
|
||||
} = route;
|
||||
|
||||
let path = `/app/accounts/${accountId}/conversations`;
|
||||
|
||||
if (conversationType === 'mention') {
|
||||
path = `/app/accounts/${accountId}/mentions/conversations`;
|
||||
} else if (conversationType === 'unattended') {
|
||||
path = `/app/accounts/${accountId}/unattended/conversations`;
|
||||
} else if (props.foldersId) {
|
||||
path = `/app/accounts/${accountId}/custom_view/${props.foldersId}`;
|
||||
} else if (props.teamId) {
|
||||
path = `/app/accounts/${accountId}/team/${props.teamId}`;
|
||||
} else if (props.label) {
|
||||
path = `/app/accounts/${accountId}/label/${props.label}`;
|
||||
} else if (inboxId) {
|
||||
path = `/app/accounts/${accountId}/inbox/${inboxId}`;
|
||||
let conversationType = '';
|
||||
if (isOnMentionsView({ route: { name } })) {
|
||||
conversationType = 'mention';
|
||||
} else if (isOnUnattendedView({ route: { name } })) {
|
||||
conversationType = 'unattended';
|
||||
}
|
||||
|
||||
router.push(path);
|
||||
router.push(
|
||||
conversationListPageURL({
|
||||
accountId,
|
||||
conversationType: conversationType,
|
||||
customViewId: props.foldersId,
|
||||
inboxId,
|
||||
label,
|
||||
teamId,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async function deleteConversation() {
|
||||
|
||||
Reference in New Issue
Block a user