## Description * Added the ability to sort for 4 sub-sections under conversations folders, teams, channels and labels. * the sort options are basically created at, alphabetical and unread counts along with both directions. * for folders we don't have an unread count, so we sort it by only created and alphabetical. * all the sort preferences are stored on the frontend - easiest implementation for now. Fixes # CW-7193 ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) - [ ] This change requires a documentation update ## How Has This Been Tested? Tested this locally by visually verifying the changes. Also ran the newly added tests for component level changes. Here is the screenshot of the changes: Added the sort option to sub sections in the conversation sidebar: <img width="282" height="848" alt="Screenshot 2026-06-02 at 1 58 12 AM" src="https://github.com/user-attachments/assets/4a7c6061-86e3-438a-92ae-ee643a0128b6" /> The sort options looks like this: <img width="783" height="698" alt="Screenshot 2026-06-02 at 1 58 49 AM" src="https://github.com/user-attachments/assets/a15bb0a7-b810-4423-a88c-fbd84d0476c0" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: iamsivin <iamsivin@gmail.com>
206 lines
5.4 KiB
JavaScript
206 lines
5.4 KiB
JavaScript
import {
|
|
DEFAULT_SIDEBAR_SORT_PREFERENCES,
|
|
SIDEBAR_SORT_KEYS,
|
|
SIDEBAR_SORT_SECTIONS,
|
|
getSidebarSortOptions,
|
|
normalizeSidebarSortPreferences,
|
|
resolveSidebarSort,
|
|
sortSidebarItems,
|
|
} from '../sidebarSort';
|
|
|
|
const items = [
|
|
{
|
|
id: 1,
|
|
name: 'Billing',
|
|
created_at: '2024-01-01T00:00:00.000Z',
|
|
},
|
|
{
|
|
id: 3,
|
|
name: 'Accounts',
|
|
created_at: '2024-03-01T00:00:00.000Z',
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'Support',
|
|
created_at: '2024-02-01T00:00:00.000Z',
|
|
},
|
|
];
|
|
|
|
describe('#sortSidebarItems', () => {
|
|
it('sorts by created date descending', () => {
|
|
const sortedItems = sortSidebarItems(items, {
|
|
sortBy: SIDEBAR_SORT_KEYS.CREATED_DESC,
|
|
labelKey: item => item.name,
|
|
});
|
|
|
|
expect(sortedItems.map(item => item.name)).toEqual([
|
|
'Accounts',
|
|
'Support',
|
|
'Billing',
|
|
]);
|
|
});
|
|
|
|
it('sorts by created date ascending', () => {
|
|
const sortedItems = sortSidebarItems(items, {
|
|
sortBy: SIDEBAR_SORT_KEYS.CREATED_ASC,
|
|
labelKey: item => item.name,
|
|
});
|
|
|
|
expect(sortedItems.map(item => item.name)).toEqual([
|
|
'Billing',
|
|
'Support',
|
|
'Accounts',
|
|
]);
|
|
});
|
|
|
|
it('falls back to id when created date is not present', () => {
|
|
const sortedItems = sortSidebarItems(
|
|
items.map(({ created_at: _createdAt, ...item }) => item),
|
|
{
|
|
sortBy: SIDEBAR_SORT_KEYS.CREATED_DESC,
|
|
labelKey: item => item.name,
|
|
}
|
|
);
|
|
|
|
expect(sortedItems.map(item => item.id)).toEqual([3, 2, 1]);
|
|
});
|
|
|
|
it('sorts alphabetically from A to Z', () => {
|
|
const sortedItems = sortSidebarItems(items, {
|
|
sortBy: SIDEBAR_SORT_KEYS.ALPHABETICAL_ASC,
|
|
labelKey: item => item.name,
|
|
});
|
|
|
|
expect(sortedItems.map(item => item.name)).toEqual([
|
|
'Accounts',
|
|
'Billing',
|
|
'Support',
|
|
]);
|
|
});
|
|
|
|
it('sorts alphabetically from Z to A', () => {
|
|
const sortedItems = sortSidebarItems(items, {
|
|
sortBy: SIDEBAR_SORT_KEYS.ALPHABETICAL_DESC,
|
|
labelKey: item => item.name,
|
|
});
|
|
|
|
expect(sortedItems.map(item => item.name)).toEqual([
|
|
'Support',
|
|
'Billing',
|
|
'Accounts',
|
|
]);
|
|
});
|
|
|
|
it('sorts by unread count descending and falls back to alphabetical order', () => {
|
|
const unreadCounts = {
|
|
1: 3,
|
|
2: 3,
|
|
3: 7,
|
|
};
|
|
|
|
const sortedItems = sortSidebarItems(items, {
|
|
sortBy: SIDEBAR_SORT_KEYS.UNREAD_COUNT_DESC,
|
|
labelKey: item => item.name,
|
|
unreadCountKey: item => unreadCounts[item.id],
|
|
});
|
|
|
|
expect(sortedItems.map(item => item.name)).toEqual([
|
|
'Accounts',
|
|
'Billing',
|
|
'Support',
|
|
]);
|
|
});
|
|
|
|
it('sorts by unread count ascending and falls back to alphabetical order', () => {
|
|
const unreadCounts = {
|
|
1: 3,
|
|
2: 3,
|
|
3: 7,
|
|
};
|
|
|
|
const sortedItems = sortSidebarItems(items, {
|
|
sortBy: SIDEBAR_SORT_KEYS.UNREAD_COUNT_ASC,
|
|
labelKey: item => item.name,
|
|
unreadCountKey: item => unreadCounts[item.id],
|
|
});
|
|
|
|
expect(sortedItems.map(item => item.name)).toEqual([
|
|
'Billing',
|
|
'Support',
|
|
'Accounts',
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('#normalizeSidebarSortPreferences', () => {
|
|
it('keeps valid preferences', () => {
|
|
const preferences = normalizeSidebarSortPreferences({
|
|
[SIDEBAR_SORT_SECTIONS.FOLDERS]: SIDEBAR_SORT_KEYS.ALPHABETICAL_DESC,
|
|
[SIDEBAR_SORT_SECTIONS.TEAMS]: SIDEBAR_SORT_KEYS.CREATED_ASC,
|
|
});
|
|
|
|
expect(preferences).toEqual({
|
|
...DEFAULT_SIDEBAR_SORT_PREFERENCES,
|
|
[SIDEBAR_SORT_SECTIONS.FOLDERS]: SIDEBAR_SORT_KEYS.ALPHABETICAL_DESC,
|
|
[SIDEBAR_SORT_SECTIONS.TEAMS]: SIDEBAR_SORT_KEYS.CREATED_ASC,
|
|
});
|
|
});
|
|
|
|
it('falls back to defaults for unsupported preferences', () => {
|
|
const preferences = normalizeSidebarSortPreferences({
|
|
[SIDEBAR_SORT_SECTIONS.FOLDERS]: SIDEBAR_SORT_KEYS.UNREAD_COUNT_DESC,
|
|
});
|
|
|
|
expect(preferences).toEqual(DEFAULT_SIDEBAR_SORT_PREFERENCES);
|
|
});
|
|
|
|
it('falls back to defaults when stored preferences are null', () => {
|
|
expect(normalizeSidebarSortPreferences(null)).toEqual(
|
|
DEFAULT_SIDEBAR_SORT_PREFERENCES
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('#getSidebarSortOptions', () => {
|
|
it('keeps unread count options when unread counts are enabled', () => {
|
|
const options = getSidebarSortOptions(SIDEBAR_SORT_SECTIONS.TEAMS, {
|
|
hasUnreadCounts: true,
|
|
});
|
|
|
|
expect(options).toContain(SIDEBAR_SORT_KEYS.UNREAD_COUNT_DESC);
|
|
expect(options).toContain(SIDEBAR_SORT_KEYS.UNREAD_COUNT_ASC);
|
|
});
|
|
|
|
it('removes unread count options when unread counts are disabled', () => {
|
|
const options = getSidebarSortOptions(SIDEBAR_SORT_SECTIONS.TEAMS, {
|
|
hasUnreadCounts: false,
|
|
});
|
|
|
|
expect(options).not.toContain(SIDEBAR_SORT_KEYS.UNREAD_COUNT_DESC);
|
|
expect(options).not.toContain(SIDEBAR_SORT_KEYS.UNREAD_COUNT_ASC);
|
|
expect(options).toContain(SIDEBAR_SORT_KEYS.ALPHABETICAL_ASC);
|
|
});
|
|
});
|
|
|
|
describe('#resolveSidebarSort', () => {
|
|
it('keeps unread count sort when unread counts are enabled', () => {
|
|
const sortBy = resolveSidebarSort(
|
|
SIDEBAR_SORT_SECTIONS.TEAMS,
|
|
SIDEBAR_SORT_KEYS.UNREAD_COUNT_DESC,
|
|
{ hasUnreadCounts: true }
|
|
);
|
|
|
|
expect(sortBy).toBe(SIDEBAR_SORT_KEYS.UNREAD_COUNT_DESC);
|
|
});
|
|
|
|
it('falls back to alphabetical sort when unread counts are disabled', () => {
|
|
const sortBy = resolveSidebarSort(
|
|
SIDEBAR_SORT_SECTIONS.TEAMS,
|
|
SIDEBAR_SORT_KEYS.UNREAD_COUNT_DESC,
|
|
{ hasUnreadCounts: false }
|
|
);
|
|
|
|
expect(sortBy).toBe(SIDEBAR_SORT_KEYS.ALPHABETICAL_ASC);
|
|
});
|
|
});
|