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

Get rid of this.disposers while registering stuff in extensions (#1148)

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2020-10-27 17:07:21 +02:00 committed by GitHub
parent b765ee11bb
commit 67754ffbb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 141 additions and 197 deletions

View File

@ -1,26 +1,16 @@
import { LensRendererExtension, Registry } from "@k8slens/extensions"; import { LensRendererExtension } from "@k8slens/extensions";
import { ExamplePage, ExampleIcon } from "./page" import { ExampleIcon, ExamplePage } from "./page"
import React from "react" import React from "react"
export default class ExampleExtension extends LensRendererExtension { export default class ExampleExtension extends LensRendererExtension {
onActivate() { clusterPages = [
console.log('EXAMPLE EXTENSION RENDERER: ACTIVATED', this.getMeta()); {
} path: "/extension-example",
title: "Example Extension",
registerClusterPage(registry: Registry.ClusterPageRegistry) { components: {
this.disposers.push( Page: () => <ExamplePage extension={this}/>,
registry.add({ MenuIcon: ExampleIcon,
path: "/extension-example", }
title: "Example Extension", }
components: { ]
Page: () => <ExamplePage extension={this} />,
MenuIcon: ExampleIcon,
}
})
)
}
onDeactivate() {
console.log('EXAMPLE EXTENSION RENDERER: DEACTIVATED', this.getMeta());
}
} }

View File

@ -1,25 +1,23 @@
import { Registry, LensRendererExtension } from "@k8slens/extensions" import { LensRendererExtension } from "@k8slens/extensions"
import { MetricsFeature } from "./src/metrics-feature" import { MetricsFeature } from "./src/metrics-feature"
import React from "react" import React from "react"
export default class ClusterMetricsFeatureExtension extends LensRendererExtension { export default class ClusterMetricsFeatureExtension extends LensRendererExtension {
registerClusterFeatures(registry: Registry.ClusterFeatureRegistry) { clusterFeatures = [
this.disposers.push( {
registry.add({ title: "Metrics Stack",
title: "Metrics Stack", components: {
components: { Description: () => {
Description: () => { return (
return ( <span>
<span>
Enable timeseries data visualization (Prometheus stack) for your cluster. Enable timeseries data visualization (Prometheus stack) for your cluster.
Install this only if you don't have existing Prometheus stack installed. Install this only if you don't have existing Prometheus stack installed.
You can see preview of manifests <a href="https://github.com/lensapp/lens/tree/master/extensions/lens-metrics/resources" target="_blank">here</a>. You can see preview of manifests <a href="https://github.com/lensapp/lens/tree/master/extensions/lens-metrics/resources" target="_blank">here</a>.
</span> </span>
) )
} }
}, },
feature: new MetricsFeature() feature: new MetricsFeature()
}) }
) ]
}
} }

View File

@ -1,21 +1,15 @@
import { Registry, LensRendererExtension } from "@k8slens/extensions"; import { LensRendererExtension } from "@k8slens/extensions";
import React from "react" import React from "react"
import { NodeMenu } from "./src/node-menu" import { NodeMenu, NodeMenuProps } from "./src/node-menu"
export default class NodeMenuRendererExtension extends LensRendererExtension { export default class NodeMenuRendererExtension extends LensRendererExtension {
async onActivate() { kubeObjectMenuItems = [
console.log("node-menu extension activated") {
} kind: "Node",
apiVersions: ["v1"],
registerKubeObjectMenus(registry: Registry.KubeObjectMenuRegistry) { components: {
this.disposers.push( MenuItem: (props: NodeMenuProps) => <NodeMenu {...props} />
registry.add({ }
kind: "Node", }
apiVersions: ["v1"], ]
components: {
MenuItem: (props) => <NodeMenu {...props} />
}
})
)
}
} }

View File

@ -1,7 +1,10 @@
import React from "react"; import React from "react";
import { Component, K8sApi, Navigation} from "@k8slens/extensions" import { Component, K8sApi, Navigation} from "@k8slens/extensions"
export function NodeMenu(props: Component.KubeObjectMenuProps<K8sApi.Node>) { export interface NodeMenuProps extends Component.KubeObjectMenuProps<K8sApi.Node> {
}
export function NodeMenu(props: NodeMenuProps) {
const { object: node, toolbar } = props; const { object: node, toolbar } = props;
if (!node) return null; if (!node) return null;
const nodeName = node.getName(); const nodeName = node.getName();

View File

@ -1,31 +1,23 @@
import { Registry, LensRendererExtension } from "@k8slens/extensions"; import { LensRendererExtension } from "@k8slens/extensions";
import { PodShellMenu } from "./src/shell-menu" import { PodShellMenu, PodShellMenuProps } from "./src/shell-menu"
import { PodLogsMenu } from "./src/logs-menu" import { PodLogsMenu, PodLogsMenuProps } from "./src/logs-menu"
import React from "react" import React from "react"
export default class PodMenuRendererExtension extends LensRendererExtension { export default class PodMenuRendererExtension extends LensRendererExtension {
async onActivate() { kubeObjectMenuItems = [
console.log("pod-menu extension activated") {
} kind: "Pod",
apiVersions: ["v1"],
registerKubeObjectMenus(registry: Registry.KubeObjectMenuRegistry) { components: {
this.disposers.push( MenuItem: (props: PodShellMenuProps) => <PodShellMenu {...props} />
registry.add({ }
kind: "Pod", },
apiVersions: ["v1"], {
components: { kind: "Pod",
MenuItem: (props) => <PodShellMenu {...props} /> apiVersions: ["v1"],
} components: {
}) MenuItem: (props: PodLogsMenuProps) => <PodLogsMenu {...props} />
) }
this.disposers.push( }
registry.add({ ]
kind: "Pod",
apiVersions: ["v1"],
components: {
MenuItem: (props) => <PodLogsMenu {...props} />
}
})
)
}
} }

View File

@ -1,10 +1,10 @@
import React from "react"; import React from "react";
import { Component, K8sApi, Util, Navigation } from "@k8slens/extensions"; import { Component, K8sApi, Util, Navigation } from "@k8slens/extensions";
interface Props extends Component.KubeObjectMenuProps<K8sApi.Pod> { export interface PodLogsMenuProps extends Component.KubeObjectMenuProps<K8sApi.Pod> {
} }
export class PodLogsMenu extends React.Component<Props> { export class PodLogsMenu extends React.Component<PodLogsMenuProps> {
showLogs(container: K8sApi.IPodContainer) { showLogs(container: K8sApi.IPodContainer) {
Navigation.hideDetails(); Navigation.hideDetails();
const pod = this.props.object; const pod = this.props.object;

View File

@ -3,10 +3,10 @@
import React from "react"; import React from "react";
import { Component, K8sApi, Util, Navigation } from "@k8slens/extensions"; import { Component, K8sApi, Util, Navigation } from "@k8slens/extensions";
interface Props extends Component.KubeObjectMenuProps<K8sApi.Pod> { export interface PodShellMenuProps extends Component.KubeObjectMenuProps<K8sApi.Pod> {
} }
export class PodShellMenu extends React.Component<Props> { export class PodShellMenu extends React.Component<PodShellMenuProps> {
async execShell(container?: string) { async execShell(container?: string) {
Navigation.hideDetails(); Navigation.hideDetails();
const { object: pod } = this.props const { object: pod } = this.props

View File

@ -1,20 +1,14 @@
import { LensMainExtension, Registry, windowManager } from "@k8slens/extensions"; import { LensMainExtension, windowManager } from "@k8slens/extensions";
import { supportPageURL } from "./src/support.route"; import { supportPageURL } from "./src/support.route";
export default class SupportPageMainExtension extends LensMainExtension { export default class SupportPageMainExtension extends LensMainExtension {
async onActivate() { appMenus = [
console.log("support page extension activated") {
} parentId: "help",
label: "Support",
async registerAppMenus(registry: Registry.MenuRegistry) { click() {
this.disposers.push( windowManager.navigate(supportPageURL());
registry.add({ }
parentId: "help", }
label: "Support", ]
click() {
windowManager.navigate(supportPageURL());
}
})
)
}
} }

View File

@ -1,39 +1,31 @@
import React from "react"; import React from "react";
import { Component, LensRendererExtension, Navigation, Registry } from "@k8slens/extensions"; import { Component, LensRendererExtension, Navigation } from "@k8slens/extensions";
import { supportPageRoute, supportPageURL } from "./src/support.route"; import { supportPageRoute, supportPageURL } from "./src/support.route";
import { Support } from "./src/support"; import { Support } from "./src/support";
export default class SupportPageRendererExtension extends LensRendererExtension { export default class SupportPageRendererExtension extends LensRendererExtension {
async onActivate() { globalPages = [
console.log("support page extension activated") {
} ...supportPageRoute,
url: supportPageURL(),
hideInMenu: true,
components: {
Page: Support,
}
}
]
registerGlobalPage(registry: Registry.GlobalPageRegistry) { statusBarItems = [
this.disposers.push( {
registry.add({ item: (
...supportPageRoute, <div
url: supportPageURL(), className="flex align-center gaps hover-highlight"
hideInMenu: true, onClick={() => Navigation.navigate(supportPageURL())}
components: { >
Page: Support, <Component.Icon material="help_outline" small/>
} <span>Support</span>
}) </div>
) )
} }
]
registerStatusBarItem(registry: Registry.StatusBarRegistry) {
this.disposers.push(
registry.add({
item: (
<div
className="flex align-center gaps hover-highlight"
onClick={() => Navigation.navigate(supportPageURL())}
>
<Component.Icon material="help_outline" small />
<span>Support</span>
</div>
)
})
)
}
} }

View File

@ -1,29 +1,23 @@
import { LensRendererExtension, Registry } from "@k8slens/extensions"; import { LensRendererExtension } from "@k8slens/extensions";
import { telemetryPreferencesStore } from "./src/telemetry-preferences-store" import { telemetryPreferencesStore } from "./src/telemetry-preferences-store"
import { TelemetryPreferenceHint, TelemetryPreferenceInput } from "./src/telemetry-preference" import { TelemetryPreferenceHint, TelemetryPreferenceInput } from "./src/telemetry-preference"
import { tracker } from "./src/tracker" import { tracker } from "./src/tracker"
import React from "react" import React from "react"
export default class TelemetryRendererExtension extends LensRendererExtension { export default class TelemetryRendererExtension extends LensRendererExtension {
appPreferences = [
{
title: "Telemetry & Usage Tracking",
components: {
Hint: () => <TelemetryPreferenceHint/>,
Input: () => <TelemetryPreferenceInput telemetry={telemetryPreferencesStore}/>
}
}
];
async onActivate() { async onActivate() {
console.log("telemetry extension activated") console.log("telemetry extension activated")
tracker.start() tracker.start()
await telemetryPreferencesStore.loadExtension(this) await telemetryPreferencesStore.loadExtension(this)
} }
registerAppPreferences(registry: Registry.AppPreferenceRegistry) {
this.disposers.push(
registry.add({
title: "Telemetry & Usage Tracking",
components: {
Hint: () => <TelemetryPreferenceHint />,
Input: () => <TelemetryPreferenceInput telemetry={telemetryPreferencesStore} />
}
})
)
}
onDeactivate() {
console.log("telemetry extension deactivated")
}
} }

View File

@ -36,26 +36,26 @@ export class ExtensionLoader {
loadOnMain() { loadOnMain() {
logger.info('[EXTENSIONS-LOADER]: load on main') logger.info('[EXTENSIONS-LOADER]: load on main')
this.autoloadExtensions((instance: LensMainExtension) => { this.autoloadExtensions((extension: LensMainExtension) => {
instance.registerAppMenus(menuRegistry); extension.registerTo(menuRegistry, extension.appMenus)
}) })
} }
loadOnClusterManagerRenderer() { loadOnClusterManagerRenderer() {
logger.info('[EXTENSIONS-LOADER]: load on main renderer (cluster manager)') logger.info('[EXTENSIONS-LOADER]: load on main renderer (cluster manager)')
this.autoloadExtensions((instance: LensRendererExtension) => { this.autoloadExtensions((extension: LensRendererExtension) => {
instance.registerGlobalPage(globalPageRegistry) extension.registerTo(globalPageRegistry, extension.globalPages)
instance.registerAppPreferences(appPreferenceRegistry) extension.registerTo(appPreferenceRegistry, extension.appPreferences)
instance.registerClusterFeatures(clusterFeatureRegistry) extension.registerTo(clusterFeatureRegistry, extension.clusterFeatures)
instance.registerStatusBarItem(statusBarRegistry) extension.registerTo(statusBarRegistry, extension.statusBarItems)
}) })
} }
loadOnClusterRenderer() { loadOnClusterRenderer() {
logger.info('[EXTENSIONS-LOADER]: load on cluster renderer (dashboard)') logger.info('[EXTENSIONS-LOADER]: load on cluster renderer (dashboard)')
this.autoloadExtensions((instance: LensRendererExtension) => { this.autoloadExtensions((extension: LensRendererExtension) => {
instance.registerClusterPage(clusterPageRegistry) extension.registerTo(clusterPageRegistry, extension.clusterPages)
instance.registerKubeObjectMenus(kubeObjectMenuRegistry) extension.registerTo(kubeObjectMenuRegistry, extension.kubeObjectMenuItems)
}) })
} }

View File

@ -1,6 +1,7 @@
import { readJsonSync } from "fs-extra"; import { readJsonSync } from "fs-extra";
import { action, observable, toJS } from "mobx"; import { action, observable, toJS } from "mobx";
import logger from "../main/logger"; import logger from "../main/logger";
import { BaseRegistry } from "./registries/base-registry";
export type ExtensionId = string | ExtensionPackageJsonPath; export type ExtensionId = string | ExtensionPackageJsonPath;
export type ExtensionPackageJsonPath = string; export type ExtensionPackageJsonPath = string;
@ -25,7 +26,7 @@ export interface ExtensionManifest extends ExtensionModel {
export class LensExtension implements ExtensionModel { export class LensExtension implements ExtensionModel {
public id: ExtensionId; public id: ExtensionId;
public updateUrl: string; public updateUrl: string;
protected disposers: Function[] = []; protected disposers: (() => void)[] = [];
@observable name = ""; @observable name = "";
@observable description = ""; @observable description = "";
@ -77,6 +78,14 @@ export class LensExtension implements ExtensionModel {
// mock // mock
} }
registerTo<T = any>(registry: BaseRegistry<T>, items: T[] = []) {
const disposers = items.map(item => registry.add(item));
this.disposers.push(...disposers);
return () => {
this.disposers = this.disposers.filter(disposer => !disposers.includes(disposer))
};
}
getMeta() { getMeta() {
return toJS({ return toJS({
id: this.id, id: this.id,

View File

@ -1,12 +1,7 @@
import type { MenuRegistration } from "./registries/menu-registry";
import { observable } from "mobx";
import { LensExtension } from "./lens-extension" import { LensExtension } from "./lens-extension"
import type { MenuRegistry } from "./registries/menu-registry";
export class LensMainExtension extends LensExtension { export class LensMainExtension extends LensExtension {
registerAppMenus(registry: MenuRegistry) { @observable.shallow appMenus: MenuRegistration[] = []
//
}
registerPrometheusProviders(registry: any) {
//
}
} }

View File

@ -1,28 +1,12 @@
import type { AppPreferenceRegistration, ClusterFeatureRegistration, KubeObjectMenuRegistration, PageRegistration, StatusBarRegistration } from "./registries"
import { observable } from "mobx";
import { LensExtension } from "./lens-extension" import { LensExtension } from "./lens-extension"
import type { GlobalPageRegistry, ClusterPageRegistry, AppPreferenceRegistry, StatusBarRegistry, KubeObjectMenuRegistry, ClusterFeatureRegistry } from "./registries"
export class LensRendererExtension extends LensExtension { export class LensRendererExtension extends LensExtension {
registerGlobalPage(registry: GlobalPageRegistry) { @observable.shallow globalPages: PageRegistration[] = []
return @observable.shallow clusterPages: PageRegistration[] = []
} @observable.shallow appPreferences: AppPreferenceRegistration[] = []
@observable.shallow clusterFeatures: ClusterFeatureRegistration[] = []
registerClusterPage(registry: ClusterPageRegistry) { @observable.shallow statusBarItems: StatusBarRegistration[] = []
return @observable.shallow kubeObjectMenuItems: KubeObjectMenuRegistration[] = []
}
registerAppPreferences(registry: AppPreferenceRegistry) {
return
}
registerClusterFeatures(registry: ClusterFeatureRegistry) {
return
}
registerStatusBarItem(registry: StatusBarRegistry) {
return
}
registerKubeObjectMenus(registry: KubeObjectMenuRegistry) {
return
}
} }

View File

@ -1,11 +1,10 @@
// Extensions API -> Global menu customizations // Extensions API -> Global menu customizations
import type { MenuTopId } from "../../main/menu";
import type { MenuItemConstructorOptions } from "electron"; import type { MenuItemConstructorOptions } from "electron";
import { BaseRegistry } from "./base-registry"; import { BaseRegistry } from "./base-registry";
export interface MenuRegistration extends MenuItemConstructorOptions { export interface MenuRegistration extends MenuItemConstructorOptions {
parentId?: MenuTopId; parentId: string;
} }
export class MenuRegistry extends BaseRegistry<MenuRegistration> { export class MenuRegistry extends BaseRegistry<MenuRegistration> {