From 70eb09a3ca31aff7c606c783d940c9bdd8476c92 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 1 Oct 2024 15:28:35 +0200 Subject: [PATCH 01/11] =?UTF-8?q?=F0=9F=90=9B(frontend)=20fix=20sticky=20p?= =?UTF-8?q?anel=20editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the sticky panel editor is not working properly, the panel editor should be sticky until the bottom when the user scrolls the page. --- .../src/features/docs/doc-editor/components/PanelEditor.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/PanelEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/PanelEditor.tsx index 1d81731a0..56638d612 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/PanelEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/PanelEditor.tsx @@ -35,7 +35,6 @@ export const PanelEditor = ({ $css={` top: 0vh; transform: translateX(0%); - overflow: hidden; flex: 1; margin-left: 1rem; ${ From 443a012ca2780c7f5208bfedd864b34866842940 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 1 Oct 2024 15:40:39 +0200 Subject: [PATCH 02/11] =?UTF-8?q?=F0=9F=9B=82(frontend)=20redirect=20to=20?= =?UTF-8?q?the=20OIDC=20when=20private=20doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now redirect to the OIDC when a user is on a private doc and get a 401 error. --- src/frontend/apps/impress/src/pages/docs/[id]/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx b/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx index 2f2d92b97..378713c92 100644 --- a/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx +++ b/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx @@ -32,7 +32,7 @@ interface DocProps { } const DocPage = ({ id }: DocProps) => { - const { authenticated, login } = useAuthStore(); + const { login } = useAuthStore(); const { data: docQuery, isError, error } = useDoc({ id }); const [doc, setDoc] = useState(docQuery); @@ -60,7 +60,7 @@ const DocPage = ({ id }: DocProps) => { return null; } - if (error.status === 401 && !authenticated) { + if (error.status === 401) { login(); return null; } From 1979f88f15a4d5a543282c9bc06b6d4d2d901778 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 1 Oct 2024 15:42:13 +0200 Subject: [PATCH 03/11] =?UTF-8?q?=F0=9F=9A=9A(frontend)=20add=20utils=20us?= =?UTF-8?q?erAgent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to stay DRY, we moved the function to know if a user is from a firefox browser from useSaveDoc to utils userAgent. --- .../src/features/docs/doc-editor/hook/useSaveDoc.tsx | 6 ++---- src/frontend/apps/impress/src/utils/index.ts | 2 ++ src/frontend/apps/impress/src/utils/userAgent.ts | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 src/frontend/apps/impress/src/utils/userAgent.ts diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx index 0a21cd45c..ca1ed0054 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx @@ -4,6 +4,7 @@ import * as Y from 'yjs'; import { useUpdateDoc } from '@/features/docs/doc-management/'; import { KEY_LIST_DOC_VERSIONS } from '@/features/docs/doc-versioning'; +import { isFirefox } from '@/utils/userAgent'; import { toBase64 } from '../utils'; @@ -87,10 +88,7 @@ const useSaveDoc = (docId: string, doc: Y.Doc, canSave: boolean) => { * if he wants to leave the page, by adding the popup, we let the time to the * request to be sent, and intercepted by the service worker (for the offline part). */ - const isFirefox = - navigator.userAgent.toLowerCase().indexOf('firefox') > -1; - - if (typeof e !== 'undefined' && e.preventDefault && isFirefox) { + if (typeof e !== 'undefined' && e.preventDefault && isFirefox()) { e.preventDefault(); } }; diff --git a/src/frontend/apps/impress/src/utils/index.ts b/src/frontend/apps/impress/src/utils/index.ts index 559df58c4..4f8237310 100644 --- a/src/frontend/apps/impress/src/utils/index.ts +++ b/src/frontend/apps/impress/src/utils/index.ts @@ -1,2 +1,4 @@ +export * from './userAgent'; export * from './string'; +export * from './styleBuilder'; export * from './system'; diff --git a/src/frontend/apps/impress/src/utils/userAgent.ts b/src/frontend/apps/impress/src/utils/userAgent.ts new file mode 100644 index 000000000..fa30acf28 --- /dev/null +++ b/src/frontend/apps/impress/src/utils/userAgent.ts @@ -0,0 +1,2 @@ +export const isFirefox = () => + navigator.userAgent.toLowerCase().indexOf('firefox') > -1; From e0ea9cfbb223c9576a44aa29053dc9820f186319 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 1 Oct 2024 15:50:19 +0200 Subject: [PATCH 04/11] =?UTF-8?q?=F0=9F=9A=9A(frontend)=20rename=20useTran?= =?UTF-8?q?sRole=20to=20useTrans?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We rename useTransRole to useTrans to make it more general and reusable. It will be used for all reusable doc translation. --- .../src/features/docs/doc-management/hooks/index.ts | 2 +- .../hooks/{useTransRole.tsx => useTrans.tsx} | 11 ++++++----- .../features/docs/docs-grid/components/DocsGrid.tsx | 4 ++-- .../members/members-add/components/ChooseRole.tsx | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) rename src/frontend/apps/impress/src/features/docs/doc-management/hooks/{useTransRole.tsx => useTrans.tsx} (63%) diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/hooks/index.ts b/src/frontend/apps/impress/src/features/docs/doc-management/hooks/index.ts index 9a820990c..7697d915a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/hooks/index.ts +++ b/src/frontend/apps/impress/src/features/docs/doc-management/hooks/index.ts @@ -1 +1 @@ -export * from './useTransRole'; +export * from './useTrans'; diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useTransRole.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useTrans.tsx similarity index 63% rename from src/frontend/apps/impress/src/features/docs/doc-management/hooks/useTransRole.tsx rename to src/frontend/apps/impress/src/features/docs/doc-management/hooks/useTrans.tsx index 337555787..b7bc24f5a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useTransRole.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useTrans.tsx @@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next'; import { Role } from '../types'; -export const useTransRole = () => { +export const useTrans = () => { const { t } = useTranslation(); const translatedRoles = { @@ -12,9 +12,10 @@ export const useTransRole = () => { [Role.EDITOR]: t('Editor'), }; - const transRole = (role: Role) => { - return translatedRoles[role]; + return { + transRole: (role: Role) => { + return translatedRoles[role]; + }, + untitledDocument: t('Untitled document'), }; - - return transRole; }; diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx index cbab72d45..ea755d2e3 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx @@ -12,7 +12,7 @@ import { currentDocRole, isDocsOrdering, useDocs, - useTransRole, + useTrans, } from '@/features/docs/doc-management'; import { useDate } from '@/hook/'; @@ -48,7 +48,7 @@ function formatSortModel(sortModel: SortModelItem): DocsOrdering | undefined { export const DocsGrid = () => { const { colorsTokens } = useCunninghamTheme(); - const transRole = useTransRole(); + const { transRole } = useTrans(); const { t } = useTranslation(); const { formatDate } = useDate(); const pagination = usePagination({ diff --git a/src/frontend/apps/impress/src/features/docs/members/members-add/components/ChooseRole.tsx b/src/frontend/apps/impress/src/features/docs/members/members-add/components/ChooseRole.tsx index 7a61fd28f..ba95302fb 100644 --- a/src/frontend/apps/impress/src/features/docs/members/members-add/components/ChooseRole.tsx +++ b/src/frontend/apps/impress/src/features/docs/members/members-add/components/ChooseRole.tsx @@ -1,7 +1,7 @@ import { Select } from '@openfun/cunningham-react'; import { useTranslation } from 'react-i18next'; -import { Role, useTransRole } from '@/features/docs/doc-management'; +import { Role, useTrans } from '@/features/docs/doc-management'; interface ChooseRoleProps { currentRole: Role; @@ -19,7 +19,7 @@ export const ChooseRole = ({ label, }: ChooseRoleProps) => { const { t } = useTranslation(); - const transRole = useTransRole(); + const { transRole } = useTrans(); return ( { - setDocName(e.target.value); - setIsInputError(false); - }} - rightIcon={edit} - state={isInputError ? 'error' : 'default'} - /> - {isError && error && } - {isPending && ( - - - - )} - - ); -}; diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalCreateUpdateDoc.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalCreateUpdateDoc.tsx deleted file mode 100644 index c883715d3..000000000 --- a/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalCreateUpdateDoc.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { - Alert, - Button, - Modal, - ModalSize, - VariantType, - useToastProvider, -} from '@openfun/cunningham-react'; -import { UseMutationResult } from '@tanstack/react-query'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; -import { useTranslation } from 'react-i18next'; - -import { APIError } from '@/api'; -import { Box, Text } from '@/components'; -import useCunninghamTheme from '@/cunningham/useCunninghamTheme'; - -import { KEY_DOC, KEY_LIST_DOC } from '../api'; -import { useCreateDoc } from '../api/useCreateDoc'; -import { useUpdateDoc } from '../api/useUpdateDoc'; -import IconEdit from '../assets/icon-edit.svg'; -import { Doc } from '../types'; - -import { InputDocName } from './InputDocName'; - -interface ModalCreateDocProps { - onClose: () => void; -} - -export const ModalCreateDoc = ({ onClose }: ModalCreateDocProps) => { - const router = useRouter(); - const api = useCreateDoc({ - onSuccess: (doc) => { - router.push(`/docs/${doc.id}`); - }, - }); - const { t } = useTranslation(); - - return ( - - api.mutate({ - title, - }), - ...api, - }} - /> - ); -}; - -interface ModalUpdateDocProps { - onClose: () => void; - doc: Doc; -} - -export const ModalUpdateDoc = ({ onClose, doc }: ModalUpdateDocProps) => { - const { toast } = useToastProvider(); - const { t } = useTranslation(); - - const api = useUpdateDoc({ - onSuccess: () => { - toast(t('The document has been updated.'), VariantType.SUCCESS, { - duration: 4000, - }); - onClose(); - }, - listInvalideQueries: [KEY_DOC, KEY_LIST_DOC], - }); - - return ( - - api.mutate({ - title, - id: doc.id, - }), - ...api, - }} - /> - ); -}; - -type ModalDoc = { - buttonText: string; - onClose: () => void; - titleModal: string; - validate: (title: string) => void; - initialTitle?: string; - infoText?: string; -} & UseMutationResult, T, unknown>; - -const ModalDoc = ({ - buttonText, - infoText, - initialTitle, - onClose, - titleModal, - validate, - ...api -}: ModalDoc) => { - const { colorsTokens } = useCunninghamTheme(); - const { t } = useTranslation(); - const [title, setTitle] = useState(initialTitle || ''); - - return ( - onClose()} - > - {t('Cancel')} - - } - onClose={() => onClose()} - rightActions={ - - } - size={ModalSize.MEDIUM} - title={ - - - - {titleModal} - - - } - > - - {infoText && ( - - {infoText} - - )} - - - - - - - ); -}; 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 index 04d5b0c9c..120ce76ff 100644 --- 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 @@ -1,3 +1,2 @@ -export * from './ModalCreateUpdateDoc'; export * from './ModalRemoveDoc'; export * from './ModalShare'; diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridActions.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridActions.tsx index d9ae203f5..6a57a2fb0 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridActions.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridActions.tsx @@ -2,12 +2,7 @@ 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'; +import { Doc, ModalRemoveDoc } from '@/features/docs/doc-management'; interface DocsGridActionsProps { doc: Doc; @@ -15,58 +10,24 @@ interface DocsGridActionsProps { export const DocsGridActions = ({ doc }: DocsGridActionsProps) => { const { t } = useTranslation(); - const [isModalUpdateOpen, setIsModalUpdateOpen] = useState(false); const [isModalRemoveOpen, setIsModalRemoveOpen] = useState(false); - const [isDropOpen, setIsDropOpen] = useState(false); - if (!doc.abilities.partial_update && !doc.abilities.destroy) { + if (!doc.abilities.destroy) { return null; } return ( <> - - } - onOpenChange={(isOpen) => setIsDropOpen(isOpen)} - isOpen={isDropOpen} - > - - {doc.abilities.partial_update && ( - - )} - {doc.abilities.destroy && ( - - )} - - - {isModalUpdateOpen && ( - setIsModalUpdateOpen(false)} doc={doc} /> - )} +