From 42f809f6d4d50b3db0a5f44bff7c0e79ea04c32d Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Thu, 21 Nov 2024 10:43:01 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20get=20collaborat?= =?UTF-8?q?ion=20server=20url=20from=20config=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We centralized the configuration on the backend side, it is easier to manage and we can change the configuration without having to rebuild the frontend. We now use the config endpoint to get the collaboration server url, we refacto to remove the frontend env occurences and to adapt with the new way to get the collaboration server url. --- src/frontend/Dockerfile | 3 --- .../e2e/__tests__/app-impress/config.spec.ts | 22 +++++++++++++++++++ src/frontend/apps/impress/.env | 1 - src/frontend/apps/impress/.env.development | 1 - src/frontend/apps/impress/src/core/conf.ts | 8 ------- .../impress/src/core/config/hooks/index.ts | 1 + .../core/config/hooks/useCollaborationUrl.tsx | 15 +++++++++++++ src/frontend/apps/impress/src/core/index.ts | 1 + .../apps/impress/src/custom-next.d.ts | 1 - .../docs/doc-editor/components/DocEditor.tsx | 8 ++++--- .../doc-management/stores/useDocStore.tsx | 11 ++++++---- .../impress/src/pages/docs/[id]/index.tsx | 8 ++++--- 12 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 src/frontend/apps/impress/src/core/config/hooks/useCollaborationUrl.tsx diff --git a/src/frontend/Dockerfile b/src/frontend/Dockerfile index 972c71603..8a179a9a5 100644 --- a/src/frontend/Dockerfile +++ b/src/frontend/Dockerfile @@ -61,9 +61,6 @@ FROM impress AS impress-builder WORKDIR /home/frontend/apps/impress -ARG Y_PROVIDER_URL -ENV NEXT_PUBLIC_Y_PROVIDER_URL=${Y_PROVIDER_URL} - ARG API_ORIGIN ENV NEXT_PUBLIC_API_ORIGIN=${API_ORIGIN} diff --git a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts index 5e63d5a28..2ae8746f7 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts @@ -110,4 +110,26 @@ test.describe('Config', () => { /http:\/\/localhost:8083\/media\/.*\/attachments\/.*.png/, ); }); + + test('it checks that collaboration server is configured from config endpoint', async ({ + page, + browserName, + }) => { + const webSocketPromise = page.waitForEvent('websocket', (webSocket) => { + return webSocket.url().includes('ws://localhost:4444/'); + }); + + await page.goto('/'); + + const randomDoc = await createDoc( + page, + 'doc-collaboration', + browserName, + 1, + ); + await expect(page.locator('h2').getByText(randomDoc[0])).toBeVisible(); + + const webSocket = await webSocketPromise; + expect(webSocket.url()).toContain('ws://localhost:4444/'); + }); }); diff --git a/src/frontend/apps/impress/.env b/src/frontend/apps/impress/.env index afe20085d..3cf0e897e 100644 --- a/src/frontend/apps/impress/.env +++ b/src/frontend/apps/impress/.env @@ -1,3 +1,2 @@ NEXT_PUBLIC_API_ORIGIN= -NEXT_PUBLIC_Y_PROVIDER_URL= NEXT_PUBLIC_SW_DEACTIVATED= diff --git a/src/frontend/apps/impress/.env.development b/src/frontend/apps/impress/.env.development index e174f537b..f26afb11b 100644 --- a/src/frontend/apps/impress/.env.development +++ b/src/frontend/apps/impress/.env.development @@ -1,3 +1,2 @@ NEXT_PUBLIC_API_ORIGIN=http://localhost:8071 -NEXT_PUBLIC_Y_PROVIDER_URL=ws://localhost:4444 NEXT_PUBLIC_SW_DEACTIVATED=true diff --git a/src/frontend/apps/impress/src/core/conf.ts b/src/frontend/apps/impress/src/core/conf.ts index 1424dfa6e..118f58142 100644 --- a/src/frontend/apps/impress/src/core/conf.ts +++ b/src/frontend/apps/impress/src/core/conf.ts @@ -4,11 +4,3 @@ export const backendUrl = () => export const baseApiUrl = (apiVersion: string = '1.0') => `${backendUrl()}/api/v${apiVersion}/`; - -export const providerUrl = (docId: string) => { - const base = - process.env.NEXT_PUBLIC_Y_PROVIDER_URL || - (typeof window !== 'undefined' ? `wss://${window.location.host}/ws` : ''); - - return `${base}/${docId}`; -}; diff --git a/src/frontend/apps/impress/src/core/config/hooks/index.ts b/src/frontend/apps/impress/src/core/config/hooks/index.ts index 41d6d8de9..e1b2dff21 100644 --- a/src/frontend/apps/impress/src/core/config/hooks/index.ts +++ b/src/frontend/apps/impress/src/core/config/hooks/index.ts @@ -1 +1,2 @@ export * from './useMediaUrl'; +export * from './useCollaborationUrl'; diff --git a/src/frontend/apps/impress/src/core/config/hooks/useCollaborationUrl.tsx b/src/frontend/apps/impress/src/core/config/hooks/useCollaborationUrl.tsx new file mode 100644 index 000000000..d945cb233 --- /dev/null +++ b/src/frontend/apps/impress/src/core/config/hooks/useCollaborationUrl.tsx @@ -0,0 +1,15 @@ +import { useConfig } from '../api'; + +export const useCollaborationUrl = (room?: string) => { + const { data: conf } = useConfig(); + + if (!room) { + return; + } + + const base = + conf?.COLLABORATION_SERVER_URL || + (typeof window !== 'undefined' ? `wss://${window.location.host}/ws` : ''); + + return `${base}/${room}`; +}; diff --git a/src/frontend/apps/impress/src/core/index.ts b/src/frontend/apps/impress/src/core/index.ts index 97ec48976..99176076a 100644 --- a/src/frontend/apps/impress/src/core/index.ts +++ b/src/frontend/apps/impress/src/core/index.ts @@ -1,3 +1,4 @@ export * from './AppProvider'; export * from './auth'; export * from './conf'; +export * from './config'; diff --git a/src/frontend/apps/impress/src/custom-next.d.ts b/src/frontend/apps/impress/src/custom-next.d.ts index 9dadec0c6..2f5af6382 100644 --- a/src/frontend/apps/impress/src/custom-next.d.ts +++ b/src/frontend/apps/impress/src/custom-next.d.ts @@ -20,7 +20,6 @@ declare module '*.svg?url' { namespace NodeJS { interface ProcessEnv { NEXT_PUBLIC_API_ORIGIN?: string; - NEXT_PUBLIC_Y_PROVIDER_URL?: string; NEXT_PUBLIC_SW_DEACTIVATED?: string; } } 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 a664eb359..50b2b73aa 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 @@ -4,6 +4,7 @@ import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Box, Card, Text, TextErrors } from '@/components'; +import { useCollaborationUrl } from '@/core'; import { useCunninghamTheme } from '@/cunningham'; import { DocHeader } from '@/features/docs/doc-header'; import { Doc, useDocStore } from '@/features/docs/doc-management'; @@ -98,19 +99,20 @@ export const DocVersionEditor = ({ doc, versionId }: DocVersionEditorProps) => { versionId, }); const { createProvider, providers } = useDocStore(); + const collaborationUrl = useCollaborationUrl(versionId); const { replace } = useRouter(); useEffect(() => { - if (!version?.id) { + if (!version?.id || !collaborationUrl) { return; } const provider = providers?.[version.id]; if (!provider || provider.document.guid !== version.id) { - createProvider(version.id, version.content); + createProvider(collaborationUrl, version.id, version.content); } - }, [createProvider, providers, version]); + }, [createProvider, providers, version, collaborationUrl]); if (isError && error) { if (error.status === 404) { diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/stores/useDocStore.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/stores/useDocStore.tsx index 3bc2a95cf..3b01ecc0b 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/stores/useDocStore.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/stores/useDocStore.tsx @@ -2,7 +2,6 @@ import { HocuspocusProvider } from '@hocuspocus/provider'; import * as Y from 'yjs'; import { create } from 'zustand'; -import { providerUrl } from '@/core'; import { Base64, Doc, blocksToYDoc } from '@/features/docs/doc-management'; export interface UseDocStore { @@ -10,7 +9,11 @@ export interface UseDocStore { providers: { [storeId: string]: HocuspocusProvider; }; - createProvider: (storeId: string, initialDoc: Base64) => HocuspocusProvider; + createProvider: ( + providerUrl: string, + storeId: string, + initialDoc: Base64, + ) => HocuspocusProvider; setProviders: (storeId: string, providers: HocuspocusProvider) => void; setCurrentDoc: (doc: Doc | undefined) => void; } @@ -18,7 +21,7 @@ export interface UseDocStore { export const useDocStore = create((set, get) => ({ currentDoc: undefined, providers: {}, - createProvider: (storeId: string, initialDoc: Base64) => { + createProvider: (providerUrl, storeId, initialDoc) => { const doc = new Y.Doc({ guid: storeId, }); @@ -37,7 +40,7 @@ export const useDocStore = create((set, get) => ({ } const provider = new HocuspocusProvider({ - url: providerUrl(storeId), + url: providerUrl, name: storeId, document: doc, }); 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 7ea5fd500..92410f8e4 100644 --- a/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx +++ b/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx @@ -6,6 +6,7 @@ import { useEffect, useState } from 'react'; import { Box, Text } from '@/components'; import { TextErrors } from '@/components/TextErrors'; +import { useCollaborationUrl } from '@/core'; import { useAuthStore } from '@/core/auth'; import { DocEditor } from '@/features/docs/doc-editor'; import { KEY_DOC, useDoc, useDocStore } from '@/features/docs/doc-management'; @@ -47,6 +48,7 @@ const DocPage = ({ id }: DocProps) => { const queryClient = useQueryClient(); const { replace } = useRouter(); const provider = providers?.[id]; + const collaborationUrl = useCollaborationUrl(doc?.id); useEffect(() => { if (doc?.title) { @@ -70,17 +72,17 @@ const DocPage = ({ id }: DocProps) => { }, [docQuery, setCurrentDoc]); useEffect(() => { - if (!doc?.id) { + if (!doc?.id || !collaborationUrl) { return; } let newProvider = provider; if (!provider || provider.document.guid !== doc.id) { - newProvider = createProvider(doc.id, doc.content); + newProvider = createProvider(collaborationUrl, doc.id, doc.content); } setBroadcastProvider(newProvider); - }, [createProvider, doc, provider, setBroadcastProvider]); + }, [createProvider, doc, provider, setBroadcastProvider, collaborationUrl]); /** * We add a broadcast task to reset the query cache