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/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/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)} />
+
);
});
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`] = `
-