mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Make tab groups and tabs in preferences not render when there is no content
Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>
This commit is contained in:
parent
f48dcba59d
commit
ca5e5034e6
File diff suppressed because it is too large
Load Diff
194
src/features/preferences/hiding-of-empty-branches.test.tsx
Normal file
194
src/features/preferences/hiding-of-empty-branches.test.tsx
Normal file
@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import React from "react";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { RenderResult } from "@testing-library/react";
|
||||
import { runInAction } from "mobx";
|
||||
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import { preferenceItemInjectionToken } from "./renderer/preference-items/preference-item-injection-token";
|
||||
|
||||
describe("preferences - hiding-of-empty-branches, given in preferences page", () => {
|
||||
let builder: ApplicationBuilder;
|
||||
let rendered: RenderResult;
|
||||
let windowDi: DiContainer;
|
||||
|
||||
beforeEach(async () => {
|
||||
builder = getApplicationBuilder();
|
||||
|
||||
rendered = await builder.render();
|
||||
|
||||
builder.preferences.navigate();
|
||||
|
||||
windowDi = builder.applicationWindow.only.di;
|
||||
});
|
||||
|
||||
describe("given tab group and empty tabs", () => {
|
||||
beforeEach(() => {
|
||||
const someTabGroupInjectable = getInjectable({
|
||||
id: "some-tab-group",
|
||||
|
||||
instantiate: () => ({
|
||||
kind: "tab-group" as const,
|
||||
id: "some-tab-group",
|
||||
testId: "some-tab-group-test-id",
|
||||
parentId: "preference-tabs" as const,
|
||||
label: "Some tab group label",
|
||||
orderNumber: 10,
|
||||
}),
|
||||
|
||||
injectionToken: preferenceItemInjectionToken,
|
||||
});
|
||||
|
||||
const tabWithItemsInjectable = getInjectable({
|
||||
id: "some-tab",
|
||||
|
||||
instantiate: () => ({
|
||||
kind: "tab" as const,
|
||||
id: "some-tab-with-items-id",
|
||||
parentId: "some-tab-group" as const,
|
||||
testId: "some-tab-with-items",
|
||||
pathId: "irrelevant",
|
||||
label: "Some label for tab with items",
|
||||
orderNumber: 10,
|
||||
}),
|
||||
|
||||
injectionToken: preferenceItemInjectionToken,
|
||||
});
|
||||
|
||||
const tabWithoutItemsInjectable = getInjectable({
|
||||
id: "some-empty-tab",
|
||||
|
||||
instantiate: () => ({
|
||||
kind: "tab" as const,
|
||||
id: "some-tab-without-items-id",
|
||||
parentId: "some-tab-group" as const,
|
||||
testId: "some-tab-without-items",
|
||||
pathId: "irrelevant",
|
||||
label: "Some label for tab without items",
|
||||
orderNumber: 10,
|
||||
}),
|
||||
|
||||
injectionToken: preferenceItemInjectionToken,
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
windowDi.register(
|
||||
someTabGroupInjectable,
|
||||
tabWithItemsInjectable,
|
||||
tabWithoutItemsInjectable,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("does not render the empty tab group", () => {
|
||||
const someTabGroup = rendered.queryByTestId("some-tab-group-test-id");
|
||||
|
||||
expect(someTabGroup).toBeNull();
|
||||
});
|
||||
|
||||
it("does not render the empty tabs", () => {
|
||||
const someTab = rendered.queryByTestId("some-tab-with-items");
|
||||
const someOtherTab = rendered.queryByTestId("some-tab-without-items");
|
||||
|
||||
expect([someTab, someOtherTab]).toEqual([null, null]);
|
||||
});
|
||||
|
||||
describe("when an item appears for one of the tabs", () => {
|
||||
beforeEach(() => {
|
||||
const itemForTabInjectable = getInjectable({
|
||||
id: "some-preference-item",
|
||||
|
||||
instantiate: () => ({
|
||||
kind: "item" as const,
|
||||
id: "some-preference-item-id",
|
||||
parentId: "some-tab-with-items-id" as const,
|
||||
testId: "some-preference-item",
|
||||
Component: () => <div>Irrelevant</div>,
|
||||
orderNumber: 10,
|
||||
}),
|
||||
|
||||
injectionToken: preferenceItemInjectionToken,
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
windowDi.register(itemForTabInjectable);
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders the tab group that is no longer empty", () => {
|
||||
const someTabGroup = rendered.queryByTestId("some-tab-group-test-id");
|
||||
|
||||
expect(someTabGroup).not.toBeNull();
|
||||
});
|
||||
|
||||
it("renders the tab that is no longer empty", () => {
|
||||
const someTab = rendered.queryByTestId("some-tab-with-items");
|
||||
|
||||
expect(someTab).not.toBeNull();
|
||||
});
|
||||
|
||||
it("does not render the tab that is still empty", () => {
|
||||
const someTab = rendered.queryByTestId("some-tab-without-items");
|
||||
|
||||
expect(someTab).toBeNull();
|
||||
});
|
||||
|
||||
describe("when an item appears for the remaining tab", () => {
|
||||
beforeEach(() => {
|
||||
const itemForTabInjectable = getInjectable({
|
||||
id: "some-other-preference-item",
|
||||
|
||||
instantiate: () => ({
|
||||
kind: "item" as const,
|
||||
id: "some-other-preference-item-id",
|
||||
parentId: "some-tab-without-items-id" as const,
|
||||
testId: "some-other-preference-item",
|
||||
Component: () => <div>Irrelevant</div>,
|
||||
orderNumber: 10,
|
||||
}),
|
||||
|
||||
injectionToken: preferenceItemInjectionToken,
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
windowDi.register(itemForTabInjectable);
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("still renders the tab group that is not empty", () => {
|
||||
const someTabGroup = rendered.queryByTestId("some-tab-group-test-id");
|
||||
|
||||
expect(someTabGroup).not.toBeNull();
|
||||
});
|
||||
|
||||
it("still renders the tab that is not empty", () => {
|
||||
const someTab = rendered.queryByTestId("some-tab-with-items");
|
||||
|
||||
expect(someTab).not.toBeNull();
|
||||
});
|
||||
|
||||
it("now renders the other tab that is no longer empty", () => {
|
||||
const someTab = rendered.queryByTestId("some-tab-without-items");
|
||||
|
||||
expect(someTab).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -11,6 +11,7 @@ const extensionsPreferenceTabGroupInjectable = getInjectable({
|
||||
instantiate: () => ({
|
||||
kind: "tab-group" as const,
|
||||
id: "extensions-tab-group",
|
||||
testId: "extensions-tab-group",
|
||||
parentId: "preference-tabs" as const,
|
||||
label: "Extensions",
|
||||
orderNumber: 20,
|
||||
|
||||
@ -11,6 +11,7 @@ const generalPreferenceTabGroupInjectable = getInjectable({
|
||||
instantiate: () => ({
|
||||
kind: "tab-group" as const,
|
||||
id: "general-tab-group",
|
||||
testId: "general-tab-group",
|
||||
parentId: "preference-tabs" as const,
|
||||
label: "Preferences",
|
||||
orderNumber: 10,
|
||||
|
||||
@ -22,6 +22,7 @@ export interface PreferenceTabGroup {
|
||||
kind: "tab-group";
|
||||
id: string;
|
||||
parentId: "preference-tabs";
|
||||
testId: string;
|
||||
label: string;
|
||||
orderNumber: number;
|
||||
isShown?: boolean;
|
||||
|
||||
@ -23,7 +23,7 @@ interface PreferenceNavigationTabProps {
|
||||
const NonInjectedPreferencesNavigationTab = observer(({ navigateToTab, tabIsActive, tab } : Dependencies & PreferenceNavigationTabProps) => (
|
||||
<Tab
|
||||
onClick={() => navigateToTab(tab.pathId)}
|
||||
data-testid={`tab-link-for-${tab.pathId}`}
|
||||
data-testid={tab.testId}
|
||||
active={tabIsActive.get()}
|
||||
label={tab.label}
|
||||
/>
|
||||
|
||||
@ -12,6 +12,7 @@ import type { IComputedValue } from "mobx";
|
||||
import preferencesCompositeInjectable from "../preference-items/preferences-composite.injectable";
|
||||
import { observer } from "mobx-react";
|
||||
import { PreferencesNavigationTab } from "./preferences-navigation-tab";
|
||||
import { compositeHasDescendant } from "../../../application-menu/main/menu-items/get-composite/composite-has-descendant/composite-has-descendant";
|
||||
|
||||
interface Dependencies {
|
||||
composite: IComputedValue<Composite<PreferenceTypes>>;
|
||||
@ -35,21 +36,34 @@ export const PreferencesNavigation = withInjectables<Dependencies>(
|
||||
|
||||
|
||||
const toNavigationHierarchy = (composite: Composite<PreferenceTypes>) => {
|
||||
// Note: This makes tab groups and tabs without content not render anything in navigation.
|
||||
if (!hasContent(composite)) {
|
||||
return emptyRender;
|
||||
}
|
||||
|
||||
const value = composite.value;
|
||||
|
||||
switch (value.kind) {
|
||||
case "page":
|
||||
case "item":
|
||||
// Note: These preference item types are not rendered in navigation,
|
||||
// yet they are interesting for deciding if eg. a tab group or a tab has content
|
||||
// somewhere in structure, and therefore not be hidden.
|
||||
case "page": {
|
||||
return emptyRender;
|
||||
}
|
||||
|
||||
case "item": {
|
||||
return emptyRender;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-fallthrough
|
||||
case "group": {
|
||||
throw new Error("Should never come here");
|
||||
return emptyRender;
|
||||
}
|
||||
|
||||
case "tab-group": {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="header">{value.label}</div>
|
||||
<div data-testid={value.testId} className="header">{value.label}</div>
|
||||
|
||||
<Map items={composite.children}>{toNavigationHierarchy}</Map>
|
||||
</>
|
||||
@ -76,3 +90,10 @@ const toNavigationHierarchy = (composite: Composite<PreferenceTypes>) => {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const hasContent = compositeHasDescendant<PreferenceTypes>(
|
||||
(composite) => composite.value.kind === "item",
|
||||
);
|
||||
|
||||
const emptyRender = <></>;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user