feat: drag-and-drop columns (#2142)

This commit is contained in:
Jacob Fletcher
2023-02-28 09:35:03 -05:00
committed by GitHub
parent 523d9d4952
commit e2c65e3fa5
45 changed files with 2763 additions and 2150 deletions

View File

@@ -82,6 +82,8 @@ export default buildConfig({
description: { en: 'Description en', es: 'Description es' },
listSearchableFields: ['title', 'description', 'number'],
group: { en: 'One', es: 'Una' },
useAsTitle: 'title',
defaultColumns: ['id', 'number', 'title', 'description'],
},
fields: [
{
@@ -100,6 +102,15 @@ export default buildConfig({
name: 'number',
type: 'number',
},
{
name: 'richText',
type: 'richText',
admin: {
elements: [
'relationship',
],
},
},
],
},
{

View File

@@ -152,13 +152,13 @@ describe('admin', () => {
});
test('should delete existing', async () => {
const { id } = await createPost();
const { id, ...post } = await createPost();
await page.goto(url.edit(id));
await page.locator('#action-delete').click();
await page.locator('#confirm-delete').click();
await expect(page.locator(`text=Post en "${id}" successfully deleted.`)).toBeVisible();
await expect(page.locator(`text=Post en "${post.title}" successfully deleted.`)).toBeVisible();
expect(page.url()).toContain(url.list);
});
@@ -231,28 +231,63 @@ describe('admin', () => {
const columnCountLocator = 'table >> thead >> tr >> th';
await createPost();
await page.locator('.list-controls__toggle-columns').click();
await wait(1000); // Wait for column toggle UI, should probably use waitForSelector
await wait(500); // Wait for column toggle UI, should probably use waitForSelector
const numberOfColumns = await page.locator(columnCountLocator).count();
const idButton = page.locator('.column-selector >> text=ID');
await expect(await page.locator('table >> thead >> tr >> th:first-child')).toHaveText('ID');
const idButton = await page.locator('.column-selector >> text=ID');
// Remove ID column
await idButton.click({ delay: 100 });
await expect(page.locator(columnCountLocator)).toHaveCount(numberOfColumns - 1);
await idButton.click();
await wait(100);
await expect(await page.locator(columnCountLocator)).toHaveCount(numberOfColumns - 1);
await expect(await page.locator('table >> thead >> tr >> th:first-child')).toHaveText('Number');
// Add back ID column
await idButton.click({ delay: 100 });
await expect(page.locator(columnCountLocator)).toHaveCount(numberOfColumns);
await idButton.click();
await wait(100);
await expect(await page.locator(columnCountLocator)).toHaveCount(numberOfColumns);
await expect(await page.locator('table >> thead >> tr >> th:first-child')).toHaveText('ID');
});
test('first cell is a link', async () => {
const { id } = await createPost();
const firstCell = await page.locator(`${tableRowLocator} td`).first().locator('a');
await expect(firstCell).toHaveAttribute('href', `/admin/collections/posts/${id}`);
// open the column controls
await page.locator('.list-controls__toggle-columns').click();
await wait(500); // Wait for column toggle UI, should probably use waitForSelector (same as above)
// toggle off the ID column
page.locator('.column-selector >> text=ID').click();
await wait(200);
// recheck that the first cell is still a link
await expect(firstCell).toHaveAttribute('href', `/admin/collections/posts/${id}`);
});
test('filter rows', async () => {
const { id } = await createPost({ title: 'post1' });
await createPost({ title: 'post2' });
// open the column controls
await page.locator('.list-controls__toggle-columns').click();
await wait(500); // Wait for column toggle UI, should probably use waitForSelector (same as above)
// ensure the ID column is active
const idButton = await page.locator('.column-selector >> text=ID');
const buttonClasses = await idButton.getAttribute('class');
if (buttonClasses && !buttonClasses.includes('column-selector__column--active')) {
await idButton.click();
await wait(200);
}
await expect(page.locator(tableRowLocator)).toHaveCount(2);
await page.locator('.list-controls__toggle-where').click();
await wait(1000); // Wait for column toggle UI, should probably use waitForSelector
await wait(500); // Wait for column toggle UI, should probably use waitForSelector (same as above)
await page.locator('.where-builder__add-first-filter').click();
@@ -277,6 +312,58 @@ describe('admin', () => {
await wait(1000);
await expect(page.locator(tableRowLocator)).toHaveCount(2);
});
test('drag and reorder columns', async () => {
await createPost();
// open the column controls
await page.locator('.list-controls__toggle-columns').click();
await wait(500); // Wait for column toggle UI, should probably use waitForSelector (same as above)
const numberBoundingBox = await page.locator('.column-selector >> text=Number').boundingBox();
const idBoundingBox = await page.locator('.column-selector >> text=ID').boundingBox();
if (!numberBoundingBox || !idBoundingBox) return;
// drag the "number" column to the left of the "ID" column
await page.mouse.move(numberBoundingBox.x + 2, numberBoundingBox.y + 2, { steps: 10 });
await page.mouse.down();
await wait(200);
await page.mouse.move(idBoundingBox.x - 2, idBoundingBox.y - 2, { steps: 10 });
await page.mouse.up();
// wait for the new preferences to save and internal state to update and re-render
await wait(400);
// ensure the "number" column is now first
await expect(await page.locator('.list-controls .column-selector .column-selector__column').first()).toHaveText('Number');
await expect(await page.locator('table >> thead >> tr >> th').first()).toHaveText('Number');
// reload to ensure the preferred order was stored in the database
await page.reload();
await expect(await page.locator('.list-controls .column-selector .column-selector__column').first()).toHaveText('Number');
await expect(await page.locator('table >> thead >> tr >> th').first()).toHaveText('Number');
});
test('reorder columns from drawer', async () => {
await page.goto(url.create);
// Open the drawer
await page.locator('.rich-text .list-drawer__toggler').click();
const listDrawer = page.locator('[id^=list-drawer_1_]');
await expect(listDrawer).toBeVisible();
await page.locator('[id^=list-drawer_1_] .list-drawer__select-collection.react-select').click();
// select the "post en" collection
await page.locator('[id^=list-drawer_1_] .list-drawer__select-collection.react-select .rs__option >> text="Post en"').click();
// open the column controls
await page.locator('[id^=list-drawer_1_] .list-controls__toggle-columns').click();
await wait(500); // Wait for column toggle UI, should probably use waitForSelector (same as above)
// ensure that the columns are in the correct order
await expect(await page.locator('[id^=list-drawer_1_] .list-controls .column-selector .column-selector__column').first()).toHaveText('Number');
});
});
describe('pagination', () => {
@@ -394,7 +481,7 @@ describe('admin', () => {
});
async function createPost(overrides?: Partial<Post>): Promise<Post> {
return payload.create<Post>({
return payload.create({
collection: slug,
data: {
title,
@@ -405,7 +492,7 @@ async function createPost(overrides?: Partial<Post>): Promise<Post> {
}
async function clearDocs(): Promise<void> {
const allDocs = await payload.find<Post>({ collection: slug, limit: 100 });
const allDocs = await payload.find({ collection: slug, limit: 100 });
const ids = allDocs.docs.map((doc) => doc.id);
await mapAsync(ids, async (id) => {
await payload.delete({ collection: slug, id });