diff --git a/docs/custom_theme/main.html b/docs/custom_theme/main.html
index b6ad2467dd..94d9808cc7 100644
--- a/docs/custom_theme/main.html
+++ b/docs/custom_theme/main.html
@@ -1,12 +1 @@
{% extends "base.html" %}
-
-{% block analytics %}
-
-
-
-{% endblock %}
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index fe42cbccf5..7001e41ce5 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -7,6 +7,9 @@ repo_name: GitHub
repo_url: https://github.com/lensapp/lens
copyright: Copyright © 2021 Mirantis Inc. - All rights reserved.
edit_uri: ""
+google_analytics:
+ - UA-159377374-2
+ - auto
nav:
- Overview: README.md
- Getting Started: getting-started/README.md
diff --git a/src/common/__tests__/hotbar-store.test.ts b/src/common/__tests__/hotbar-store.test.ts
index 92e5a3f35b..51002fee23 100644
--- a/src/common/__tests__/hotbar-store.test.ts
+++ b/src/common/__tests__/hotbar-store.test.ts
@@ -20,7 +20,6 @@
*/
import mockFs from "mock-fs";
-import { CatalogEntityItem } from "../../renderer/components/+catalog/catalog-entity.store";
import { ClusterStore } from "../cluster-store";
import { HotbarStore } from "../hotbar-store";
@@ -159,10 +158,9 @@ describe("HotbarStore", () => {
it("adds items", () => {
const hotbarStore = HotbarStore.createInstance();
- const entity = new CatalogEntityItem(testCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(entity);
+ hotbarStore.addToHotbar(testCluster);
const items = hotbarStore.getActive().items.filter(Boolean);
expect(items.length).toEqual(1);
@@ -170,10 +168,9 @@ describe("HotbarStore", () => {
it("removes items", () => {
const hotbarStore = HotbarStore.createInstance();
- const entity = new CatalogEntityItem(testCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(entity);
+ hotbarStore.addToHotbar(testCluster);
hotbarStore.removeFromHotbar("test");
const items = hotbarStore.getActive().items.filter(Boolean);
@@ -182,10 +179,9 @@ describe("HotbarStore", () => {
it("does nothing if removing with invalid uid", () => {
const hotbarStore = HotbarStore.createInstance();
- const entity = new CatalogEntityItem(testCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(entity);
+ hotbarStore.addToHotbar(testCluster);
hotbarStore.removeFromHotbar("invalid uid");
const items = hotbarStore.getActive().items.filter(Boolean);
@@ -194,14 +190,11 @@ describe("HotbarStore", () => {
it("moves item to empty cell", () => {
const hotbarStore = HotbarStore.createInstance();
- const test = new CatalogEntityItem(testCluster);
- const minikube = new CatalogEntityItem(minikubeCluster);
- const aws = new CatalogEntityItem(awsCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(test);
- hotbarStore.addToHotbar(minikube);
- hotbarStore.addToHotbar(aws);
+ hotbarStore.addToHotbar(testCluster);
+ hotbarStore.addToHotbar(minikubeCluster);
+ hotbarStore.addToHotbar(awsCluster);
expect(hotbarStore.getActive().items[5]).toBeNull();
@@ -213,14 +206,11 @@ describe("HotbarStore", () => {
it("moves items down", () => {
const hotbarStore = HotbarStore.createInstance();
- const test = new CatalogEntityItem(testCluster);
- const minikube = new CatalogEntityItem(minikubeCluster);
- const aws = new CatalogEntityItem(awsCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(test);
- hotbarStore.addToHotbar(minikube);
- hotbarStore.addToHotbar(aws);
+ hotbarStore.addToHotbar(testCluster);
+ hotbarStore.addToHotbar(minikubeCluster);
+ hotbarStore.addToHotbar(awsCluster);
// aws -> test
hotbarStore.restackItems(2, 0);
@@ -232,14 +222,11 @@ describe("HotbarStore", () => {
it("moves items up", () => {
const hotbarStore = HotbarStore.createInstance();
- const test = new CatalogEntityItem(testCluster);
- const minikube = new CatalogEntityItem(minikubeCluster);
- const aws = new CatalogEntityItem(awsCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(test);
- hotbarStore.addToHotbar(minikube);
- hotbarStore.addToHotbar(aws);
+ hotbarStore.addToHotbar(testCluster);
+ hotbarStore.addToHotbar(minikubeCluster);
+ hotbarStore.addToHotbar(awsCluster);
// test -> aws
hotbarStore.restackItems(0, 2);
@@ -251,10 +238,9 @@ describe("HotbarStore", () => {
it("does nothing when item moved to same cell", () => {
const hotbarStore = HotbarStore.createInstance();
- const test = new CatalogEntityItem(testCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(test);
+ hotbarStore.addToHotbar(testCluster);
hotbarStore.restackItems(0, 0);
expect(hotbarStore.getActive().items[0].entity.uid).toEqual("test");
@@ -262,15 +248,12 @@ describe("HotbarStore", () => {
it("new items takes first empty cell", () => {
const hotbarStore = HotbarStore.createInstance();
- const test = new CatalogEntityItem(testCluster);
- const minikube = new CatalogEntityItem(minikubeCluster);
- const aws = new CatalogEntityItem(awsCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(test);
- hotbarStore.addToHotbar(aws);
+ hotbarStore.addToHotbar(testCluster);
+ hotbarStore.addToHotbar(awsCluster);
hotbarStore.restackItems(0, 3);
- hotbarStore.addToHotbar(minikube);
+ hotbarStore.addToHotbar(minikubeCluster);
expect(hotbarStore.getActive().items[0].entity.uid).toEqual("minikube");
});
@@ -282,10 +265,9 @@ describe("HotbarStore", () => {
console.error = jest.fn();
const hotbarStore = HotbarStore.createInstance();
- const test = new CatalogEntityItem(testCluster);
hotbarStore.load();
- hotbarStore.addToHotbar(test);
+ hotbarStore.addToHotbar(testCluster);
expect(() => hotbarStore.restackItems(-5, 0)).toThrow();
expect(() => hotbarStore.restackItems(2, -1)).toThrow();
diff --git a/src/common/hotbar-store.ts b/src/common/hotbar-store.ts
index b2d5af0f2a..53c1c5b3ef 100644
--- a/src/common/hotbar-store.ts
+++ b/src/common/hotbar-store.ts
@@ -23,8 +23,8 @@ import { action, comparer, observable, toJS } from "mobx";
import { BaseStore } from "./base-store";
import migrations from "../migrations/hotbar-store";
import * as uuid from "uuid";
-import { CatalogEntityItem } from "../renderer/components/+catalog/catalog-entity.store";
import isNull from "lodash/isNull";
+import { CatalogEntity } from "./catalog";
export interface HotbarItem {
entity: {
@@ -151,15 +151,15 @@ export class HotbarStore extends BaseStore {
}
@action
- addToHotbar(item: CatalogEntityItem, cellIndex = -1) {
+ addToHotbar(item: CatalogEntity, cellIndex = -1) {
const hotbar = this.getActive();
const newItem = { entity: {
- uid: item.id,
- name: item.name,
- source: item.source
+ uid: item.metadata.uid,
+ name: item.metadata.name,
+ source: item.metadata.source
}};
- if (hotbar.items.find(i => i?.entity.uid === item.id)) {
+ if (hotbar.items.find(i => i?.entity.uid === item.metadata.uid)) {
return;
}
diff --git a/src/renderer/components/+catalog/catalog.tsx b/src/renderer/components/+catalog/catalog.tsx
index cb5d16fbfb..63239eb5d1 100644
--- a/src/renderer/components/+catalog/catalog.tsx
+++ b/src/renderer/components/+catalog/catalog.tsx
@@ -67,7 +67,7 @@ export class Catalog extends React.Component {
}
addToHotbar(item: CatalogEntityItem): void {
- HotbarStore.getInstance().addToHotbar(item);
+ HotbarStore.getInstance().addToHotbar(item.entity);
}
onDetails(item: CatalogEntityItem) {
@@ -143,7 +143,7 @@ export class Catalog extends React.Component {
))
}
);
diff --git a/src/renderer/components/hotbar/hotbar-entity-icon.tsx b/src/renderer/components/hotbar/hotbar-entity-icon.tsx
index 7e2b7f79bf..41b0a69da0 100644
--- a/src/renderer/components/hotbar/hotbar-entity-icon.tsx
+++ b/src/renderer/components/hotbar/hotbar-entity-icon.tsx
@@ -18,26 +18,26 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-import "./hotbar-icon.scss";
import React, { DOMAttributes } from "react";
import { observable } from "mobx";
import { observer } from "mobx-react";
-import randomColor from "randomcolor";
-import { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog";
+import { CatalogEntity, CatalogEntityContextMenuContext } from "../../../common/catalog";
import { catalogCategoryRegistry } from "../../api/catalog-category-registry";
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
import { navigate } from "../../navigation";
import { cssNames, IClassName } from "../../utils";
-import { ConfirmDialog } from "../confirm-dialog";
import { Icon } from "../icon";
import { HotbarIcon } from "./hotbar-icon";
+import { HotbarStore } from "../../../common/hotbar-store";
interface Props extends DOMAttributes {
entity: CatalogEntity;
+ index: number;
className?: IClassName;
errorClass?: IClassName;
+ add: (item: CatalogEntity, index: number) => void;
remove: (uid: string) => void;
}
@@ -77,33 +77,18 @@ export class HotbarEntityIcon extends React.Component {
return catalogEntityRegistry.activeEntity?.metadata?.uid == item.getId();
}
- onMenuItemClick(menuItem: CatalogEntityContextMenu) {
- if (menuItem.confirm) {
- ConfirmDialog.open({
- okButtonProps: {
- primary: false,
- accent: true,
- },
- ok: () => {
- menuItem.onClick();
- },
- message: menuItem.confirm.message
- });
- } else {
- menuItem.onClick();
- }
- }
-
- generateAvatarStyle(entity: CatalogEntity): React.CSSProperties {
- return {
- "backgroundColor": randomColor({ seed: `${entity.metadata.name}-${entity.metadata.source}`, luminosity: "dark" })
- };
+ isPersisted(entity: CatalogEntity) {
+ return HotbarStore.getInstance().getActive().items.find((item) => item?.entity?.uid === entity.metadata.uid) !== undefined;
}
render() {
+ if (!this.contextMenu) {
+ return null;
+ }
+
const {
- entity, errorClass, remove,
- children, ...elemProps
+ entity, errorClass, add, remove,
+ index, children, ...elemProps
} = this.props;
const className = cssNames("HotbarEntityIcon", this.props.className, {
interactive: true,
@@ -113,16 +98,29 @@ export class HotbarEntityIcon extends React.Component {
const onOpen = async () => {
await entity.onContextMenuOpen(this.contextMenu);
};
+ const isActive = this.isActive(entity);
+ const isPersisted = this.isPersisted(entity);
const menuItems = this.contextMenu?.menuItems.filter((menuItem) => !menuItem.onlyVisibleForSource || menuItem.onlyVisibleForSource === entity.metadata.source);
+ if (!isPersisted) {
+ menuItems.unshift({
+ title: "Pin to Hotbar",
+ onClick: () => add(entity, index)
+ });
+ } else {
+ menuItems.unshift({
+ title: "Unpin from Hotbar",
+ onClick: () => remove(entity.metadata.uid)
+ });
+ }
+
return (
.led {
+ div.MuiAvatar-root {
+ &.active {
+ box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent);
+ transition: all 0s 0.8s;
+ }
+
+ &:hover {
+ &:not(.active) {
+ box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff30;
+ }
+ }
+ }
+
+ .led {
position: absolute;
left: 3px;
top: 3px;
diff --git a/src/renderer/components/hotbar/hotbar-icon.tsx b/src/renderer/components/hotbar/hotbar-icon.tsx
index ecfa4dce0a..ddfa512dcd 100644
--- a/src/renderer/components/hotbar/hotbar-icon.tsx
+++ b/src/renderer/components/hotbar/hotbar-icon.tsx
@@ -31,12 +31,12 @@ import { cssNames, IClassName, iter } from "../../utils";
import { ConfirmDialog } from "../confirm-dialog";
import { Menu, MenuItem } from "../menu";
import { MaterialTooltip } from "../+catalog/material-tooltip/material-tooltip";
+import { observer } from "mobx-react";
interface Props extends DOMAttributes {
uid: string;
title: string;
source: string;
- remove: (uid: string) => void;
onMenuOpen?: () => void;
className?: IClassName;
active?: boolean;
@@ -83,8 +83,8 @@ function getNameParts(name: string): string[] {
return name.split(/@+/);
}
-export function HotbarIcon(props: Props) {
- const { uid, title, className, source, active, remove, disabled, menuItems, onMenuOpen, children, ...rest } = props;
+export const HotbarIcon = observer(({menuItems = [], ...props}: Props) => {
+ const { uid, title, active, className, source, disabled, onMenuOpen, children, ...rest } = props;
const id = `hotbarIcon-${uid}`;
const [menuOpen, setMenuOpen] = useState(false);
@@ -133,12 +133,6 @@ export function HotbarIcon(props: Props) {
toggleMenu();
}}
close={() => toggleMenu()}>
-
{ menuItems.map((menuItem) => {
return (