From 9dc671cf14fc44f6dbfa402cbc0dbc9febd027b0 Mon Sep 17 00:00:00 2001 From: Alexandre Neuwald Date: Wed, 18 Dec 2024 15:19:13 +0000 Subject: [PATCH] add warning when layout defined is not in the list --- packages/suite-base/src/App.tsx | 8 ++--- packages/suite-base/src/i18n/en/general.ts | 2 ++ .../CurrentLayoutProvider/index.test.tsx | 32 ++++++++++++++++++- .../providers/CurrentLayoutProvider/index.tsx | 12 ++++++- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/suite-base/src/App.tsx b/packages/suite-base/src/App.tsx index 4d7bb78fa9..c8b88d1502 100644 --- a/packages/suite-base/src/App.tsx +++ b/packages/suite-base/src/App.tsx @@ -108,10 +108,6 @@ export function App(props: AppProps): React.JSX.Element { providers.unshift(...extraProviders); } - // The toast and logs provider comes first so they are available to all downstream providers - providers.unshift(); - providers.unshift(); - // Problems provider also must come before other, dependent contexts. providers.unshift(); providers.unshift(); @@ -121,6 +117,10 @@ export function App(props: AppProps): React.JSX.Element { const layoutStorage = useMemo(() => new IdbLayoutStorage(), []); providers.unshift(); + // The toast and logs provider comes first so they are available to all downstream providers + providers.unshift(); + providers.unshift(); + const MaybeLaunchPreference = enableLaunchPreferenceScreen === true ? LaunchPreference : Fragment; useEffect(() => { diff --git a/packages/suite-base/src/i18n/en/general.ts b/packages/suite-base/src/i18n/en/general.ts index 760a3e7b9a..105d78cf06 100644 --- a/packages/suite-base/src/i18n/en/general.ts +++ b/packages/suite-base/src/i18n/en/general.ts @@ -9,4 +9,6 @@ export const general = { foxglove: "Foxglove", learnMore: "Learn more", + noDefaultLayoutParameter: + "The layout '{{layoutName}}' specified in the app parameters does not exist.", }; diff --git a/packages/suite-base/src/providers/CurrentLayoutProvider/index.test.tsx b/packages/suite-base/src/providers/CurrentLayoutProvider/index.test.tsx index b76055ad67..290785d4e0 100644 --- a/packages/suite-base/src/providers/CurrentLayoutProvider/index.test.tsx +++ b/packages/suite-base/src/providers/CurrentLayoutProvider/index.test.tsx @@ -2,12 +2,13 @@ // SPDX-FileCopyrightText: Copyright (C) 2023-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // SPDX-License-Identifier: MPL-2.0 + // This Source Code Form is subject to the terms of the Mozilla Public // License, v2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/ import { act, renderHook } from "@testing-library/react"; -import { SnackbarProvider } from "notistack"; +import { SnackbarProvider, useSnackbar } from "notistack"; import { useEffect } from "react"; import { Condvar } from "@lichtblick/den/async"; @@ -28,6 +29,14 @@ import AppParametersProvider from "@lichtblick/suite-base/providers/AppParameter import CurrentLayoutProvider from "@lichtblick/suite-base/providers/CurrentLayoutProvider"; import { MAX_SUPPORTED_LAYOUT_VERSION } from "@lichtblick/suite-base/providers/CurrentLayoutProvider/constants"; import { ILayoutManager } from "@lichtblick/suite-base/services/ILayoutManager"; +import BasicBuilder from "@lichtblick/suite-base/testing/builders/BasicBuilder"; + +jest.mock("notistack", () => ({ + ...jest.requireActual("notistack"), + useSnackbar: jest.fn().mockReturnValue({ + enqueueSnackbar: jest.fn(), + }), +})); const TEST_LAYOUT: LayoutData = { layout: "ExamplePanel!1", @@ -316,4 +325,25 @@ describe("CurrentLayoutProvider", () => { expect(selectedLayout).toBeDefined(); expect(selectedLayout).toBe("layout2"); }); + + it("should show a message to the user if the defaultLayout from app parameter is not found", async () => { + const mockAppParameters = { defaultLayout: BasicBuilder.string() }; + + const { result } = renderTest({ + mockLayoutManager, + mockUserProfile, + mockAppParameters, + }); + + await act(async () => { + await result.current.childMounted; + }); + + const { enqueueSnackbar } = useSnackbar(); + + expect(enqueueSnackbar).toHaveBeenCalledWith( + `The layout '${mockAppParameters.defaultLayout}' specified in the app parameters does not exist.`, + { variant: "warning" }, + ); + }); }); diff --git a/packages/suite-base/src/providers/CurrentLayoutProvider/index.tsx b/packages/suite-base/src/providers/CurrentLayoutProvider/index.tsx index 911e701a43..93e2f3456d 100644 --- a/packages/suite-base/src/providers/CurrentLayoutProvider/index.tsx +++ b/packages/suite-base/src/providers/CurrentLayoutProvider/index.tsx @@ -8,6 +8,7 @@ import * as _ from "lodash-es"; import { useSnackbar } from "notistack"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; import { getNodeAtPath } from "react-mosaic-component"; import { useAsync, useAsyncFn, useMountedState } from "react-use"; import shallowequal from "shallowequal"; @@ -71,6 +72,8 @@ export default function CurrentLayoutProvider({ const analytics = useAnalytics(); const isMounted = useMountedState(); + const { t } = useTranslation("general"); + const appParameters = useAppParameters(); const [mosaicId] = useState(() => uuidv4()); @@ -285,13 +288,20 @@ export default function CurrentLayoutProvider({ const layouts = await layoutManager.getLayouts(); - // // Check if there's a layout specified by app parameter + // Check if there's a layout specified by app parameter const defaultLayoutFromParameters = layouts.find((l) => l.name === appParameters.defaultLayout); if (defaultLayoutFromParameters) { await setSelectedLayoutId(defaultLayoutFromParameters.id, { saveToProfile: false }); return; } + // It there is a defaultLayout setted but didnt found a layout, show a error to the user + if (appParameters.defaultLayout) { + enqueueSnackbar(t("noDefaultLayoutParameter", { layoutName: appParameters.defaultLayout }), { + variant: "warning", + }); + } + // Retreive the selected layout id from the user's profile. If there's no layout specified // or we can't load it then save and select a default layout const layout = currentLayoutId ? await layoutManager.getLayout(currentLayoutId) : undefined;