1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Cleanup and fix activate-entity

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2021-10-05 14:40:25 -04:00
parent c264d5f1e2
commit 87babc8f2c
10 changed files with 56 additions and 79 deletions

View File

@ -230,7 +230,7 @@ export abstract class CatalogEntity<
return this.metadata.name; return this.metadata.name;
} }
public abstract onRun?(context: CatalogEntityActionContext): void | Promise<void>; public abstract onRun(context: CatalogEntityActionContext): void | Promise<void>;
public abstract onContextMenuOpen(context: CatalogEntityContextMenuContext): void | Promise<void>; public abstract onContextMenuOpen(context: CatalogEntityContextMenuContext): void | Promise<void>;
public abstract onSettingsOpen(context: CatalogEntitySettingsContext): void | Promise<void>; public abstract onSettingsOpen(context: CatalogEntitySettingsContext): void | Promise<void>;
} }

View File

@ -23,6 +23,7 @@
import type { CatalogCategory, CatalogEntity } from "../../common/catalog"; import type { CatalogCategory, CatalogEntity } from "../../common/catalog";
import { catalogEntityRegistry as registry } from "../../renderer/api/catalog-entity-registry"; import { catalogEntityRegistry as registry } from "../../renderer/api/catalog-entity-registry";
import type { CatalogEntityOnBeforeRun } from "../../renderer/api/catalog-entity-registry"; import type { CatalogEntityOnBeforeRun } from "../../renderer/api/catalog-entity-registry";
import type { Disposer } from "../../common/utils";
export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog/catalog-category-registry"; export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog/catalog-category-registry";
export class CatalogEntityRegistry { export class CatalogEntityRegistry {
@ -50,21 +51,14 @@ export class CatalogEntityRegistry {
} }
/** /**
* Add a onBeforeRun hook to a catalog entity. * Add a onRun hook to a catalog entity. If `onBeforeRun` was previously added then it will not be added again
* @param catalogEntityUid The uid of the catalog entity * @param catalogEntityUid The uid of the catalog entity
* @param onBeforeRun The function that should return a boolean if the onBeforeRun of catalog entity should be triggered. * @param onBeforeRun The function that should return a boolean if the onRun of catalog entity should be triggered.
* @returns A function to remove that hook * @returns A function to remove that hook
*/ */
addOnBeforeRun(entity: CatalogEntity, onBeforeRun: CatalogEntityOnBeforeRun) { addOnBeforeRun(entity: CatalogEntity, onBeforeRun: CatalogEntityOnBeforeRun): Disposer {
return registry.addOnBeforeRun(entity, onBeforeRun); return registry.addOnBeforeRun(entity, onBeforeRun);
} }
/**
* Returns one catalog entity onBeforeRun by catalog entity uid
*/
onBeforeRun(entity: CatalogEntity): Promise<boolean> {
return registry.onBeforeRun(entity);
}
} }
export const catalogEntities = new CatalogEntityRegistry(); export const catalogEntities = new CatalogEntityRegistry();

View File

@ -229,6 +229,10 @@ export class CatalogEntityRegistry {
return true; return true;
} }
/**
* Perform the onBeforeRun check and, if successful, then proceed to call `entity`'s onRun method
* @param entity The instance to invoke the hooks and then execute the onRun
*/
onRun(entity: CatalogEntity): void { onRun(entity: CatalogEntity): void {
this.onBeforeRun(entity) this.onBeforeRun(entity)
.then(doOnRun => { .then(doOnRun => {

View File

@ -34,7 +34,6 @@ import { isDevelopment } from "../../../common/vars";
interface Props<T extends CatalogEntity> { interface Props<T extends CatalogEntity> {
item: CatalogEntityItem<T> | null | undefined; item: CatalogEntityItem<T> | null | undefined;
hideDetails(): void; hideDetails(): void;
onClickDetailPanelIcon: (catalogEntitiyItem: CatalogEntityItem<T>) => void;
} }
@observer @observer
@ -68,9 +67,7 @@ export class CatalogEntityDetails<T extends CatalogEntity> extends Component<Pro
material={item.entity.spec.icon?.material} material={item.entity.spec.icon?.material}
background={item.entity.spec.icon?.background} background={item.entity.spec.icon?.background}
disabled={!item?.enabled} disabled={!item?.enabled}
onClick={() => { onClick={() => item.onRun()}
this.props.onClickDetailPanelIcon(item);
}}
size={128} size={128}
data-testid="detail-panel-hot-bar-icon" data-testid="detail-panel-hot-bar-icon"
/> />

View File

@ -21,18 +21,19 @@
import styles from "./catalog.module.css"; import styles from "./catalog.module.css";
import React from "react"; import React from "react";
import { action, computed } from "mobx"; import { action, computed } from "mobx";
import type { CatalogEntity, CatalogEntityActionContext } from "../../api/catalog-entity"; import type { CatalogEntity } from "../../api/catalog-entity";
import type { ItemObject } from "../../../common/item.store"; import type { ItemObject } from "../../../common/item.store";
import { Badge } from "../badge"; import { Badge } from "../badge";
import { navigation } from "../../navigation"; import { navigation } from "../../navigation";
import { searchUrlParam } from "../input"; import { searchUrlParam } from "../input";
import { makeCss } from "../../../common/utils/makeCss"; import { makeCss } from "../../../common/utils/makeCss";
import { KubeObject } from "../../../common/k8s-api/kube-object"; import { KubeObject } from "../../../common/k8s-api/kube-object";
import type { CatalogEntityRegistry } from "../../api/catalog-entity-registry";
const css = makeCss(styles); const css = makeCss(styles);
export class CatalogEntityItem<T extends CatalogEntity> implements ItemObject { export class CatalogEntityItem<T extends CatalogEntity> implements ItemObject {
constructor(public entity: T) {} constructor(public entity: T, private registry: CatalogEntityRegistry) {}
get kind() { get kind() {
return this.entity.kind; return this.entity.kind;
@ -102,8 +103,8 @@ export class CatalogEntityItem<T extends CatalogEntity> implements ItemObject {
]; ];
} }
onRun(ctx: CatalogEntityActionContext) { onRun() {
this.entity.onRun(ctx); this.registry.onRun(this.entity);
} }
@action @action

View File

@ -39,20 +39,16 @@ export class CatalogEntityStore extends ItemStore<CatalogEntityItem<CatalogEntit
@computed get entities() { @computed get entities() {
if (!this.activeCategory) { if (!this.activeCategory) {
return this.registry.filteredItems.map(entity => new CatalogEntityItem(entity)); return this.registry.filteredItems.map(entity => new CatalogEntityItem(entity, this.registry));
} }
return this.registry.getItemsForCategory(this.activeCategory, { filtered: true }).map(entity => new CatalogEntityItem(entity)); return this.registry.getItemsForCategory(this.activeCategory, { filtered: true }).map(entity => new CatalogEntityItem(entity, this.registry));
} }
@computed get selectedItem() { @computed get selectedItem() {
return this.entities.find(e => e.getId() === this.selectedItemId); return this.entities.find(e => e.getId() === this.selectedItemId);
} }
onRun(entity: CatalogEntity): void {
this.registry.onRun(entity);
}
watch() { watch() {
return disposer( return disposer(
reaction(() => this.entities, () => this.loadAll()), reaction(() => this.entities, () => this.loadAll()),

View File

@ -41,11 +41,15 @@ function getCategories() {
} }
function getCategoryIcon(category: CatalogCategory) { function getCategoryIcon(category: CatalogCategory) {
if (!category.metadata?.icon) return null; const { icon } = category.metadata ?? {};
return category.metadata.icon.includes?.("<svg") if (typeof icon === "string") {
? <Icon small svg={category.metadata.icon}/> return icon.includes("<svg")
: <Icon small material={category.metadata.icon}/>; ? <Icon small svg={icon}/>
: <Icon small material={icon}/>;
}
return null;
} }
function Item(props: TreeItemProps) { function Item(props: TreeItemProps) {

View File

@ -113,16 +113,15 @@ describe("<Catalog />", () => {
}); });
it("can use catalogEntityRegistry.addOnBeforeRun to add hooks for catalog entities", (done) => { it("can use catalogEntityRegistry.addOnBeforeRun to add hooks for catalog entities", (done) => {
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
const onRun = jest.fn(); const onRun = jest.fn();
const catalogEntityItem = new CatalogEntityItem({ const catalogEntityItem = new CatalogEntityItem({
...catalogEntity, ...catalogEntity,
...catalogEntityItemMethods, ...catalogEntityItemMethods,
onRun, onRun,
}); }, catalogEntityRegistry);
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
// mock as if there is a selected item > the detail panel opens // mock as if there is a selected item > the detail panel opens
jest jest
@ -178,16 +177,15 @@ describe("<Catalog />", () => {
}); });
it("onBeforeRun return false => onRun wont be triggered", (done) => { it("onBeforeRun return false => onRun wont be triggered", (done) => {
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
const onRun = jest.fn(); const onRun = jest.fn();
const catalogEntityItem = new CatalogEntityItem({ const catalogEntityItem = new CatalogEntityItem({
...catalogEntity, ...catalogEntity,
...catalogEntityItemMethods, ...catalogEntityItemMethods,
onRun, onRun,
}); }, catalogEntityRegistry);
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
// mock as if there is a selected item > the detail panel opens // mock as if there is a selected item > the detail panel opens
jest jest
@ -219,16 +217,15 @@ describe("<Catalog />", () => {
}); });
it("addOnBeforeRun throw an exception => onRun wont be triggered", (done) => { it("addOnBeforeRun throw an exception => onRun wont be triggered", (done) => {
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
const onRun = jest.fn(); const onRun = jest.fn();
const catalogEntityItem = new CatalogEntityItem({ const catalogEntityItem = new CatalogEntityItem({
...catalogEntity, ...catalogEntity,
...catalogEntityItemMethods, ...catalogEntityItemMethods,
onRun, onRun,
}); }, catalogEntityRegistry);
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
// mock as if there is a selected item > the detail panel opens // mock as if there is a selected item > the detail panel opens
jest jest
@ -260,21 +257,15 @@ describe("<Catalog />", () => {
}); });
it("addOnRunHook return a promise and resolve true => onRun()", (done) => { it("addOnRunHook return a promise and resolve true => onRun()", (done) => {
let onRunTriggered = false; const catalogCategoryRegistry = new CatalogCategoryRegistry();
const onRun = () => { const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
onRunTriggered = true; const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
expect(onRunTriggered).toBeTruthy(); const onRun = jest.fn(() => done());
done();
};
const catalogEntityItem = new CatalogEntityItem({ const catalogEntityItem = new CatalogEntityItem({
...catalogEntity, ...catalogEntity,
...catalogEntityItemMethods, ...catalogEntityItemMethods,
onRun, onRun,
}); }, catalogEntityRegistry);
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
// mock as if there is a selected item > the detail panel opens // mock as if there is a selected item > the detail panel opens
jest jest
@ -301,19 +292,15 @@ describe("<Catalog />", () => {
}); });
it("addOnRunHook return a promise and resolve false => onRun() wont be triggered", (done) => { it("addOnRunHook return a promise and resolve false => onRun() wont be triggered", (done) => {
let onRunTriggered = false; const catalogCategoryRegistry = new CatalogCategoryRegistry();
const onRun = () => { const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
onRunTriggered = true; const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
}; const onRun = jest.fn();
const catalogEntityItem = new CatalogEntityItem({ const catalogEntityItem = new CatalogEntityItem({
...catalogEntity, ...catalogEntity,
...catalogEntityItemMethods, ...catalogEntityItemMethods,
onRun, onRun,
}); }, catalogEntityRegistry);
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
// mock as if there is a selected item > the detail panel opens // mock as if there is a selected item > the detail panel opens
jest jest
@ -323,10 +310,10 @@ describe("<Catalog />", () => {
catalogEntityRegistry.addOnBeforeRun( catalogEntityRegistry.addOnBeforeRun(
catalogEntityUid, catalogEntityUid,
async () => { async () => {
expect(onRunTriggered).toBeFalsy(); expect(onRun).not.toBeCalled();
setTimeout(() => { setTimeout(() => {
expect(onRunTriggered).toBeFalsy(); expect(onRun).not.toBeCalled();
done(); done();
}, 500); }, 500);
@ -347,16 +334,15 @@ describe("<Catalog />", () => {
}); });
it("addOnRunHook return a promise and reject => onRun wont be triggered", (done) => { it("addOnRunHook return a promise and reject => onRun wont be triggered", (done) => {
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
const onRun = jest.fn(); const onRun = jest.fn();
const catalogEntityItem = new CatalogEntityItem({ const catalogEntityItem = new CatalogEntityItem({
...catalogEntity, ...catalogEntity,
...catalogEntityItemMethods, ...catalogEntityItemMethods,
onRun, onRun,
}); }, catalogEntityRegistry);
const catalogCategoryRegistry = new CatalogCategoryRegistry();
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
// mock as if there is a selected item > the detail panel opens // mock as if there is a selected item > the detail panel opens
jest jest

View File

@ -133,14 +133,10 @@ export class Catalog extends React.Component<Props> {
if (this.catalogEntityStore.selectedItemId) { if (this.catalogEntityStore.selectedItemId) {
this.catalogEntityStore.selectedItemId = null; this.catalogEntityStore.selectedItemId = null;
} else { } else {
this.catalogEntityStore.onRun(item.entity); item.onRun();
} }
}; };
onClickDetailPanelIcon = (item: CatalogEntityItem<CatalogEntity>) => {
this.catalogEntityStore.onRun(item.entity);
};
onMenuItemClick(menuItem: CatalogEntityContextMenu) { onMenuItemClick(menuItem: CatalogEntityContextMenu) {
if (menuItem.confirm) { if (menuItem.confirm) {
ConfirmDialog.open({ ConfirmDialog.open({
@ -286,7 +282,6 @@ export class Catalog extends React.Component<Props> {
? <CatalogEntityDetails ? <CatalogEntityDetails
item={this.catalogEntityStore.selectedItem} item={this.catalogEntityStore.selectedItem}
hideDetails={() => this.catalogEntityStore.selectedItemId = null} hideDetails={() => this.catalogEntityStore.selectedItemId = null}
onClickDetailPanelIcon={this.onClickDetailPanelIcon}
/> />
: ( : (
<RenderDelay> <RenderDelay>

View File

@ -22,7 +22,7 @@
import { computed } from "mobx"; import { computed } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import React from "react"; import React from "react";
import { CatalogEntity, catalogEntityRunContext } from "../../api/catalog-entity"; import type { CatalogEntity } from "../../api/catalog-entity";
import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
import { CommandOverlay } from "../command-palette"; import { CommandOverlay } from "../command-palette";
import { Select } from "../select"; import { Select } from "../select";
@ -37,7 +37,7 @@ export class ActivateEntityCommand extends React.Component {
} }
onSelect(entity: CatalogEntity): void { onSelect(entity: CatalogEntity): void {
entity.onRun?.(catalogEntityRunContext); catalogEntityRegistry.onRun(entity);
CommandOverlay.close(); CommandOverlay.close();
} }