1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Showing a links for each extension in sidebar

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
Alex Andreev 2022-04-21 16:52:27 +03:00
parent bff5282824
commit fa9277fb8c
6 changed files with 316 additions and 66 deletions

View File

@ -1,5 +1,216 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`preferences - navigation to extension specific preferences given in preferences, when rendered given multiple extensions with specific preferences, when navigating to extension specific preferences page renders 1`] = `
<div>
<div
class="SettingLayout showNavigation Preferences"
data-testid="extension-preferences-page"
>
<nav
class="sidebarRegion"
>
<div
class="sidebar"
>
<div
class="Tabs flex column"
>
<div
class="header"
>
Preferences
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-application"
role="tab"
tabindex="0"
>
<div
class="label"
>
App
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-proxy"
role="tab"
tabindex="0"
>
<div
class="label"
>
Proxy
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-extension-some-test-extension-id"
role="tab"
tabindex="0"
>
<div
class="label"
>
some-test-extension-id
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-extension-some-other-test-extension-id"
role="tab"
tabindex="0"
>
<div
class="label"
>
some-other-test-extension-id
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-kubernetes"
role="tab"
tabindex="0"
>
<div
class="label"
>
Kubernetes
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-editor"
role="tab"
tabindex="0"
>
<div
class="label"
>
Editor
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-terminal"
role="tab"
tabindex="0"
>
<div
class="label"
>
Terminal
</div>
</div>
</div>
</div>
</nav>
<div
class="contentRegion"
id="ScrollSpyRoot"
>
<div
class="content"
>
<section
id="extensions"
>
<h2>
Extensions
</h2>
<section
class="small"
data-testid="extension-preference-item-for-some-preference-item-id"
id="some-preference-item-id"
>
<div
class="SubTitle"
>
Some preference item
</div>
<div
data-testid="some-preference-item-input"
/>
<div
class="hint"
>
<div
data-testid="some-preference-item-hint"
/>
</div>
</section>
<hr
class="small"
/>
<section
class="small"
data-testid="extension-preference-item-for-some-other-preference-item-id"
id="some-other-preference-item-id"
>
<div
class="SubTitle"
>
Test preference item
</div>
<div
data-testid="some-other-preference-item-input"
/>
<div
class="hint"
>
<div
data-testid="some-other-preference-item-hint"
/>
</div>
</section>
<hr
class="small"
/>
</section>
</div>
<div
class="toolsRegion"
>
<div
class="fixed top-[60px]"
>
<div
data-testid="close-preferences"
>
<div
aria-label="Close"
class="closeButton"
role="button"
>
<i
class="Icon icon material focusable"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
<div
aria-hidden="true"
class="esc"
>
ESC
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`preferences - navigation to extension specific preferences given in preferences, when rendered renders 1`] = `
<div>
<div
@ -541,6 +752,18 @@ exports[`preferences - navigation to extension specific preferences given in pre
Proxy
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-extension-some-test-extension-id"
role="tab"
tabindex="0"
>
<div
class="label"
>
some-test-extension-id
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-kubernetes"
@ -577,18 +800,6 @@ exports[`preferences - navigation to extension specific preferences given in pre
Terminal
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-extensions"
role="tab"
tabindex="0"
>
<div
class="label"
>
Extensions
</div>
</div>
</div>
</div>
</nav>
@ -1050,6 +1261,18 @@ exports[`preferences - navigation to extension specific preferences given in pre
Proxy
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-extension-some-test-extension-id"
role="tab"
tabindex="0"
>
<div
class="label"
>
some-test-extension-id
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-kubernetes"
@ -1086,18 +1309,6 @@ exports[`preferences - navigation to extension specific preferences given in pre
Terminal
</div>
</div>
<div
class="Tab flex gaps align-center active"
data-testid="tab-link-for-extensions"
role="tab"
tabindex="0"
>
<div
class="label"
>
Extensions
</div>
</div>
</div>
</div>
</nav>

View File

@ -59,11 +59,37 @@ describe("preferences - navigation to extension specific preferences", () => {
expect(actual).toBeNull();
});
describe("given multiple extensions with specific preferences, when navigating to extension specific preferences page", () => {
beforeEach(async () => {
const someTestExtension = getRendererExtensionFake(extensionStubWithExtensionSpecificPreferenceItems);
const someOtherTestExtension = getRendererExtensionFake(someOtherExtensionStubWithExtensionSpecificPreferenceItems);
await applicationBuilder.addExtensions(someTestExtension, someOtherTestExtension);
applicationBuilder.preferences.navigation.click("extension-some-test-extension-id");
});
it("renders", () => {
expect(rendered.container).toMatchSnapshot();
});
it("doesn't show preferences from unrelated extension", () => {
const actual = rendered.getByTestId("extension-preference-item-for-some-other-preference-item-id");
expect(actual).toBeNull();
});
it("shows preferences from related extension", () => {
const actual = rendered.getByTestId("extension-preference-item-for-some-preference-item-id");
expect(actual).not.toBeNull();
});
});
describe("when extension with specific preferences is enabled", () => {
beforeEach(() => {
beforeEach(async () => {
const testExtension = getRendererExtensionFake(extensionStubWithExtensionSpecificPreferenceItems);
applicationBuilder.addExtensions(testExtension);
await applicationBuilder.addExtensions(testExtension);
});
it("renders", () => {
@ -71,14 +97,14 @@ describe("preferences - navigation to extension specific preferences", () => {
});
it("shows link for extension preferences", () => {
const actual = rendered.getByTestId("tab-link-for-extensions");
const actual = rendered.getByTestId("tab-link-for-extension-some-test-extension-id");
expect(actual).not.toBeNull();
});
describe("when navigating to extension preferences using navigation", () => {
beforeEach(() => {
applicationBuilder.preferences.navigation.click("extensions");
applicationBuilder.preferences.navigation.click("extension-some-test-extension-id");
});
it("renders", () => {
@ -134,3 +160,19 @@ const extensionStubWithExtensionSpecificPreferenceItems: Partial<LensRendererExt
],
};
const someOtherExtensionStubWithExtensionSpecificPreferenceItems: Partial<LensRendererExtension> = {
id: "some-other-test-extension-id",
appPreferences: [
{
title: "Test preference item",
id: "some-other-preference-item-id",
components: {
Hint: () => <div data-testid="some-other-preference-item-hint" />,
Input: () => <div data-testid="some-other-preference-item-input" />,
},
},
],
};

View File

@ -4,13 +4,18 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import type { Route } from "../../../route-injection-token";
import { routeInjectionToken } from "../../../route-injection-token";
interface ExtensionPreferenceRouteParams {
extensionId: string;
}
const extensionPreferencesRouteInjectable = getInjectable({
id: "extension-preferences-route",
instantiate: () => ({
path: "/preferences/extensions",
instantiate: (): Route<ExtensionPreferenceRouteParams> => ({
path: "/preferences/extension/:extensionId",
clusterFrame: false,
isEnabled: computed(() => true),
}),

View File

@ -13,7 +13,9 @@ const navigateToExtensionPreferencesInjectable = getInjectable({
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
const route = di.inject(extensionPreferencesRouteInjectable);
return () => navigateToRoute(route);
return (extensionId: string) => navigateToRoute(route, { parameters: {
extensionId,
}});
},
});

View File

@ -3,49 +3,39 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { preferenceNavigationItemInjectionToken } from "./preference-navigation-items.injectable";
import routeIsActiveInjectable from "../../../routes/route-is-active.injectable";
import { computed } from "mobx";
import extensionsPreferenceItemsInjectable from "../extension-preference-items.injectable";
import extensionPreferencesRouteInjectable from "../../../../common/front-end-routing/routes/preferences/extension/extension-preferences-route.injectable";
import navigateToPreferenceTabInjectable from "./navigate-to-preference-tab.injectable";
import navigateToExtensionPreferencesInjectable from "../../../../common/front-end-routing/routes/preferences/extension/navigate-to-extension-preferences.injectable";
import { extensionRegistratorInjectionToken } from "../../../../extensions/extension-loader/extension-registrator-injection-token";
import type { LensRendererExtension } from "../../../../extensions/lens-renderer-extension";
import { preferenceNavigationItemInjectionToken } from "./preference-navigation-items.injectable";
const extensionsPreferencesNavigationItemInjectable = getInjectable({
const extensionPreferencesNavigationItemRegistratorInjectable = getInjectable({
id: "extension-preferences-navigation-item",
instantiate: (di) => {
const preferenceItems = di.inject(
extensionsPreferenceItemsInjectable,
);
return (extension: LensRendererExtension) => {
const navigateToExtensionPreferences = di.inject(
navigateToExtensionPreferencesInjectable,
);
const navigateToPreferenceTab = di.inject(
navigateToPreferenceTabInjectable,
);
const extensionInjectable = getInjectable({
id: `extension-preferences-navigation-item-${extension.sanitizedExtensionId}`,
instantiate: () => ({
id: `extension-${extension.sanitizedExtensionId}`,
label: `${extension.name}`,
navigate: () => navigateToExtensionPreferences(extension.sanitizedExtensionId),
isActive: computed(() => false),
isVisible: computed(() => true),
orderNumber: 20,
}),
injectionToken: preferenceNavigationItemInjectionToken,
});
const route = di.inject(
extensionPreferencesRouteInjectable,
);
const routeIsActive = di.inject(
routeIsActiveInjectable,
route,
);
return {
id: "extensions",
label: "Extensions",
navigate: navigateToPreferenceTab(route),
isActive: routeIsActive,
isVisible: computed(
() => preferenceItems.get().length > 0,
),
orderNumber: 70,
di.register(extensionInjectable);
};
},
injectionToken: preferenceNavigationItemInjectionToken,
injectionToken: extensionRegistratorInjectionToken,
});
export default extensionsPreferencesNavigationItemInjectable;
export default extensionPreferencesNavigationItemRegistratorInjectable;

View File

@ -12,7 +12,7 @@ const navigateToPreferenceTabInjectable = getInjectable({
instantiate: (di) => {
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
return (route: Route) => () => {
return (route: Route<unknown>) => () => {
navigateToRoute(route, { withoutAffectingBackButton: true });
};
},