diff --git a/src/behaviours/preferences/closing-preferences.test.tsx b/src/behaviours/preferences/closing-preferences.test.tsx index 0ca2c91da7..dddd7e18dc 100644 --- a/src/behaviours/preferences/closing-preferences.test.tsx +++ b/src/behaviours/preferences/closing-preferences.test.tsx @@ -250,6 +250,7 @@ const testNavigationItemInjectable = getInjectable({ return { id: "some-test-preference-navigation-item-id", label: "Some preference navigation item", + parent: "general", isActive: routeIsActive, isVisible: testRoute.isEnabled, navigate: navigateToPreferenceTab(testRoute), diff --git a/src/renderer/components/+preferences/preferences-navigation/__tests__/preferences-navigation.test.tsx b/src/renderer/components/+preferences/preferences-navigation/__tests__/preferences-navigation.test.tsx index 8dce193fd4..0d4547ae6a 100644 --- a/src/renderer/components/+preferences/preferences-navigation/__tests__/preferences-navigation.test.tsx +++ b/src/renderer/components/+preferences/preferences-navigation/__tests__/preferences-navigation.test.tsx @@ -6,13 +6,11 @@ import "@testing-library/jest-dom/extend-expect"; import type { RenderResult } from "@testing-library/react"; import { computed } from "mobx"; -import type { IComputedValue } from "mobx/dist/internal"; import { noop } from "../../../../utils"; import type { ApplicationBuilder } from "../../../test-utils/get-application-builder"; import { getApplicationBuilder } from "../../../test-utils/get-application-builder"; -import extensionsPreferenceNavigationItemsInjectable from "../extension-preference-navigation-items.injectable"; -import generalPreferenceNavigationItemsInjectable from "../general-preference-navigation-items.injectable"; import type { PreferenceNavigationItem } from "../preference-navigation-items.injectable"; +import preferenceNavigationItemsInjectable from "../preference-navigation-items.injectable"; describe.only("preferences - navigation block with links", () => { let applicationBuilder: ApplicationBuilder; @@ -26,31 +24,9 @@ describe.only("preferences - navigation block with links", () => { describe("when general navigation items passed", () => { beforeEach(async () => { - const generalNavItems: IComputedValue = computed(() => [ - { - id: "general", - label: "General", - isActive: computed(() => false), - isVisible: computed(() => true), - navigate: () => noop, - orderNumber: 0, - parent: "", - }, - { - id: "proxy", - label: "Proxy", - isActive: computed(() => false), - isVisible: computed(() => true), - navigate: () => noop, - orderNumber: 1, - parent: "", - }, - ]); - applicationBuilder.beforeApplicationStart(({ rendererDi }) => { - rendererDi.override( - generalPreferenceNavigationItemsInjectable, - () => generalNavItems, + rendererDi.override(preferenceNavigationItemsInjectable, () => + computed(() => generalNavItems), ); }); @@ -68,103 +44,109 @@ describe.only("preferences - navigation block with links", () => { }); it("does not show custom settings block", () => { - expect(renderer.queryByTestId("extension-settings")).not.toBeInTheDocument(); + expect( + renderer.queryByTestId("extension-settings"), + ).not.toBeInTheDocument(); }); }); describe("when general + extension navigation items passed", () => { beforeEach(async () => { - const generalNavItems: IComputedValue = computed(() => [ - { - id: "general", - label: "General", - isActive: computed(() => false), - isVisible: computed(() => true), - navigate: () => noop, - orderNumber: 0, - parent: "", - }, - { - id: "proxy", - label: "Proxy", - isActive: computed(() => false), - isVisible: computed(() => true), - navigate: () => noop, - orderNumber: 1, - parent: "", - }, - ]); - - const extensionNavItems: IComputedValue = computed(() => [ - { - id: "extension-preferences-navigation-item-lensapp-node-menu", - label: "lensapp-node-menu", - isActive: computed(() => false), - isVisible: computed(() => true), - navigate: () => noop, - orderNumber: 0, - parent: "extensions", - }, - { - id: "extension-preferences-navigation-item-lensapp-pod-menu", - label: "lensapp-pod-menu", - isActive: computed(() => false), - isVisible: computed(() => true), - navigate: () => noop, - orderNumber: 0, - parent: "extensions", - }, - { - id: "extension-preferences-navigation-item-metrics-plugin", - label: "metrics-plugin", - isActive: computed(() => false), - isVisible: computed(() => false), - navigate: () => noop, - orderNumber: 0, - parent: "extensions", - }, - ]); - applicationBuilder.beforeApplicationStart(({ rendererDi }) => { - rendererDi.override( - generalPreferenceNavigationItemsInjectable, - () => generalNavItems, - ); - - rendererDi.override( - extensionsPreferenceNavigationItemsInjectable, - () => extensionNavItems, + rendererDi.override(preferenceNavigationItemsInjectable, () => + computed(() => [...generalNavItems, ...extensionNavItems]), ); }); - + applicationBuilder.beforeRender(() => { applicationBuilder.preferences.navigate(); }); - + renderer = await applicationBuilder.render(); }); const generalLinks = ["General", "Proxy"]; - - it.each(generalLinks)("renders general link with text content %s", (link) => { - expect(renderer.container).toHaveTextContent(link); - }); - + + it.each(generalLinks)( + "renders general link with text content %s", + (link) => { + expect(renderer.container).toHaveTextContent(link); + }, + ); + it("shows custom settings block", () => { - expect(renderer.queryByTestId("extension-settings")).toBeInTheDocument(); + expect( + renderer.queryByTestId("extension-settings"), + ).toBeInTheDocument(); }); const extensionLinks = ["lensapp-node-menu", "lensapp-pod-menu"]; it.each(extensionLinks)("shows extension navigation item %s", (link) => { - expect(renderer.getByTestId(`tab-link-for-extension-preferences-navigation-item-${link}`)).toBeInTheDocument(); + expect( + renderer.getByTestId( + `tab-link-for-extension-preferences-navigation-item-${link}`, + ), + ).toBeInTheDocument(); }); - + it("renders extension navigation items inside custom settings block", () => { const settingsBlock = renderer.getByTestId("extension-settings"); - + expect(settingsBlock).toHaveTextContent("lensapp-node-menu"); }); }); }); }); + +const generalNavItems: PreferenceNavigationItem[] = [ + { + id: "general", + label: "General", + isActive: computed(() => false), + isVisible: computed(() => true), + navigate: () => noop, + orderNumber: 0, + parent: "general", + }, + { + id: "proxy", + label: "Proxy", + isActive: computed(() => false), + isVisible: computed(() => true), + navigate: () => noop, + orderNumber: 1, + parent: "general", + }, +]; + +const extensionNavItems = [ + { + id: "extension-preferences-navigation-item-lensapp-node-menu", + label: "lensapp-node-menu", + isActive: computed(() => false), + isVisible: computed(() => true), + navigate: () => noop, + orderNumber: 0, + parent: "extensions", + }, + { + id: "extension-preferences-navigation-item-lensapp-pod-menu", + label: "lensapp-pod-menu", + isActive: computed(() => false), + isVisible: computed(() => true), + navigate: () => noop, + orderNumber: 0, + parent: "extensions", + }, + { + id: "extension-preferences-navigation-item-metrics-plugin", + label: "metrics-plugin", + isActive: computed(() => false), + isVisible: computed(() => false), + navigate: () => noop, + orderNumber: 0, + parent: "extensions", + }, +]; + diff --git a/src/renderer/components/+preferences/preferences-navigation/application-preferences-navigation-item.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/application-preferences-navigation-item.injectable.ts index 0b333f4fed..a3e35d35a9 100644 --- a/src/renderer/components/+preferences/preferences-navigation/application-preferences-navigation-item.injectable.ts +++ b/src/renderer/components/+preferences/preferences-navigation/application-preferences-navigation-item.injectable.ts @@ -24,6 +24,7 @@ const applicationPreferencesNavigationItemInjectable = getInjectable({ return { id: "application", label: "App", + parent: "general", navigate: navigateToPreferenceTab(route), isActive: routeIsActive, isVisible: computed(() => true), diff --git a/src/renderer/components/+preferences/preferences-navigation/editor-preferences-navigation-item.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/editor-preferences-navigation-item.injectable.ts index f5738cf985..686a688aa6 100644 --- a/src/renderer/components/+preferences/preferences-navigation/editor-preferences-navigation-item.injectable.ts +++ b/src/renderer/components/+preferences/preferences-navigation/editor-preferences-navigation-item.injectable.ts @@ -24,6 +24,7 @@ const editorPreferencesNavigationItemInjectable = getInjectable({ return { id: "editor", label: "Editor", + parent: "general", navigate: navigateToPreferenceTab(route), isActive: routeIsActive, isVisible: computed(() => true), diff --git a/src/renderer/components/+preferences/preferences-navigation/extension-preference-navigation-items.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/extension-preference-navigation-items.injectable.ts deleted file mode 100644 index 1e6aa49206..0000000000 --- a/src/renderer/components/+preferences/preferences-navigation/extension-preference-navigation-items.injectable.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { pipeline } from "@ogre-tools/fp"; -import { getInjectable } from "@ogre-tools/injectable"; -import { filter, orderBy } from "lodash/fp"; -import { computed } from "mobx"; -import type { PreferenceNavigationItem } from "./preference-navigation-items.injectable"; -import { preferenceNavigationItemInjectionToken } from "./preference-navigation-items.injectable"; - -const extensionsPreferenceNavigationItemsInjectable = getInjectable({ - id: "extension-preference-navigation-items", - - instantiate: (di) => - computed((): PreferenceNavigationItem[] => - pipeline( - di.injectMany(preferenceNavigationItemInjectionToken), - filter((item) => !!item.isVisible.get()), - filter((item) => item.parent == "extensions"), - (items) => orderBy([(item) => item.orderNumber], ["asc"], items), - ), - ), -}); - -export default extensionsPreferenceNavigationItemsInjectable; - diff --git a/src/renderer/components/+preferences/preferences-navigation/extension-tab-preferences-navigation-item.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/extension-tab-preferences-navigation-item.injectable.ts index 6397b3d538..8cd0c4895b 100644 --- a/src/renderer/components/+preferences/preferences-navigation/extension-tab-preferences-navigation-item.injectable.ts +++ b/src/renderer/components/+preferences/preferences-navigation/extension-tab-preferences-navigation-item.injectable.ts @@ -43,6 +43,7 @@ const extensionSpecificTabNavigationItemRegistratorInjectable = getInjectable({ instantiate: () => ({ id, label: tab.title, + parent: "general", orderNumber: tab.orderNumber || 100, navigate: () => navigateToExtensionPreferences(extension.sanitizedExtensionId, tab.id), isVisible: computed(() => true), diff --git a/src/renderer/components/+preferences/preferences-navigation/extensions-nav-group.tsx b/src/renderer/components/+preferences/preferences-navigation/extensions-nav-group.tsx index 7f8a9fae19..c617b4bb1a 100644 --- a/src/renderer/components/+preferences/preferences-navigation/extensions-nav-group.tsx +++ b/src/renderer/components/+preferences/preferences-navigation/extensions-nav-group.tsx @@ -8,7 +8,7 @@ import type { IComputedValue } from "mobx"; import type { PreferenceNavigationItem } from "./preference-navigation-items.injectable"; import { Icon } from "../../icon"; import { PreferencesNavigationTab } from "./preference-navigation-tab"; -import extensionsPreferenceNavigationItemsInjectable from "./extension-preference-navigation-items.injectable"; +import preferenceNavigationItemsForGroupInjectable from "./preference-navigation-items-for-group.injectable"; interface Dependencies { navigationItems: IComputedValue; @@ -45,11 +45,11 @@ function NonInjectedExtensionsNavGroup(props: Dependencies) { } export const ExtensionsNavGroup = withInjectables( - NonInjectedExtensionsNavGroup, + NonInjectedExtensionsNavGroup, { getProps: (di) => ({ - navigationItems: di.inject(extensionsPreferenceNavigationItemsInjectable), + navigationItems: di.inject(preferenceNavigationItemsForGroupInjectable, "extensions"), }), }, ); diff --git a/src/renderer/components/+preferences/preferences-navigation/general-nav-group.tsx b/src/renderer/components/+preferences/preferences-navigation/general-nav-group.tsx index f8956372e3..71775a0e4a 100644 --- a/src/renderer/components/+preferences/preferences-navigation/general-nav-group.tsx +++ b/src/renderer/components/+preferences/preferences-navigation/general-nav-group.tsx @@ -7,7 +7,7 @@ import { withInjectables } from "@ogre-tools/injectable-react"; import type { IComputedValue } from "mobx"; import type { PreferenceNavigationItem } from "./preference-navigation-items.injectable"; import { PreferencesNavigationTab } from "./preference-navigation-tab"; -import generalPreferenceNavigationItemsInjectable from "./general-preference-navigation-items.injectable"; +import preferenceNavigationItemsForGroupInjectable from "./preference-navigation-items-for-group.injectable"; interface Dependencies { navigationItems: IComputedValue; @@ -34,11 +34,11 @@ function NonInjectedGeneralNavGroup(props: Dependencies) { } export const GeneralNavGroup = withInjectables( - NonInjectedGeneralNavGroup, + NonInjectedGeneralNavGroup, { getProps: (di) => ({ - navigationItems: di.inject(generalPreferenceNavigationItemsInjectable), + navigationItems: di.inject(preferenceNavigationItemsForGroupInjectable, "general"), }), }, ); diff --git a/src/renderer/components/+preferences/preferences-navigation/general-preference-navigation-items.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/general-preference-navigation-items.injectable.ts deleted file mode 100644 index 80a72a3b33..0000000000 --- a/src/renderer/components/+preferences/preferences-navigation/general-preference-navigation-items.injectable.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { pipeline } from "@ogre-tools/fp"; -import { getInjectable } from "@ogre-tools/injectable"; -import { filter, orderBy } from "lodash/fp"; -import { computed } from "mobx"; -import type { PreferenceNavigationItem } from "./preference-navigation-items.injectable"; -import { preferenceNavigationItemInjectionToken } from "./preference-navigation-items.injectable"; - -const generalPreferenceNavigationItemsInjectable = getInjectable({ - id: "general-preference-navigation-items", - - instantiate: (di) => - computed((): PreferenceNavigationItem[] => - pipeline( - di.injectMany(preferenceNavigationItemInjectionToken), - filter((item) => !!item.isVisible.get()), - filter((item) => !item.parent), - (items) => orderBy([(item) => item.orderNumber], ["asc"], items), - ), - ), -}); - -export default generalPreferenceNavigationItemsInjectable; - diff --git a/src/renderer/components/+preferences/preferences-navigation/kubernetes-preferences-navigation-item.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/kubernetes-preferences-navigation-item.injectable.ts index ec3429a212..6147021087 100644 --- a/src/renderer/components/+preferences/preferences-navigation/kubernetes-preferences-navigation-item.injectable.ts +++ b/src/renderer/components/+preferences/preferences-navigation/kubernetes-preferences-navigation-item.injectable.ts @@ -27,6 +27,7 @@ const kubernetesPreferencesNavigationItemInjectable = getInjectable({ return { id: "kubernetes", label: "Kubernetes", + parent: "general", navigate: navigateToPreferenceTab(route), isActive: routeIsActive, isVisible: computed(() => true), diff --git a/src/renderer/components/+preferences/preferences-navigation/preference-navigation-items-for-group.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/preference-navigation-items-for-group.injectable.ts new file mode 100644 index 0000000000..9c63626f2b --- /dev/null +++ b/src/renderer/components/+preferences/preferences-navigation/preference-navigation-items-for-group.injectable.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { + getInjectable, + lifecycleEnum, +} from "@ogre-tools/injectable"; +import { computed } from "mobx"; +import type { PreferenceNavigationItem } from "./preference-navigation-items.injectable"; +import preferenceNavigationItemsInjectable from "./preference-navigation-items.injectable"; + +const preferenceNavigationItemsForGroupInjectable = getInjectable({ + id: "preference-navigation-items-for-group", + + instantiate: (di, group: string) => { + const preferenceNavigationItems = di.inject(preferenceNavigationItemsInjectable); + + return computed((): PreferenceNavigationItem[] => + preferenceNavigationItems.get().filter((item) => item.parent == group), + ); + }, + + lifecycle: lifecycleEnum.keyedSingleton({ + getInstanceKey: (di, group: string) => group, + }), +}); + +export default preferenceNavigationItemsForGroupInjectable; + diff --git a/src/renderer/components/+preferences/preferences-navigation/preference-navigation-items.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/preference-navigation-items.injectable.ts index cfc6dfbdfc..9709f4bf51 100644 --- a/src/renderer/components/+preferences/preferences-navigation/preference-navigation-items.injectable.ts +++ b/src/renderer/components/+preferences/preferences-navigation/preference-navigation-items.injectable.ts @@ -20,7 +20,7 @@ export interface PreferenceNavigationItem { isVisible: IComputedValue; navigate: () => void; orderNumber: number; - parent?: string; + parent: string; } const preferenceNavigationItemsInjectable = getInjectable({ diff --git a/src/renderer/components/+preferences/preferences-navigation/proxy-preferences-navigation-item.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/proxy-preferences-navigation-item.injectable.ts index d4a588db87..fd0b835d12 100644 --- a/src/renderer/components/+preferences/preferences-navigation/proxy-preferences-navigation-item.injectable.ts +++ b/src/renderer/components/+preferences/preferences-navigation/proxy-preferences-navigation-item.injectable.ts @@ -24,6 +24,7 @@ const proxyPreferencesNavigationItemInjectable = getInjectable({ return { id: "proxy", label: "Proxy", + parent: "general", navigate: navigateToPreferenceTab(route), isActive: routeIsActive, isVisible: computed(() => true), diff --git a/src/renderer/components/+preferences/preferences-navigation/telemetry-preferences-navigation-item.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/telemetry-preferences-navigation-item.injectable.ts index f6576696c6..1f95c74a0d 100644 --- a/src/renderer/components/+preferences/preferences-navigation/telemetry-preferences-navigation-item.injectable.ts +++ b/src/renderer/components/+preferences/preferences-navigation/telemetry-preferences-navigation-item.injectable.ts @@ -32,6 +32,7 @@ const terminalPreferencesNavigationItemInjectable = getInjectable({ return { id: "telemetry", label: "Telemetry", + parent: "general", navigate: navigateToPreferenceTab(route), isActive: routeIsActive, diff --git a/src/renderer/components/+preferences/preferences-navigation/terminal-preferences-navigation-item.injectable.ts b/src/renderer/components/+preferences/preferences-navigation/terminal-preferences-navigation-item.injectable.ts index b623148c10..f5ad555c3b 100644 --- a/src/renderer/components/+preferences/preferences-navigation/terminal-preferences-navigation-item.injectable.ts +++ b/src/renderer/components/+preferences/preferences-navigation/terminal-preferences-navigation-item.injectable.ts @@ -24,6 +24,7 @@ const terminalPreferencesNavigationItemInjectable = getInjectable({ return { id: "terminal", label: "Terminal", + parent: "general", navigate: navigateToPreferenceTab(route), isActive: routeIsActive, isVisible: computed(() => true),