From cf2a02c8de79307f36c3cbea60375b5228b7f82a Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Fri, 23 May 2025 10:17:00 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A9(frontend)=20feature=20flag=20on=20?= =?UTF-8?q?blocking=20edition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If users were not connected to the collaboration server, they were not be able to edit documents. We decided to add a feature flag on this feature as it can be quite restrictive. We can now enable or disable this feature at runtime thanks to the env variable "COLLABORATION_WS_NOT_CONNECTED_READY_ONLY". --- CHANGELOG.md | 1 + docs/env.md | 1 + src/backend/core/api/viewsets.py | 1 + src/backend/core/tests/test_api_config.py | 2 ++ src/backend/impress/settings.py | 5 +++++ src/frontend/apps/e2e/__tests__/app-impress/common.ts | 1 + .../apps/e2e/__tests__/app-impress/doc-editor.spec.ts | 1 + .../apps/impress/src/core/config/api/useConfig.tsx | 1 + .../features/docs/doc-header/components/AlertNetwork.tsx | 2 +- .../doc-management/hooks/useIsCollaborativeEditable.tsx | 9 +++++++++ 10 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f02bbfa1..1e21202b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to - ✨(frontend) create generic theme #792 - 🛂(frontend) block edition to not connected users #945 - 🚸 Let loader during upload analyze #984 +- 🚩(frontend) feature flag on blocking edition #997 ### Changed diff --git a/docs/env.md b/docs/env.md index 67d52b2b..a41d7ef9 100644 --- a/docs/env.md +++ b/docs/env.md @@ -47,6 +47,7 @@ These are the environment variables you can set for the `impress-backend` contai | COLLABORATION_API_URL | collaboration api host | | | COLLABORATION_SERVER_SECRET | collaboration api secret | | | COLLABORATION_WS_URL | collaboration websocket url | | +| COLLABORATION_WS_NOT_CONNECTED_READY_ONLY | Users not connected to the collaboration server cannot edit | false | | FRONTEND_CSS_URL | To add a external css file to the app | | | FRONTEND_HOMEPAGE_FEATURE_ENABLED | frontend feature flag to display the homepage | false | | FRONTEND_THEME | frontend theme to use | | diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index cc90dcb2..cf993070 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -1785,6 +1785,7 @@ class ConfigView(drf.views.APIView): array_settings = [ "AI_FEATURE_ENABLED", "COLLABORATION_WS_URL", + "COLLABORATION_WS_NOT_CONNECTED_READY_ONLY", "CRISP_WEBSITE_ID", "ENVIRONMENT", "FRONTEND_CSS_URL", diff --git a/src/backend/core/tests/test_api_config.py b/src/backend/core/tests/test_api_config.py index b81be32a..2d74594c 100644 --- a/src/backend/core/tests/test_api_config.py +++ b/src/backend/core/tests/test_api_config.py @@ -20,6 +20,7 @@ pytestmark = pytest.mark.django_db @override_settings( AI_FEATURE_ENABLED=False, COLLABORATION_WS_URL="http://testcollab/", + COLLABORATION_WS_NOT_CONNECTED_READY_ONLY=True, CRISP_WEBSITE_ID="123", FRONTEND_CSS_URL="http://testcss/", FRONTEND_THEME="test-theme", @@ -41,6 +42,7 @@ def test_api_config(is_authenticated): assert response.status_code == HTTP_200_OK assert response.json() == { "COLLABORATION_WS_URL": "http://testcollab/", + "COLLABORATION_WS_NOT_CONNECTED_READY_ONLY": True, "CRISP_WEBSITE_ID": "123", "ENVIRONMENT": "test", "FRONTEND_CSS_URL": "http://testcss/", diff --git a/src/backend/impress/settings.py b/src/backend/impress/settings.py index a67a2282..737bb338 100755 --- a/src/backend/impress/settings.py +++ b/src/backend/impress/settings.py @@ -413,6 +413,11 @@ class Base(Configuration): COLLABORATION_WS_URL = values.Value( None, environ_name="COLLABORATION_WS_URL", environ_prefix=None ) + COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = values.BooleanValue( + False, + environ_name="COLLABORATION_WS_NOT_CONNECTED_READY_ONLY", + environ_prefix=None, + ) # Frontend FRONTEND_THEME = values.Value( diff --git a/src/frontend/apps/e2e/__tests__/app-impress/common.ts b/src/frontend/apps/e2e/__tests__/app-impress/common.ts index ee5f24de..9c5d5b02 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/common.ts @@ -4,6 +4,7 @@ export const CONFIG = { AI_FEATURE_ENABLED: true, CRISP_WEBSITE_ID: null, COLLABORATION_WS_URL: 'ws://localhost:4444/collaboration/ws/', + COLLABORATION_WS_NOT_CONNECTED_READY_ONLY: false, ENVIRONMENT: 'development', FRONTEND_CSS_URL: null, FRONTEND_HOMEPAGE_FEATURE_ENABLED: true, 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 3996abb1..722769af 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 @@ -516,6 +516,7 @@ test.describe('Doc Editor', () => { json: { ...CONFIG, COLLABORATION_WS_URL: 'ws://localhost:5555/collaboration/ws/', + COLLABORATION_WS_NOT_CONNECTED_READY_ONLY: true, }, }); } else { diff --git a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx index 306cf100..761c588c 100644 --- a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx +++ b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx @@ -12,6 +12,7 @@ interface ThemeCustomization { interface ConfigResponse { AI_FEATURE_ENABLED?: boolean; COLLABORATION_WS_URL?: string; + COLLABORATION_WS_NOT_CONNECTED_READY_ONLY?: boolean; CRISP_WEBSITE_ID?: string; ENVIRONMENT: string; FRONTEND_CSS_URL?: string; diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/AlertNetwork.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/AlertNetwork.tsx index ac230310..b070356c 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/AlertNetwork.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/AlertNetwork.tsx @@ -29,7 +29,7 @@ export const AlertNetwork = () => { border: 1px solid var(--c--theme--colors--warning-300); `} > - + {t('Your network do not allow you to edit')} diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useIsCollaborativeEditable.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useIsCollaborativeEditable.tsx index b5f97f58..0bb4f8f2 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useIsCollaborativeEditable.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useIsCollaborativeEditable.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react'; +import { useConfig } from '@/core'; import { useIsOffline } from '@/features/service-worker'; import { useProviderStore } from '../stores'; @@ -7,6 +8,7 @@ import { Doc, LinkReach } from '../types'; export const useIsCollaborativeEditable = (doc: Doc) => { const { isConnected } = useProviderStore(); + const { data: conf } = useConfig(); const docIsPublic = doc.link_reach === LinkReach.PUBLIC; const docIsAuth = doc.link_reach === LinkReach.AUTHENTICATED; @@ -37,6 +39,13 @@ export const useIsCollaborativeEditable = (doc: Doc) => { return () => clearTimeout(timer); }, [isConnected, isOffline, isShared]); + if (!conf?.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY) { + return { + isEditable: true, + isLoading: false, + }; + } + return { isEditable, isLoading,