## Description Added ability to collapse conversation sidebar sections (folders, teams, inboxes and labels) Fixes #CW-7059 ## 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 locally. Added specs. Attaching the loom for them same. https://github.com/user-attachments/assets/40d613e7-6c82-4078-abf4-79739a00f718 ## 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>
173 lines
5.0 KiB
JavaScript
173 lines
5.0 KiB
JavaScript
import { mount } from '@vue/test-utils';
|
|
import { ref } from 'vue';
|
|
import SidebarSubGroup from '../SidebarSubGroup.vue';
|
|
import { LOCAL_STORAGE_KEYS } from 'dashboard/constants/localStorage';
|
|
import { provideSidebarContext } from '../provider';
|
|
|
|
vi.mock('dashboard/composables/store', () => ({
|
|
useMapGetter: () => ref(1),
|
|
}));
|
|
|
|
vi.mock('dashboard/composables/usePolicy', () => ({
|
|
usePolicy: () => ({
|
|
shouldShow: () => true,
|
|
}),
|
|
}));
|
|
|
|
vi.mock('vue-router', () => ({
|
|
useRouter: () => ({
|
|
resolve: () => ({ path: '/' }),
|
|
getRoutes: () => [],
|
|
}),
|
|
}));
|
|
|
|
const children = [
|
|
{
|
|
name: 'Sales-1',
|
|
label: 'Sales',
|
|
to: { name: 'team_conversations' },
|
|
},
|
|
];
|
|
|
|
const mountSubGroup = props => {
|
|
return mount(
|
|
{
|
|
components: { SidebarSubGroup },
|
|
setup() {
|
|
provideSidebarContext({});
|
|
},
|
|
template: '<SidebarSubGroup v-bind="$attrs" />',
|
|
},
|
|
{
|
|
attrs: {
|
|
name: 'Conversation:Teams',
|
|
label: 'Teams',
|
|
icon: 'i-lucide-users',
|
|
children,
|
|
isExpanded: true,
|
|
collapsible: true,
|
|
...props,
|
|
},
|
|
global: {
|
|
stubs: {
|
|
SidebarGroupLeaf: {
|
|
props: {
|
|
label: { type: String, required: true },
|
|
hideTreeLine: { type: Boolean, default: false },
|
|
thinTreeLine: { type: Boolean, default: false },
|
|
},
|
|
template:
|
|
'<li class="sidebar-leaf" :data-hide-tree-line="String(hideTreeLine)" :data-thin-tree-line="String(thinTreeLine)">{{ label }}</li>',
|
|
},
|
|
},
|
|
},
|
|
}
|
|
);
|
|
};
|
|
|
|
describe('SidebarSubGroup', () => {
|
|
let localStorageStore;
|
|
|
|
beforeEach(() => {
|
|
localStorageStore = {};
|
|
Object.defineProperty(window, 'localStorage', {
|
|
value: {
|
|
getItem: key => localStorageStore[key] || null,
|
|
setItem: (key, value) => {
|
|
localStorageStore[key] = String(value);
|
|
},
|
|
removeItem: key => {
|
|
delete localStorageStore[key];
|
|
},
|
|
clear: () => {
|
|
localStorageStore = {};
|
|
},
|
|
},
|
|
configurable: true,
|
|
});
|
|
|
|
window.localStorage.clear();
|
|
});
|
|
|
|
it('keeps collapsible sections expanded by default', () => {
|
|
const wrapper = mountSubGroup();
|
|
|
|
expect(wrapper.find('button').attributes('aria-expanded')).toBe('true');
|
|
expect(wrapper.find('.sidebar-leaf').isVisible()).toBe(true);
|
|
});
|
|
|
|
it('renders the tree line on the separator, positioned relative to it', () => {
|
|
const wrapper = mountSubGroup({ showTreeLine: true });
|
|
const button = wrapper.find('button');
|
|
|
|
expect(button.classes()).toContain('relative');
|
|
expect(button.classes()).toContain('before:bg-n-slate-4');
|
|
expect(button.classes()).toContain('before:-bottom-1');
|
|
});
|
|
|
|
it('renders the end curve on the last separator', () => {
|
|
const wrapper = mountSubGroup({ showTreeLine: true, endTreeLine: true });
|
|
const button = wrapper.find('button');
|
|
|
|
expect(button.classes()).toContain('before:h-3');
|
|
expect(button.classes()).toContain('after:border-b-2');
|
|
});
|
|
|
|
it('draws nested item tree lines via the leaf connectors', () => {
|
|
const wrapper = mountSubGroup({ showTreeLine: true });
|
|
|
|
expect(
|
|
wrapper.find('.sidebar-leaf').attributes('data-hide-tree-line')
|
|
).toBe('false');
|
|
});
|
|
|
|
it('marks nested item connectors as thin', () => {
|
|
const wrapper = mountSubGroup({ showTreeLine: true });
|
|
|
|
expect(
|
|
wrapper.find('.sidebar-leaf').attributes('data-thin-tree-line')
|
|
).toBe('true');
|
|
});
|
|
|
|
it('minimizes the section and stores it by account and section name', async () => {
|
|
const wrapper = mountSubGroup();
|
|
|
|
await wrapper.find('button').trigger('click');
|
|
|
|
const storedSections = JSON.parse(
|
|
window.localStorage.getItem(LOCAL_STORAGE_KEYS.SIDEBAR_MINIMIZED_SECTIONS)
|
|
);
|
|
expect(wrapper.find('button').attributes('aria-expanded')).toBe('false');
|
|
expect(wrapper.find('.sidebar-leaf').isVisible()).toBe(false);
|
|
expect(storedSections).toEqual({ '1:Conversation:Teams': true });
|
|
});
|
|
|
|
it('uses the stored minimized state when mounted again', () => {
|
|
window.localStorage.setItem(
|
|
LOCAL_STORAGE_KEYS.SIDEBAR_MINIMIZED_SECTIONS,
|
|
JSON.stringify({ '1:Conversation:Teams': true })
|
|
);
|
|
|
|
const wrapper = mountSubGroup();
|
|
|
|
expect(wrapper.find('button').attributes('aria-expanded')).toBe('false');
|
|
expect(wrapper.find('.sidebar-leaf').isVisible()).toBe(false);
|
|
});
|
|
|
|
it('expands a stored minimized section when one of its children is active', () => {
|
|
window.localStorage.setItem(
|
|
LOCAL_STORAGE_KEYS.SIDEBAR_MINIMIZED_SECTIONS,
|
|
JSON.stringify({ '1:Conversation:Teams': true })
|
|
);
|
|
|
|
const wrapper = mountSubGroup({ activeChild: children[0] });
|
|
|
|
const storedSections = JSON.parse(
|
|
window.localStorage.getItem(LOCAL_STORAGE_KEYS.SIDEBAR_MINIMIZED_SECTIONS)
|
|
);
|
|
expect(wrapper.find('button').attributes('aria-expanded')).toBe('true');
|
|
expect(wrapper.find('.sidebar-leaf').isVisible()).toBe(true);
|
|
expect(storedSections).toEqual({});
|
|
});
|
|
});
|