From 1fefed2aa0dbd51f893750e2e179f65bd9386372 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Tue, 12 May 2026 15:38:27 +0700 Subject: [PATCH] chore: enhance data source configuration and mock data handling - Added support for mock data mode in the frontend by introducing a new environment variable in the Dockerfile and workflow configuration. - Updated the settings page to conditionally display options based on the availability of mock data, improving user experience. - Refactored data source logic to include a check for mock data availability, ensuring proper mode handling in the application. --- .gitea/workflows/docker.yml | 1 + Dockerfile.frontend | 2 ++ app/(main)/settings/page.tsx | 50 +++++++++++++++++++++--------------- lib/backend-url.ts | 5 ++++ lib/data-source.tsx | 13 +++++++--- 5 files changed, 48 insertions(+), 23 deletions(-) diff --git a/.gitea/workflows/docker.yml b/.gitea/workflows/docker.yml index 8c82a1d..b1ceca7 100644 --- a/.gitea/workflows/docker.yml +++ b/.gitea/workflows/docker.yml @@ -129,6 +129,7 @@ jobs: BACKEND_INTERNAL_URL=http://backend:8000 NEXT_PUBLIC_BACKEND_URL=same-origin NEXT_PUBLIC_DEFAULT_DATA_SOURCE=live + NEXT_PUBLIC_ALLOW_MOCK_DATA=false tags: | ${{ env.IMAGE_NAME }}:latest ${{ env.IMAGE_NAME }}:${{ gitea.sha }} diff --git a/Dockerfile.frontend b/Dockerfile.frontend index 01ad06f..1542326 100644 --- a/Dockerfile.frontend +++ b/Dockerfile.frontend @@ -11,9 +11,11 @@ FROM deps AS build ARG BACKEND_INTERNAL_URL=http://backend:8000 ARG NEXT_PUBLIC_BACKEND_URL=same-origin ARG NEXT_PUBLIC_DEFAULT_DATA_SOURCE=live +ARG NEXT_PUBLIC_ALLOW_MOCK_DATA=false ENV BACKEND_INTERNAL_URL=$BACKEND_INTERNAL_URL ENV NEXT_PUBLIC_BACKEND_URL=$NEXT_PUBLIC_BACKEND_URL ENV NEXT_PUBLIC_DEFAULT_DATA_SOURCE=$NEXT_PUBLIC_DEFAULT_DATA_SOURCE +ENV NEXT_PUBLIC_ALLOW_MOCK_DATA=$NEXT_PUBLIC_ALLOW_MOCK_DATA COPY packages/contracts packages/contracts COPY next.config.ts tsconfig.json postcss.config.mjs components.json ./ COPY app app diff --git a/app/(main)/settings/page.tsx b/app/(main)/settings/page.tsx index 4314e81..7ec6b1c 100644 --- a/app/(main)/settings/page.tsx +++ b/app/(main)/settings/page.tsx @@ -825,7 +825,7 @@ export default function SettingsPage() { const [copied, setCopied] = useState(null) // data source - const { mode, setMode, backendUrl, setBackendUrl, backendUrlLocked, backendStatus, checkBackend } = useDataSource() + const { mode, setMode, backendUrl, setBackendUrl, backendUrlLocked, mockModeAvailable, backendStatus, checkBackend } = useDataSource() const evo = useEvoBGP() const [evoBaseDraft, setEvoBaseDraft] = useState("") const [evoEnabledDraft, setEvoEnabledDraft] = useState(false) @@ -969,30 +969,40 @@ export default function SettingsPage() { Источник данных - Переключите между живыми данными от бекенда и суррогатными моками из lib/data.ts + {mockModeAvailable + ? "Переключите между живыми данными от бекенда и суррогатными моками из lib/data.ts" + : "В продакшен-образе доступны только живые данные от бекенда"} {/* mode toggle */} - -
- {([["mock", "Моковые"], ["live", "Живые"]] as const).map(([v, l], i) => ( - - ))} -
-
+ {mockModeAvailable ? ( + +
+ {([["mock", "Моковые"], ["live", "Живые"]] as const).map(([v, l], i) => ( + + ))} +
+
+ ) : ( + + + Живые + + + )} {/* backend URL — visible in both modes so user can configure before switching */} void backendUrlLocked: boolean + mockModeAvailable: boolean /** undefined = не проверялось, true = OK, false = недоступен */ backendStatus: boolean | undefined checkBackend: () => Promise @@ -32,9 +34,12 @@ const LS_MODE = "routerlists:data-source" const LS_BACKEND = "routerlists:backend-url" function readStoredMode(): DataSourceMode { + if (!isMockDataSourceAvailable()) return "live" if (typeof window === "undefined") return defaultDataSourceMode() const stored = localStorage.getItem(LS_MODE) as DataSourceMode | null - return stored === "mock" || stored === "live" ? stored : defaultDataSourceMode() + if (stored === "live") return "live" + if (stored === "mock") return "mock" + return defaultDataSourceMode() } function readStoredBackendUrl(): string { @@ -55,6 +60,7 @@ export function DataSourceProvider({ children }: { children: React.ReactNode }) ) const [backendStatus, setBackendStatus] = useState(undefined) const backendUrlLocked = isBackendUrlLocked() + const mockModeAvailable = isMockDataSourceAvailable() useEffect(() => { if (configuredBackendUrl().kind !== "same-origin") return @@ -62,9 +68,10 @@ export function DataSourceProvider({ children }: { children: React.ReactNode }) }, []) const setMode = useCallback((m: DataSourceMode) => { + if (!mockModeAvailable && m === "mock") return setModeState(m) localStorage.setItem(LS_MODE, m) - }, []) + }, [mockModeAvailable]) const setBackendUrl = useCallback((url: string) => { if (backendUrlLocked) return @@ -89,7 +96,7 @@ export function DataSourceProvider({ children }: { children: React.ReactNode }) return ( {children}