Merge branch 'develop' into fix/CW-6859

This commit is contained in:
Sivin Varghese
2026-04-16 12:49:09 +05:30
committed by GitHub
12 changed files with 371 additions and 176 deletions
@@ -66,8 +66,7 @@ const selectionModel = computed({
return;
}
const shouldSelectAll =
newSet.size === props.visibleContactIds.length && newSet.size > 0;
const shouldSelectAll = props.visibleContactIds.every(id => newSet.has(id));
emit('toggleAll', shouldSelectAll);
},
});
@@ -151,7 +151,13 @@ const openBulkDeleteDialog = () => {
};
const toggleSelectAll = shouldSelect => {
selectedContactIds.value = shouldSelect ? [...visibleContactIds.value] : [];
const currentSelection = new Set(selectedContactIds.value);
if (shouldSelect) {
visibleContactIds.value.forEach(id => currentSelection.add(id));
} else {
visibleContactIds.value.forEach(id => currentSelection.delete(id));
}
selectedContactIds.value = Array.from(currentSelection);
};
const toggleContactSelection = ({ id, value }) => {
@@ -190,16 +196,28 @@ const getCommonFetchParams = (page = 1) => ({
label: activeLabel.value,
});
const fetchContacts = async (page = 1) => {
clearSelection();
const fetchContacts = async (page = 1, options = {}) => {
const { clearSelection: shouldClearSelection = true } = options;
if (shouldClearSelection) {
clearSelection();
}
await store.dispatch('contacts/clearContactFilters');
await store.dispatch('contacts/get', getCommonFetchParams(page));
updatePageParam(page);
};
const fetchSavedOrAppliedFilteredContact = async (payload, page = 1) => {
const fetchSavedOrAppliedFilteredContact = async (
payload,
page = 1,
options = {}
) => {
if (!activeSegmentId.value && !hasAppliedFilters.value) return;
clearSelection();
const { clearSelection: shouldClearSelection = true } = options;
if (shouldClearSelection) {
clearSelection();
}
await store.dispatch('contacts/filter', {
...getCommonFetchParams(page),
queryPayload: payload,
@@ -207,8 +225,12 @@ const fetchSavedOrAppliedFilteredContact = async (payload, page = 1) => {
updatePageParam(page);
};
const fetchActiveContacts = async (page = 1) => {
clearSelection();
const fetchActiveContacts = async (page = 1, options = {}) => {
const { clearSelection: shouldClearSelection = true } = options;
if (shouldClearSelection) {
clearSelection();
}
await store.dispatch('contacts/clearContactFilters');
await store.dispatch('contacts/active', {
page,
@@ -217,28 +239,36 @@ const fetchActiveContacts = async (page = 1) => {
updatePageParam(page);
};
const searchContacts = debounce(async (value, page = 1, append = false) => {
if (!append) {
clearSelection();
searchPageNumber.value = 1;
}
await store.dispatch('contacts/clearContactFilters');
searchValue.value = value;
const searchContacts = debounce(
async (value, page = 1, append = false, options = {}) => {
const { clearSelection: shouldClearSelection = true } = options;
if (!value) {
updatePageParam(page);
await fetchContacts(page);
return;
}
if (!append) {
searchPageNumber.value = 1;
updatePageParam(page, value);
await store.dispatch('contacts/search', {
...getCommonFetchParams(page),
search: encodeURIComponent(value),
append,
});
searchPageNumber.value = page;
}, DEBOUNCE_DELAY);
if (shouldClearSelection) {
clearSelection();
}
}
await store.dispatch('contacts/clearContactFilters');
searchValue.value = value;
if (!value) {
updatePageParam(page);
await fetchContacts(page, { clearSelection: false });
return;
}
updatePageParam(page, value);
await store.dispatch('contacts/search', {
...getCommonFetchParams(page),
search: encodeURIComponent(value),
append,
});
searchPageNumber.value = page;
},
DEBOUNCE_DELAY
);
const loadMoreSearchResults = async () => {
if (!hasMore.value || isLoadingMore.value) return;
@@ -256,19 +286,26 @@ const loadMoreSearchResults = async () => {
isLoadingMore.value = false;
};
const fetchContactsBasedOnContext = async page => {
clearSelection();
const fetchContactsBasedOnContext = async (page, options = {}) => {
const { clearSelection: shouldClearSelection = true } = options;
if (shouldClearSelection) {
clearSelection();
}
updatePageParam(page, searchValue.value);
if (isFetchingList.value) return;
if (searchQuery.value) {
await searchContacts(searchQuery.value, page);
await searchContacts(searchQuery.value, page, false, {
clearSelection: shouldClearSelection,
});
return;
}
// Reset the search value when we change the view
searchValue.value = '';
// If we're on the active route, fetch active contacts
if (isActiveView.value) {
await fetchActiveContacts(page);
await fetchActiveContacts(page, {
clearSelection: shouldClearSelection,
});
return;
}
// If there are applied filters or active segment with query
@@ -278,13 +315,20 @@ const fetchContactsBasedOnContext = async page => {
) {
const queryPayload =
activeSegment.value?.query || filterQueryGenerator(appliedFilters.value);
await fetchSavedOrAppliedFilteredContact(queryPayload, page);
await fetchSavedOrAppliedFilteredContact(queryPayload, page, {
clearSelection: shouldClearSelection,
});
return;
}
// Default case: fetch regular contacts + label
await fetchContacts(page);
await fetchContacts(page, {
clearSelection: shouldClearSelection,
});
};
const onPageChange = page =>
fetchContactsBasedOnContext(page, { clearSelection: false });
const assignLabels = async labels => {
if (!labels.length || !selectedContactIds.value.length) {
return;
@@ -338,7 +382,9 @@ const handleSort = async ({ sort, order }) => {
});
if (searchQuery.value) {
await searchContacts(searchValue.value);
await searchContacts(searchValue.value, pageNumber.value, false, {
clearSelection: false,
});
return;
}
@@ -360,17 +406,6 @@ const createContact = async contact => {
await store.dispatch('contacts/create', contact);
};
watch(
contacts,
newContacts => {
const idsOnPage = newContacts.map(contact => contact.id);
selectedContactIds.value = selectedContactIds.value.filter(id =>
idsOnPage.includes(id)
);
},
{ deep: true }
);
watch(hasSelection, value => {
if (!value) {
bulkDeleteDialogRef.value?.close?.();
@@ -416,7 +451,9 @@ watch(searchQuery, value => {
onMounted(async () => {
if (!activeSegmentId.value) {
if (searchQuery.value) {
await searchContacts(searchQuery.value, pageNumber.value);
await searchContacts(searchQuery.value, pageNumber.value, false, {
clearSelection: false,
});
return;
}
if (isActiveView.value) {
@@ -452,8 +489,10 @@ onMounted(async () => {
:use-infinite-scroll="isSearchView"
:has-more="hasMore"
:is-loading-more="isLoadingMore"
@update:current-page="fetchContactsBasedOnContext"
@search="searchContacts"
@update:current-page="onPageChange"
@search="
value => searchContacts(value, 1, false, { clearSelection: false })
"
@update:sort="handleSort"
@apply-filter="fetchSavedOrAppliedFilteredContact"
@clear-filters="fetchContacts"
@@ -485,6 +524,7 @@ onMounted(async () => {
:button-label="t('CONTACTS_LAYOUT.EMPTY_STATE.BUTTON_LABEL')"
@create="createContact"
/>
<div
v-else-if="showEmptyText"
class="flex items-center justify-center py-10"
@@ -493,6 +533,7 @@ onMounted(async () => {
{{ emptyStateMessage }}
</span>
</div>
<div v-else class="flex flex-col gap-4 pt-4 pb-6">
<ContactsList
:contacts="contacts"