mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(editor): Fix pagination and sorting issue for insights (#16288)
This commit is contained in:
committed by
GitHub
parent
8d6e796b92
commit
84c51b1bd9
@@ -1,8 +1,22 @@
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render, within } from '@testing-library/vue';
|
||||
import { render, screen, waitFor, within } from '@testing-library/vue';
|
||||
import { config } from '@vue/test-utils';
|
||||
import ElementPlus from 'element-plus';
|
||||
|
||||
import { createComponentRenderer } from '@n8n/design-system/__tests__/render';
|
||||
|
||||
import N8nDataTableServer, { type TableHeader } from './N8nDataTableServer.vue';
|
||||
|
||||
const renderComponent = createComponentRenderer(N8nDataTableServer);
|
||||
|
||||
const getRenderedOptions = async () => {
|
||||
const dropdown = await waitFor(() => screen.getByRole('listbox'));
|
||||
expect(dropdown).toBeInTheDocument();
|
||||
return dropdown.querySelectorAll('.el-select-dropdown__item');
|
||||
};
|
||||
|
||||
config.global.plugins.push(ElementPlus);
|
||||
|
||||
const itemFactory = () => ({
|
||||
id: crypto.randomUUID() as string,
|
||||
firstName: crypto.randomUUID() as string,
|
||||
@@ -84,8 +98,7 @@ describe('N8nDataTableServer', () => {
|
||||
});
|
||||
|
||||
it('should emit options for sorting / pagination', async () => {
|
||||
const { container, emitted, getByTestId } = render(N8nDataTableServer, {
|
||||
//@ts-expect-error testing-library errors due to header generics
|
||||
const { container, emitted, getByTestId, findAllByRole } = renderComponent({
|
||||
props: { items, headers, itemsLength: 100 },
|
||||
});
|
||||
|
||||
@@ -93,7 +106,17 @@ describe('N8nDataTableServer', () => {
|
||||
await userEvent.click(container.querySelector('thead tr th')!);
|
||||
await userEvent.click(within(getByTestId('pagination')).getByLabelText('page 2'));
|
||||
|
||||
expect(emitted('update:options').length).toBe(3);
|
||||
// change the page size select option
|
||||
const selectInput = await findAllByRole('combobox'); // Find the select input
|
||||
await userEvent.click(selectInput[0]);
|
||||
|
||||
const options = await getRenderedOptions();
|
||||
expect(options.length).toBe(4);
|
||||
|
||||
const option50 = Array.from(options).find((option) => option.textContent === '50');
|
||||
await userEvent.click(option50!);
|
||||
|
||||
expect(emitted('update:options').length).toBeGreaterThanOrEqual(4);
|
||||
expect(emitted('update:options')[0]).toStrictEqual([
|
||||
expect.objectContaining({ sortBy: [{ id: 'id', desc: false }] }),
|
||||
]);
|
||||
@@ -101,6 +124,24 @@ describe('N8nDataTableServer', () => {
|
||||
expect.objectContaining({ sortBy: [{ id: 'id', desc: true }] }),
|
||||
]);
|
||||
expect(emitted('update:options')[2]).toStrictEqual([expect.objectContaining({ page: 1 })]);
|
||||
expect(emitted('update:options')[3]).toStrictEqual([
|
||||
expect.objectContaining({ itemsPerPage: 50 }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should emit options for sorting with initial sort', async () => {
|
||||
const { container, emitted } = renderComponent({
|
||||
props: { items, headers, itemsLength: 100, sortBy: [{ id: 'id', desc: true }] },
|
||||
});
|
||||
|
||||
await userEvent.click(container.querySelector('thead tr th')!);
|
||||
await userEvent.click(container.querySelector('thead tr th')!);
|
||||
|
||||
expect(emitted('update:options').length).toBe(2);
|
||||
expect(emitted('update:options')[0]).toStrictEqual([expect.objectContaining({ sortBy: [] })]);
|
||||
expect(emitted('update:options')[1]).toStrictEqual([
|
||||
expect.objectContaining({ sortBy: [{ id: 'id', desc: false }] }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not show the pagination if there are no items', async () => {
|
||||
|
||||
@@ -205,7 +205,10 @@ const page = defineModel<number>('page', { default: 0 });
|
||||
watch(page, () => table.setPageIndex(page.value));
|
||||
|
||||
const itemsPerPage = defineModel<number>('items-per-page', { default: 10 });
|
||||
watch(itemsPerPage, () => (page.value = 0));
|
||||
watch(itemsPerPage, () => {
|
||||
page.value = 0;
|
||||
table.setPageSize(itemsPerPage.value);
|
||||
});
|
||||
|
||||
const pagination = computed<PaginationState>({
|
||||
get() {
|
||||
@@ -225,13 +228,16 @@ const showPagination = computed(() => props.itemsLength > Math.min(...props.page
|
||||
const sortBy = defineModel<SortingState>('sort-by', { default: [], required: false });
|
||||
|
||||
function handleSortingChange(updaterOrValue: Updater<SortingState>) {
|
||||
sortBy.value =
|
||||
const newValue =
|
||||
typeof updaterOrValue === 'function' ? updaterOrValue(sortBy.value) : updaterOrValue;
|
||||
sortBy.value = newValue;
|
||||
|
||||
// Use newValue instead of sortBy.value to ensure the latest value is used
|
||||
// This is because of the async nature of the Vue reactivity system
|
||||
emit('update:options', {
|
||||
page: page.value,
|
||||
itemsPerPage: itemsPerPage.value,
|
||||
sortBy: sortBy.value,
|
||||
sortBy: newValue,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ const transformFilter = ({ id, desc }: { id: string; desc: boolean }) => {
|
||||
|
||||
const fetchPaginatedTableData = ({
|
||||
page = 0,
|
||||
itemsPerPage = 20,
|
||||
itemsPerPage = 25,
|
||||
sortBy,
|
||||
dateRange = selectedDateRange.value,
|
||||
}: {
|
||||
|
||||
Reference in New Issue
Block a user