mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix stale UI state in extension preferences
Co-authored-by: Alex Andreev <alex.andreev.email@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
4e15279894
commit
e2e0fd3860
@ -2155,6 +2155,165 @@ exports[`preferences - navigation to extension specific preferences given in pre
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`preferences - navigation to extension specific preferences given in preferences, when rendered when extension with specific preferences is enabled when navigating to extension preferences using navigation when extension is disabled renders 1`] = `
|
||||
<body>
|
||||
<div>
|
||||
<div
|
||||
class="StatusBar"
|
||||
>
|
||||
<div
|
||||
class="leftSide"
|
||||
/>
|
||||
<div
|
||||
class="rightSide"
|
||||
/>
|
||||
</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-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>
|
||||
|
||||
preferences
|
||||
</h2>
|
||||
<div
|
||||
class="flex items-center"
|
||||
data-testid="error-for-extension-not-being-present"
|
||||
>
|
||||
No extension found
|
||||
</div>
|
||||
</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
|
||||
class="Notifications flex column align-flex-end"
|
||||
/>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`preferences - navigation to extension specific preferences when navigating to extension specific tab renders 1`] = `
|
||||
<div>
|
||||
<div
|
||||
|
||||
@ -7,12 +7,13 @@ import type { ApplicationBuilder } from "../../renderer/components/test-utils/ge
|
||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import React from "react";
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
import type { FakeExtensionData } from "../../renderer/components/test-utils/get-renderer-extension-fake";
|
||||
import type { FakeExtensionData, TestExtension } from "../../renderer/components/test-utils/get-renderer-extension-fake";
|
||||
import { getRendererExtensionFakeFor } from "../../renderer/components/test-utils/get-renderer-extension-fake";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import { getDiForUnitTesting } from "../../renderer/getDiForUnitTesting";
|
||||
import extensionPreferencesRouteInjectable from "../../common/front-end-routing/routes/preferences/extension/extension-preferences-route.injectable";
|
||||
|
||||
|
||||
describe("preferences - navigation to extension specific preferences", () => {
|
||||
let applicationBuilder: ApplicationBuilder;
|
||||
|
||||
@ -98,9 +99,14 @@ describe("preferences - navigation to extension specific preferences", () => {
|
||||
});
|
||||
|
||||
describe("when extension with specific preferences is enabled", () => {
|
||||
let testExtension: TestExtension;
|
||||
|
||||
beforeEach(() => {
|
||||
const getRendererExtensionFake = getRendererExtensionFakeFor(applicationBuilder);
|
||||
const testExtension = getRendererExtensionFake(extensionStubWithExtensionSpecificPreferenceItems);
|
||||
|
||||
testExtension = getRendererExtensionFake(
|
||||
extensionStubWithExtensionSpecificPreferenceItems,
|
||||
);
|
||||
|
||||
applicationBuilder.extensions.renderer.enable(testExtension);
|
||||
});
|
||||
@ -159,6 +165,26 @@ describe("preferences - navigation to extension specific preferences", () => {
|
||||
|
||||
expect(actual).toHaveClass("active");
|
||||
});
|
||||
|
||||
describe("when extension is disabled", () => {
|
||||
beforeEach(() => {
|
||||
applicationBuilder.extensions.renderer.disable(testExtension);
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows the error message about extension not being present", () => {
|
||||
expect(rendered.getByTestId("error-for-extension-not-being-present")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("when extension is enabled again, does not show the error message anymore", () => {
|
||||
applicationBuilder.extensions.renderer.enable(testExtension);
|
||||
|
||||
expect(rendered.queryByTestId("error-for-extension-not-being-present")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import type { RegisteredAppPreference } from "./app-preferences/app-preference-registration";
|
||||
@ -12,44 +13,50 @@ import { ExtensionSettings } from "./extension-settings";
|
||||
import { Preferences } from "./preferences";
|
||||
|
||||
interface Dependencies {
|
||||
preferenceItems: RegisteredAppPreference[];
|
||||
extensionName?: string;
|
||||
model: IComputedValue<{
|
||||
preferenceItems: RegisteredAppPreference[];
|
||||
extensionName?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
const NonInjectedExtensions = ({ preferenceItems, extensionName }: Dependencies) => (
|
||||
<Preferences data-testid="extension-preferences-page">
|
||||
<section id="extensions">
|
||||
<h2>
|
||||
{extensionName}
|
||||
{" "}
|
||||
preferences
|
||||
</h2>
|
||||
{!extensionName && (
|
||||
<div className="flex items-center">No extension found</div>
|
||||
)}
|
||||
{preferenceItems.map((preferenceItem, index) => (
|
||||
<ExtensionSettings
|
||||
key={`${preferenceItem.id}-${index}`}
|
||||
setting={preferenceItem}
|
||||
size="small"
|
||||
data-testid={`extension-preference-item-for-${preferenceItem.id}`}
|
||||
/>
|
||||
))}
|
||||
</section>
|
||||
</Preferences>
|
||||
);
|
||||
const NonInjectedExtensions = ({ model }: Dependencies) => {
|
||||
const { extensionName, preferenceItems } = model.get();
|
||||
|
||||
return (
|
||||
<Preferences data-testid="extension-preferences-page">
|
||||
<section id="extensions">
|
||||
<h2>
|
||||
{extensionName}
|
||||
{" "}
|
||||
preferences
|
||||
</h2>
|
||||
{!extensionName && (
|
||||
<div
|
||||
className="flex items-center"
|
||||
data-testid="error-for-extension-not-being-present"
|
||||
>
|
||||
No extension found
|
||||
</div>
|
||||
)}
|
||||
{preferenceItems.map((preferenceItem, index) => (
|
||||
<ExtensionSettings
|
||||
key={`${preferenceItem.id}-${index}`}
|
||||
setting={preferenceItem}
|
||||
size="small"
|
||||
data-testid={`extension-preference-item-for-${preferenceItem.id}`}
|
||||
/>
|
||||
))}
|
||||
</section>
|
||||
</Preferences>
|
||||
);
|
||||
};
|
||||
|
||||
export const Extensions = withInjectables<Dependencies>(
|
||||
observer(NonInjectedExtensions),
|
||||
|
||||
{
|
||||
getProps: (di) => {
|
||||
const { preferenceItems, extensionName } = di.inject(extensionPreferencesModelInjectable).get();
|
||||
|
||||
return {
|
||||
preferenceItems,
|
||||
extensionName,
|
||||
};
|
||||
},
|
||||
getProps: (di) => ({
|
||||
model: di.inject(extensionPreferencesModelInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
@ -9,12 +9,13 @@ import type { PreferenceNavigationItem } from "./preference-navigation-items.inj
|
||||
import { Icon } from "../../icon";
|
||||
import { PreferencesNavigationTab } from "./preference-navigation-tab";
|
||||
import preferenceNavigationItemsForGroupInjectable from "./preference-navigation-items-for-group.injectable";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
interface Dependencies {
|
||||
navigationItems: IComputedValue<PreferenceNavigationItem[]>;
|
||||
}
|
||||
|
||||
function NonInjectedExtensionsNavGroup(props: Dependencies) {
|
||||
const NonInjectedExtensionsNavGroup = observer((props: Dependencies) => {
|
||||
if (!props.navigationItems.get().length) {
|
||||
return null;
|
||||
}
|
||||
@ -42,7 +43,7 @@ function NonInjectedExtensionsNavGroup(props: Dependencies) {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export const ExtensionsNavGroup = withInjectables<Dependencies>(
|
||||
NonInjectedExtensionsNavGroup,
|
||||
|
||||
@ -8,12 +8,13 @@ import type { IComputedValue } from "mobx";
|
||||
import type { PreferenceNavigationItem } from "./preference-navigation-items.injectable";
|
||||
import { PreferencesNavigationTab } from "./preference-navigation-tab";
|
||||
import preferenceNavigationItemsForGroupInjectable from "./preference-navigation-items-for-group.injectable";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
interface Dependencies {
|
||||
navigationItems: IComputedValue<PreferenceNavigationItem[]>;
|
||||
}
|
||||
|
||||
function NonInjectedGeneralNavGroup(props: Dependencies) {
|
||||
const NonInjectedGeneralNavGroup = observer((props: Dependencies) => {
|
||||
if (!props.navigationItems.get().length) {
|
||||
return null;
|
||||
}
|
||||
@ -31,7 +32,7 @@ function NonInjectedGeneralNavGroup(props: Dependencies) {
|
||||
))}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export const GeneralNavGroup = withInjectables<Dependencies>(
|
||||
NonInjectedGeneralNavGroup,
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
*/
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
||||
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||
import { filter, orderBy } from "lodash/fp";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { computed } from "mobx";
|
||||
@ -26,14 +27,18 @@ export interface PreferenceNavigationItem {
|
||||
const preferenceNavigationItemsInjectable = getInjectable({
|
||||
id: "preference-navigation-items",
|
||||
|
||||
instantiate: (di) =>
|
||||
computed((): PreferenceNavigationItem[] =>
|
||||
instantiate: (di) => {
|
||||
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||
const navigationItems = computedInjectMany(preferenceNavigationItemInjectionToken);
|
||||
|
||||
return computed((): PreferenceNavigationItem[] =>
|
||||
pipeline(
|
||||
di.injectMany(preferenceNavigationItemInjectionToken),
|
||||
navigationItems.get(),
|
||||
filter((item) => !!item.isVisible.get()),
|
||||
(items) => orderBy([(item) => item.orderNumber], ["asc"], items),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default preferenceNavigationItemsInjectable;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user