feat: Advanced conversation sort options (#8532)

Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Muhsin Keloth
2023-12-13 09:29:31 +05:30
committed by GitHub
parent 8c9a351c84
commit 60a312ace5
8 changed files with 251 additions and 60 deletions

View File

@@ -1,8 +1,5 @@
import {
MESSAGE_TYPE,
CONVERSATION_PRIORITY_ORDER,
} from 'shared/constants/messages';
import { applyPageFilters } from './helpers';
import { MESSAGE_TYPE } from 'shared/constants/messages';
import { applyPageFilters, sortComparator } from './helpers';
export const getSelectedChatConversation = ({
allConversations,
@@ -10,36 +7,9 @@ export const getSelectedChatConversation = ({
}) =>
allConversations.filter(conversation => conversation.id === selectedChatId);
const sortComparator = {
latest: (a, b) => b.last_activity_at - a.last_activity_at,
sort_on_created_at: (a, b) => a.created_at - b.created_at,
sort_on_priority: (a, b) => {
return (
CONVERSATION_PRIORITY_ORDER[a.priority] -
CONVERSATION_PRIORITY_ORDER[b.priority]
);
},
sort_on_waiting_since: (a, b) => {
if (!a.waiting_since && !b.waiting_since) {
return a.created_at - b.created_at;
}
if (!a.waiting_since) {
return 1;
}
if (!b.waiting_since) {
return -1;
}
return a.waiting_since - b.waiting_since;
},
};
// getters
const getters = {
getAllConversations: ({ allConversations, chatSortFilter }) => {
return allConversations.sort(sortComparator[chatSortFilter]);
getAllConversations: ({ allConversations, chatSortFilter: sortKey }) => {
return allConversations.sort((a, b) => sortComparator(a, b, sortKey));
},
getSelectedChat: ({ selectedChatId, allConversations }) => {
const selectedChat = allConversations.find(

View File

@@ -1,3 +1,5 @@
import { CONVERSATION_PRIORITY_ORDER } from 'shared/constants/messages';
export const findPendingMessageIndex = (chat, message) => {
const { echo_id: tempMessageId } = message;
return chat.messages.findIndex(
@@ -59,3 +61,53 @@ export const applyPageFilters = (conversation, filters) => {
return shouldFilter;
};
const SORT_OPTIONS = {
last_activity_at_asc: ['sortOnLastActivityAt', 'asc'],
last_activity_at_desc: ['sortOnLastActivityAt', 'desc'],
created_at_asc: ['sortOnCreatedAt', 'asc'],
created_at_desc: ['sortOnCreatedAt', 'desc'],
priority_asc: ['sortOnPriority', 'asc'],
priority_desc: ['sortOnPriority', 'desc'],
waiting_since_asc: ['sortOnWaitingSince', 'asc'],
waiting_since_desc: ['sortOnWaitingSince', 'desc'],
};
const sortAscending = (valueA, valueB) => valueA - valueB;
const sortDescending = (valueA, valueB) => valueB - valueA;
const getSortOrderFunction = sortOrder =>
sortOrder === 'asc' ? sortAscending : sortDescending;
const sortConfig = {
sortOnLastActivityAt: (a, b, sortDirection) =>
getSortOrderFunction(sortDirection)(a.last_activity_at, b.last_activity_at),
sortOnCreatedAt: (a, b, sortDirection) =>
getSortOrderFunction(sortDirection)(a.created_at, b.created_at),
sortOnPriority: (a, b, sortDirection) => {
const DEFAULT_FOR_NULL = sortDirection === 'asc' ? 5 : 0;
const p1 = CONVERSATION_PRIORITY_ORDER[a.priority] || DEFAULT_FOR_NULL;
const p2 = CONVERSATION_PRIORITY_ORDER[b.priority] || DEFAULT_FOR_NULL;
return getSortOrderFunction(sortDirection)(p1, p2);
},
sortOnWaitingSince: (a, b, sortDirection) => {
const sortFunc = getSortOrderFunction(sortDirection);
if (!a.waiting_since || !b.waiting_since) {
if (!a.waiting_since && !b.waiting_since) {
return sortFunc(a.created_at, b.created_at);
}
return sortFunc(a.waiting_since ? 0 : 1, b.waiting_since ? 0 : 1);
}
return sortFunc(a.waiting_since, b.waiting_since);
},
};
export const sortComparator = (a, b, sortKey) => {
const [sortMethod, sortDirection] = SORT_OPTIONS[sortKey] || [];
return sortConfig[sortMethod](a, b, sortDirection);
};

View File

@@ -47,6 +47,49 @@ describe('#getters', () => {
},
]);
});
it('order conversations based on last activity with ascending order', () => {
const state = {
allConversations: [
{
id: 1,
messages: [
{
content: 'test1',
},
],
created_at: 2466424490,
last_activity_at: 2466424490,
},
{
id: 2,
messages: [{ content: 'test2' }],
created_at: 1466424480,
last_activity_at: 1466424480,
},
],
chatSortFilter: 'latest_last',
};
expect(getters.getAllConversations(state)).toEqual([
{
id: 2,
messages: [{ content: 'test2' }],
created_at: 1466424480,
last_activity_at: 1466424480,
},
{
id: 1,
messages: [
{
content: 'test1',
},
],
created_at: 2466424490,
last_activity_at: 2466424490,
},
]);
});
it('order conversations based on created at', () => {
const state = {
allConversations: [
@@ -67,7 +110,7 @@ describe('#getters', () => {
last_activity_at: 1466424480,
},
],
chatSortFilter: 'sort_on_created_at',
chatSortFilter: 'created_at_last',
};
expect(getters.getAllConversations(state)).toEqual([
@@ -89,6 +132,50 @@ describe('#getters', () => {
},
]);
});
it('order conversations based on created at with descending order', () => {
const state = {
allConversations: [
{
id: 1,
messages: [
{
content: 'test1',
},
],
created_at: 1683645801, // Tuesday, 9 May 2023
last_activity_at: 2466424490,
},
{
id: 2,
messages: [{ content: 'test2' }],
created_at: 1652109801, // Monday, 9 May 2022
last_activity_at: 1466424480,
},
],
chatSortFilter: 'created_at_first',
};
expect(getters.getAllConversations(state)).toEqual([
{
id: 1,
messages: [
{
content: 'test1',
},
],
created_at: 1683645801,
last_activity_at: 2466424490,
},
{
id: 2,
messages: [{ content: 'test2' }],
created_at: 1652109801,
last_activity_at: 1466424480,
},
]);
});
it('order conversations based on default order', () => {
const state = {
allConversations: [
@@ -159,7 +246,7 @@ describe('#getters', () => {
last_activity_at: 1466421280,
},
],
chatSortFilter: 'sort_on_priority',
chatSortFilter: 'priority_first',
};
expect(getters.getAllConversations(state)).toEqual([
@@ -190,6 +277,68 @@ describe('#getters', () => {
},
]);
});
it('order conversations based on with descending order', () => {
const state = {
allConversations: [
{
id: 1,
messages: [
{
content: 'test1',
},
],
priority: 'low',
created_at: 1683645801,
last_activity_at: 2466424490,
},
{
id: 2,
messages: [{ content: 'test2' }],
priority: 'urgent',
created_at: 1652109801,
last_activity_at: 1466424480,
},
{
id: 3,
messages: [{ content: 'test3' }],
priority: 'medium',
created_at: 1652109801,
last_activity_at: 1466421280,
},
],
chatSortFilter: 'priority_last',
};
expect(getters.getAllConversations(state)).toEqual([
{
id: 1,
messages: [
{
content: 'test1',
},
],
priority: 'low',
created_at: 1683645801,
last_activity_at: 2466424490,
},
{
id: 3,
messages: [{ content: 'test3' }],
priority: 'medium',
created_at: 1652109801,
last_activity_at: 1466421280,
},
{
id: 2,
messages: [{ content: 'test2' }],
priority: 'urgent',
created_at: 1652109801,
last_activity_at: 1466424480,
},
]);
});
it('order conversations based on waiting_since', () => {
const state = {
allConversations: [
@@ -214,7 +363,7 @@ describe('#getters', () => {
waiting_since: 1683645800,
},
],
chatSortFilter: 'sort_on_waiting_since',
chatSortFilter: 'waiting_since_last',
};
expect(getters.getAllConversations(state)).toEqual([