Skip to content

Commit

Permalink
feat: Advanced conversation sort options (#8532)
Browse files Browse the repository at this point in the history
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
  • Loading branch information
muhsin-k and pranavrajs committed Dec 13, 2023
1 parent 8c9a351 commit 60a312a
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 60 deletions.
7 changes: 5 additions & 2 deletions app/javascript/dashboard/components/ChatList.vue
Expand Up @@ -269,7 +269,7 @@ export default {
return {
activeAssigneeTab: wootConstants.ASSIGNEE_TYPE.ME,
activeStatus: wootConstants.STATUS_TYPE.OPEN,
activeSortBy: wootConstants.SORT_BY_TYPE.LATEST,
activeSortBy: wootConstants.SORT_BY_TYPE.LAST_ACTIVITY_AT_DESC,
showAdvancedFilters: false,
advancedFilterTypes: advancedFilterTypes.map(filter => ({
...filter,
Expand Down Expand Up @@ -553,7 +553,10 @@ export default {
const { conversations_filter_by: filterBy = {} } = this.uiSettings;
const { status, order_by: orderBy } = filterBy;
this.activeStatus = status || wootConstants.STATUS_TYPE.OPEN;
this.activeSortBy = orderBy || wootConstants.SORT_BY_TYPE.LATEST;
this.activeSortBy =
Object.keys(wootConstants.SORT_BY_TYPE).find(
sortField => sortField === orderBy
) || wootConstants.SORT_BY_TYPE.LAST_ACTIVITY_AT_DESC;
},
onClickOpenAddFoldersModal() {
this.showAddFoldersModal = true;
Expand Down
Expand Up @@ -34,7 +34,7 @@
type="sort"
:selected-value="sortFilter"
:items="chatSortItems"
path-prefix="CHAT_LIST.CHAT_SORT_FILTER_ITEMS"
path-prefix="CHAT_LIST.SORT_ORDER_ITEMS"
@onChangeFilter="onChangeFilter"
/>
</div>
Expand All @@ -58,7 +58,7 @@ export default {
return {
showActionsDropdown: false,
chatStatusItems: this.$t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS'),
chatSortItems: this.$t('CHAT_LIST.CHAT_SORT_FILTER_ITEMS'),
chatSortItems: this.$t('CHAT_LIST.SORT_ORDER_ITEMS'),
};
},
computed: {
Expand All @@ -70,7 +70,9 @@ export default {
return this.chatStatusFilter || wootConstants.STATUS_TYPE.OPEN;
},
sortFilter() {
return this.chatSortFilter || wootConstants.SORT_BY_TYPE.LATEST;
return (
this.chatSortFilter || wootConstants.SORT_BY_TYPE.LAST_ACTIVITY_AT_DESC
);
},
},
methods: {
Expand Down
12 changes: 8 additions & 4 deletions app/javascript/dashboard/constants/globals.js
Expand Up @@ -13,10 +13,14 @@ export default {
ALL: 'all',
},
SORT_BY_TYPE: {
LATEST: 'latest',
CREATED_AT: 'sort_on_created_at',
PRIORITY: 'sort_on_priority',
WATIING_SINCE: 'waiting_since',
LAST_ACTIVITY_AT_ASC: 'last_activity_at_asc',
LAST_ACTIVITY_AT_DESC: 'last_activity_at_desc',
CREATED_AT_ASC: 'created_at_asc',
CREATED_AT_DESC: 'created_at_desc',
PRIORITY_ASC: 'priority_asc',
PRIORITY_DESC: 'priority_desc',
WAITING_SINCE_ASC: 'waiting_since_asc',
WAITING_SINCE_DESC: 'waiting_since_desc',
},
ARTICLE_STATUS_TYPES: {
DRAFT: 0,
Expand Down
30 changes: 21 additions & 9 deletions app/javascript/dashboard/i18n/locale/en/chatlist.json
Expand Up @@ -51,18 +51,30 @@
"ACTIVE": "Last activity"
}
},
"CHAT_SORT_FILTER_ITEMS": {
"latest": {
"TEXT": "Last activity"
"SORT_ORDER_ITEMS": {
"last_activity_at_asc": {
"TEXT": "Last activity: Oldest first"
},
"sort_on_created_at": {
"TEXT": "Created at"
"last_activity_at_desc": {
"TEXT": "Last activity: Newest first"
},
"sort_on_priority": {
"TEXT": "Priority"
"created_at_desc": {
"TEXT": "Created at: Newest first"
},
"sort_on_waiting_since": {
"TEXT": "Pending Response"
"created_at_asc": {
"TEXT": "Created at: Oldest first"
},
"priority_desc": {
"TEXT": "Priority: Highest first"
},
"priority_asc": {
"TEXT": "Priority: Lowest first"
},
"waiting_since_asc": {
"TEXT": "Pending Response: Longest first"
},
"waiting_since_desc": {
"TEXT": "Pending Response: Shortest first"
}
},
"ATTACHMENTS": {
Expand Down
38 changes: 4 additions & 34 deletions app/javascript/dashboard/store/modules/conversations/getters.js
@@ -1,45 +1,15 @@
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,
selectedChatId,
}) =>
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(
Expand Down
52 changes: 52 additions & 0 deletions app/javascript/dashboard/store/modules/conversations/helpers.js
@@ -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(
Expand Down Expand Up @@ -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);
};

0 comments on commit 60a312a

Please sign in to comment.