Files
d8a16278b9 fix: added ordering capability for sidebar sections folders, teams, channels and labels (CW-7193) (#14609)
## 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>
2026-06-15 21:34:19 +05:30

105 lines
3.0 KiB
Vue

<script setup>
import Icon from 'next/icon/Icon.vue';
import SidebarSortMenu from './SidebarSortMenu.vue';
defineProps({
collapsible: {
type: Boolean,
default: false,
},
isExpanded: {
type: Boolean,
default: true,
},
label: {
type: String,
default: '',
},
icon: {
type: [Object, String],
default: '',
},
sortOptions: {
type: Array,
default: () => [],
},
activeSort: {
type: String,
default: '',
},
showTreeLine: {
type: Boolean,
default: false,
},
endTreeLine: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['toggle', 'update-sort']);
const TREE_VERTICAL_LINE =
"before:content-[''] before:absolute before:-top-1 before:w-0.5 before:bg-n-slate-4 before:start-[-0.5rem]";
const TREE_ELBOW =
"after:content-[''] after:absolute after:w-2.5 after:h-3 after:bottom-1/2 after:start-[-0.5rem] after:border-b-2 after:border-s-2 after:rounded-es after:border-n-slate-4";
</script>
<template>
<div class="relative min-w-0" :class="{ 'ms-5': collapsible }">
<component
:is="collapsible ? 'button' : 'div'"
:type="collapsible ? 'button' : undefined"
:aria-expanded="collapsible ? isExpanded : undefined"
:title="label"
class="relative flex h-8 w-full min-w-0 items-center justify-between gap-2 rounded-lg px-2 py-1.5 text-n-slate-10 select-none"
:class="[
showTreeLine && TREE_VERTICAL_LINE,
showTreeLine &&
(endTreeLine ? `before:h-3 ${TREE_ELBOW}` : 'before:-bottom-1'),
{
'pointer-events-none': !collapsible,
'cursor-pointer hover:bg-n-alpha-2': collapsible,
'pe-14': collapsible && sortOptions.length,
'pe-8': collapsible && !sortOptions.length,
'pe-10': !collapsible && sortOptions.length,
},
]"
@click.stop="collapsible ? emit('toggle') : undefined"
>
<div class="inline-flex min-w-0 items-center gap-2">
<Icon v-if="icon" :icon="icon" class="size-4 flex-shrink-0" />
<span
class="flex-grow truncate text-start text-sm font-medium leading-5"
>
{{ label }}
</span>
</div>
</component>
<div
v-if="collapsible || sortOptions.length"
class="absolute end-2 top-1/2 flex -translate-y-1/2 items-center gap-1"
>
<SidebarSortMenu
v-if="sortOptions.length"
:active-sort="activeSort"
:options="sortOptions"
@sort="sortBy => emit('update-sort', sortBy)"
/>
<button
v-if="collapsible"
type="button"
class="flex size-6 flex-shrink-0 items-center justify-center rounded-md text-n-slate-10 hover:bg-n-alpha-2 focus-visible:bg-n-alpha-2 focus-visible:outline-none"
:aria-expanded="isExpanded"
:aria-label="label"
@click.stop="emit('toggle')"
>
<span
class="size-3 flex-shrink-0"
:class="isExpanded ? 'i-lucide-chevron-up' : 'i-lucide-chevron-down'"
/>
</button>
</div>
</div>
</template>