mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Allow reactive tray item labels for extensions (#6036)
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
6d37019089
commit
d6ca2c2cd7
@ -8,6 +8,7 @@ import type { ApplicationBuilder } from "../../renderer/components/test-utils/ge
|
|||||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
import loggerInjectable from "../../common/logger.injectable";
|
import loggerInjectable from "../../common/logger.injectable";
|
||||||
import type { Logger } from "../../common/logger";
|
import type { Logger } from "../../common/logger";
|
||||||
|
import getRandomIdInjectable from "../../common/utils/get-random-id.injectable";
|
||||||
|
|
||||||
describe("clicking tray menu item originating from extension", () => {
|
describe("clicking tray menu item originating from extension", () => {
|
||||||
let applicationBuilder: ApplicationBuilder;
|
let applicationBuilder: ApplicationBuilder;
|
||||||
@ -20,6 +21,7 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
logErrorMock = jest.fn();
|
logErrorMock = jest.fn();
|
||||||
|
|
||||||
mainDi.override(loggerInjectable, () => ({ error: logErrorMock }) as unknown as Logger);
|
mainDi.override(loggerInjectable, () => ({ error: logErrorMock }) as unknown as Logger);
|
||||||
|
mainDi.override(getRandomIdInjectable, () => () => "some-random-id");
|
||||||
});
|
});
|
||||||
|
|
||||||
await applicationBuilder.render();
|
await applicationBuilder.render();
|
||||||
@ -42,7 +44,7 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
|
|
||||||
it("when item is clicked, triggers the click handler", () => {
|
it("when item is clicked, triggers the click handler", () => {
|
||||||
applicationBuilder.tray.click(
|
applicationBuilder.tray.click(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id",
|
"some-random-id-tray-menu-item-for-extension-some-extension-id",
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(clickMock).toHaveBeenCalled();
|
expect(clickMock).toHaveBeenCalled();
|
||||||
@ -55,13 +57,13 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
applicationBuilder.tray.click(
|
applicationBuilder.tray.click(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id",
|
"some-random-id-tray-menu-item-for-extension-some-extension-id",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("logs the error", () => {
|
it("logs the error", () => {
|
||||||
expect(logErrorMock).toHaveBeenCalledWith(
|
expect(logErrorMock).toHaveBeenCalledWith(
|
||||||
'[TRAY]: Clicking of tray item "some-label" from extension "some-extension-id" failed.',
|
'[TRAY]: Clicking of tray item "some-random-id" from extension "some-extension-id" failed.',
|
||||||
expect.any(Error),
|
expect.any(Error),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -72,13 +74,13 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
clickMock.mockImplementation(() => Promise.reject("some-rejection"));
|
clickMock.mockImplementation(() => Promise.reject("some-rejection"));
|
||||||
|
|
||||||
applicationBuilder.tray.click(
|
applicationBuilder.tray.click(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id",
|
"some-random-id-tray-menu-item-for-extension-some-extension-id",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("logs the error", () => {
|
it("logs the error", () => {
|
||||||
expect(logErrorMock).toHaveBeenCalledWith(
|
expect(logErrorMock).toHaveBeenCalledWith(
|
||||||
'[TRAY]: Clicking of tray item "some-label" from extension "some-extension-id" failed.',
|
'[TRAY]: Clicking of tray item "some-random-id" from extension "some-extension-id" failed.',
|
||||||
"some-rejection",
|
"some-rejection",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -92,7 +94,7 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
it("does not have the tray menu item from extension", () => {
|
it("does not have the tray menu item from extension", () => {
|
||||||
expect(
|
expect(
|
||||||
applicationBuilder.tray.get(
|
applicationBuilder.tray.get(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id",
|
"some-random-id-tray-menu-item-for-extension-some-extension-id",
|
||||||
),
|
),
|
||||||
).toBeNull();
|
).toBeNull();
|
||||||
});
|
});
|
||||||
@ -103,7 +105,7 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
applicationBuilder.tray.get(
|
applicationBuilder.tray.get(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id",
|
"some-random-id-tray-menu-item-for-extension-some-extension-id",
|
||||||
),
|
),
|
||||||
).not.toBeNull();
|
).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,6 +13,7 @@ describe("preferences: extension adding tray items", () => {
|
|||||||
let builder: ApplicationBuilder;
|
let builder: ApplicationBuilder;
|
||||||
let someObservableForVisibility: IObservableValue<boolean>;
|
let someObservableForVisibility: IObservableValue<boolean>;
|
||||||
let someObservableForEnabled: IObservableValue<boolean>;
|
let someObservableForEnabled: IObservableValue<boolean>;
|
||||||
|
let someObservableLabel: IObservableValue<string>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
builder = getApplicationBuilder();
|
builder = getApplicationBuilder();
|
||||||
@ -25,6 +26,7 @@ describe("preferences: extension adding tray items", () => {
|
|||||||
|
|
||||||
someObservableForVisibility = observable.box(false);
|
someObservableForVisibility = observable.box(false);
|
||||||
someObservableForEnabled = observable.box(false);
|
someObservableForEnabled = observable.box(false);
|
||||||
|
someObservableLabel = observable.box("Some label");
|
||||||
|
|
||||||
const testExtension = getExtensionFake({
|
const testExtension = getExtensionFake({
|
||||||
id: "some-extension-id",
|
id: "some-extension-id",
|
||||||
@ -33,38 +35,51 @@ describe("preferences: extension adding tray items", () => {
|
|||||||
mainOptions: {
|
mainOptions: {
|
||||||
trayMenus: [
|
trayMenus: [
|
||||||
{
|
{
|
||||||
|
id: "some-controlled-visibility",
|
||||||
label: "some-controlled-visibility",
|
label: "some-controlled-visibility",
|
||||||
click: () => {},
|
click: () => {},
|
||||||
visible: computed(() => someObservableForVisibility.get()),
|
visible: computed(() => someObservableForVisibility.get()),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
id: "some-uncontrolled-visibility",
|
||||||
label: "some-uncontrolled-visibility",
|
label: "some-uncontrolled-visibility",
|
||||||
click: () => {},
|
click: () => {},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
id: "some-controlled-enabled",
|
||||||
label: "some-controlled-enabled",
|
label: "some-controlled-enabled",
|
||||||
click: () => {},
|
click: () => {},
|
||||||
enabled: computed(() => someObservableForEnabled.get()),
|
enabled: computed(() => someObservableForEnabled.get()),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
id: "some-uncontrolled-enabled",
|
||||||
label: "some-uncontrolled-enabled",
|
label: "some-uncontrolled-enabled",
|
||||||
click: () => {},
|
click: () => {},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
id: "some-statically-enabled",
|
||||||
label: "some-statically-enabled",
|
label: "some-statically-enabled",
|
||||||
click: () => {},
|
click: () => {},
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
id: "some-statically-disabled",
|
||||||
label: "some-statically-disabled",
|
label: "some-statically-disabled",
|
||||||
click: () => {},
|
click: () => {},
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: "some-item-with-controlled-label",
|
||||||
|
label: computed(() => someObservableLabel.get()),
|
||||||
|
click: () => {},
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -72,6 +87,37 @@ describe("preferences: extension adding tray items", () => {
|
|||||||
builder.extensions.enable(testExtension);
|
builder.extensions.enable(testExtension);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("given controlled label", () => {
|
||||||
|
it("has the label", () => {
|
||||||
|
const item = builder.tray.get(
|
||||||
|
"some-item-with-controlled-label-tray-menu-item-for-extension-some-extension",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(item?.label).toBe("Some label");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when label changes, updates the label", () => {
|
||||||
|
runInAction(() => {
|
||||||
|
someObservableLabel.set("Some new label");
|
||||||
|
});
|
||||||
|
|
||||||
|
const item = builder.tray.get(
|
||||||
|
"some-item-with-controlled-label-tray-menu-item-for-extension-some-extension",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(item?.label).toBe("Some new label");
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given item is statically disabled, item is disabled", () => {
|
||||||
|
const item = builder.tray.get(
|
||||||
|
"some-statically-disabled-tray-menu-item-for-extension-some-extension",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(item?.enabled).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it("shows item which doesn't control the visibility", () => {
|
it("shows item which doesn't control the visibility", () => {
|
||||||
expect(
|
expect(
|
||||||
builder.tray.get(
|
builder.tray.get(
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { pipeline } from "@ogre-tools/fp";
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
import { kebabCase } from "lodash/fp";
|
|
||||||
import type { Injectable } from "@ogre-tools/injectable";
|
import type { Injectable } from "@ogre-tools/injectable";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
@ -16,7 +15,7 @@ import { withErrorSuppression } from "../../../common/utils/with-error-suppressi
|
|||||||
import type { WithErrorLoggingFor } from "../../../common/utils/with-error-logging/with-error-logging.injectable";
|
import type { WithErrorLoggingFor } from "../../../common/utils/with-error-logging/with-error-logging.injectable";
|
||||||
import withErrorLoggingInjectable from "../../../common/utils/with-error-logging/with-error-logging.injectable";
|
import withErrorLoggingInjectable from "../../../common/utils/with-error-logging/with-error-logging.injectable";
|
||||||
import getRandomIdInjectable from "../../../common/utils/get-random-id.injectable";
|
import getRandomIdInjectable from "../../../common/utils/get-random-id.injectable";
|
||||||
import { isBoolean } from "../../../common/utils";
|
import { isBoolean, isString } from "../../../common/utils";
|
||||||
|
|
||||||
const trayMenuItemRegistratorInjectable = getInjectable({
|
const trayMenuItemRegistratorInjectable = getInjectable({
|
||||||
id: "tray-menu-item-registrator",
|
id: "tray-menu-item-registrator",
|
||||||
@ -38,7 +37,7 @@ export default trayMenuItemRegistratorInjectable;
|
|||||||
|
|
||||||
const toItemInjectablesFor = (extension: LensMainExtension, withErrorLoggingFor: WithErrorLoggingFor, getRandomId: () => string) => {
|
const toItemInjectablesFor = (extension: LensMainExtension, withErrorLoggingFor: WithErrorLoggingFor, getRandomId: () => string) => {
|
||||||
const _toItemInjectables = (parentId: string | null) => (registration: TrayMenuRegistration): Injectable<TrayMenuItem, TrayMenuItem, void>[] => {
|
const _toItemInjectables = (parentId: string | null) => (registration: TrayMenuRegistration): Injectable<TrayMenuItem, TrayMenuItem, void>[] => {
|
||||||
const trayItemId = registration.id || kebabCase(registration.label || getRandomId());
|
const trayItemId = registration.id || getRandomId();
|
||||||
const id = `${trayItemId}-tray-menu-item-for-extension-${extension.sanitizedExtensionId}`;
|
const id = `${trayItemId}-tray-menu-item-for-extension-${extension.sanitizedExtensionId}`;
|
||||||
|
|
||||||
const parentInjectable = getInjectable({
|
const parentInjectable = getInjectable({
|
||||||
@ -51,7 +50,18 @@ const toItemInjectablesFor = (extension: LensMainExtension, withErrorLoggingFor:
|
|||||||
|
|
||||||
separator: registration.type === "separator",
|
separator: registration.type === "separator",
|
||||||
|
|
||||||
label: computed(() => registration.label || ""),
|
label: computed(() => {
|
||||||
|
if (!registration.label) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isString(registration.label)) {
|
||||||
|
return registration.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return registration.label.get();
|
||||||
|
}),
|
||||||
|
|
||||||
tooltip: registration.toolTip,
|
tooltip: registration.toolTip,
|
||||||
|
|
||||||
click: () => {
|
click: () => {
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
|
|
||||||
export interface TrayMenuRegistration {
|
export interface TrayMenuRegistration {
|
||||||
label?: string;
|
label?: string | IComputedValue<string>;
|
||||||
click?: (menuItem: TrayMenuRegistration) => void;
|
click?: (menuItem: TrayMenuRegistration) => void;
|
||||||
id?: string;
|
id?: string;
|
||||||
type?: "normal" | "separator" | "submenu";
|
type?: "normal" | "separator" | "submenu";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user