diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e315e38..33dc1cd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to - ⚡️(e2e) unique login between tests (#80) - ⚡️(CI) improve e2e job (#86) - ♻️(frontend) improve the error and message info ui (#93) +- ♻️(frontend) improve the error and message info ui (#93) +- ✏️(frontend) change all occurences of pad to doc (#99) ## Fixed diff --git a/src/frontend/apps/e2e/__tests__/app-impress/common.ts b/src/frontend/apps/e2e/__tests__/app-impress/common.ts index d237270a..a0a2f03b 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/common.ts @@ -26,9 +26,9 @@ export const randomName = (name: string, browserName: string, length: number) => return `${browserName}-${Math.floor(Math.random() * 10000)}-${index}-${name}`; }); -export const createPad = async ( +export const createDoc = async ( page: Page, - padName: string, + docName: string, browserName: string, length: number, isPublic: boolean = false, @@ -38,11 +38,11 @@ export const createPad = async ( name: 'Create the document', }); - const randomPads = randomName(padName, browserName, length); + const randomDocs = randomName(docName, browserName, length); - for (let i = 0; i < randomPads.length; i++) { + for (let i = 0; i < randomDocs.length; i++) { await panel.getByRole('button', { name: 'Add a document' }).click(); - await page.getByText('Document name').fill(randomPads[i]); + await page.getByText('Document name').fill(randomDocs[i]); if (isPublic) { await page.getByText('Is it public ?').click(); @@ -50,10 +50,10 @@ export const createPad = async ( await expect(buttonCreate).toBeEnabled(); await buttonCreate.click(); - await expect(panel.locator('li').getByText(randomPads[i])).toBeVisible(); + await expect(panel.locator('li').getByText(randomDocs[i])).toBeVisible(); } - return randomPads; + return randomDocs; }; export const createTemplate = async ( diff --git a/src/frontend/apps/e2e/__tests__/app-impress/pad-add-members.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-add-members.spec.ts similarity index 95% rename from src/frontend/apps/e2e/__tests__/app-impress/pad-add-members.spec.ts rename to src/frontend/apps/e2e/__tests__/app-impress/doc-add-members.spec.ts index d1828a67..b5b80ffb 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/pad-add-members.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-add-members.spec.ts @@ -1,6 +1,6 @@ import { expect, test } from '@playwright/test'; -import { createPad, randomName } from './common'; +import { createDoc, randomName } from './common'; test.beforeEach(async ({ page }) => { await page.goto('/'); @@ -12,7 +12,7 @@ test.describe('Document add users', () => { (response) => response.url().includes('/users/?q=user') && response.status() === 200, ); - await createPad(page, 'select-multi-users', browserName, 1); + await createDoc(page, 'select-multi-users', browserName, 1); await page.getByLabel('Open the document options').click(); await page.getByRole('button', { name: 'Add members' }).click(); @@ -73,7 +73,7 @@ test.describe('Document add users', () => { response.url().includes('/users/?q=user') && response.status() === 200, ); - await createPad(page, 'user-invitation', browserName, 1); + await createDoc(page, 'user-invitation', browserName, 1); await page.getByLabel('Open the document options').click(); await page.getByRole('button', { name: 'Add members' }).click(); @@ -125,7 +125,7 @@ test.describe('Document add users', () => { response.url().includes('/users/?q=user') && response.status() === 200, ); - await createPad(page, 'user-twice', browserName, 1); + await createDoc(page, 'user-twice', browserName, 1); await page.getByLabel('Open the document options').click(); await page.getByRole('button', { name: 'Add members' }).click(); @@ -165,7 +165,7 @@ test.describe('Document add users', () => { page, browserName, }) => { - await createPad(page, 'invitation-twice', browserName, 1); + await createDoc(page, 'invitation-twice', browserName, 1); await page.getByLabel('Open the document options').click(); await page.getByRole('button', { name: 'Add members' }).click(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/pad-create.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts similarity index 75% rename from src/frontend/apps/e2e/__tests__/app-impress/pad-create.spec.ts rename to src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts index 6949d267..4854f342 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/pad-create.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts @@ -4,8 +4,8 @@ test.beforeEach(async ({ page }) => { await page.goto('/'); }); -test.describe('Pad Create', () => { - test('checks all the create pad elements are visible', async ({ page }) => { +test.describe('Doc Create', () => { + test('checks all the create doc elements are visible', async ({ page }) => { const buttonCreateHomepage = page.getByRole('button', { name: 'Create a new document', }); @@ -58,7 +58,7 @@ test.describe('Pad Create', () => { await expect(buttonCreateHomepage).toBeVisible(); }); - test('checks the routing on new pad created', async ({ + test('checks the routing on new doc created', async ({ page, browserName, }) => { @@ -66,21 +66,21 @@ test.describe('Pad Create', () => { await panel.getByRole('button', { name: 'Add a document' }).click(); - const padName = `My routing pad ${browserName}-${Math.floor(Math.random() * 1000)}`; - await page.getByText('Document name').fill(padName); + const docName = `My routing doc ${browserName}-${Math.floor(Math.random() * 1000)}`; + await page.getByText('Document name').fill(docName); await page.getByRole('button', { name: 'Create the document' }).click(); - const elPad = page.locator('h2').getByText(padName); - await expect(elPad).toBeVisible(); + const elDoc = page.locator('h2').getByText(docName); + await expect(elDoc).toBeVisible(); await panel.getByRole('button', { name: 'Add a document' }).click(); - await expect(elPad).toBeHidden(); + await expect(elDoc).toBeHidden(); - await panel.locator('li').getByText(padName).click(); - await expect(elPad).toBeVisible(); + await panel.locator('li').getByText(docName).click(); + await expect(elDoc).toBeVisible(); }); - test('checks alias pads url with homepage', async ({ page }) => { + test('checks alias docs url with homepage', async ({ page }) => { await expect(page).toHaveURL('/'); const buttonCreateHomepage = page.getByRole('button', { @@ -98,7 +98,7 @@ test.describe('Pad Create', () => { // eslint-disable-next-line playwright/no-wait-for-timeout await page.waitForTimeout(300); - await page.goto('/docs/some-unknown-pad'); + await page.goto('/docs/some-unknown-doc'); await expect( page.getByText( 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', @@ -108,8 +108,8 @@ test.describe('Pad Create', () => { }); }); - test('checks that the pad is public', async ({ page, browserName }) => { - const responsePromisePad = page.waitForResponse( + test('checks that the doc is public', async ({ page, browserName }) => { + const responsePromiseDoc = page.waitForResponse( (response) => response.url().includes('/documents/') && response.status() === 201, ); @@ -118,13 +118,13 @@ test.describe('Pad Create', () => { await panel.getByRole('button', { name: 'Add a document' }).click(); - const padName = `My routing pad ${browserName}-${Math.floor(Math.random() * 1000)}`; - await page.getByText('Document name').fill(padName); + const docName = `My routing doc ${browserName}-${Math.floor(Math.random() * 1000)}`; + await page.getByText('Document name').fill(docName); await page.getByText('Is it public ?').click(); await page.getByRole('button', { name: 'Create the document' }).click(); - const responsePad = await responsePromisePad; - const is_public = (await responsePad.json()).is_public; + const responseDoc = await responsePromiseDoc; + const is_public = (await responseDoc.json()).is_public; expect(is_public).toBeTruthy(); }); }); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/pad-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts similarity index 66% rename from src/frontend/apps/e2e/__tests__/app-impress/pad-editor.spec.ts rename to src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts index 4c56af1f..27dee6f0 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/pad-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts @@ -1,26 +1,26 @@ import { expect, test } from '@playwright/test'; -import { createPad } from './common'; +import { createDoc } from './common'; test.beforeEach(async ({ page }) => { await page.goto('/'); }); -test.describe('Pad Editor', () => { - test('checks the Pad Editor interact correctly', async ({ +test.describe('Doc Editor', () => { + test('checks the Doc Editor interact correctly', async ({ page, browserName, }) => { - const randomPad = await createPad(page, 'pad-editor', browserName, 1); + const randomDoc = await createDoc(page, 'doc-editor', browserName, 1); - await expect(page.locator('h2').getByText(randomPad[0])).toBeVisible(); + await expect(page.locator('h2').getByText(randomDoc[0])).toBeVisible(); await page.locator('.ProseMirror.bn-editor').click(); await page.locator('.ProseMirror.bn-editor').fill('Hello World'); await expect(page.getByText('Hello World')).toBeVisible(); }); - test('checks the Pad is connected to the webrtc server', async ({ + test('checks the Doc is connected to the webrtc server', async ({ page, browserName, }) => { @@ -28,8 +28,8 @@ test.describe('Pad Editor', () => { return webSocket.url().includes('ws://localhost:4444/'); }); - const randomPad = await createPad(page, 'pad-editor', browserName, 1); - await expect(page.locator('h2').getByText(randomPad[0])).toBeVisible(); + const randomDoc = await createDoc(page, 'doc-editor', browserName, 1); + await expect(page.locator('h2').getByText(randomDoc[0])).toBeVisible(); const webSocket = await webSocketPromise; expect(webSocket.url()).toContain('ws://localhost:4444/'); @@ -52,9 +52,9 @@ test.describe('Pad Editor', () => { page, browserName, }) => { - const randomPad = await createPad(page, 'pad-markdown', browserName, 1); + const randomDoc = await createDoc(page, 'doc-markdown', browserName, 1); - await expect(page.locator('h2').getByText(randomPad[0])).toBeVisible(); + await expect(page.locator('h2').getByText(randomDoc[0])).toBeVisible(); await page.locator('.ProseMirror.bn-editor').click(); await page @@ -74,57 +74,57 @@ test.describe('Pad Editor', () => { ).toHaveAttribute('href', 'http://test-markdown.html'); }); - test('it renders correctly when we switch from one pad to another', async ({ + test('it renders correctly when we switch from one doc to another', async ({ page, browserName, }) => { - const [firstPad, secondPad] = await createPad( + const [firstDoc, secondDoc] = await createDoc( page, - 'pad-multiple', + 'doc-multiple', browserName, 2, ); const panel = page.getByLabel('Documents panel').first(); - // Check the first pad - await panel.getByText(firstPad).click(); - await expect(page.locator('h2').getByText(firstPad)).toBeVisible(); + // Check the first doc + await panel.getByText(firstDoc).click(); + await expect(page.locator('h2').getByText(firstDoc)).toBeVisible(); await page.locator('.ProseMirror.bn-editor').click(); - await page.locator('.ProseMirror.bn-editor').fill('Hello World Pad 1'); - await expect(page.getByText('Hello World Pad 1')).toBeVisible(); + await page.locator('.ProseMirror.bn-editor').fill('Hello World Doc 1'); + await expect(page.getByText('Hello World Doc 1')).toBeVisible(); - // Check the second pad - await panel.getByText(secondPad).click(); - await expect(page.locator('h2').getByText(secondPad)).toBeVisible(); - await expect(page.getByText('Hello World Pad 1')).toBeHidden(); + // Check the second doc + await panel.getByText(secondDoc).click(); + await expect(page.locator('h2').getByText(secondDoc)).toBeVisible(); + await expect(page.getByText('Hello World Doc 1')).toBeHidden(); await page.locator('.ProseMirror.bn-editor').click(); - await page.locator('.ProseMirror.bn-editor').fill('Hello World Pad 2'); - await expect(page.getByText('Hello World Pad 2')).toBeVisible(); + await page.locator('.ProseMirror.bn-editor').fill('Hello World Doc 2'); + await expect(page.getByText('Hello World Doc 2')).toBeVisible(); - // Check the first pad again - await panel.getByText(firstPad).click(); - await expect(page.locator('h2').getByText(firstPad)).toBeVisible(); - await expect(page.getByText('Hello World Pad 2')).toBeHidden(); - await expect(page.getByText('Hello World Pad 1')).toBeVisible(); + // Check the first doc again + await panel.getByText(firstDoc).click(); + await expect(page.locator('h2').getByText(firstDoc)).toBeVisible(); + await expect(page.getByText('Hello World Doc 2')).toBeHidden(); + await expect(page.getByText('Hello World Doc 1')).toBeVisible(); }); test('it saves the doc when we change pages', async ({ page, browserName, }) => { - const [pad] = await createPad(page, 'pad-save-page', browserName, 1); + const [doc] = await createDoc(page, 'doc-save-page', browserName, 1); const panel = page.getByLabel('Documents panel').first(); - // Check the first pad - await panel.getByText(pad).click(); - await expect(page.locator('h2').getByText(pad)).toBeVisible(); + // Check the first doc + await panel.getByText(doc).click(); + await expect(page.locator('h2').getByText(doc)).toBeVisible(); await page.locator('.ProseMirror.bn-editor').click(); await page .locator('.ProseMirror.bn-editor') - .fill('Hello World Pad persisted 1'); - await expect(page.getByText('Hello World Pad persisted 1')).toBeVisible(); + .fill('Hello World Doc persisted 1'); + await expect(page.getByText('Hello World Doc persisted 1')).toBeVisible(); await panel .getByRole('button', { @@ -142,33 +142,33 @@ test.describe('Pad Editor', () => { await page.goto('/'); - await panel.getByText(pad).click(); + await panel.getByText(doc).click(); - await expect(page.getByText('Hello World Pad persisted 1')).toBeVisible(); + await expect(page.getByText('Hello World Doc persisted 1')).toBeVisible(); }); test('it saves the doc when we quit pages', async ({ page, browserName }) => { // eslint-disable-next-line playwright/no-skipped-test test.skip(browserName === 'webkit', 'This test is very flaky with webkit'); - const [pad] = await createPad(page, 'pad-save-quit', browserName, 1); + const [doc] = await createDoc(page, 'doc-save-quit', browserName, 1); const panel = page.getByLabel('Documents panel').first(); - // Check the first pad - await panel.getByText(pad).click(); - await expect(page.locator('h2').getByText(pad)).toBeVisible(); + // Check the first doc + await panel.getByText(doc).click(); + await expect(page.locator('h2').getByText(doc)).toBeVisible(); await page.locator('.ProseMirror.bn-editor').click(); await page .locator('.ProseMirror.bn-editor') - .fill('Hello World Pad persisted 2'); - await expect(page.getByText('Hello World Pad persisted 2')).toBeVisible(); + .fill('Hello World Doc persisted 2'); + await expect(page.getByText('Hello World Doc persisted 2')).toBeVisible(); await page.goto('/'); - await panel.getByText(pad).click(); + await panel.getByText(doc).click(); - await expect(page.getByText('Hello World Pad persisted 2')).toBeVisible(); + await expect(page.getByText('Hello World Doc persisted 2')).toBeVisible(); }); test('it cannot edit if viewer', async ({ page, browserName }) => { @@ -202,7 +202,7 @@ test.describe('Pad Editor', () => { } }); - await createPad(page, 'pad-right-edit', browserName, 1); + await createDoc(page, 'doc-right-edit', browserName, 1); await expect( page.getByText( diff --git a/src/frontend/apps/e2e/__tests__/app-impress/pad-member-delete.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-delete.spec.ts similarity index 93% rename from src/frontend/apps/e2e/__tests__/app-impress/pad-member-delete.spec.ts rename to src/frontend/apps/e2e/__tests__/app-impress/doc-member-delete.spec.ts index caa7e6cd..8a83298c 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/pad-member-delete.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-delete.spec.ts @@ -1,6 +1,6 @@ import { expect, test } from '@playwright/test'; -import { addNewMember, createPad } from './common'; +import { addNewMember, createDoc } from './common'; test.beforeEach(async ({ page }) => { await page.goto('/'); @@ -11,7 +11,7 @@ test.describe('Members Delete', () => { page, browserName, }) => { - await createPad(page, 'member-delete-1', browserName, 1); + await createDoc(page, 'member-delete-1', browserName, 1); await page.getByLabel('Open the document options').click(); await page.getByRole('button', { name: 'Manage members' }).click(); @@ -37,7 +37,7 @@ test.describe('Members Delete', () => { page, browserName, }) => { - await createPad(page, 'member-delete-2', browserName, 1); + await createDoc(page, 'member-delete-2', browserName, 1); await addNewMember(page, 0, 'Owner'); @@ -64,7 +64,7 @@ test.describe('Members Delete', () => { }); test('it cannot delete owner member', async ({ page, browserName }) => { - await createPad(page, 'member-delete-3', browserName, 1); + await createDoc(page, 'member-delete-3', browserName, 1); const username = await addNewMember(page, 0, 'Owner'); @@ -88,7 +88,7 @@ test.describe('Members Delete', () => { }); test('it deletes admin member', async ({ page, browserName }) => { - await createPad(page, 'member-delete-4', browserName, 1); + await createDoc(page, 'member-delete-4', browserName, 1); const username = await addNewMember(page, 0, 'Admin'); @@ -116,7 +116,7 @@ test.describe('Members Delete', () => { page, browserName, }) => { - await createPad(page, 'member-delete-5', browserName, 1); + await createDoc(page, 'member-delete-5', browserName, 1); const username = await addNewMember(page, 0, 'Owner'); @@ -146,7 +146,7 @@ test.describe('Members Delete', () => { }); test('it deletes admin member when admin', async ({ page, browserName }) => { - await createPad(page, 'member-delete-6', browserName, 1); + await createDoc(page, 'member-delete-6', browserName, 1); // To not be the only owner await addNewMember(page, 0, 'Owner'); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/pad-member-grid.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-grid.spec.ts similarity index 95% rename from src/frontend/apps/e2e/__tests__/app-impress/pad-member-grid.spec.ts rename to src/frontend/apps/e2e/__tests__/app-impress/doc-member-grid.spec.ts index 38429299..1a3ddbff 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/pad-member-grid.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-grid.spec.ts @@ -1,6 +1,6 @@ import { expect, test } from '@playwright/test'; -import { createPad } from './common'; +import { createDoc } from './common'; test.beforeEach(async ({ page }) => { await page.goto('/'); @@ -8,7 +8,7 @@ test.beforeEach(async ({ page }) => { test.describe('Document grid members', () => { test('it display the grid', async ({ page, browserName }) => { - await createPad(page, 'grid-display', browserName, 1); + await createDoc(page, 'grid-display', browserName, 1); await page.getByLabel('Open the document options').click(); await page.getByRole('button', { name: 'Manage members' }).click(); @@ -91,7 +91,7 @@ test.describe('Document grid members', () => { }, ); - await createPad(page, 'grid-no-member', browserName, 1); + await createDoc(page, 'grid-no-member', browserName, 1); await page.getByLabel('Open the document options').click(); await page.getByRole('button', { name: 'Manage members' }).click(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/pad-panel.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-panel.spec.ts similarity index 93% rename from src/frontend/apps/e2e/__tests__/app-impress/pad-panel.spec.ts rename to src/frontend/apps/e2e/__tests__/app-impress/doc-panel.spec.ts index 3d782af9..27a2e82d 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/pad-panel.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-panel.spec.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'; import { waitForElementCount } from '../helpers'; -import { createPad } from './common'; +import { createDoc } from './common'; test.beforeEach(async ({ page }) => { await page.goto('/'); @@ -146,16 +146,16 @@ test.describe('Documents Panel', () => { test('checks the hover and selected state', async ({ page, browserName }) => { const panel = page.getByLabel('Documents panel').first(); - await createPad(page, 'pad-hover', browserName, 2); + await createDoc(page, 'doc-hover', browserName, 2); - const selectedPad = panel.locator('li').nth(0); - await expect(selectedPad).toHaveCSS( + const selectedDoc = panel.locator('li').nth(0); + await expect(selectedDoc).toHaveCSS( 'background-color', 'rgb(202, 202, 251)', ); - const hoverPad = panel.locator('li').nth(1); - await hoverPad.hover(); - await expect(hoverPad).toHaveCSS('background-color', 'rgb(227, 227, 253)'); + const hoverDoc = panel.locator('li').nth(1); + await hoverDoc.hover(); + await expect(hoverDoc).toHaveCSS('background-color', 'rgb(227, 227, 253)'); }); }); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/pad-tools.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-tools.spec.ts similarity index 85% rename from src/frontend/apps/e2e/__tests__/app-impress/pad-tools.spec.ts rename to src/frontend/apps/e2e/__tests__/app-impress/doc-tools.spec.ts index 3b728062..3a6a7d6c 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/pad-tools.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-tools.spec.ts @@ -2,24 +2,24 @@ import { expect, test } from '@playwright/test'; import cs from 'convert-stream'; import pdf from 'pdf-parse'; -import { createPad } from './common'; +import { createDoc } from './common'; test.beforeEach(async ({ page }) => { await page.goto('/'); }); -test.describe('Pad Tools', () => { - test('it converts the pad to pdf with a template integrated', async ({ +test.describe('Doc Tools', () => { + test('it converts the doc to pdf with a template integrated', async ({ page, browserName, }) => { - const [randomPad] = await createPad(page, 'pad-editor', browserName, 1); + const [randomDoc] = await createDoc(page, 'doc-editor', browserName, 1); const downloadPromise = page.waitForEvent('download', (download) => { - return download.suggestedFilename().includes(`${randomPad}.pdf`); + return download.suggestedFilename().includes(`${randomDoc}.pdf`); }); - await expect(page.locator('h2').getByText(randomPad)).toBeVisible(); + await expect(page.locator('h2').getByText(randomDoc)).toBeVisible(); await page.locator('.ProseMirror.bn-editor').click(); await page.locator('.ProseMirror.bn-editor').fill('Hello World'); @@ -38,19 +38,19 @@ test.describe('Pad Tools', () => { .click(); const download = await downloadPromise; - expect(download.suggestedFilename()).toBe(`${randomPad}.pdf`); + expect(download.suggestedFilename()).toBe(`${randomDoc}.pdf`); const pdfBuffer = await cs.toBuffer(await download.createReadStream()); const pdfText = (await pdf(pdfBuffer)).text; - expect(pdfText).toContain('Hello World'); // This is the pad text + expect(pdfText).toContain('Hello World'); // This is the doc text }); test('it converts the blocknote json in correct html for the pdf', async ({ page, browserName, }) => { - const [randomPad] = await createPad(page, 'pad-editor', browserName, 1); + const [randomDoc] = await createDoc(page, 'doc-editor', browserName, 1); let body = ''; await page.route('**/templates/*/generate-document/', async (route) => { @@ -60,7 +60,7 @@ test.describe('Pad Tools', () => { await route.continue(); }); - await expect(page.locator('h2').getByText(randomPad)).toBeVisible(); + await expect(page.locator('h2').getByText(randomDoc)).toBeVisible(); await page.locator('.bn-block-outer').last().fill('Hello World'); await page.locator('.bn-block-outer').last().click(); @@ -85,15 +85,15 @@ test.describe('Pad Tools', () => { expect(body).toContain('

'); }); - test('it updates the pad', async ({ page, browserName }) => { - const [randomPad] = await createPad( + test('it updates the doc', async ({ page, browserName }) => { + const [randomDoc] = await createDoc( page, - 'pad-update', + 'doc-update', browserName, 1, true, ); - await expect(page.locator('h2').getByText(randomPad)).toBeVisible(); + await expect(page.locator('h2').getByText(randomDoc)).toBeVisible(); await page.getByLabel('Open the document options').click(); await page @@ -103,14 +103,14 @@ test.describe('Pad Tools', () => { .click(); await expect( - page.locator('h2').getByText(`Update document "${randomPad}"`), + page.locator('h2').getByText(`Update document "${randomDoc}"`), ).toBeVisible(); await expect( page.getByRole('checkbox', { name: 'Is it public ?' }), ).toBeChecked(); - await page.getByText('Document name').fill(`${randomPad}-updated`); + await page.getByText('Document name').fill(`${randomDoc}-updated`); await page.getByText('Is it public ?').click(); await page @@ -125,7 +125,7 @@ test.describe('Pad Tools', () => { const panel = page.getByLabel('Documents panel').first(); await expect( - panel.locator('li').getByText(`${randomPad}-updated`), + panel.locator('li').getByText(`${randomDoc}-updated`), ).toBeVisible(); await page.getByLabel('Open the document options').click(); @@ -140,9 +140,9 @@ test.describe('Pad Tools', () => { ).not.toBeChecked(); }); - test('it deletes the pad', async ({ page, browserName }) => { - const [randomPad] = await createPad(page, 'pad-delete', browserName, 1); - await expect(page.locator('h2').getByText(randomPad)).toBeVisible(); + test('it deletes the doc', async ({ page, browserName }) => { + const [randomDoc] = await createDoc(page, 'doc-delete', browserName, 1); + await expect(page.locator('h2').getByText(randomDoc)).toBeVisible(); await page.getByLabel('Open the document options').click(); await page @@ -152,7 +152,7 @@ test.describe('Pad Tools', () => { .click(); await expect( - page.locator('h2').getByText(`Deleting the document "${randomPad}"`), + page.locator('h2').getByText(`Deleting the document "${randomDoc}"`), ).toBeVisible(); await page @@ -170,7 +170,7 @@ test.describe('Pad Tools', () => { ).toBeVisible(); const panel = page.getByLabel('Documents panel').first(); - await expect(panel.locator('li').getByText(randomPad)).toBeHidden(); + await expect(panel.locator('li').getByText(randomDoc)).toBeHidden(); }); test('it checks the options available if administrator', async ({ @@ -207,7 +207,7 @@ test.describe('Pad Tools', () => { } }); - await createPad(page, 'pad-tools-right-admin', browserName, 1); + await createDoc(page, 'doc-tools-right-admin', browserName, 1); await expect(page.locator('h2').getByText('Mocked document')).toBeVisible(); @@ -261,7 +261,7 @@ test.describe('Pad Tools', () => { } }); - await createPad(page, 'pad-tools-right-editor', browserName, 1); + await createDoc(page, 'doc-tools-right-editor', browserName, 1); await expect(page.locator('h2').getByText('Mocked document')).toBeVisible(); @@ -315,7 +315,7 @@ test.describe('Pad Tools', () => { } }); - await createPad(page, 'pad-tools-right-reader', browserName, 1); + await createDoc(page, 'doc-tools-right-reader', browserName, 1); await expect(page.locator('h2').getByText('Mocked document')).toBeVisible(); diff --git a/src/frontend/apps/impress/src/core/conf.ts b/src/frontend/apps/impress/src/core/conf.ts index d5449221..dc778311 100644 --- a/src/frontend/apps/impress/src/core/conf.ts +++ b/src/frontend/apps/impress/src/core/conf.ts @@ -6,10 +6,10 @@ export const baseApiUrl = (apiVersion: string = '1.0') => { return `${origin}/api/v${apiVersion}/`; }; -export const signalingUrl = (padId: string) => { +export const signalingUrl = (docId: string) => { const base = process.env.NEXT_PUBLIC_SIGNALING_URL || (typeof window !== 'undefined' ? `wss://${window.location.host}/ws` : ''); - return `${base}/${padId}`; + return `${base}/${docId}`; }; diff --git a/src/frontend/apps/impress/src/features/pads/pad-editor/components/BlockNoteEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx similarity index 65% rename from src/frontend/apps/impress/src/features/pads/pad-editor/components/BlockNoteEditor.tsx rename to src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx index 47d404de..cfbc09f2 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-editor/components/BlockNoteEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx @@ -7,41 +7,41 @@ import { WebrtcProvider } from 'y-webrtc'; import { Box } from '@/components'; import { useAuthStore } from '@/core/auth'; -import { Pad } from '@/features/pads/pad-management'; +import { Doc } from '@/features/docs/doc-management'; -import useSavePad from '../hook/useSavePad'; -import { usePadStore } from '../stores'; +import useSaveDoc from '../hook/useSaveDoc'; +import { useDocStore } from '../stores'; import { randomColor } from '../utils'; import { BlockNoteToolbar } from './BlockNoteToolbar'; interface BlockNoteEditorProps { - pad: Pad; + doc: Doc; } -export const BlockNoteEditor = ({ pad }: BlockNoteEditorProps) => { - const { createProvider, padsStore } = usePadStore(); - const provider = padsStore?.[pad.id]?.provider; +export const BlockNoteEditor = ({ doc }: BlockNoteEditorProps) => { + const { createProvider, docsStore } = useDocStore(); + const provider = docsStore?.[doc.id]?.provider; if (!provider) { - createProvider(pad.id, pad.content); + createProvider(doc.id, doc.content); return null; } - return ; + return ; }; interface BlockNoteContentProps { - pad: Pad; + doc: Doc; provider: WebrtcProvider; } -export const BlockNoteContent = ({ pad, provider }: BlockNoteContentProps) => { +export const BlockNoteContent = ({ doc, provider }: BlockNoteContentProps) => { const { userData } = useAuthStore(); - const { setEditor, padsStore } = usePadStore(); - useSavePad(pad.id, provider.doc, pad.abilities.partial_update); + const { setEditor, docsStore } = useDocStore(); + useSaveDoc(doc.id, provider.doc, doc.abilities.partial_update); - const storedEditor = padsStore?.[pad.id]?.editor; + const storedEditor = docsStore?.[doc.id]?.editor; const editor = useMemo(() => { if (storedEditor) { return storedEditor; @@ -60,8 +60,8 @@ export const BlockNoteContent = ({ pad, provider }: BlockNoteContentProps) => { }, [provider, storedEditor, userData?.email]); useEffect(() => { - setEditor(pad.id, editor); - }, [setEditor, pad.id, editor]); + setEditor(doc.id, editor); + }, [setEditor, doc.id, editor]); return ( { diff --git a/src/frontend/apps/impress/src/features/pads/pad-editor/components/BlockNoteToolbar.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolbar.tsx similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-editor/components/BlockNoteToolbar.tsx rename to src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolbar.tsx diff --git a/src/frontend/apps/impress/src/features/pads/pad-editor/components/PadEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx similarity index 70% rename from src/frontend/apps/impress/src/features/pads/pad-editor/components/PadEditor.tsx rename to src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx index 8d039870..1076709f 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-editor/components/PadEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx @@ -2,16 +2,16 @@ import { Alert, VariantType } from '@openfun/cunningham-react'; import React from 'react'; import { Box, Card, Text } from '@/components'; -import { Pad } from '@/features/pads/pad-management'; -import { PadToolBox } from '@/features/pads/pad-tools'; +import { Doc } from '@/features/docs/doc-management'; +import { DocToolBox } from '@/features/docs/doc-tools'; import { BlockNoteEditor } from './BlockNoteEditor'; -interface PadEditorProps { - pad: Pad; +interface DocEditorProps { + doc: Doc; } -export const PadEditor = ({ pad }: PadEditorProps) => { +export const DocEditor = ({ doc }: DocEditorProps) => { return ( <> { $position="relative" > - {pad.title} + {doc.title} - + - {!pad.abilities.partial_update && ( + {!doc.abilities.partial_update && ( { $css="flex:1;" $overflow="auto" > - + ); diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/index.ts b/src/frontend/apps/impress/src/features/docs/doc-editor/components/index.ts new file mode 100644 index 00000000..6d59303e --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/index.ts @@ -0,0 +1 @@ +export * from './DocEditor'; diff --git a/src/frontend/apps/impress/src/features/pads/pad-editor/hook/useSavePad.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx similarity index 82% rename from src/frontend/apps/impress/src/features/pads/pad-editor/hook/useSavePad.tsx rename to src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx index 42e0b208..f02fe2ea 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-editor/hook/useSavePad.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx @@ -2,12 +2,12 @@ import { useRouter } from 'next/router'; import { useCallback, useEffect, useRef, useState } from 'react'; import * as Y from 'yjs'; -import { useUpdatePad } from '@/features/pads/pad-management/'; +import { useUpdateDoc } from '@/features/docs/doc-management/'; import { toBase64 } from '../utils'; -const useSavePad = (padId: string, doc: Y.Doc, canSave: boolean) => { - const { mutate: updatePad } = useUpdatePad(); +const useSaveDoc = (docId: string, doc: Y.Doc, canSave: boolean) => { + const { mutate: updateDoc } = useUpdateDoc(); const [initialDoc, setInitialDoc] = useState( toBase64(Y.encodeStateAsUpdate(doc)), ); @@ -40,7 +40,7 @@ const useSavePad = (padId: string, doc: Y.Doc, canSave: boolean) => { }; }, [doc]); - const savePad = useCallback(() => { + const saveDoc = useCallback(() => { const newDoc = toBase64(Y.encodeStateAsUpdate(doc)); /** @@ -52,11 +52,11 @@ const useSavePad = (padId: string, doc: Y.Doc, canSave: boolean) => { setInitialDoc(newDoc); - updatePad({ - id: padId, + updateDoc({ + id: docId, content: newDoc, }); - }, [initialDoc, padId, doc, updatePad, canSave]); + }, [initialDoc, docId, doc, updateDoc, canSave]); const timeout = useRef(); const router = useRouter(); @@ -67,7 +67,7 @@ const useSavePad = (padId: string, doc: Y.Doc, canSave: boolean) => { } const onSave = () => { - savePad(); + saveDoc(); }; // Save every minute @@ -82,7 +82,7 @@ const useSavePad = (padId: string, doc: Y.Doc, canSave: boolean) => { removeEventListener('beforeunload', onSave); router.events.off('routeChangeStart', onSave); }; - }, [router.events, savePad]); + }, [router.events, saveDoc]); }; -export default useSavePad; +export default useSaveDoc; diff --git a/src/frontend/apps/impress/src/features/pads/pad-editor/index.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/index.tsx similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-editor/index.tsx rename to src/frontend/apps/impress/src/features/docs/doc-editor/index.tsx diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/stores/index.ts b/src/frontend/apps/impress/src/features/docs/doc-editor/stores/index.ts new file mode 100644 index 00000000..e742cba5 --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/stores/index.ts @@ -0,0 +1 @@ +export * from './useDocStore'; diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useDocStore.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useDocStore.tsx new file mode 100644 index 00000000..2eaf0159 --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useDocStore.tsx @@ -0,0 +1,66 @@ +import { BlockNoteEditor } from '@blocknote/core'; +import { WebrtcProvider } from 'y-webrtc'; +import * as Y from 'yjs'; +import { create } from 'zustand'; + +import { signalingUrl } from '@/core'; +import { Base64, Doc } from '@/features/docs/doc-management'; + +export interface DocStore { + docsStore: { + [docId: Doc['id']]: { + provider: WebrtcProvider; + editor?: BlockNoteEditor; + }; + }; + createProvider: (docId: Doc['id'], initialDoc: Base64) => WebrtcProvider; + setEditor: (docId: Doc['id'], editor: BlockNoteEditor) => void; +} + +const initialState = { + docsStore: {}, +}; + +export const useDocStore = create((set) => ({ + docsStore: initialState.docsStore, + createProvider: (docId: string, initialDoc: Base64) => { + const doc = new Y.Doc({ + guid: docId, + }); + + if (initialDoc) { + Y.applyUpdate(doc, Buffer.from(initialDoc, 'base64')); + } + + const provider = new WebrtcProvider(docId, doc, { + signaling: [signalingUrl(docId)], + maxConns: 5, + }); + + set(({ docsStore }) => { + return { + docsStore: { + ...docsStore, + [docId]: { + provider, + }, + }, + }; + }); + + return provider; + }, + setEditor: (docId, editor) => { + set(({ docsStore }) => { + return { + docsStore: { + ...docsStore, + [docId]: { + ...docsStore[docId], + editor, + }, + }, + }; + }); + }, +})); diff --git a/src/frontend/apps/impress/src/features/pads/pad-editor/utils.ts b/src/frontend/apps/impress/src/features/docs/doc-editor/utils.ts similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-editor/utils.ts rename to src/frontend/apps/impress/src/features/docs/doc-editor/utils.ts diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/api/index.ts b/src/frontend/apps/impress/src/features/docs/doc-management/api/index.ts new file mode 100644 index 00000000..4adddaae --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-management/api/index.ts @@ -0,0 +1,3 @@ +export * from './useDoc'; +export * from './useDocs'; +export * from './useUpdateDoc'; diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/api/useCreateDoc.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/api/useCreateDoc.tsx new file mode 100644 index 00000000..e7d2363f --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-management/api/useCreateDoc.tsx @@ -0,0 +1,42 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { APIError, errorCauses, fetchAPI } from '@/api'; +import { Doc, KEY_LIST_DOC } from '@/features/docs'; + +type CreateDocParam = Pick; + +export const createDoc = async ({ + title, + is_public, +}: CreateDocParam): Promise => { + const response = await fetchAPI(`documents/`, { + method: 'POST', + body: JSON.stringify({ + title, + is_public, + }), + }); + + if (!response.ok) { + throw new APIError('Failed to create the doc', await errorCauses(response)); + } + + return response.json() as Promise; +}; + +interface CreateDocProps { + onSuccess: (data: Doc) => void; +} + +export function useCreateDoc({ onSuccess }: CreateDocProps) { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: createDoc, + onSuccess: (data) => { + void queryClient.invalidateQueries({ + queryKey: [KEY_LIST_DOC], + }); + onSuccess(data); + }, + }); +} diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/api/useDoc.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/api/useDoc.tsx new file mode 100644 index 00000000..9aeb9bda --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-management/api/useDoc.tsx @@ -0,0 +1,32 @@ +import { UseQueryOptions, useQuery } from '@tanstack/react-query'; + +import { APIError, errorCauses, fetchAPI } from '@/api'; + +import { Doc } from '../types'; + +export type DocParams = { + id: string; +}; + +export const getDoc = async ({ id }: DocParams): Promise => { + const response = await fetchAPI(`documents/${id}/`); + + if (!response.ok) { + throw new APIError('Failed to get the doc', await errorCauses(response)); + } + + return response.json() as Promise; +}; + +export const KEY_DOC = 'doc'; + +export function useDoc( + param: DocParams, + queryConfig?: UseQueryOptions, +) { + return useQuery({ + queryKey: [KEY_DOC, param], + queryFn: () => getDoc(param), + ...queryConfig, + }); +} diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/api/usePads.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/api/useDocs.tsx similarity index 59% rename from src/frontend/apps/impress/src/features/pads/pad-management/api/usePads.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/api/useDocs.tsx index a0c29025..92568f14 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/api/usePads.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/api/useDocs.tsx @@ -6,59 +6,59 @@ import { } from '@tanstack/react-query'; import { APIError, APIList, errorCauses, fetchAPI } from '@/api'; -import { Pad } from '@/features/pads/pad-management'; +import { Doc } from '@/features/docs/doc-management'; -export enum PadsOrdering { +export enum DocsOrdering { BY_CREATED_ON = 'created_at', BY_CREATED_ON_DESC = '-created_at', } -export type PadsParams = { - ordering: PadsOrdering; +export type DocsParams = { + ordering: DocsOrdering; }; -type PadsAPIParams = PadsParams & { +type DocsAPIParams = DocsParams & { page: number; }; -type PadsResponse = APIList; +type DocsResponse = APIList; -export const getPads = async ({ +export const getDocs = async ({ ordering, page, -}: PadsAPIParams): Promise => { +}: DocsAPIParams): Promise => { const orderingQuery = ordering ? `&ordering=${ordering}` : ''; const response = await fetchAPI(`documents/?page=${page}${orderingQuery}`); if (!response.ok) { - throw new APIError('Failed to get the pads', await errorCauses(response)); + throw new APIError('Failed to get the docs', await errorCauses(response)); } - return response.json() as Promise; + return response.json() as Promise; }; -export const KEY_LIST_PAD = 'pads'; +export const KEY_LIST_DOC = 'docs'; -export function usePads( - param: PadsParams, +export function useDocs( + param: DocsParams, queryConfig?: DefinedInitialDataInfiniteOptions< - PadsResponse, + DocsResponse, APIError, - InfiniteData, + InfiniteData, QueryKey, number >, ) { return useInfiniteQuery< - PadsResponse, + DocsResponse, APIError, - InfiniteData, + InfiniteData, QueryKey, number >({ initialPageParam: 1, - queryKey: [KEY_LIST_PAD, param], + queryKey: [KEY_LIST_DOC, param], queryFn: ({ pageParam }) => - getPads({ + getDocs({ ...param, page: pageParam, }), diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/api/useRemovePad.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/api/useRemoveDoc.tsx similarity index 55% rename from src/frontend/apps/impress/src/features/pads/pad-management/api/useRemovePad.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/api/useRemoveDoc.tsx index 02871c6c..c64ee3b2 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/api/useRemovePad.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/api/useRemoveDoc.tsx @@ -6,32 +6,32 @@ import { import { APIError, errorCauses, fetchAPI } from '@/api'; -import { KEY_LIST_PAD } from './usePads'; +import { KEY_LIST_DOC } from './useDocs'; -interface RemovePadProps { - padId: string; +interface RemoveDocProps { + docId: string; } -export const removePad = async ({ padId }: RemovePadProps): Promise => { - const response = await fetchAPI(`documents/${padId}/`, { +export const removeDoc = async ({ docId }: RemoveDocProps): Promise => { + const response = await fetchAPI(`documents/${docId}/`, { method: 'DELETE', }); if (!response.ok) { - throw new APIError('Failed to delete the pad', await errorCauses(response)); + throw new APIError('Failed to delete the doc', await errorCauses(response)); } }; -type UseRemovePadOptions = UseMutationOptions; +type UseRemoveDocOptions = UseMutationOptions; -export const useRemovePad = (options?: UseRemovePadOptions) => { +export const useRemoveDoc = (options?: UseRemoveDocOptions) => { const queryClient = useQueryClient(); - return useMutation({ - mutationFn: removePad, + return useMutation({ + mutationFn: removeDoc, ...options, onSuccess: (data, variables, context) => { void queryClient.invalidateQueries({ - queryKey: [KEY_LIST_PAD], + queryKey: [KEY_LIST_DOC], }); if (options?.onSuccess) { options.onSuccess(data, variables, context); diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/api/useUpdatePad.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/api/useUpdateDoc.tsx similarity index 55% rename from src/frontend/apps/impress/src/features/pads/pad-management/api/useUpdatePad.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/api/useUpdateDoc.tsx index 8c59a9b9..79ae14a3 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/api/useUpdatePad.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/api/useUpdateDoc.tsx @@ -1,15 +1,15 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { APIError, errorCauses, fetchAPI } from '@/api'; -import { Pad } from '@/features/pads'; +import { Doc } from '@/features/docs'; -export type UpdatePadParams = Pick & - Partial>; +export type UpdateDocParams = Pick & + Partial>; -export const updatePad = async ({ +export const updateDoc = async ({ id, ...params -}: UpdatePadParams): Promise => { +}: UpdateDocParams): Promise => { const response = await fetchAPI(`documents/${id}/`, { method: 'PATCH', body: JSON.stringify({ @@ -18,24 +18,24 @@ export const updatePad = async ({ }); if (!response.ok) { - throw new APIError('Failed to update the pad', await errorCauses(response)); + throw new APIError('Failed to update the doc', await errorCauses(response)); } - return response.json() as Promise; + return response.json() as Promise; }; -interface UpdatePadProps { - onSuccess?: (data: Pad) => void; +interface UpdateDocProps { + onSuccess?: (data: Doc) => void; listInvalideQueries?: string[]; } -export function useUpdatePad({ +export function useUpdateDoc({ onSuccess, listInvalideQueries, -}: UpdatePadProps = {}) { +}: UpdateDocProps = {}) { const queryClient = useQueryClient(); - return useMutation({ - mutationFn: updatePad, + return useMutation({ + mutationFn: updateDoc, onSuccess: (data) => { listInvalideQueries?.forEach((queryKey) => { void queryClient.invalidateQueries({ diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/assets/icon-pad.svg b/src/frontend/apps/impress/src/features/docs/doc-management/assets/icon-doc.svg similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-management/assets/icon-pad.svg rename to src/frontend/apps/impress/src/features/docs/doc-management/assets/icon-doc.svg diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/assets/icon-edit.svg b/src/frontend/apps/impress/src/features/docs/doc-management/assets/icon-edit.svg similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-management/assets/icon-edit.svg rename to src/frontend/apps/impress/src/features/docs/doc-management/assets/icon-edit.svg diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/assets/icon-trash.svg b/src/frontend/apps/impress/src/features/docs/doc-management/assets/icon-trash.svg similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-management/assets/icon-trash.svg rename to src/frontend/apps/impress/src/features/docs/doc-management/assets/icon-trash.svg diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/components/CardCreatePad.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/CardCreateDoc.tsx similarity index 72% rename from src/frontend/apps/impress/src/features/pads/pad-management/components/CardCreatePad.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/components/CardCreateDoc.tsx index cf60ca45..df007119 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/components/CardCreatePad.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/components/CardCreateDoc.tsx @@ -7,25 +7,25 @@ import IconGroup from '@/assets/icons/icon-group2.svg'; import { Box, Card, StyledLink, Text } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; -import { useCreatePad } from '../api/useCreatePad'; +import { useCreateDoc } from '../api/useCreateDoc'; -import { InputPadName } from './InputPadName'; +import { InputDocName } from './InputDocName'; -export const CardCreatePad = () => { +export const CardCreateDoc = () => { const { t } = useTranslation(); const router = useRouter(); const { - mutate: createPad, + mutate: createDoc, isError, isPending, error, - } = useCreatePad({ - onSuccess: (pad) => { - router.push(`/docs/${pad.id}`); + } = useCreateDoc({ + onSuccess: (doc) => { + router.push(`/docs/${doc.id}`); }, }); - const [padName, setPadName] = useState(''); - const [padPublic, setPadPublic] = useState(false); + const [docName, setDocName] = useState(''); + const [docPublic, setDocPublic] = useState(false); const { colorsTokens } = useCunninghamTheme(); return ( @@ -49,14 +49,14 @@ export const CardCreatePad = () => { {t('Name the document')} - setPadPublic(!padPublic)} + onChange={() => setDocPublic(!docPublic)} /> @@ -64,8 +64,8 @@ export const CardCreatePad = () => { diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/components/InputPadName.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/InputDocName.tsx similarity index 84% rename from src/frontend/apps/impress/src/features/pads/pad-management/components/InputPadName.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/components/InputDocName.tsx index d3d78704..7e1f58de 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/components/InputPadName.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/components/InputDocName.tsx @@ -4,23 +4,23 @@ import { useEffect, useState } from 'react'; import { APIError } from '@/api'; import { Box, TextErrors } from '@/components'; -interface InputPadNameProps { +interface InputDocNameProps { error: APIError | null; isError: boolean; isPending: boolean; label: string; - setPadName: (newPadName: string) => void; + setDocName: (newDocName: string) => void; defaultValue?: string; } -export const InputPadName = ({ +export const InputDocName = ({ defaultValue, error, isError, isPending, label, - setPadName, -}: InputPadNameProps) => { + setDocName, +}: InputDocNameProps) => { const [isInputError, setIsInputError] = useState(isError); useEffect(() => { @@ -37,7 +37,7 @@ export const InputPadName = ({ label={label} defaultValue={defaultValue} onChange={(e) => { - setPadName(e.target.value); + setDocName(e.target.value); setIsInputError(false); }} rightIcon={edit} diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/components/ModalRemovePad.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalRemoveDoc.tsx similarity index 85% rename from src/frontend/apps/impress/src/features/pads/pad-management/components/ModalRemovePad.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/components/ModalRemoveDoc.tsx index d3b71122..2e4fc9b1 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/components/ModalRemovePad.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalRemoveDoc.tsx @@ -12,26 +12,26 @@ import { useRouter } from 'next/navigation'; import { Box, Text, TextErrors } from '@/components'; import useCunninghamTheme from '@/cunningham/useCunninghamTheme'; -import { useRemovePad } from '../api/useRemovePad'; -import IconPad from '../assets/icon-pad.svg'; +import { useRemoveDoc } from '../api/useRemoveDoc'; +import IconDoc from '../assets/icon-doc.svg'; import IconRemove from '../assets/icon-trash.svg'; -import { Pad } from '../types'; +import { Doc } from '../types'; -interface ModalRemovePadProps { +interface ModalRemoveDocProps { onClose: () => void; - pad: Pad; + doc: Doc; } -export const ModalRemovePad = ({ onClose, pad }: ModalRemovePadProps) => { +export const ModalRemoveDoc = ({ onClose, doc }: ModalRemoveDocProps) => { const { colorsTokens } = useCunninghamTheme(); const { toast } = useToastProvider(); const router = useRouter(); const { - mutate: removePad, + mutate: removeDoc, isError, error, - } = useRemovePad({ + } = useRemoveDoc({ onSuccess: () => { toast(t('The document has been deleted.'), VariantType.SUCCESS, { duration: 4000, @@ -62,8 +62,8 @@ export const ModalRemovePad = ({ onClose, pad }: ModalRemovePadProps) => { color="primary" fullWidth onClick={() => - removePad({ - padId: pad.id, + removeDoc({ + docId: doc.id, }) } > @@ -75,7 +75,7 @@ export const ModalRemovePad = ({ onClose, pad }: ModalRemovePadProps) => { - {t('Deleting the document "{{title}}"', { title: pad.title })} + {t('Deleting the document "{{title}}"', { title: doc.title })} } @@ -88,7 +88,7 @@ export const ModalRemovePad = ({ onClose, pad }: ModalRemovePadProps) => { {t('Are you sure you want to delete the document "{{title}}"?', { - title: pad.title, + title: doc.title, })} @@ -106,7 +106,7 @@ export const ModalRemovePad = ({ onClose, pad }: ModalRemovePadProps) => { $align="center" $radius="2px" > - { }} /> - {pad.title} + {doc.title} diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/components/ModalUpdatePad.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalUpdateDoc.tsx similarity index 73% rename from src/frontend/apps/impress/src/features/pads/pad-management/components/ModalUpdatePad.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/components/ModalUpdateDoc.tsx index 4ef848e5..5b790dd4 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/components/ModalUpdatePad.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalUpdateDoc.tsx @@ -13,38 +13,38 @@ import { useTranslation } from 'react-i18next'; import { Box, Text } from '@/components'; import useCunninghamTheme from '@/cunningham/useCunninghamTheme'; -import { KEY_LIST_PAD, KEY_PAD } from '../api'; -import { useUpdatePad } from '../api/useUpdatePad'; +import { KEY_DOC, KEY_LIST_DOC } from '../api'; +import { useUpdateDoc } from '../api/useUpdateDoc'; import IconEdit from '../assets/icon-edit.svg'; -import { Pad } from '../types'; +import { Doc } from '../types'; -import { InputPadName } from './InputPadName'; +import { InputDocName } from './InputDocName'; -interface ModalUpdatePadProps { +interface ModalUpdateDocProps { onClose: () => void; - pad: Pad; + doc: Doc; } -export const ModalUpdatePad = ({ onClose, pad }: ModalUpdatePadProps) => { +export const ModalUpdateDoc = ({ onClose, doc }: ModalUpdateDocProps) => { const { colorsTokens } = useCunninghamTheme(); - const [title, setTitle] = useState(pad.title); + const [title, setTitle] = useState(doc.title); const { toast } = useToastProvider(); - const [padPublic, setPadPublic] = useState(pad.is_public); + const [docPublic, setDocPublic] = useState(doc.is_public); const { t } = useTranslation(); const { - mutate: updatePad, + mutate: updateDoc, isError, isPending, error, - } = useUpdatePad({ + } = useUpdateDoc({ onSuccess: () => { toast(t('The document has been updated.'), VariantType.SUCCESS, { duration: 4000, }); onClose(); }, - listInvalideQueries: [KEY_PAD, KEY_LIST_PAD], + listInvalideQueries: [KEY_DOC, KEY_LIST_DOC], }); return ( @@ -69,10 +69,10 @@ export const ModalUpdatePad = ({ onClose, pad }: ModalUpdatePadProps) => { color="primary" fullWidth onClick={() => - updatePad({ + updateDoc({ title, - id: pad.id, - is_public: padPublic, + id: doc.id, + is_public: docPublic, }) } > @@ -85,7 +85,7 @@ export const ModalUpdatePad = ({ onClose, pad }: ModalUpdatePadProps) => { {t('Update document "{{documentTitle}}"', { - documentTitle: pad.title, + documentTitle: doc.title, })} @@ -101,16 +101,16 @@ export const ModalUpdatePad = ({ onClose, pad }: ModalUpdatePadProps) => { - setPadPublic(!padPublic)} + defaultChecked={docPublic} + onChange={() => setDocPublic(!docPublic)} /> diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/components/index.ts b/src/frontend/apps/impress/src/features/docs/doc-management/components/index.ts new file mode 100644 index 00000000..bbd7b69f --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-management/components/index.ts @@ -0,0 +1,3 @@ +export * from './CardCreateDoc'; +export * from './ModalRemoveDoc'; +export * from './ModalUpdateDoc'; diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/index.ts b/src/frontend/apps/impress/src/features/docs/doc-management/index.ts similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-management/index.ts rename to src/frontend/apps/impress/src/features/docs/doc-management/index.ts diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/types.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/types.tsx similarity index 97% rename from src/frontend/apps/impress/src/features/pads/pad-management/types.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/types.tsx index e3c2784c..5db4d395 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/types.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/types.tsx @@ -22,7 +22,7 @@ export enum Role { export type Base64 = string; -export interface Pad { +export interface Doc { id: string; title: string; content: Base64; diff --git a/src/frontend/apps/impress/src/features/pads/pad-management/utils.ts b/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts similarity index 67% rename from src/frontend/apps/impress/src/features/pads/pad-management/utils.ts rename to src/frontend/apps/impress/src/features/docs/doc-management/utils.ts index 99e9682e..c1437e2f 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-management/utils.ts +++ b/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts @@ -1,6 +1,6 @@ -import { Pad, Role } from './types'; +import { Doc, Role } from './types'; -export const currentDocRole = (doc: Pad): Role => { +export const currentDocRole = (doc: Doc): Role => { return doc.abilities.destroy ? Role.OWNER : doc.abilities.manage_accesses diff --git a/src/frontend/apps/impress/src/features/pads/pad-tools/api/useCreatePdf.tsx b/src/frontend/apps/impress/src/features/docs/doc-tools/api/useCreatePdf.tsx similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-tools/api/useCreatePdf.tsx rename to src/frontend/apps/impress/src/features/docs/doc-tools/api/useCreatePdf.tsx diff --git a/src/frontend/apps/impress/src/features/pads/pad-tools/api/useTemplates.tsx b/src/frontend/apps/impress/src/features/docs/doc-tools/api/useTemplates.tsx similarity index 100% rename from src/frontend/apps/impress/src/features/pads/pad-tools/api/useTemplates.tsx rename to src/frontend/apps/impress/src/features/docs/doc-tools/api/useTemplates.tsx diff --git a/src/frontend/apps/impress/src/features/pads/pad-tools/components/PadToolBox.tsx b/src/frontend/apps/impress/src/features/docs/doc-tools/components/DocToolBox.tsx similarity index 85% rename from src/frontend/apps/impress/src/features/pads/pad-tools/components/PadToolBox.tsx rename to src/frontend/apps/impress/src/features/docs/doc-tools/components/DocToolBox.tsx index ed530719..0bf498f1 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-tools/components/PadToolBox.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-tools/components/DocToolBox.tsx @@ -3,24 +3,24 @@ import React, { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Box, DropButton, IconOptions, Text } from '@/components'; -import { ModalAddMembers } from '@/features/pads/members/members-add'; -import { ModalGridMembers } from '@/features/pads/members/members-grid/'; import { - ModalRemovePad, - ModalUpdatePad, - Pad, + Doc, + ModalRemoveDoc, + ModalUpdateDoc, currentDocRole, -} from '@/features/pads/pad-management'; +} from '@/features/docs/doc-management'; +import { ModalAddMembers } from '@/features/docs/members/members-add'; +import { ModalGridMembers } from '@/features/docs/members/members-grid/'; import { TemplatesOrdering, useTemplates } from '../api/useTemplates'; import { ModalPDF } from './ModalPDF'; -interface PadToolBoxProps { - pad: Pad; +interface DocToolBoxProps { + doc: Doc; } -export const PadToolBox = ({ pad }: PadToolBoxProps) => { +export const DocToolBox = ({ doc }: DocToolBoxProps) => { const { t } = useTranslation(); const { data: templates } = useTemplates({ ordering: TemplatesOrdering.BY_CREATED_ON_DESC, @@ -62,7 +62,7 @@ export const PadToolBox = ({ pad }: PadToolBoxProps) => { isOpen={isDropOpen} > - {pad.abilities.manage_accesses && ( + {doc.abilities.manage_accesses && ( <> )} - {pad.abilities.partial_update && ( + {doc.abilities.partial_update && ( )} - {pad.abilities.destroy && ( + {doc.abilities.destroy && (