✨(frontend) add doc grid actions button
Add document action buttons to the document grid: - update document - delete document
This commit is contained in:
@@ -12,6 +12,7 @@ and this project adheres to
|
|||||||
|
|
||||||
- 🤡(demo) generate dummy documents on dev users #120
|
- 🤡(demo) generate dummy documents on dev users #120
|
||||||
- ✨(frontend) create side modal component #134
|
- ✨(frontend) create side modal component #134
|
||||||
|
- ✨(frontend) Doc grid actions (update / delete) #136
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
|
|||||||
@@ -171,14 +171,9 @@ test.describe('Documents Grid', () => {
|
|||||||
const responsePage1 = await responsePromisePage1;
|
const responsePage1 = await responsePromisePage1;
|
||||||
expect(responsePage1.ok()).toBeTruthy();
|
expect(responsePage1.ok()).toBeTruthy();
|
||||||
|
|
||||||
const docNamePage1 = datagridPage1
|
await expect(
|
||||||
.getByRole('row')
|
datagridPage1.getByRole('row').nth(1).getByRole('cell').nth(1),
|
||||||
.nth(1)
|
).toHaveText(/.*/);
|
||||||
.getByRole('cell')
|
|
||||||
.nth(1);
|
|
||||||
|
|
||||||
await expect(docNamePage1).toHaveText(/.*/);
|
|
||||||
const textDocNamePage1 = await docNamePage1.textContent();
|
|
||||||
|
|
||||||
await page.getByLabel('Go to page 2').click();
|
await page.getByLabel('Go to page 2').click();
|
||||||
|
|
||||||
@@ -189,17 +184,62 @@ test.describe('Documents Grid', () => {
|
|||||||
const responsePage2 = await responsePromisePage2;
|
const responsePage2 = await responsePromisePage2;
|
||||||
expect(responsePage2.ok()).toBeTruthy();
|
expect(responsePage2.ok()).toBeTruthy();
|
||||||
|
|
||||||
const docNamePage2 = datagridPage2
|
await expect(
|
||||||
.getByRole('row')
|
datagridPage2.getByRole('row').nth(1).getByRole('cell').nth(1),
|
||||||
.nth(1)
|
).toHaveText(/.*/);
|
||||||
.getByRole('cell')
|
});
|
||||||
.nth(1);
|
|
||||||
|
|
||||||
await expect(datagridPage2.getByLabel('Loading data')).toBeHidden();
|
test('it updates document', async ({ page }) => {
|
||||||
|
const datagrid = page
|
||||||
|
.getByLabel('Datagrid of the documents page 1')
|
||||||
|
.getByRole('table');
|
||||||
|
|
||||||
await expect(docNamePage2).toHaveText(/.*/);
|
const docRow = datagrid.getByRole('row').nth(1).getByRole('cell');
|
||||||
const textDocNamePage2 = await docNamePage2.textContent();
|
|
||||||
|
|
||||||
expect(textDocNamePage1 !== textDocNamePage2).toBeTruthy();
|
const docName = await docRow.nth(1).textContent();
|
||||||
|
|
||||||
|
await docRow.getByLabel('Open the document options').click();
|
||||||
|
|
||||||
|
await page.getByText('Update document').click();
|
||||||
|
|
||||||
|
await page.getByLabel('Document name').fill(`${docName} updated`);
|
||||||
|
|
||||||
|
await page.getByText('Validate the modification').click();
|
||||||
|
|
||||||
|
await expect(datagrid.getByText(`${docName} updated`)).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it deletes the document', async ({ page }) => {
|
||||||
|
const datagrid = page
|
||||||
|
.getByLabel('Datagrid of the documents page 1')
|
||||||
|
.getByRole('table');
|
||||||
|
|
||||||
|
const docRow = datagrid.getByRole('row').nth(1).getByRole('cell');
|
||||||
|
|
||||||
|
const docName = await docRow.nth(1).textContent();
|
||||||
|
|
||||||
|
await docRow.getByLabel('Open the document options').click();
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'Delete document',
|
||||||
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.locator('h2').getByText(`Deleting the document "${docName}"`),
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'Confirm deletion',
|
||||||
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByText('The document has been deleted.'),
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
|
await expect(datagrid.getByText(docName!)).toBeHidden();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import {
|
|||||||
|
|
||||||
import { PAGE_SIZE } from '../conf';
|
import { PAGE_SIZE } from '../conf';
|
||||||
|
|
||||||
|
import { DocsGridActions } from './DocsGridActions';
|
||||||
|
|
||||||
const DocsGridStyle = createGlobalStyle`
|
const DocsGridStyle = createGlobalStyle`
|
||||||
& .c__datagrid{
|
& .c__datagrid{
|
||||||
max-height: 91%;
|
max-height: 91%;
|
||||||
@@ -191,6 +193,12 @@ export const DocsGrid = () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'column-actions',
|
||||||
|
renderCell: ({ row }) => {
|
||||||
|
return <DocsGridActions doc={row} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
rows={docs}
|
rows={docs}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import { Button } from '@openfun/cunningham-react';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { Box, DropButton, IconOptions, Text } from '@/components';
|
||||||
|
import {
|
||||||
|
Doc,
|
||||||
|
ModalRemoveDoc,
|
||||||
|
ModalUpdateDoc,
|
||||||
|
} from '@/features/docs/doc-management';
|
||||||
|
|
||||||
|
interface DocsGridActionsProps {
|
||||||
|
doc: Doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DocsGridActions = ({ doc }: DocsGridActionsProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [isModalUpdateOpen, setIsModalUpdateOpen] = useState(false);
|
||||||
|
const [isModalRemoveOpen, setIsModalRemoveOpen] = useState(false);
|
||||||
|
const [isDropOpen, setIsDropOpen] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DropButton
|
||||||
|
button={
|
||||||
|
<IconOptions
|
||||||
|
isOpen={isDropOpen}
|
||||||
|
aria-label={t('Open the document options')}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onOpenChange={(isOpen) => setIsDropOpen(isOpen)}
|
||||||
|
isOpen={isDropOpen}
|
||||||
|
>
|
||||||
|
<Box>
|
||||||
|
{doc.abilities.partial_update && (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setIsModalUpdateOpen(true);
|
||||||
|
setIsDropOpen(false);
|
||||||
|
}}
|
||||||
|
color="primary-text"
|
||||||
|
icon={<span className="material-icons">edit</span>}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<Text $theme="primary">{t('Update document')}</Text>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{doc.abilities.destroy && (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setIsModalRemoveOpen(true);
|
||||||
|
setIsDropOpen(false);
|
||||||
|
}}
|
||||||
|
color="primary-text"
|
||||||
|
icon={<span className="material-icons">delete</span>}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<Text $theme="primary">{t('Delete document')}</Text>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</DropButton>
|
||||||
|
{isModalUpdateOpen && (
|
||||||
|
<ModalUpdateDoc onClose={() => setIsModalUpdateOpen(false)} doc={doc} />
|
||||||
|
)}
|
||||||
|
{isModalRemoveOpen && (
|
||||||
|
<ModalRemoveDoc onClose={() => setIsModalRemoveOpen(false)} doc={doc} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user