diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts index 476510e1..035e39e0 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts @@ -1,3 +1,5 @@ +/* eslint-disable playwright/no-conditional-expect */ +/* eslint-disable playwright/no-conditional-in-test */ import path from 'path'; import { expect, test } from '@playwright/test'; @@ -368,4 +370,77 @@ test.describe('Doc Editor', () => { await expect(editor.getByText('Bonjour le monde')).toBeVisible(); }); + + [ + { ai_transform: false, ai_translate: false }, + { ai_transform: true, ai_translate: false }, + { ai_transform: false, ai_translate: true }, + ].forEach(({ ai_transform, ai_translate }) => { + test(`it checks AI buttons when can transform is at "${ai_transform}" and can translate is at "${ai_translate}"`, async ({ + page, + }) => { + await mockedDocument(page, { + accesses: [ + { + id: 'b0df4343-c8bd-4c20-9ff6-fbf94fc94egg', + role: 'owner', + user: { + email: 'super@owner.com', + full_name: 'Super Owner', + }, + }, + ], + abilities: { + destroy: true, // Means owner + link_configuration: true, + ai_transform, + ai_translate, + accesses_manage: true, + accesses_view: true, + update: true, + partial_update: true, + retrieve: true, + }, + link_reach: 'public', + link_role: 'editor', + created_at: '2021-09-01T09:00:00Z', + }); + + await goToGridDoc(page); + + await verifyDocName(page, 'Mocked document'); + + await page.locator('.bn-block-outer').last().fill('Hello World'); + + const editor = page.locator('.ProseMirror'); + await editor.getByText('Hello').dblclick(); + + if (!ai_transform && !ai_translate) { + await expect(page.getByRole('button', { name: 'AI' })).toBeHidden(); + return; + } + + await page.getByRole('button', { name: 'AI' }).click(); + + if (ai_transform) { + await expect( + page.getByRole('menuitem', { name: 'Use as prompt' }), + ).toBeVisible(); + } else { + await expect( + page.getByRole('menuitem', { name: 'Use as prompt' }), + ).toBeHidden(); + } + + if (ai_translate) { + await expect( + page.getByRole('menuitem', { name: 'Language' }), + ).toBeVisible(); + } else { + await expect( + page.getByRole('menuitem', { name: 'Language' }), + ).toBeHidden(); + } + }); + }); }); diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/AIButton.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/AIButton.tsx index 31c98291..f30ccc5b 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/AIButton.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/AIButton.tsx @@ -92,6 +92,13 @@ export function AIGroupButton() { return null; } + const canAITransform = currentDoc.abilities.ai_transform; + const canAITranslate = currentDoc.abilities.ai_translate; + + if (!canAITransform && !canAITranslate) { + return null; + } + return ( @@ -111,79 +118,85 @@ export function AIGroupButton() { className="bn-menu-dropdown bn-drag-handle-menu" sub={true} > - - text_fields - - } - > - {t('Use as prompt')} - - - refresh - - } - > - {t('Rephrase')} - - - summarize - - } - > - {t('Summarize')} - - - check - - } - > - {t('Correct')} - - - - - + {canAITransform && ( + <> + - translate + text_fields - {t('Language')} - - - - - {languages.map((language) => ( - + {t('Use as prompt')} + + + refresh + + } + > + {t('Rephrase')} + + + summarize + + } + > + {t('Summarize')} + + + check + + } + > + {t('Correct')} + + + )} + {canAITranslate && ( + + + - {language.display_name} - - ))} - - + + + translate + + {t('Language')} + + + + + {languages.map((language) => ( + + {language.display_name} + + ))} + + + )} ); diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx index 6beabd79..e000a488 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx @@ -65,7 +65,7 @@ export const DocEditor = ({ doc, versionId }: DocEditorProps) => { $css="overflow-x: clip; flex: 1;" $position="relative" > - + {isVersion ? ( ) : ( diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/types.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/types.tsx index 6afcc517..8462df0e 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/types.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/types.tsx @@ -48,10 +48,20 @@ export interface Doc { abilities: { accesses_manage: boolean; accesses_view: boolean; - attachment_upload: true; + ai_transform: boolean; + ai_translate: boolean; + attachment_upload: boolean; + children_create: boolean; + children_list: boolean; + collaboration_auth: boolean; destroy: boolean; + favorite: boolean; + invite_owner: boolean; link_configuration: boolean; + media_auth: boolean; + move: boolean; partial_update: boolean; + restore: boolean; retrieve: boolean; update: boolean; versions_destroy: boolean; diff --git a/src/frontend/apps/impress/src/features/service-worker/ApiPlugin.ts b/src/frontend/apps/impress/src/features/service-worker/ApiPlugin.ts index 2195c00b..875bb87c 100644 --- a/src/frontend/apps/impress/src/features/service-worker/ApiPlugin.ts +++ b/src/frontend/apps/impress/src/features/service-worker/ApiPlugin.ts @@ -195,10 +195,20 @@ export class ApiPlugin implements WorkboxPlugin { abilities: { accesses_manage: true, accesses_view: true, + ai_transform: true, + ai_translate: true, attachment_upload: true, + children_create: true, + children_list: true, + collaboration_auth: true, destroy: true, + favorite: true, + invite_owner: true, link_configuration: true, + media_auth: true, + move: true, partial_update: true, + restore: true, retrieve: true, update: true, versions_destroy: true,