mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
hotbar context menu & command palette
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
92c1d73700
commit
1f8b388bd4
@ -38,6 +38,7 @@ export type CatalogEntityStatus = {
|
||||
|
||||
export interface CatalogEntityActionContext {
|
||||
navigate: (url: string) => void;
|
||||
setCommandPaletteContext: (context?: CatalogEntity) => void;
|
||||
}
|
||||
|
||||
export type CatalogEntityContextMenu = {
|
||||
@ -46,7 +47,8 @@ export type CatalogEntityContextMenu = {
|
||||
onClick: () => Promise<void>;
|
||||
};
|
||||
|
||||
export interface CatalogEntityContextMenuContext extends CatalogEntityActionContext {
|
||||
export interface CatalogEntityContextMenuContext {
|
||||
navigate: (url: string) => void;
|
||||
menuItems: CatalogEntityContextMenu[];
|
||||
}
|
||||
|
||||
|
||||
@ -213,7 +213,6 @@ export class ExtensionLoader {
|
||||
registries.globalPageRegistry.add(extension.globalPages, extension),
|
||||
registries.globalPageMenuRegistry.add(extension.globalPageMenus, extension),
|
||||
registries.appPreferenceRegistry.add(extension.appPreferences),
|
||||
registries.clusterFeatureRegistry.add(extension.clusterFeatures),
|
||||
registries.statusBarRegistry.add(extension.statusBarItems),
|
||||
registries.commandRegistry.add(extension.commands),
|
||||
];
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
export type { AppPreferenceRegistration, AppPreferenceComponents } from "../registries/app-preference-registry";
|
||||
export type { ClusterFeatureRegistration, ClusterFeatureComponents } from "../registries/cluster-feature-registry";
|
||||
export type { KubeObjectDetailRegistration, KubeObjectDetailComponents } from "../registries/kube-object-detail-registry";
|
||||
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../registries/kube-object-menu-registry";
|
||||
export type { KubeObjectStatusRegistration } from "../registries/kube-object-status-registry";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { AppPreferenceRegistration, ClusterFeatureRegistration, ClusterPageMenuRegistration, KubeObjectDetailRegistration, KubeObjectMenuRegistration, KubeObjectStatusRegistration, PageMenuRegistration, PageRegistration, StatusBarRegistration, } from "./registries";
|
||||
import type { AppPreferenceRegistration, ClusterPageMenuRegistration, KubeObjectDetailRegistration, KubeObjectMenuRegistration, KubeObjectStatusRegistration, PageMenuRegistration, PageRegistration, StatusBarRegistration, } from "./registries";
|
||||
import type { Cluster } from "../main/cluster";
|
||||
import { LensExtension } from "./lens-extension";
|
||||
import { getExtensionPageUrl } from "./registries/page-registry";
|
||||
@ -11,7 +11,6 @@ export class LensRendererExtension extends LensExtension {
|
||||
clusterPageMenus: ClusterPageMenuRegistration[] = [];
|
||||
kubeObjectStatusTexts: KubeObjectStatusRegistration[] = [];
|
||||
appPreferences: AppPreferenceRegistration[] = [];
|
||||
clusterFeatures: ClusterFeatureRegistration[] = [];
|
||||
statusBarItems: StatusBarRegistration[] = [];
|
||||
kubeObjectDetailItems: KubeObjectDetailRegistration[] = [];
|
||||
kubeObjectMenuItems: KubeObjectMenuRegistration[] = [];
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
import type React from "react";
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
import { ClusterFeature } from "../cluster-feature";
|
||||
|
||||
export interface ClusterFeatureComponents {
|
||||
Description: React.ComponentType<any>;
|
||||
}
|
||||
|
||||
export interface ClusterFeatureRegistration {
|
||||
title: string;
|
||||
components: ClusterFeatureComponents
|
||||
feature: ClusterFeature
|
||||
}
|
||||
|
||||
export class ClusterFeatureRegistry extends BaseRegistry<ClusterFeatureRegistration> {
|
||||
}
|
||||
|
||||
export const clusterFeatureRegistry = new ClusterFeatureRegistry();
|
||||
@ -1,23 +1,26 @@
|
||||
// Extensions API -> Commands
|
||||
|
||||
import type { Cluster } from "../../main/cluster";
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
import { action } from "mobx";
|
||||
import { action, observable, reaction } from "mobx";
|
||||
import { LensExtension } from "../lens-extension";
|
||||
import { CatalogEntity } from "../../common/catalog-entity";
|
||||
import { catalogEntityRegistry } from "../../common/catalog-entity-registry";
|
||||
|
||||
export type CommandContext = {
|
||||
cluster?: Cluster;
|
||||
entity?: CatalogEntity;
|
||||
};
|
||||
|
||||
export interface CommandRegistration {
|
||||
id: string;
|
||||
title: string;
|
||||
scope: "cluster" | "global";
|
||||
scope: "entity" | "global";
|
||||
action: (context: CommandContext) => void;
|
||||
isActive?: (context: CommandContext) => boolean;
|
||||
}
|
||||
|
||||
export class CommandRegistry extends BaseRegistry<CommandRegistration> {
|
||||
@observable activeEntity: CatalogEntity;
|
||||
|
||||
@action
|
||||
add(items: CommandRegistration | CommandRegistration[], extension?: LensExtension) {
|
||||
const itemArray = [items].flat();
|
||||
@ -32,4 +35,16 @@ export class CommandRegistry extends BaseRegistry<CommandRegistration> {
|
||||
}
|
||||
}
|
||||
|
||||
export function syncCommandRegistryWithCatalog() {
|
||||
reaction(() => catalogEntityRegistry.items, (items) => {
|
||||
if (!commandRegistry.activeEntity) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!items.includes(commandRegistry.activeEntity)) {
|
||||
commandRegistry.activeEntity = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const commandRegistry = new CommandRegistry();
|
||||
|
||||
@ -7,6 +7,5 @@ export * from "./app-preference-registry";
|
||||
export * from "./status-bar-registry";
|
||||
export * from "./kube-object-detail-registry";
|
||||
export * from "./kube-object-menu-registry";
|
||||
export * from "./cluster-feature-registry";
|
||||
export * from "./kube-object-status-registry";
|
||||
export * from "./command-registry";
|
||||
|
||||
@ -4,8 +4,6 @@ import { CatalogEntity, CatalogEntityData } from "../../common/catalog-entity";
|
||||
import { catalogCategoryRegistry, CatalogCategoryRegistry } from "../../common/catalog-category-registry";
|
||||
import "../../common/catalog-entities";
|
||||
|
||||
export { CatalogEntity, CatalogEntityData, CatalogEntityContextMenuContext } from "../../common/catalog-entity";
|
||||
|
||||
export class CatalogEntityRegistry {
|
||||
@observable protected _items: CatalogEntity[] = observable.array([], { deep: true });
|
||||
|
||||
|
||||
12
src/renderer/api/catalog-entity.ts
Normal file
12
src/renderer/api/catalog-entity.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { navigate } from "../navigation";
|
||||
import { commandRegistry } from "../../extensions/registries";
|
||||
import { CatalogEntity } from "../../common/catalog-entity";
|
||||
|
||||
export { CatalogEntity, CatalogEntityData, CatalogEntityActionContext, CatalogEntityContextMenuContext } from "../../common/catalog-entity";
|
||||
|
||||
export const catalogEntityRunContext = {
|
||||
navigate: (url: string) => navigate(url),
|
||||
setCommandPaletteContext: (entity?: CatalogEntity) => {
|
||||
commandRegistry.activeEntity = entity;
|
||||
}
|
||||
};
|
||||
@ -6,13 +6,13 @@ import { releaseURL } from "../+apps-releases";
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewHelmCharts",
|
||||
title: "Cluster: View Helm Charts",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(helmChartsURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewHelmReleases",
|
||||
title: "Cluster: View Helm Releases",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(releaseURL())
|
||||
});
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { action, computed, reaction } from "mobx";
|
||||
import { CatalogEntity, catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import { CatalogEntity, CatalogEntityActionContext } from "../../api/catalog-entity";
|
||||
import { ItemObject, ItemStore } from "../../item.store";
|
||||
import { autobind } from "../../utils";
|
||||
|
||||
@ -42,7 +43,7 @@ export class CatalogEntityItem implements ItemObject {
|
||||
return this.entity.metadata.source || "unknown";
|
||||
}
|
||||
|
||||
onRun(ctx: any) {
|
||||
onRun(ctx: CatalogEntityActionContext) {
|
||||
this.entity.onRun(ctx);
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import { kebabCase } from "lodash";
|
||||
import { PageLayout } from "../layout/page-layout";
|
||||
import { MenuItem, MenuActions } from "../menu";
|
||||
import { Icon } from "../icon";
|
||||
import { CatalogEntityContextMenuContext } from "../../api/catalog-entity-registry";
|
||||
import { CatalogEntityContextMenuContext, catalogEntityRunContext } from "../../api/catalog-entity";
|
||||
import { Badge } from "../badge";
|
||||
import { hotbarStore } from "../../../common/hotbar-store";
|
||||
import { addClusterURL } from "../+add-cluster";
|
||||
@ -68,6 +68,10 @@ export class Catalog extends React.Component {
|
||||
hotbar.items = hotbar.items.filter((i) => i.entity.uid !== item.id);
|
||||
}
|
||||
|
||||
onDetails(item: CatalogEntityItem) {
|
||||
item.onRun(catalogEntityRunContext);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
renderItemMenu(item: CatalogEntityItem) {
|
||||
const onOpen = async () => {
|
||||
@ -124,7 +128,7 @@ export class Catalog extends React.Component {
|
||||
item.labels.map((label) => <Badge key={label} label={label} title={label} />),
|
||||
{ title: item.phase, className: kebabCase(item.phase) }
|
||||
]}
|
||||
onDetails={(item: CatalogEntityItem) => item.onRun({ navigate: (url: string) => navigate(url)})}
|
||||
onDetails={(item: CatalogEntityItem) => this.onDetails(item) }
|
||||
renderItemMenu={this.renderItemMenu}
|
||||
addRemoveButtons={{
|
||||
addTooltip: "Add Kubernetes Cluster",
|
||||
|
||||
@ -12,5 +12,5 @@ commandRegistry.add({
|
||||
clusterId: clusterStore.active.id
|
||||
}
|
||||
})),
|
||||
isActive: (context) => !!context.cluster
|
||||
isActive: (context) => !!context.entity
|
||||
});
|
||||
|
||||
@ -10,41 +10,41 @@ import { pdbURL } from "../+config-pod-disruption-budgets";
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewConfigMaps",
|
||||
title: "Cluster: View ConfigMaps",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(configMapsURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewSecrets",
|
||||
title: "Cluster: View Secrets",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(secretsURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewResourceQuotas",
|
||||
title: "Cluster: View ResourceQuotas",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(resourceQuotaURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewLimitRanges",
|
||||
title: "Cluster: View LimitRanges",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(limitRangeURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewHorizontalPodAutoscalers",
|
||||
title: "Cluster: View HorizontalPodAutoscalers (HPA)",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(hpaURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewPodDisruptionBudget",
|
||||
title: "Cluster: View PodDisruptionBudgets",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(pdbURL())
|
||||
});
|
||||
|
||||
@ -8,27 +8,27 @@ import { networkPoliciesURL } from "../+network-policies";
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewServices",
|
||||
title: "Cluster: View Services",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(servicesURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewEndpoints",
|
||||
title: "Cluster: View Endpoints",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(endpointURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewIngresses",
|
||||
title: "Cluster: View Ingresses",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(ingressURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewNetworkPolicies",
|
||||
title: "Cluster: View NetworkPolicies",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(networkPoliciesURL())
|
||||
});
|
||||
|
||||
@ -5,6 +5,6 @@ import { nodesURL } from "./nodes.route";
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewNodes",
|
||||
title: "Cluster: View Nodes",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(nodesURL())
|
||||
});
|
||||
|
||||
@ -5,41 +5,41 @@ import { cronJobsURL, daemonSetsURL, deploymentsURL, jobsURL, podsURL, statefulS
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewPods",
|
||||
title: "Cluster: View Pods",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(podsURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewDeployments",
|
||||
title: "Cluster: View Deployments",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(deploymentsURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewDaemonSets",
|
||||
title: "Cluster: View DaemonSets",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(daemonSetsURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewStatefulSets",
|
||||
title: "Cluster: View StatefulSets",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(statefulSetsURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewJobs",
|
||||
title: "Cluster: View Jobs",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(jobsURL())
|
||||
});
|
||||
|
||||
commandRegistry.add({
|
||||
id: "cluster.viewCronJobs",
|
||||
title: "Cluster: View CronJobs",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => navigate(cronJobsURL())
|
||||
});
|
||||
|
||||
@ -8,7 +8,6 @@ import { EventEmitter } from "../../../common/event-emitter";
|
||||
import { subscribeToBroadcast } from "../../../common/ipc";
|
||||
import { CommandDialog } from "./command-dialog";
|
||||
import { CommandRegistration, commandRegistry } from "../../../extensions/registries/command-registry";
|
||||
import { clusterStore } from "../../../common/cluster-store";
|
||||
|
||||
export type CommandDialogEvent = {
|
||||
component: React.ReactElement
|
||||
@ -48,7 +47,7 @@ export class CommandContainer extends React.Component<{ clusterId?: string }> {
|
||||
|
||||
private runCommand(command: CommandRegistration) {
|
||||
command.action({
|
||||
cluster: clusterStore.active
|
||||
entity: commandRegistry.activeEntity
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -16,11 +16,11 @@ export class CommandDialog extends React.Component {
|
||||
|
||||
@computed get options() {
|
||||
const context = {
|
||||
cluster: clusterStore.active
|
||||
entity: commandRegistry.activeEntity
|
||||
};
|
||||
|
||||
return commandRegistry.getItems().filter((command) => {
|
||||
if (command.scope === "cluster" && !clusterStore.active) {
|
||||
if (command.scope === "entity" && !clusterStore.active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -54,15 +54,15 @@ export class CommandDialog extends React.Component {
|
||||
|
||||
if (command.scope === "global") {
|
||||
action({
|
||||
cluster: clusterStore.active
|
||||
entity: commandRegistry.activeEntity
|
||||
});
|
||||
} else if(clusterStore.active) {
|
||||
} else if(commandRegistry.activeEntity) {
|
||||
navigate(clusterViewURL({
|
||||
params: {
|
||||
clusterId: clusterStore.active.id
|
||||
clusterId: commandRegistry.activeEntity.metadata.uid
|
||||
}
|
||||
}));
|
||||
broadcastMessage(`command-palette:run-action:${clusterStore.active.id}`, command.id);
|
||||
broadcastMessage(`command-palette:run-action:${commandRegistry.activeEntity.metadata.uid}`, command.id);
|
||||
}
|
||||
} catch(error) {
|
||||
console.error("[COMMAND-DIALOG] failed to execute command", command.id, error);
|
||||
|
||||
@ -136,7 +136,7 @@ export class Dock extends React.Component<Props> {
|
||||
commandRegistry.add({
|
||||
id: "cluster.openTerminal",
|
||||
title: "Cluster: Open terminal",
|
||||
scope: "cluster",
|
||||
scope: "entity",
|
||||
action: () => createTerminalTab(),
|
||||
isActive: (context) => !!context.cluster
|
||||
isActive: (context) => !!context.entity
|
||||
});
|
||||
|
||||
@ -39,7 +39,7 @@ export class ErrorBoundary extends React.Component<Props, State> {
|
||||
if (error) {
|
||||
const slackLink = <a href={slackUrl} rel="noreferrer" target="_blank">Slack</a>;
|
||||
const githubLink = <a href={issuesTrackerUrl} rel="noreferrer" target="_blank">Github</a>;
|
||||
const pageUrl = location.href;
|
||||
const pageUrl = location.pathname;
|
||||
|
||||
return (
|
||||
<div className="ErrorBoundary flex column gaps">
|
||||
|
||||
@ -5,7 +5,12 @@ import { observer } from "mobx-react";
|
||||
import { cssNames, IClassName } from "../../utils";
|
||||
import { Tooltip } from "../tooltip";
|
||||
import { Avatar } from "@material-ui/core";
|
||||
import { CatalogEntity } from "../../../common/catalog-entity";
|
||||
import { CatalogEntity, CatalogEntityContextMenuContext } from "../../../common/catalog-entity";
|
||||
import { Menu, MenuItem } from "../menu";
|
||||
import { Icon } from "../icon";
|
||||
import { observable } from "mobx";
|
||||
import { navigate } from "../../navigation";
|
||||
import { hotbarStore } from "../../../common/hotbar-store";
|
||||
|
||||
interface Props extends DOMAttributes<HTMLElement> {
|
||||
entity: CatalogEntity;
|
||||
@ -16,6 +21,16 @@ interface Props extends DOMAttributes<HTMLElement> {
|
||||
|
||||
@observer
|
||||
export class HotbarIcon extends React.Component<Props> {
|
||||
@observable.deep private contextMenu: CatalogEntityContextMenuContext;
|
||||
@observable menuOpen = false;
|
||||
|
||||
componentDidMount() {
|
||||
this.contextMenu = {
|
||||
menuItems: [],
|
||||
navigate: (url: string) => navigate(url)
|
||||
};
|
||||
}
|
||||
|
||||
get iconString() {
|
||||
let splittedName = this.props.entity.metadata.name.split(" ");
|
||||
|
||||
@ -36,6 +51,20 @@ export class HotbarIcon extends React.Component<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
this.menuOpen = !this.menuOpen;
|
||||
}
|
||||
|
||||
removeFromHotbar(item: CatalogEntity) {
|
||||
const hotbar = hotbarStore.getByName("default"); // FIXME
|
||||
|
||||
if (!hotbar) {
|
||||
return;
|
||||
}
|
||||
|
||||
hotbar.items = hotbar.items.filter((i) => i.entity.uid !== item.metadata.uid);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
entity, errorClass, isActive,
|
||||
@ -46,11 +75,34 @@ export class HotbarIcon extends React.Component<Props> {
|
||||
interactive: true,
|
||||
active: isActive,
|
||||
});
|
||||
const onOpen = async () => {
|
||||
await entity.onContextMenuOpen(this.contextMenu);
|
||||
this.toggleMenu();
|
||||
};
|
||||
|
||||
return (
|
||||
<div {...elemProps} className={className} id={entityIconId}>
|
||||
<Tooltip targetId={entityIconId}>{entity.metadata.name}</Tooltip>
|
||||
<Avatar variant="square" className={isActive ? "active" : "default"}>{this.iconString}</Avatar>
|
||||
<Menu
|
||||
usePortal={true}
|
||||
htmlFor={entityIconId}
|
||||
isOpen={this.menuOpen}
|
||||
toggleEvent="contextmenu"
|
||||
position={{right: true, top: true}} // FIXME: position does not work
|
||||
open={() => onOpen()}
|
||||
close={() => this.toggleMenu()}>
|
||||
<MenuItem key="remove-from-hotbar" onClick={() => this.removeFromHotbar(entity) }>
|
||||
<Icon material="clear" interactive={true} title="Remove from hotbar"/> Remove from Hotbar
|
||||
</MenuItem>
|
||||
{ this.contextMenu && this.contextMenu.menuItems.map((menuItem) => {
|
||||
return (
|
||||
<MenuItem key={menuItem.title} onClick={() => menuItem.onClick()}>
|
||||
<Icon material={menuItem.icon} interactive={true} title={menuItem.title}/> {menuItem.title}
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</Menu>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -5,8 +5,8 @@ import { observer } from "mobx-react";
|
||||
import { HotbarIcon } from "./hotbar-icon";
|
||||
import { cssNames, IClassName } from "../../utils";
|
||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import { navigate } from "../../navigation";
|
||||
import { hotbarStore } from "../../../common/hotbar-store";
|
||||
import { catalogEntityRunContext } from "../../api/catalog-entity";
|
||||
|
||||
interface Props {
|
||||
className?: IClassName;
|
||||
@ -23,9 +23,6 @@ export class HotbarMenu extends React.Component<Props> {
|
||||
}
|
||||
|
||||
const items = hotbar.items.map((item) => catalogEntityRegistry.items.find((entity) => entity.metadata.uid === item.entity.uid)).filter(Boolean);
|
||||
const runContext = {
|
||||
navigate: (url: string) => navigate(url)
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cssNames("HotbarMenu flex column", className)}>
|
||||
@ -36,7 +33,7 @@ export class HotbarMenu extends React.Component<Props> {
|
||||
key={entity.metadata.uid}
|
||||
entity={entity}
|
||||
isActive={entity.status.active}
|
||||
onClick={() => entity.onRun(runContext)}
|
||||
onClick={() => entity.onRun(catalogEntityRunContext)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@ -17,6 +17,8 @@ import { registerIpcHandlers } from "./ipc";
|
||||
import { ipcRenderer } from "electron";
|
||||
import { IpcRendererNavigationEvents } from "./navigation/events";
|
||||
import { catalogEntityRegistry } from "./api/catalog-entity-registry";
|
||||
import { commandRegistry } from "../extensions/registries";
|
||||
import { reaction } from "mobx";
|
||||
|
||||
@observer
|
||||
export class LensApp extends React.Component {
|
||||
@ -36,6 +38,18 @@ export class LensApp extends React.Component {
|
||||
ipcRenderer.send(IpcRendererNavigationEvents.LOADED);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
reaction(() => catalogEntityRegistry.items, (items) => {
|
||||
if (!commandRegistry.activeEntity) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!items.includes(commandRegistry.activeEntity)) {
|
||||
commandRegistry.activeEntity = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Router history={history}>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user