chore: Fix issues with Contact pages (#10544)
This commit is contained in:
@@ -50,7 +50,7 @@ const handleBreadcrumbClick = () => {
|
||||
|
||||
<template>
|
||||
<section
|
||||
class="flex w-full h-full gap-4 overflow-hidden justify-evenly bg-n-background"
|
||||
class="flex w-full h-full overflow-hidden justify-evenly bg-n-background"
|
||||
>
|
||||
<div
|
||||
class="flex flex-col w-full h-full transition-all duration-300 ltr:2xl:ml-56 rtl:2xl:mr-56"
|
||||
|
||||
@@ -93,7 +93,7 @@ const emit = defineEmits([
|
||||
"
|
||||
color="slate"
|
||||
size="sm"
|
||||
class="relative"
|
||||
class="relative w-8"
|
||||
variant="ghost"
|
||||
@click="emit('filter')"
|
||||
>
|
||||
@@ -109,7 +109,6 @@ const emit = defineEmits([
|
||||
icon="i-lucide-save"
|
||||
color="slate"
|
||||
size="sm"
|
||||
class="relative"
|
||||
variant="ghost"
|
||||
@click="emit('createSegment')"
|
||||
/>
|
||||
@@ -118,7 +117,6 @@ const emit = defineEmits([
|
||||
icon="i-lucide-trash"
|
||||
color="slate"
|
||||
size="sm"
|
||||
class="relative"
|
||||
variant="ghost"
|
||||
@click="emit('deleteSegment')"
|
||||
/>
|
||||
|
||||
@@ -1,28 +1,67 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useMapGetter } from 'dashboard/composables/store';
|
||||
import { useCamelCase } from 'dashboard/composables/useTransformKeys';
|
||||
|
||||
import ActiveFilterPreview from 'dashboard/components-next/filter/ActiveFilterPreview.vue';
|
||||
|
||||
const props = defineProps({
|
||||
activeSegment: { type: Object, default: null },
|
||||
});
|
||||
|
||||
const emit = defineEmits(['clearFilters', 'openFilter']);
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
const appliedFilters = useMapGetter('contacts/getAppliedContactFiltersV4');
|
||||
const activeSegmentId = computed(() => route.params.segmentId);
|
||||
|
||||
const activeSegmentQuery = computed(() => {
|
||||
const query = props.activeSegment?.query?.payload;
|
||||
if (!Array.isArray(query)) return [];
|
||||
|
||||
const newFilters = query.map(filter => {
|
||||
const transformed = useCamelCase(filter);
|
||||
return {
|
||||
attributeKey: transformed.attributeKey,
|
||||
attributeModel: transformed.attributeModel,
|
||||
customAttributeType: transformed.customAttributeType,
|
||||
filterOperator: transformed.filterOperator,
|
||||
queryOperator: transformed.queryOperator ?? 'and',
|
||||
values: transformed.values,
|
||||
};
|
||||
});
|
||||
|
||||
return newFilters;
|
||||
});
|
||||
|
||||
const hasActiveSegments = computed(
|
||||
() => props.activeSegment && activeSegmentId.value !== 0
|
||||
);
|
||||
|
||||
const activeFilterQueryData = computed(() => {
|
||||
return hasActiveSegments.value
|
||||
? activeSegmentQuery.value
|
||||
: appliedFilters.value;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ActiveFilterPreview
|
||||
:applied-filters="appliedFilters"
|
||||
:applied-filters="activeFilterQueryData"
|
||||
:max-visible-filters="2"
|
||||
:more-filters-label="
|
||||
t('CONTACTS_LAYOUT.FILTER.ACTIVE_FILTERS.MORE_FILTERS', {
|
||||
count: appliedFilters.length - 2,
|
||||
count: activeFilterQueryData.length - 2,
|
||||
})
|
||||
"
|
||||
:clear-button-label="
|
||||
t('CONTACTS_LAYOUT.FILTER.ACTIVE_FILTERS.CLEAR_FILTERS')
|
||||
"
|
||||
:show-clear-button="!hasActiveSegments"
|
||||
class="max-w-[960px] px-6"
|
||||
@open-filter="emit('openFilter')"
|
||||
@clear-filters="emit('clearFilters')"
|
||||
|
||||
@@ -7,50 +7,18 @@ import ContactsActiveFiltersPreview from 'dashboard/components-next/Contacts/Con
|
||||
import PaginationFooter from 'dashboard/components-next/pagination/PaginationFooter.vue';
|
||||
|
||||
defineProps({
|
||||
searchValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
headerTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
showPaginationFooter: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
currentPage: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
totalItems: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
},
|
||||
itemsPerPage: {
|
||||
type: Number,
|
||||
default: 15,
|
||||
},
|
||||
activeSort: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
activeOrdering: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
activeSegment: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
segmentsId: {
|
||||
type: [String, Number],
|
||||
default: 0,
|
||||
},
|
||||
hasAppliedFilters: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
searchValue: { type: String, default: '' },
|
||||
headerTitle: { type: String, default: '' },
|
||||
showPaginationFooter: { type: Boolean, default: true },
|
||||
currentPage: { type: Number, default: 1 },
|
||||
totalItems: { type: Number, default: 100 },
|
||||
itemsPerPage: { type: Number, default: 15 },
|
||||
activeSort: { type: String, default: '' },
|
||||
activeOrdering: { type: String, default: '' },
|
||||
activeSegment: { type: Object, default: null },
|
||||
segmentsId: { type: [String, Number], default: 0 },
|
||||
hasAppliedFilters: { type: Boolean, default: false },
|
||||
isFetchingList: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
@@ -106,7 +74,12 @@ const openFilter = () => {
|
||||
<main class="flex-1 overflow-y-auto">
|
||||
<div class="w-full mx-auto max-w-[960px]">
|
||||
<ContactsActiveFiltersPreview
|
||||
v-if="hasAppliedFilters && isNotSegmentView"
|
||||
v-if="
|
||||
(hasAppliedFilters || !isNotSegmentView) &&
|
||||
!isFetchingList &&
|
||||
!isLabelView
|
||||
"
|
||||
:active-segment="activeSegment"
|
||||
@clear-filters="emit('clearFilters')"
|
||||
@open-filter="openFilter"
|
||||
/>
|
||||
|
||||
@@ -34,22 +34,19 @@ const contactConversations = computed(() =>
|
||||
>
|
||||
<Spinner />
|
||||
</div>
|
||||
<div v-else-if="contactConversations.length > 0" class="flex flex-col py-6">
|
||||
<div
|
||||
<div
|
||||
v-else-if="contactConversations.length > 0"
|
||||
class="px-6 py-4 divide-y divide-n-strong [&>*:hover]:!border-y-transparent [&>*:hover+*]:!border-t-transparent"
|
||||
>
|
||||
<ConversationCard
|
||||
v-for="conversation in contactConversations"
|
||||
:key="conversation.id"
|
||||
class="border-b border-n-strong"
|
||||
>
|
||||
<ConversationCard
|
||||
v-if="conversation"
|
||||
:key="conversation.id"
|
||||
:conversation="conversation"
|
||||
:contact="contactsById(conversation.meta.sender.id)"
|
||||
:state-inbox="stateInbox(conversation.inboxId)"
|
||||
:account-labels="accountLabelsValue"
|
||||
class="px-6 !rounded-none dark:hover:bg-n-alpha-3 hover:bg-n-alpha-1"
|
||||
/>
|
||||
</div>
|
||||
:conversation="conversation"
|
||||
:contact="contactsById(conversation.meta.sender.id)"
|
||||
:state-inbox="stateInbox(conversation.inboxId)"
|
||||
:account-labels="accountLabelsValue"
|
||||
class="rounded-none hover:rounded-xl hover:bg-n-alpha-1 dark:hover:bg-n-alpha-3"
|
||||
/>
|
||||
</div>
|
||||
<p v-else class="px-6 py-10 text-sm leading-6 text-center text-n-slate-11">
|
||||
{{ t('CONTACTS_LAYOUT.SIDEBAR.HISTORY.EMPTY_STATE') }}
|
||||
|
||||
@@ -28,7 +28,7 @@ const handleDelete = () => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex flex-col gap-2 px-6 py-2 border-b border-n-strong group/note"
|
||||
class="flex flex-col gap-2 py-2 mx-6 border-b border-n-strong group/note"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-1.5 py-2.5 min-w-0">
|
||||
|
||||
@@ -82,7 +82,7 @@ const onCardClick = e => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex w-full gap-3 px-3 py-4 transition-colors duration-300 ease-in-out cursor-pointer rounded-xl"
|
||||
class="flex w-full gap-3 px-3 py-4 transition-all duration-300 ease-in-out cursor-pointer"
|
||||
@click="onCardClick"
|
||||
>
|
||||
<Avatar
|
||||
|
||||
@@ -4,22 +4,11 @@ import { replaceUnderscoreWithSpace } from './helper/filterHelper.js';
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
|
||||
defineProps({
|
||||
appliedFilters: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
maxVisibleFilters: {
|
||||
type: Number,
|
||||
default: 2,
|
||||
},
|
||||
clearButtonLabel: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
moreFiltersLabel: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
appliedFilters: { type: Array, default: () => [] },
|
||||
maxVisibleFilters: { type: Number, default: 2 },
|
||||
clearButtonLabel: { type: String, default: '' },
|
||||
moreFiltersLabel: { type: String, default: '' },
|
||||
showClearButton: { type: Boolean, default: true },
|
||||
});
|
||||
|
||||
const emit = defineEmits(['clearFilters', 'openFilter']);
|
||||
@@ -46,6 +35,9 @@ const formatOperatorLabel = operator => {
|
||||
|
||||
const formatFilterValue = value => {
|
||||
if (!value) return '';
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(', ');
|
||||
}
|
||||
if (typeof value === 'object' && value.name) {
|
||||
return value.name;
|
||||
}
|
||||
@@ -55,10 +47,7 @@ const formatFilterValue = value => {
|
||||
|
||||
<template>
|
||||
<div class="flex flex-wrap items-center w-full gap-2 mx-auto">
|
||||
<template
|
||||
v-for="(filter, index) in appliedFilters"
|
||||
:key="filter.attributeKey"
|
||||
>
|
||||
<template v-for="(filter, index) in appliedFilters" :key="index">
|
||||
<div
|
||||
v-if="index < maxVisibleFilters"
|
||||
class="inline-flex items-center gap-2 h-7"
|
||||
@@ -107,8 +96,9 @@ const formatFilterValue = value => {
|
||||
>
|
||||
{{ moreFiltersLabel }}
|
||||
</div>
|
||||
<div class="w-px h-3 rounded-lg bg-n-strong" />
|
||||
<div v-if="showClearButton" class="w-px h-3 rounded-lg bg-n-strong" />
|
||||
<Button
|
||||
v-if="showClearButton"
|
||||
:label="clearButtonLabel"
|
||||
size="xs"
|
||||
class="!px-1"
|
||||
|
||||
@@ -256,6 +256,7 @@ onMounted(async () => {
|
||||
:active-ordering="sortState.activeOrdering"
|
||||
:active-segment="activeSegment"
|
||||
:segments-id="activeSegmentId"
|
||||
:is-fetching-list="isFetchingList"
|
||||
:has-applied-filters="hasAppliedFilters"
|
||||
@update:current-page="fetchContactsBasedOnContext"
|
||||
@search="searchContacts"
|
||||
|
||||
Reference in New Issue
Block a user