mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Replace StatusBarRegistry with reactive solution (#4728)
This commit is contained in:
parent
8d8491a035
commit
09b33633f7
@ -2,13 +2,12 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
export type { StatusBarRegistration } from "../../renderer/components/cluster-manager/status-bar-registration";
|
||||
export type { AppPreferenceRegistration, AppPreferenceComponents } from "../../renderer/components/+preferences/app-preferences/app-preference-registration";
|
||||
export type { KubeObjectDetailRegistration, KubeObjectDetailComponents } from "../registries/kube-object-detail-registry";
|
||||
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../registries/kube-object-menu-registry";
|
||||
export type { KubeObjectStatusRegistration } from "../registries/kube-object-status-registry";
|
||||
export type { PageRegistration, RegisteredPage, PageParams, PageComponentProps, PageComponents, PageTarget } from "../registries/page-registry";
|
||||
export type { ClusterPageMenuRegistration, ClusterPageMenuComponents } from "../registries/page-menu-registry";
|
||||
export type { StatusBarRegistration } from "../registries/status-bar-registry";
|
||||
export type { ProtocolHandlerRegistration, RouteParams as ProtocolRouteParams, RouteHandler as ProtocolRouteHandler } from "../registries/protocol-handler";
|
||||
export type { CustomCategoryViewProps, CustomCategoryViewComponents, CustomCategoryViewRegistration } from "../../renderer/components/+catalog/custom-views";
|
||||
|
||||
@ -249,7 +249,6 @@ export class ExtensionLoader {
|
||||
const removeItems = [
|
||||
registries.GlobalPageRegistry.getInstance().add(extension.globalPages, extension),
|
||||
registries.EntitySettingRegistry.getInstance().add(extension.entitySettings),
|
||||
registries.StatusBarRegistry.getInstance().add(extension.statusBarItems),
|
||||
registries.CatalogEntityDetailRegistry.getInstance().add(extension.catalogEntityDetailItems),
|
||||
];
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ import type { CommandRegistration } from "../renderer/components/command-palette
|
||||
import type { AppPreferenceRegistration } from "../renderer/components/+preferences/app-preferences/app-preference-registration";
|
||||
import type { AdditionalCategoryColumnRegistration } from "../renderer/components/+catalog/custom-category-columns";
|
||||
import type { CustomCategoryViewRegistration } from "../renderer/components/+catalog/custom-views";
|
||||
import type { StatusBarRegistration } from "../renderer/components/cluster-manager/status-bar-registration";
|
||||
|
||||
export class LensRendererExtension extends LensExtension {
|
||||
globalPages: registries.PageRegistration[] = [];
|
||||
@ -26,7 +27,7 @@ export class LensRendererExtension extends LensExtension {
|
||||
kubeObjectStatusTexts: registries.KubeObjectStatusRegistration[] = [];
|
||||
appPreferences: AppPreferenceRegistration[] = [];
|
||||
entitySettings: registries.EntitySettingRegistration[] = [];
|
||||
statusBarItems: registries.StatusBarRegistration[] = [];
|
||||
statusBarItems: StatusBarRegistration[] = [];
|
||||
kubeObjectDetailItems: registries.KubeObjectDetailRegistration[] = [];
|
||||
kubeObjectMenuItems: registries.KubeObjectMenuRegistration[] = [];
|
||||
kubeWorkloadsOverviewItems: registries.WorkloadsOverviewDetailRegistration[] = [];
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
|
||||
export * from "./page-registry";
|
||||
export * from "./page-menu-registry";
|
||||
export * from "./status-bar-registry";
|
||||
export * from "./kube-object-detail-registry";
|
||||
export * from "./kube-object-menu-registry";
|
||||
export * from "./kube-object-status-registry";
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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 rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
||||
import type { StatusBarRegistration } from "./status-bar-registration";
|
||||
|
||||
const bottomBarItemsInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
const extensions = di.inject(rendererExtensionsInjectable);
|
||||
|
||||
return computed(() =>
|
||||
extensions
|
||||
.get()
|
||||
.flatMap((extension) => extension.statusBarItems)
|
||||
.sort(leftItemsBeforeRight),
|
||||
);
|
||||
},
|
||||
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
});
|
||||
|
||||
export default bottomBarItemsInjectable;
|
||||
|
||||
const leftItemsBeforeRight = (firstItem: StatusBarRegistration, secondItem: StatusBarRegistration) =>
|
||||
firstItem.components?.position?.localeCompare(secondItem.components?.position);
|
||||
@ -4,10 +4,15 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
import { BottomBar } from "./bottom-bar";
|
||||
import { StatusBarRegistry } from "../../../extensions/registries";
|
||||
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
||||
import type { DiRender } from "../test-utils/renderFor";
|
||||
import { renderFor } from "../test-utils/renderFor";
|
||||
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
||||
import { computed, IObservableArray, observable, runInAction } from "mobx";
|
||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
||||
|
||||
jest.mock("electron", () => ({
|
||||
app: {
|
||||
@ -15,13 +20,43 @@ jest.mock("electron", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
describe("<BottomBar />", () => {
|
||||
beforeEach(() => {
|
||||
StatusBarRegistry.createInstance();
|
||||
class SomeTestExtension extends LensRendererExtension {
|
||||
constructor(statusBarItems: IObservableArray<any>) {
|
||||
super({
|
||||
id: "some-id",
|
||||
absolutePath: "irrelevant",
|
||||
isBundled: false,
|
||||
isCompatible: false,
|
||||
isEnabled: false,
|
||||
manifest: { name: "some-id", version: "some-version" },
|
||||
manifestPath: "irrelevant",
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
StatusBarRegistry.resetInstance();
|
||||
this.statusBarItems = statusBarItems;
|
||||
}
|
||||
}
|
||||
|
||||
describe("<BottomBar />", () => {
|
||||
let render: DiRender;
|
||||
let statusBarItems: IObservableArray<any>;
|
||||
|
||||
beforeEach(async () => {
|
||||
|
||||
statusBarItems = observable.array([]);
|
||||
|
||||
const someTestExtension = new SomeTestExtension(statusBarItems);
|
||||
|
||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||
|
||||
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||
|
||||
di.override(rendererExtensionsInjectable, () => {
|
||||
return computed(() => [someTestExtension]);
|
||||
});
|
||||
|
||||
render = renderFor(di);
|
||||
|
||||
await di.runSetups();
|
||||
});
|
||||
|
||||
it("renders w/o errors", () => {
|
||||
@ -30,6 +65,7 @@ describe("<BottomBar />", () => {
|
||||
expect(container).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
|
||||
|
||||
it.each([
|
||||
undefined,
|
||||
"hello",
|
||||
@ -39,7 +75,10 @@ describe("<BottomBar />", () => {
|
||||
[{}],
|
||||
{},
|
||||
])("renders w/o errors when .getItems() returns not type compliant (%p)", val => {
|
||||
StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => val);
|
||||
runInAction(() => {
|
||||
statusBarItems.replace([val]);
|
||||
});
|
||||
|
||||
expect(() => render(<BottomBar />)).not.toThrow();
|
||||
});
|
||||
|
||||
@ -47,9 +86,12 @@ describe("<BottomBar />", () => {
|
||||
const testId = "testId";
|
||||
const text = "heee";
|
||||
|
||||
StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => [
|
||||
runInAction(() => {
|
||||
statusBarItems.replace([
|
||||
{ item: <span data-testid={testId} >{text}</span> },
|
||||
]);
|
||||
});
|
||||
|
||||
const { getByTestId } = render(<BottomBar />);
|
||||
|
||||
expect(getByTestId(testId)).toHaveTextContent(text);
|
||||
@ -59,9 +101,12 @@ describe("<BottomBar />", () => {
|
||||
const testId = "testId";
|
||||
const text = "heee";
|
||||
|
||||
StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => [
|
||||
runInAction(() => {
|
||||
statusBarItems.replace([
|
||||
{ item: () => <span data-testid={testId} >{text}</span> },
|
||||
]);
|
||||
});
|
||||
|
||||
const { getByTestId } = render(<BottomBar />);
|
||||
|
||||
expect(getByTestId(testId)).toHaveTextContent(text);
|
||||
@ -69,7 +114,8 @@ describe("<BottomBar />", () => {
|
||||
|
||||
|
||||
it("sort positioned items properly", () => {
|
||||
StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => [
|
||||
runInAction(() => {
|
||||
statusBarItems.replace([
|
||||
{
|
||||
components: {
|
||||
Item: () => <div data-testid="sortedElem">right</div>,
|
||||
@ -94,6 +140,7 @@ describe("<BottomBar />", () => {
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
const { getAllByTestId } = render(<BottomBar />);
|
||||
const elems = getAllByTestId("sortedElem");
|
||||
|
||||
@ -7,11 +7,18 @@ import styles from "./bottom-bar.module.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { StatusBarRegistration, StatusBarRegistry } from "../../../extensions/registries";
|
||||
import { cssNames } from "../../utils";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import bottomBarItemsInjectable from "./bottom-bar-items.injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { StatusBarRegistration } from "./status-bar-registration";
|
||||
|
||||
interface Dependencies {
|
||||
items: IComputedValue<StatusBarRegistration[]>
|
||||
}
|
||||
|
||||
@observer
|
||||
export class BottomBar extends React.Component {
|
||||
class NonInjectedBottomBar extends React.Component<Dependencies> {
|
||||
renderRegisteredItem(registration: StatusBarRegistration) {
|
||||
const { item } = registration;
|
||||
|
||||
@ -23,19 +30,9 @@ export class BottomBar extends React.Component {
|
||||
}
|
||||
|
||||
renderRegisteredItems() {
|
||||
const items = StatusBarRegistry.getInstance().getItems();
|
||||
|
||||
if (!Array.isArray(items)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
items.sort(function sortLeftPositionFirst(a, b) {
|
||||
return a.components?.position?.localeCompare(b.components?.position);
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{items.map((registration, index) => {
|
||||
{this.props.items.get().map((registration, index) => {
|
||||
if (!registration?.item && !registration?.components?.Item) {
|
||||
return null;
|
||||
}
|
||||
@ -64,3 +61,14 @@ export class BottomBar extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const BottomBar = withInjectables<Dependencies>(
|
||||
NonInjectedBottomBar,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
items: di.inject(bottomBarItemsInjectable),
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
@ -2,12 +2,6 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
// Extensions API -> Status bar customizations
|
||||
|
||||
import type React from "react";
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
|
||||
interface StatusBarComponents {
|
||||
Item?: React.ComponentType;
|
||||
/**
|
||||
@ -28,6 +22,3 @@ export interface StatusBarRegistration extends StatusBarRegistrationV2 {
|
||||
*/
|
||||
item?: React.ReactNode;
|
||||
}
|
||||
|
||||
export class StatusBarRegistry extends BaseRegistry<StatusBarRegistration> {
|
||||
}
|
||||
@ -14,6 +14,5 @@ export function initRegistries() {
|
||||
registries.KubeObjectDetailRegistry.createInstance();
|
||||
registries.KubeObjectMenuRegistry.createInstance();
|
||||
registries.KubeObjectStatusRegistry.createInstance();
|
||||
registries.StatusBarRegistry.createInstance();
|
||||
registries.WorkloadsOverviewDetailRegistry.createInstance();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user