From 66330485b17c3ffe3f8eda962c1e016e8632e1ff Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Wed, 6 Apr 2022 14:28:07 +0300 Subject: [PATCH 1/3] Fix broken hotbar switcher (#5182) * Getting this context for switch hotbar methods Signed-off-by: Alex Andreev * Do not convert store methods to arrow functions Signed-off-by: Alex Andreev --- .../components/hotbar/hotbar-selector.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/renderer/components/hotbar/hotbar-selector.tsx b/src/renderer/components/hotbar/hotbar-selector.tsx index 59e39605e2..d3d6b314e0 100644 --- a/src/renderer/components/hotbar/hotbar-selector.tsx +++ b/src/renderer/components/hotbar/hotbar-selector.tsx @@ -44,9 +44,14 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv tooltipTimeout.current = setTimeout(() => setTooltipVisible(false), 1500); } - function onArrowClick(switchTo: () => void) { + function onPrevClick() { onTooltipShow(); - switchTo(); + hotbarStore.switchToPrevious(); + } + + function onNextClick() { + onTooltipShow(); + hotbarStore.switchToNext(); } function onMouseEvent(event: React.MouseEvent) { @@ -56,11 +61,7 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv return (
- onArrowClick(hotbarStore.switchToPrevious)} - /> +
- onArrowClick(hotbarStore.switchToNext)} /> +
); }); From ca21e0842a87d29a339cacbd9ba724e28209e4f7 Mon Sep 17 00:00:00 2001 From: Panu Horsmalahti Date: Wed, 6 Apr 2022 15:20:41 +0300 Subject: [PATCH 2/3] Add optional badge to Catalog Category label (#5156) * Add optional badge to Catalog Category label. Signed-off-by: Panu Horsmalahti * Don't render badge container if there is no badge. Change CatalogCategoryLabel interface. Signed-off-by: Panu Horsmalahti * Add badgeBackgroundColor CSS variable for extensions. Regenerate theme-vars.css. Signed-off-by: Panu Horsmalahti * Use category as prop in CatalogCategoryLabel Signed-off-by: Panu Horsmalahti --- ...entity.test.ts => catalog-entity.test.tsx} | 25 ++++++++- src/common/catalog/catalog-entity.ts | 9 ++++ .../__tests__/catalog-category-label.test.tsx | 53 +++++++++++++++++++ .../+catalog/catalog-category-label.tsx | 24 +++++++++ .../components/+catalog/catalog-menu.tsx | 3 +- src/renderer/themes/lens-dark.json | 1 + src/renderer/themes/lens-light.json | 1 + src/renderer/themes/theme-vars.css | 5 +- 8 files changed, 117 insertions(+), 4 deletions(-) rename src/common/__tests__/{catalog-entity.test.ts => catalog-entity.test.tsx} (52%) create mode 100644 src/renderer/components/+catalog/__tests__/catalog-category-label.test.tsx create mode 100644 src/renderer/components/+catalog/catalog-category-label.tsx diff --git a/src/common/__tests__/catalog-entity.test.ts b/src/common/__tests__/catalog-entity.test.tsx similarity index 52% rename from src/common/__tests__/catalog-entity.test.ts rename to src/common/__tests__/catalog-entity.test.tsx index 3785ed1d49..e6d2e939c7 100644 --- a/src/common/__tests__/catalog-entity.test.ts +++ b/src/common/__tests__/catalog-entity.test.tsx @@ -3,15 +3,18 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ +import React from "react"; import { CatalogCategory, CatalogCategorySpec } from "../catalog"; -class TestCatalogCategory extends CatalogCategory { +class TestCatalogCategoryWithoutBadge extends CatalogCategory { public readonly apiVersion = "catalog.k8slens.dev/v1alpha1"; public readonly kind = "CatalogCategory"; + public metadata = { name: "Test Category", icon: "", }; + public spec: CatalogCategorySpec = { group: "entity.k8slens.dev", versions: [], @@ -21,10 +24,28 @@ class TestCatalogCategory extends CatalogCategory { }; } +class TestCatalogCategoryWithBadge extends TestCatalogCategoryWithoutBadge { + getBadge() { + return (
Test Badge
); + } +} + describe("CatalogCategory", () => { it("returns name", () => { - const category = new TestCatalogCategory(); + const category = new TestCatalogCategoryWithoutBadge(); expect(category.getName()).toEqual("Test Category"); }); + + it("doesn't return badge by default", () => { + const category = new TestCatalogCategoryWithoutBadge(); + + expect(category.getBadge()).toEqual(null); + }); + + it("returns a badge", () => { + const category = new TestCatalogCategoryWithBadge(); + + expect(category.getBadge()).toBeTruthy(); + }); }); diff --git a/src/common/catalog/catalog-entity.ts b/src/common/catalog/catalog-entity.ts index 2704bed2e0..7bc396d377 100644 --- a/src/common/catalog/catalog-entity.ts +++ b/src/common/catalog/catalog-entity.ts @@ -180,6 +180,15 @@ export abstract class CatalogCategory extends (EventEmitter as new () => TypedEm return this.metadata.name; } + /** + * Get the badge of this category. + * Defaults to no badge. + * The badge is displayed next to the Category name in the Catalog Category menu + */ + public getBadge(): React.ReactNode { + return null; + } + /** * Add a filter for menu items of catalogAddMenu * @param fn The function that should return a truthy value if that menu item should be displayed diff --git a/src/renderer/components/+catalog/__tests__/catalog-category-label.test.tsx b/src/renderer/components/+catalog/__tests__/catalog-category-label.test.tsx new file mode 100644 index 0000000000..015929b643 --- /dev/null +++ b/src/renderer/components/+catalog/__tests__/catalog-category-label.test.tsx @@ -0,0 +1,53 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { render, screen } from "@testing-library/react"; +import React from "react"; +import "@testing-library/jest-dom/extend-expect"; +import { CatalogCategory, CatalogCategorySpec } from "../../../../common/catalog"; +import { CatalogCategoryLabel } from "../catalog-category-label"; + +class CatalogCategoryWithoutBadge extends CatalogCategory { + public readonly apiVersion = "catalog.k8slens.dev/v1alpha1"; + public readonly kind = "CatalogCategory"; + + public metadata = { + name: "Test Category", + icon: "", + }; + + public spec: CatalogCategorySpec = { + group: "entity.k8slens.dev", + versions: [], + names: { + kind: "Test", + }, + }; +} + +class CatalogCategoryWithBadge extends CatalogCategoryWithoutBadge { + getBadge() { + return (
Test Badge
); + } +} + +describe("CatalogCategoryLabel", () => { + it("renders without a badge", async () => { + const category = new CatalogCategoryWithoutBadge(); + + render(); + + expect(await screen.findByText("Test Category")).toBeInTheDocument(); + }); + + it("renders with a badge", async () => { + const category = new CatalogCategoryWithBadge(); + + render(); + + expect(await screen.findByText("Test Category")).toBeInTheDocument(); + expect(await screen.findByText("Test Badge")).toBeInTheDocument(); + }); +}); diff --git a/src/renderer/components/+catalog/catalog-category-label.tsx b/src/renderer/components/+catalog/catalog-category-label.tsx new file mode 100644 index 0000000000..170d8e92b6 --- /dev/null +++ b/src/renderer/components/+catalog/catalog-category-label.tsx @@ -0,0 +1,24 @@ +/** + * 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 { CatalogCategory } from "../../../common/catalog/catalog-entity"; + +interface CatalogCategoryLabelProps { + category: CatalogCategory; +} + +/** + * Display label for Catalog Category for the Catalog menu + */ +export const CatalogCategoryLabel = ({ category }: CatalogCategoryLabelProps) => { + const badge = category.getBadge(); + + return ( +
+
{category.metadata.name}
+ {badge ? (
{badge}
) : null} +
+ ); +}; diff --git a/src/renderer/components/+catalog/catalog-menu.tsx b/src/renderer/components/+catalog/catalog-menu.tsx index 2cc543c25f..36590b82a8 100644 --- a/src/renderer/components/+catalog/catalog-menu.tsx +++ b/src/renderer/components/+catalog/catalog-menu.tsx @@ -14,6 +14,7 @@ import { StylesProvider } from "@material-ui/core"; import { cssNames } from "../../utils"; import type { CatalogCategory } from "../../api/catalog-entity"; import { observer } from "mobx-react"; +import { CatalogCategoryLabel } from "./catalog-category-label"; export interface CatalogMenuProps { activeItem: string; @@ -66,7 +67,7 @@ export const CatalogMenu = observer((props: CatalogMenuProps) => { icon={getCategoryIcon(category)} key={category.getId()} nodeId={category.getId()} - label={category.metadata.name} + label={} data-testid={`${category.getId()}-tab`} onClick={() => props.onItemClick(category.getId())} /> diff --git a/src/renderer/themes/lens-dark.json b/src/renderer/themes/lens-dark.json index f30d48197e..f0b8a97282 100644 --- a/src/renderer/themes/lens-dark.json +++ b/src/renderer/themes/lens-dark.json @@ -29,6 +29,7 @@ "sidebarActiveColor": "#ffffff", "sidebarSubmenuActiveColor": "#ffffff", "sidebarItemHoverBackground": "#3a3e44", + "badgeBackgroundColor": "#ffba44", "buttonPrimaryBackground": "#3d90ce", "buttonDefaultBackground": "#414448", "buttonLightBackground": "#f1f1f1", diff --git a/src/renderer/themes/lens-light.json b/src/renderer/themes/lens-light.json index 06ef6d79b2..d240d7df8a 100644 --- a/src/renderer/themes/lens-light.json +++ b/src/renderer/themes/lens-light.json @@ -29,6 +29,7 @@ "sidebarSubmenuActiveColor": "#3d90ce", "sidebarBackground": "#e8e8e8", "sidebarItemHoverBackground": "#f0f2f5", + "badgeBackgroundColor": "#ffba44", "buttonPrimaryBackground": "#3d90ce", "buttonDefaultBackground": "#414448", "buttonLightBackground": "#f1f1f1", diff --git a/src/renderer/themes/theme-vars.css b/src/renderer/themes/theme-vars.css index e0a695b72d..ffae94e401 100644 --- a/src/renderer/themes/theme-vars.css +++ b/src/renderer/themes/theme-vars.css @@ -29,6 +29,7 @@ --sidebarActiveColor: #ffffff; --sidebarSubmenuActiveColor: #ffffff; --sidebarItemHoverBackground: #3a3e44; +--badgeBackgroundColor: #ffba44; --buttonPrimaryBackground: #3d90ce; --buttonDefaultBackground: #414448; --buttonLightBackground: #f1f1f1; @@ -73,6 +74,8 @@ --dockEditorComment: #808080; --dockEditorActiveLineBackground: #3a3d41; --dockBadgeBackground: #36393e; +--dockTabBorderColor: #43424d; +--dockTabActiveBackground: #3a3e45; --logsBackground: #000000; --logsForeground: #ffffff; --logRowHoverBackground: #35373a; @@ -125,7 +128,7 @@ --inputControlHoverBorder: #474a4f; --lineProgressBackground: #414448; --radioActiveBackground: #36393e; ---menuActiveBackground: #36393e; +--menuActiveBackground: #3d90ce; --menuSelectedOptionBgc: #36393e; --canvasBackground: #24292e; --scrollBarColor: #5f6064; From 93a8d0f157fb707b0e86a5b566f05a10462802b5 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Wed, 6 Apr 2022 16:44:14 +0300 Subject: [PATCH 3/3] Do not render Tooltip and Menu elements until needed (#5168) * Clean up Menu DOM elements Signed-off-by: Alex Andreev * Clean up Tooltip DOM Signed-off-by: Alex Andreev * Do not render Animate when not in need Signed-off-by: Alex Andreev * Update snapshots Signed-off-by: Alex Andreev * clean up and Signed-off-by: Roman Co-authored-by: Roman --- src/renderer/components/animate/animate.tsx | 10 +- .../kube-object-menu.test.tsx.snap | 4 - .../kube-object-status-icon.test.tsx.snap | 216 ------------------ src/renderer/components/menu/menu.tsx | 5 +- src/renderer/components/tooltip/tooltip.tsx | 30 ++- 5 files changed, 31 insertions(+), 234 deletions(-) diff --git a/src/renderer/components/animate/animate.tsx b/src/renderer/components/animate/animate.tsx index f8bbd9b137..df160883fb 100644 --- a/src/renderer/components/animate/animate.tsx +++ b/src/renderer/components/animate/animate.tsx @@ -83,19 +83,23 @@ export class Animate extends React.Component { } render() { + if (!this.isVisible) { + return null; + } + const { name, enterDuration, leaveDuration } = this.props; const contentElem = this.contentElem; - const durations = { + const cssVarsForAnimation = { "--enter-duration": `${enterDuration}ms`, "--leave-duration": `${leaveDuration}ms`, } as React.CSSProperties; return React.cloneElement(contentElem, { className: cssNames("Animate", name, contentElem.props.className, this.statusClassName), - children: this.isVisible ? contentElem.props.children : null, + children: contentElem.props.children, style: { ...contentElem.props.style, - ...durations, + ...cssVarsForAnimation, }, }); } diff --git a/src/renderer/components/kube-object-menu/__snapshots__/kube-object-menu.test.tsx.snap b/src/renderer/components/kube-object-menu/__snapshots__/kube-object-menu.test.tsx.snap index 0d1d591668..b0200f73d5 100644 --- a/src/renderer/components/kube-object-menu/__snapshots__/kube-object-menu.test.tsx.snap +++ b/src/renderer/components/kube-object-menu/__snapshots__/kube-object-menu.test.tsx.snap @@ -37,10 +37,6 @@ exports[`kube-object-menu given kube object renders 1`] = ` -