From 78b771d03b0f711f9e6296dfea11c11fdec3b591 Mon Sep 17 00:00:00 2001 From: Panu Horsmalahti Date: Wed, 7 Sep 2022 15:41:50 +0300 Subject: [PATCH] Allow extensions to control status bar item visibility (#6178) * Allow extensions to control status bar item visibility. Signed-off-by: Panu Horsmalahti * Move visible to StatusBarRegistration Signed-off-by: Panu Horsmalahti Signed-off-by: Panu Horsmalahti --- ...items-originating-from-extensions.test.tsx | 28 +++++++++++++++---- ...status-bar-item-registrator.injectable.tsx | 4 ++- .../status-bar/status-bar-registration.ts | 7 +++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/features/status-bar/status-bar-items-originating-from-extensions.test.tsx b/src/features/status-bar/status-bar-items-originating-from-extensions.test.tsx index 8d81720a7a..a23ffa2dd1 100644 --- a/src/features/status-bar/status-bar-items-originating-from-extensions.test.tsx +++ b/src/features/status-bar/status-bar-items-originating-from-extensions.test.tsx @@ -8,6 +8,7 @@ import type { ApplicationBuilder } from "../../renderer/components/test-utils/ge import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import getRandomIdInjectable from "../../common/utils/get-random-id.injectable"; import type { FakeExtensionOptions } from "../../renderer/components/test-utils/get-extension-fake"; +import { computed } from "mobx"; describe("status-bar-items-originating-from-extensions", () => { let applicationBuilder: ApplicationBuilder; @@ -65,7 +66,7 @@ describe("status-bar-items-originating-from-extensions", () => { const rightSide = rendered.getByTestId("status-bar-right"); - const actual = getTestStatusBarTexts(rightSide, [ + const actual = getExpectedTestStatusBarTexts(rightSide, [ "extension1", "extension2", ]); @@ -95,6 +96,13 @@ describe("status-bar-items-originating-from-extensions", () => { position: "right" as const, }, }, + { + components: { + Item: () =>
right4
, + position: "right" as const, + }, + visible: computed(() => false), + }, { components: { Item: () =>
left1
, @@ -121,7 +129,7 @@ describe("status-bar-items-originating-from-extensions", () => { it("shows right side status bar items in the correct order", () => { const rightSide = rendered.getByTestId("status-bar-right"); - const actual = getTestStatusBarTexts(rightSide, [ + const actual = getExpectedTestStatusBarTexts(rightSide, [ "right1", "right2", "right3", @@ -130,10 +138,16 @@ describe("status-bar-items-originating-from-extensions", () => { expect(actual).toEqual(["right3", "right2", "right1"]); }); + it("doesn't show invisible status bar item", () => { + const rightSide = rendered.getByTestId("status-bar-right"); + + expect(getTestStatusBarTexts(rightSide)).not.toContain("right4"); + }); + it("shows left side status bar items in the correct order", () => { const leftSide = rendered.getByTestId("status-bar-left"); - const actual = getTestStatusBarTexts(leftSide, ["left2", "left1"]); + const actual = getExpectedTestStatusBarTexts(leftSide, ["left2", "left1"]); expect(actual).toEqual(["left1", "left2"]); }); @@ -149,7 +163,9 @@ describe("status-bar-items-originating-from-extensions", () => { }); }); -const getTestStatusBarTexts = (actual: HTMLElement, expectedTexts: string[]) => +const getTestStatusBarTexts = (actual: HTMLElement) => Array.from(actual.children) - .map((elem) => elem.textContent) - .filter((elem) => elem && expectedTexts.includes(elem)); + .map((elem) => String(elem.textContent)); + +const getExpectedTestStatusBarTexts = (actual: HTMLElement, expectedTexts: string[]) => + getTestStatusBarTexts(actual).filter((textContent) => textContent && expectedTexts.includes(textContent)); diff --git a/src/renderer/components/status-bar/status-bar-item-registrator.injectable.tsx b/src/renderer/components/status-bar/status-bar-item-registrator.injectable.tsx index 2b31c9b312..71293126f7 100644 --- a/src/renderer/components/status-bar/status-bar-item-registrator.injectable.tsx +++ b/src/renderer/components/status-bar/status-bar-item-registrator.injectable.tsx @@ -4,6 +4,7 @@ */ import type { Injectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable"; +import type { IComputedValue } from "mobx"; import { computed } from "mobx"; import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token"; import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension"; @@ -38,6 +39,7 @@ const toItemInjectableFor = (extension: LensRendererExtension, getRandomId: () = const id = `${getRandomId()}-status-bar-item-for-extension-${extension.sanitizedExtensionId}`; let component: React.ComponentType; let position: "left" | "right"; + const visible: IComputedValue | undefined = registration?.visible; if (registration?.item) { const { item } = registration; @@ -74,7 +76,7 @@ const toItemInjectableFor = (extension: LensRendererExtension, getRandomId: () = instantiate: () => ({ component, position, - visible: computed(() => true), + visible: visible ?? computed(() => true), }), injectionToken: statusBarItemInjectionToken, diff --git a/src/renderer/components/status-bar/status-bar-registration.ts b/src/renderer/components/status-bar/status-bar-registration.ts index 8e7219b953..32e7c9c88e 100644 --- a/src/renderer/components/status-bar/status-bar-registration.ts +++ b/src/renderer/components/status-bar/status-bar-registration.ts @@ -3,6 +3,8 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { IComputedValue } from "mobx"; + /** * The props for StatusBar item component */ @@ -38,4 +40,9 @@ export interface StatusBarRegistration { * The newer API, allows for registering a component instead of a ReactNode */ components?: StatusBarComponents; + + /** + * If specified, controls item visibility + */ + visible?: IComputedValue; }