From 0b8e5191395e6d49d9069cfd12581c768d75fbc8 Mon Sep 17 00:00:00 2001 From: dakshesh14 Date: Sun, 23 Mar 2025 13:26:01 +0400 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=94=A7(nginx)=20add=20nginx=20config?= =?UTF-8?q?=20to=20serve=20PDF=20inline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dakshesh14 --- docker/files/etc/nginx/conf.d/default.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker/files/etc/nginx/conf.d/default.conf b/docker/files/etc/nginx/conf.d/default.conf index 66bdada12..afa52dcf7 100644 --- a/docker/files/etc/nginx/conf.d/default.conf +++ b/docker/files/etc/nginx/conf.d/default.conf @@ -69,6 +69,9 @@ server { proxy_pass http://minio:9000/impress-media-storage/; proxy_set_header Host minio:9000; + proxy_hide_header Content-Disposition; + add_header Content-Disposition "inline"; + add_header Content-Security-Policy "default-src 'none'" always; } From 9b6a839e3bd7003b7795155aa83b394f1bd00048 Mon Sep 17 00:00:00 2001 From: dakshesh14 Date: Sun, 23 Mar 2025 13:28:42 +0400 Subject: [PATCH 2/5] =?UTF-8?q?=E2=9C=A8(frontend)=20add=20pdf=20blocks=20?= =?UTF-8?q?to=20the=20editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dakshesh14 --- .../doc-editor/components/BlockNoteEditor.tsx | 3 +- .../components/BlockNoteSuggestionMenu.tsx | 8 +- .../components/custom-blocks/PdfBlock.tsx | 121 ++++++++++++++++++ .../components/custom-blocks/index.ts | 1 + 4 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx index 8f104c13c..b684360fc 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx @@ -27,7 +27,7 @@ import { randomColor } from '../utils'; import { BlockNoteSuggestionMenu } from './BlockNoteSuggestionMenu'; import { BlockNoteToolbar } from './BlockNoteToolBar/BlockNoteToolbar'; -import { DividerBlock, QuoteBlock } from './custom-blocks'; +import { DividerBlock, PDFBlock, QuoteBlock } from './custom-blocks'; export const blockNoteSchema = withPageBreak( BlockNoteSchema.create({ @@ -35,6 +35,7 @@ export const blockNoteSchema = withPageBreak( ...defaultBlockSpecs, divider: DividerBlock, quote: QuoteBlock, + pdf: PDFBlock, }, }), ); diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx index d15e1b5ed..e9b8bdddb 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx @@ -13,13 +13,16 @@ import { DocsBlockSchema } from '../types'; import { getDividerReactSlashMenuItems, + getPdfSlackMenuItems, getQuoteReactSlashMenuItems, } from './custom-blocks'; export const BlockNoteSuggestionMenu = () => { const editor = useBlockNoteEditor(); const { t } = useTranslation(); - const basicBlocksName = useDictionary().slash_menu.page_break.group; + const dictionaryDate = useDictionary(); + const basicBlocksName = dictionaryDate.slash_menu.page_break.group; + const fileBlocksName = dictionaryDate.slash_menu.file.group; const getSlashMenuItems = useMemo(() => { return async (query: string) => @@ -30,11 +33,12 @@ export const BlockNoteSuggestionMenu = () => { getPageBreakReactSlashMenuItems(editor), getQuoteReactSlashMenuItems(editor, t, basicBlocksName), getDividerReactSlashMenuItems(editor, t, basicBlocksName), + getPdfSlackMenuItems(editor, t, fileBlocksName), ), query, ), ); - }, [basicBlocksName, editor, t]); + }, [basicBlocksName, fileBlocksName, editor, t]); return ( , + 'contentRef' + >, +) => { + const { t } = useTranslation(); + + const pdfUrl = props.block.props.url; + + return ( + props.editor.setTextCursorPosition(props.block)} + aria-label={props.block.props.name} + > +

+ {t('Your browser does not support PDFs.')}{' '} + {t('Download the pdf instead.')} +

+ + ); +}; + +export const PDFBlock = createReactBlockSpec( + { + type: 'pdf', + propSchema: { + name: { + default: '' as const, + }, + url: { + default: '' as const, + }, + caption: { + default: '' as const, + }, + showPreview: { + default: true, + }, + previewWidth: { + default: 512, + }, + }, + content: 'none', + isFileBlock: true, + } as const as FileBlockConfig, + { + render: (props) => ( +
+ {props.block.props.url === '' ? ( + + upload + + } + /> + ) : ( + + + + )} +
+ ), + }, +); + +export const getPdfSlackMenuItems = ( + editor: DocsBlockNoteEditor, + t: TFunction<'translation', undefined>, + group: string, +) => [ + { + title: t('PDF'), + onItemClick: () => { + insertOrUpdateBlock(editor, { + type: 'pdf', + }); + }, + aliases: ['pdf', 'document', 'embed', 'file'], + group, + icon: ( + + upload + + ), + subtext: t('Embed a pdf file'), + }, +]; diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/index.ts b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/index.ts index 0dbdc0329..59d6fd1ed 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/index.ts +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/index.ts @@ -1,2 +1,3 @@ export * from './DividerBlock'; export * from './QuoteBlock'; +export * from './PdfBlock'; From 3082935c8bb99dd0e2f6a26e1ca171d5628226b5 Mon Sep 17 00:00:00 2001 From: dakshesh14 Date: Sun, 23 Mar 2025 13:31:20 +0400 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=8C=90(i18n):=20add=20translation=20f?= =?UTF-8?q?or=20pdf=20block=20in=20editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dakshesh14 --- .../apps/impress/src/i18n/translations.json | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/frontend/apps/impress/src/i18n/translations.json b/src/frontend/apps/impress/src/i18n/translations.json index 97777f17d..f6fa7f493 100644 --- a/src/frontend/apps/impress/src/i18n/translations.json +++ b/src/frontend/apps/impress/src/i18n/translations.json @@ -210,7 +210,10 @@ "You do not have permission to view users sharing this document or modify link settings.": "Ihnen fehlt die Berechtigung, die das Dokument teilenden Benutzer einzusehen oder die Linkeinstellungen zu ändern.", "Your current document will revert to this version.": "Ihr aktuelles Dokument wird auf diese Version zurückgesetzt.", "Your {{format}} was downloaded succesfully": "Ihr {{format}} wurde erfolgreich heruntergeladen", - "you have reported to the website manager a lack of accessibility that prevents you from accessing content or one of the services of the portal and you have not received a satisfactory response.": "sie haben dem Website-Manager einen Mangel an Barrierefreiheit gemeldet, der Ihnen den Zugriff auf Inhalte oder einen der Dienste des Portals verwehrt, und Sie haben keine zufriedenstellende Antwort erhalten." + "you have reported to the website manager a lack of accessibility that prevents you from accessing content or one of the services of the portal and you have not received a satisfactory response.": "sie haben dem Website-Manager einen Mangel an Barrierefreiheit gemeldet, der Ihnen den Zugriff auf Inhalte oder einen der Dienste des Portals verwehrt, und Sie haben keine zufriedenstellende Antwort erhalten.", + "Embed a pdf file": "Eine PDF-Datei einbetten", + "Your browser does not support PDFs.": "Ihr Browser unterstützt keine PDFs.", + "Download the pdf instead.": "Laden Sie stattdessen die PDF herunter." } }, "en": { @@ -438,7 +441,10 @@ "home-content-open-source-part1": "Docs est construit sur <2>Django Rest Framework et <6>Next.js. Nous utilisons également <9>Yjs et <13>BlockNote.js, deux projets que nous sommes fiers de sponsoriser.", "home-content-open-source-part2": "Vous pouvez facilement auto-héberger Docs (consultez notre <2>documentation d'installation).
Docs utilise une <7>licence (MIT) adaptée à l'innovation et aux entreprises.
Les contributions sont les bienvenues (consultez notre feuille de route <13>ici).", "home-content-open-source-part3": "Docs est le résultat d'un effort conjoint mené par les gouvernements français 🇫🇷🥖 <1>(DINUM) et allemand 🇩🇪🥨 <5>(ZenDiS).", - "you have reported to the website manager a lack of accessibility that prevents you from accessing content or one of the services of the portal and you have not received a satisfactory response.": "vous avez signalé au responsable du site internet un défaut d'accessibilité qui vous empêche d'accéder à un contenu ou à un des services du portail et vous n'avez pas obtenu de réponse satisfaisante." + "you have reported to the website manager a lack of accessibility that prevents you from accessing content or one of the services of the portal and you have not received a satisfactory response.": "vous avez signalé au responsable du site internet un défaut d'accessibilité qui vous empêche d'accéder à un contenu ou à un des services du portail et vous n'avez pas obtenu de réponse satisfaisante.", + "Embed a pdf file": "Intégrer un fichier PDF", + "Your browser does not support PDFs.": "Votre navigateur ne prend pas en charge les fichiers PDF.", + "Download the pdf instead.": "Téléchargez plutôt le fichier PDF." } }, "nl": { @@ -664,7 +670,10 @@ "home-content-open-source-part1": "home-content-open-source-part1", "home-content-open-source-part2": "home-content-open-source-part2", "home-content-open-source-part3": "home-content-open-source-part3", - "you have reported to the website manager a lack of accessibility that prevents you from accessing content or one of the services of the portal and you have not received a satisfactory response.": "u heeft aan de websitebeheerder gerapporteerd dat u geen toegang heeft tot de inhoud of een van de diensten van het portaal, en u hebt geen bevredigend antwoord ontvangen." + "you have reported to the website manager a lack of accessibility that prevents you from accessing content or one of the services of the portal and you have not received a satisfactory response.": "u heeft aan de websitebeheerder gerapporteerd dat u geen toegang heeft tot de inhoud of een van de diensten van het portaal, en u hebt geen bevredigend antwoord ontvangen.", + "Embed a pdf file": "Een PDF-bestand insluiten", + "Your browser does not support PDFs.": "Uw browser ondersteunt geen PDF's.", + "Download the pdf instead.": "Download de PDF in plaats daarvan." } }, "tr": { "translation": {} } From a6f95d1f84d8cd912da7c9838025166741a05d73 Mon Sep 17 00:00:00 2001 From: dakshesh14 Date: Sun, 23 Mar 2025 13:35:37 +0400 Subject: [PATCH 4/5] =?UTF-8?q?=E2=9C=A8(frontend)=20add=20pdf=20blocks=20?= =?UTF-8?q?to=20the=20editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dakshesh14 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1fb52647..2c0ab6bbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to ## Changed - ♻️(frontend) Integrate UI kit #783 +- ✨(frontend) add pdf block to the editor #348 ## [2.6.0] - 2025-03-21 From a689bfdc29e2b481b7c96d44f9f29b19768c6d96 Mon Sep 17 00:00:00 2001 From: dakshesh14 Date: Sun, 23 Mar 2025 15:07:51 +0400 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=90=9B(frontend)=20fix=20embed=20comp?= =?UTF-8?q?atibility=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dakshesh14 --- .../components/custom-blocks/PdfBlock.tsx | 36 +++++++++++-------- .../hook/useCheckEmbedCompatibility.tsx | 16 +++++++++ 2 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 src/frontend/apps/impress/src/features/docs/doc-editor/hook/useCheckEmbedCompatibility.tsx diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx index 646d7d63e..50f8538e7 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx @@ -15,6 +15,7 @@ import { useTranslation } from 'react-i18next'; import { Text } from '@/components'; +import { useCheckEmbedCompatibility } from '../../hook/useCheckEmbedCompatibility'; import { DocsBlockNoteEditor } from '../../types'; export const PDFPreview = ( @@ -28,25 +29,30 @@ export const PDFPreview = ( >, ) => { const { t } = useTranslation(); + const { isCompatible } = useCheckEmbedCompatibility(); const pdfUrl = props.block.props.url; return ( - props.editor.setTextCursorPosition(props.block)} - aria-label={props.block.props.name} - > -

- {t('Your browser does not support PDFs.')}{' '} - {t('Download the pdf instead.')} -

- + <> + {isCompatible ? ( + props.editor.setTextCursorPosition(props.block)} + aria-label={props.block.props.name} + /> + ) : ( +

+ {t('Your browser does not support PDFs.')}{' '} + {t('Download the pdf instead.')} +

+ )} + ); }; diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useCheckEmbedCompatibility.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useCheckEmbedCompatibility.tsx new file mode 100644 index 000000000..a1f3f2ffe --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useCheckEmbedCompatibility.tsx @@ -0,0 +1,16 @@ +import { useEffect, useState } from 'react'; + +export const useCheckEmbedCompatibility = () => { + const [isCompatible, setIsCompatible] = useState(true); + + useEffect(() => { + const embedElement = document.createElement('embed'); + + setIsCompatible( + embedElement instanceof HTMLObjectElement || + embedElement instanceof HTMLEmbedElement, + ); + }, []); + + return { isCompatible } as const; +};