diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 73fe5f9ee3..afec611177 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -19,27 +19,26 @@ jobs: node_12.x: node_version: 12.x steps: - - displayName: Set the tag name as an environment variable - powershell: | + - powershell: | $CI_BUILD_TAG = git describe --tags Write-Output ("##vso[task.setvariable variable=CI_BUILD_TAG;]$CI_BUILD_TAG") condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))" + displayName: Set the tag name as an environment variable - - displayName: Install Node.js - task: NodeTool@0 + - task: NodeTool@0 inputs: versionSpec: $(node_version) + displayName: Install Node.js - - displayName: Cache Yarn packages - task: Cache@2 + - task: Cache@2 inputs: key: 'yarn | "$(Agent.OS)"" | yarn.lock' restoreKeys: | yarn | "$(Agent.OS)" path: $(YARN_CACHE_FOLDER) + displayName: Cache Yarn packages - - displayName: Customize config - bash: | + - bash: | set -e git clone "https://${GH_TOKEN}@github.com/lensapp/lens-ide.git" .lens-ide-overlay rm -rf .lens-ide-overlay/.git @@ -47,15 +46,15 @@ jobs: jq -s '.[0] * .[1]' package.json package.ide.json > package.custom.json && mv package.custom.json package.json env: GH_TOKEN: $(LENS_IDE_GH_TOKEN) + displayName: Customize config - - displayName: Install dependencies - script: make node_modules + - script: make node_modules + displayName: Install dependencies - - displayName: Generate npm package - script: make build-npm + - script: make build-npm + displayName: Generate npm package - - displayName: Build - script: make build + - script: make build condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))" env: WIN_CSC_LINK: $(WIN_CSC_LINK) @@ -63,6 +62,7 @@ jobs: AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) BUILD_NUMBER: $(Build.BuildNumber) + displayName: Build - job: macOS pool: @@ -72,25 +72,24 @@ jobs: node_12.x: node_version: 12.x steps: - - displayName: Set the tag name as an environment variable - script: CI_BUILD_TAG=`git describe --tags` && echo "##vso[task.setvariable variable=CI_BUILD_TAG]$CI_BUILD_TAG" + - script: CI_BUILD_TAG=`git describe --tags` && echo "##vso[task.setvariable variable=CI_BUILD_TAG]$CI_BUILD_TAG" condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))" + displayName: Set the tag name as an environment variable - - displayName: Install Node.js - task: NodeTool@0 + - task: NodeTool@0 inputs: versionSpec: $(node_version) + displayName: Install Node.js - - displayName: Cache Yarn packages - task: Cache@2 + - task: Cache@2 inputs: key: 'yarn | "$(Agent.OS)" | yarn.lock' restoreKeys: | yarn | "$(Agent.OS)" path: $(YARN_CACHE_FOLDER) + displayName: Cache Yarn packages - - displayName: Customize config - bash: | + - bash: | set -e git clone "https://${GH_TOKEN}@github.com/lensapp/lens-ide.git" .lens-ide-overlay rm -rf .lens-ide-overlay/.git @@ -98,15 +97,15 @@ jobs: jq -s '.[0] * .[1]' package.json package.ide.json > package.custom.json && mv package.custom.json package.json env: GH_TOKEN: $(LENS_IDE_GH_TOKEN) + displayName: Customize config - - displayName: Install dependencies - script: make node_modules + - script: make node_modules + displayName: Install dependencies - - displayName: Generate npm package - script: make build-npm + - script: make build-npm + displayName: Generate npm package - - displayName: Build - script: make build + - script: make build condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))" env: APPLEID: $(APPLEID) @@ -116,6 +115,7 @@ jobs: AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) BUILD_NUMBER: $(Build.BuildNumber) + displayName: Build - job: Linux pool: @@ -125,25 +125,24 @@ jobs: node_12.x: node_version: 12.x steps: - - displayName: Set the tag name as an environment variable - script: CI_BUILD_TAG=`git describe --tags` && echo "##vso[task.setvariable variable=CI_BUILD_TAG]$CI_BUILD_TAG" + - script: CI_BUILD_TAG=`git describe --tags` && echo "##vso[task.setvariable variable=CI_BUILD_TAG]$CI_BUILD_TAG" condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))" + displayName: Set the tag name as an environment variable - - displayName: Install Node.js - task: NodeTool@0 + - task: NodeTool@0 inputs: versionSpec: $(node_version) + displayName: Install Node.js - - displayName: Cache Yarn packages - task: Cache@2 + - task: Cache@2 inputs: key: 'yarn | "$(Agent.OS)" | yarn.lock' restoreKeys: | yarn | "$(Agent.OS)" path: $(YARN_CACHE_FOLDER) + displayName: Cache Yarn packages - - displayName: Customize config - bash: | + - bash: | set -e git clone "https://${GH_TOKEN}@github.com/lensapp/lens-ide.git" .lens-ide-overlay rm -rf .lens-ide-overlay/.git @@ -151,15 +150,15 @@ jobs: jq -s '.[0] * .[1]' package.json package.ide.json > package.custom.json && mv package.custom.json package.json env: GH_TOKEN: $(LENS_IDE_GH_TOKEN) + displayName: Customize config - - displayName: Install dependencies - script: make node_modules + - script: make node_modules + displayName: Install dependencies - - displayName: Generate npm package - script: make build-npm + - script: make build-npm + displayName: Generate npm package - - displayName: Setup snapcraft - bash: | + - bash: | sudo chown root:root / sudo apt-get update && sudo apt-get install -y snapd sudo snap install snapcraft --classic @@ -168,11 +167,12 @@ jobs: condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))" env: SNAP_LOGIN: $(SNAP_LOGIN) + displayName: Setup snapcraft - - displayName: Build - script: make build + - script: make build condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))" env: AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) BUILD_NUMBER: $(Build.BuildNumber) + displayName: Build diff --git a/extensions/kube-object-event-status/package-lock.json b/extensions/kube-object-event-status/package-lock.json index e1234ebd73..f3b0fe6669 100644 --- a/extensions/kube-object-event-status/package-lock.json +++ b/extensions/kube-object-event-status/package-lock.json @@ -1,6 +1,6 @@ { "name": "kube-object-event-status", - "version": "0.1.0", + "version": "0.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/extensions/metrics-cluster-feature/package-lock.json b/extensions/metrics-cluster-feature/package-lock.json index f6a43b3f72..15feb302b8 100644 --- a/extensions/metrics-cluster-feature/package-lock.json +++ b/extensions/metrics-cluster-feature/package-lock.json @@ -1,6 +1,6 @@ { "name": "lens-metrics-cluster-feature", - "version": "0.1.0", + "version": "0.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/extensions/metrics-cluster-feature/src/metrics-settings.tsx b/extensions/metrics-cluster-feature/src/metrics-settings.tsx index b5a78eda1a..5399cd638a 100644 --- a/extensions/metrics-cluster-feature/src/metrics-settings.tsx +++ b/extensions/metrics-cluster-feature/src/metrics-settings.tsx @@ -81,7 +81,7 @@ export class MetricsSettings extends React.Component { @computed get isTogglable() { if (this.inProgress) return false; - if (!this.props.cluster.status.active) return false; + if (this.props.cluster.status.phase !== "connected") return false; if (this.canUpgrade) return false; if (!this.isActiveMetricsProvider) return false; @@ -205,7 +205,7 @@ export class MetricsSettings extends React.Component { render() { return ( <> - { !this.props.cluster.status.active && ( + { this.props.cluster.status.phase !== "connected" && (

Lens Metrics settings requires established connection to the cluster. @@ -225,7 +225,7 @@ export class MetricsSettings extends React.Component { control={ this.togglePrometheus(v.target.checked)} name="prometheus" /> @@ -243,7 +243,7 @@ export class MetricsSettings extends React.Component { control={ this.toggleKubeStateMetrics(v.target.checked)} name="node-exporter" /> @@ -262,7 +262,7 @@ export class MetricsSettings extends React.Component { control={ this.toggleNodeExporter(v.target.checked)} name="node-exporter" /> diff --git a/extensions/node-menu/package-lock.json b/extensions/node-menu/package-lock.json index 245b548fdc..3ca2677ed4 100644 --- a/extensions/node-menu/package-lock.json +++ b/extensions/node-menu/package-lock.json @@ -1,6 +1,6 @@ { "name": "lens-node-menu", - "version": "0.1.0", + "version": "0.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/extensions/pod-menu/package-lock.json b/extensions/pod-menu/package-lock.json index e0cc8c93c0..70154d1055 100644 --- a/extensions/pod-menu/package-lock.json +++ b/extensions/pod-menu/package-lock.json @@ -1,6 +1,6 @@ { "name": "lens-pod-menu", - "version": "0.1.0", + "version": "0.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/mkdocs.yml b/mkdocs.yml index 7ef283c348..51ad079eaf 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,9 +7,6 @@ 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: @@ -86,4 +83,7 @@ extra: link: https://k8slens.dev/ name: Lens Website version: - method: mike + provider: mike + analytics: + provider: google + property: UA-159377374-2 diff --git a/mkdocs/requirements.txt b/mkdocs/requirements.txt index 4db6d92e25..f02159cf62 100644 --- a/mkdocs/requirements.txt +++ b/mkdocs/requirements.txt @@ -1,8 +1,8 @@ # Direct dependencies -mkdocs>=1.1 +mkdocs>=1.2 Pygments>=2.4 markdown>=3.2 pymdown-extensions>=7.0 mkdocs-material-extensions>=1.0 mkdocs-git-revision-date-localized-plugin>=0.7.3 -mkdocs-material>=6.1.0 \ No newline at end of file +mkdocs-material>=7.1.8 diff --git a/package.json b/package.json index b2a1699482..3d62c8558f 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "productName": "OpenLens", "description": "OpenLens - Open Source IDE for Kubernetes", "homepage": "https://github.com/lensapp/lens", - "version": "5.0.0-beta.8", + "version": "5.0.0-beta.9", "main": "static/build/main.js", "copyright": "© 2021 OpenLens Authors", "license": "MIT", @@ -39,7 +39,7 @@ "lint": "yarn run eslint --ext js,ts,tsx --max-warnings=0 .", "lint:fix": "yarn run lint --fix", "mkdocs-serve-local": "docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -it -p 8000:8000 -v ${PWD}:/docs mkdocs-serve-local:latest", - "verify-docs": "docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -v ${PWD}:/docs mkdocs-serve-local:latest build", + "verify-docs": "docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -v ${PWD}:/docs mkdocs-serve-local:latest build --strict", "typedocs-extensions-api": "yarn run typedoc src/extensions/extension-api.ts", "version-checkout": "cat package.json | jq '.version' -r | xargs printf \"release/v%s\" | xargs git checkout -b", "version-commit": "cat package.json | jq '.version' -r | xargs printf \"release v%s\" | git commit --no-edit -s -F -", diff --git a/src/common/cluster-frames.ts b/src/common/cluster-frames.ts index 794a09d827..88dc2d3163 100644 --- a/src/common/cluster-frames.ts +++ b/src/common/cluster-frames.ts @@ -21,9 +21,9 @@ import { observable } from "mobx"; -export type ClusterFrameInfo = { +export interface ClusterFrameInfo { frameId: number; processId: number -}; +} export const clusterFrameMap = observable.map(); diff --git a/src/common/utils/iter.ts b/src/common/utils/iter.ts index 277c58213e..59fce41829 100644 --- a/src/common/utils/iter.ts +++ b/src/common/utils/iter.ts @@ -140,3 +140,19 @@ export function* filterMapStrict(src: Iterable, fn: (from: T) => U | nu } } } + +/** + * Iterate through `src` until `match` returns a truthy value + * @param src A type that can be iterated over + * @param match A function that should return a truthy value for the item that you want to find + * @returns The first entry that `match` returns a truthy value for, or `undefined` + */ +export function find(src: Iterable, match: (i: T) => any): T | undefined { + for (const from of src) { + if (match(from)) { + return from; + } + } + + return void 0; +} diff --git a/src/extensions/common-api/registrations.ts b/src/extensions/common-api/registrations.ts index dadde70ceb..7b7688e85f 100644 --- a/src/extensions/common-api/registrations.ts +++ b/src/extensions/common-api/registrations.ts @@ -24,6 +24,6 @@ export type { KubeObjectDetailRegistration, KubeObjectDetailComponents } from ". export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../registries/kube-object-menu-registry"; export type { KubeObjectStatusRegistration } from "../registries/kube-object-status-registry"; export type { PageRegistration, RegisteredPage, PageParams, PageComponentProps, PageComponents, PageTarget } from "../registries/page-registry"; -export type { PageMenuRegistration, ClusterPageMenuRegistration, PageMenuComponents } from "../registries/page-menu-registry"; +export type { ClusterPageMenuRegistration, ClusterPageMenuComponents } from "../registries/page-menu-registry"; export type { StatusBarRegistration } from "../registries/status-bar-registry"; export type { ProtocolHandlerRegistration, RouteParams as ProtocolRouteParams, RouteHandler as ProtocolRouteHandler } from "../registries/protocol-handler"; diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index 4073ad1e79..d3349b3c16 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -355,6 +355,10 @@ export class ExtensionLoader extends Singleton { return this.extensions.get(extId); } + getInstanceById(extId: LensExtensionId): E { + return this.instances.get(extId) as E; + } + toJSON(): Map { return toJS(this.extensions); } diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts index 023a8b92f9..cbdba9e07c 100644 --- a/src/extensions/lens-main-extension.ts +++ b/src/extensions/lens-main-extension.ts @@ -21,7 +21,6 @@ import { LensExtension } from "./lens-extension"; import { WindowManager } from "../main/window-manager"; -import { getExtensionPageUrl } from "./registries/page-registry"; import { catalogEntityRegistry } from "../main/catalog"; import type { CatalogEntity } from "../common/catalog"; import type { IObservableArray } from "mobx"; @@ -30,15 +29,8 @@ import type { MenuRegistration } from "./registries"; export class LensMainExtension extends LensExtension { appMenus: MenuRegistration[] = []; - async navigate

(pageId?: string, params?: P, frameId?: number) { - const windowManager = WindowManager.getInstance(); - const pageUrl = getExtensionPageUrl({ - extensionId: this.name, - pageId, - params: params ?? {}, // compile to url with params - }); - - await windowManager.navigate(pageUrl, frameId); + async navigate(pageId?: string, params?: Record, frameId?: number) { + return WindowManager.getInstance().navigateExtension(this.id, pageId, params, frameId); } addCatalogSource(id: string, source: IObservableArray) { diff --git a/src/extensions/lens-renderer-extension.ts b/src/extensions/lens-renderer-extension.ts index 7119b0f7ac..a3026d99a5 100644 --- a/src/extensions/lens-renderer-extension.ts +++ b/src/extensions/lens-renderer-extension.ts @@ -19,33 +19,26 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import type { - AppPreferenceRegistration, CatalogEntityDetailRegistration, ClusterPageMenuRegistration, KubeObjectDetailRegistration, KubeObjectMenuRegistration, - KubeObjectStatusRegistration, PageMenuRegistration, PageRegistration, StatusBarRegistration, WelcomeMenuRegistration, WorkloadsOverviewDetailRegistration, -} from "./registries"; +import type * as registries from "./registries"; import type { Cluster } from "../main/cluster"; import { LensExtension } from "./lens-extension"; import { getExtensionPageUrl } from "./registries/page-registry"; -import type { CommandRegistration } from "./registries/command-registry"; -import type { EntitySettingRegistration } from "./registries/entity-setting-registry"; -import type { TopBarRegistration } from "./registries/topbar-registry"; export class LensRendererExtension extends LensExtension { - globalPages: PageRegistration[] = []; - clusterPages: PageRegistration[] = []; - globalPageMenus: PageMenuRegistration[] = []; - clusterPageMenus: ClusterPageMenuRegistration[] = []; - kubeObjectStatusTexts: KubeObjectStatusRegistration[] = []; - appPreferences: AppPreferenceRegistration[] = []; - entitySettings: EntitySettingRegistration[] = []; - statusBarItems: StatusBarRegistration[] = []; - kubeObjectDetailItems: KubeObjectDetailRegistration[] = []; - kubeObjectMenuItems: KubeObjectMenuRegistration[] = []; - kubeWorkloadsOverviewItems: WorkloadsOverviewDetailRegistration[] = []; - commands: CommandRegistration[] = []; - welcomeMenus: WelcomeMenuRegistration[] = []; - catalogEntityDetailItems: CatalogEntityDetailRegistration[] = []; - topBarItems: TopBarRegistration[] = []; + globalPages: registries.PageRegistration[] = []; + clusterPages: registries.PageRegistration[] = []; + clusterPageMenus: registries.ClusterPageMenuRegistration[] = []; + kubeObjectStatusTexts: registries.KubeObjectStatusRegistration[] = []; + appPreferences: registries.AppPreferenceRegistration[] = []; + entitySettings: registries.EntitySettingRegistration[] = []; + statusBarItems: registries.StatusBarRegistration[] = []; + kubeObjectDetailItems: registries.KubeObjectDetailRegistration[] = []; + kubeObjectMenuItems: registries.KubeObjectMenuRegistration[] = []; + kubeWorkloadsOverviewItems: registries.WorkloadsOverviewDetailRegistration[] = []; + commands: registries.CommandRegistration[] = []; + welcomeMenus: registries.WelcomeMenuRegistration[] = []; + catalogEntityDetailItems: registries.CatalogEntityDetailRegistration[] = []; + topBarItems: registries.TopBarRegistration[] = []; async navigate

(pageId?: string, params?: P) { const { navigate } = await import("../renderer/navigation"); diff --git a/src/extensions/registries/page-menu-registry.ts b/src/extensions/registries/page-menu-registry.ts index 73997fb461..17e5f10491 100644 --- a/src/extensions/registries/page-menu-registry.ts +++ b/src/extensions/registries/page-menu-registry.ts @@ -26,23 +26,20 @@ import type { PageTarget, RegisteredPage } from "./page-registry"; import type { LensExtension } from "../lens-extension"; import { BaseRegistry } from "./base-registry"; -export interface PageMenuRegistration { - target?: PageTarget; - title: React.ReactNode; - components: PageMenuComponents; -} - -export interface ClusterPageMenuRegistration extends PageMenuRegistration { +export interface ClusterPageMenuRegistration { id?: string; parentId?: string; + target?: PageTarget; + title: React.ReactNode; + components: ClusterPageMenuComponents; } -export interface PageMenuComponents { +export interface ClusterPageMenuComponents { Icon: React.ComponentType; } -export class PageMenuRegistry extends BaseRegistry { - add(items: T[], ext: LensExtension) { +export class ClusterPageMenuRegistry extends BaseRegistry { + add(items: ClusterPageMenuRegistration[], ext: LensExtension) { const normalizedItems = items.map(menuItem => { menuItem.target = { extensionId: ext.name, @@ -54,9 +51,7 @@ export class PageMenuRegistry extends BaseRegist return super.add(normalizedItems); } -} -export class ClusterPageMenuRegistry extends PageMenuRegistry { getRootItems() { return this.getItems().filter((item) => !item.parentId); } diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index b30d26d519..9a56aaafb8 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -27,7 +27,7 @@ import { appEventBus } from "../common/event-bus"; import { ipcMainOn } from "../common/ipc"; import { initMenu } from "./menu"; import { initTray } from "./tray"; -import { delay, Singleton } from "../common/utils"; +import { delay, iter, Singleton } from "../common/utils"; import { ClusterFrameInfo, clusterFrameMap } from "../common/cluster-frames"; import { IpcRendererNavigationEvents } from "../renderer/navigation/events"; import logger from "./logger"; @@ -38,6 +38,12 @@ function isHideable(window: BrowserWindow | null): boolean { return Boolean(window && !window.isDestroyed()); } +export interface SendToViewArgs { + channel: string; + frameInfo?: ClusterFrameInfo; + data?: any[]; +} + export class WindowManager extends Singleton { protected mainWindow: BrowserWindow; protected splashWindow: BrowserWindow; @@ -175,7 +181,7 @@ export class WindowManager extends Singleton { return this.mainWindow; } - sendToView({ channel, frameInfo, data = [] }: { channel: string, frameInfo?: ClusterFrameInfo, data?: any[] }) { + private sendToView({ channel, frameInfo, data = [] }: SendToViewArgs) { if (frameInfo) { this.mainWindow.webContents.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...data); } else { @@ -183,10 +189,22 @@ export class WindowManager extends Singleton { } } + async navigateExtension(extId: string, pageId?: string, params?: Record, frameId?: number) { + await this.ensureMainWindow(); + + const frameInfo = iter.find(clusterFrameMap.values(), frameInfo => frameInfo.frameId === frameId); + + this.sendToView({ + channel: "extension:navigate", + frameInfo, + data: [extId, pageId, params], + }); + } + async navigate(url: string, frameId?: number) { await this.ensureMainWindow(); - const frameInfo = Array.from(clusterFrameMap.values()).find((frameInfo) => frameInfo.frameId === frameId); + const frameInfo = iter.find(clusterFrameMap.values(), frameInfo => frameInfo.frameId === frameId); const channel = frameInfo ? IpcRendererNavigationEvents.NAVIGATE_IN_CLUSTER : IpcRendererNavigationEvents.NAVIGATE_IN_APP; diff --git a/src/renderer/bootstrap.tsx b/src/renderer/bootstrap.tsx index 5d96b3b7de..7c29e5f576 100644 --- a/src/renderer/bootstrap.tsx +++ b/src/renderer/bootstrap.tsx @@ -79,6 +79,7 @@ export async function bootstrap(App: AppComponent) { initializers.initWelcomeMenuRegistry(); initializers.initWorkloadsOverviewDetailRegistry(); initializers.initCatalog(); + initializers.initIpcRendererListeners(); ExtensionLoader.createInstance().init(); ExtensionDiscovery.createInstance().init(); diff --git a/src/renderer/components/+entity-settings/entity-settings.tsx b/src/renderer/components/+entity-settings/entity-settings.tsx index d37fdef953..16c79412cf 100644 --- a/src/renderer/components/+entity-settings/entity-settings.tsx +++ b/src/renderer/components/+entity-settings/entity-settings.tsx @@ -85,8 +85,8 @@ export class EntitySettings extends React.Component { <>

{this.entity.metadata.name}

- { groups.map((group) => ( - <> + { groups.map((group, groupIndex) => ( +
{group[0]}
{ group[1].map((setting, index) => ( { data-testid={`${setting.id}-tab`} /> ))} - +
))}
diff --git a/src/renderer/components/+namespaces/namespace.store.ts b/src/renderer/components/+namespaces/namespace.store.ts index f865787d76..c292f0f9fa 100644 --- a/src/renderer/components/+namespaces/namespace.store.ts +++ b/src/renderer/components/+namespaces/namespace.store.ts @@ -112,7 +112,7 @@ export class NamespaceStore extends KubeObjectStore { protected async loadItems(params: KubeObjectStoreLoadingParams) { const { allowedNamespaces } = this; - let namespaces = (await super.loadItems(params)) || []; + let namespaces = await super.loadItems(params).catch(() => []); namespaces = namespaces.filter(namespace => allowedNamespaces.includes(namespace.getName())); diff --git a/src/renderer/components/+user-management/+role-bindings/dialog.tsx b/src/renderer/components/+user-management/+role-bindings/dialog.tsx index 0bed732381..c163a01b83 100644 --- a/src/renderer/components/+user-management/+role-bindings/dialog.tsx +++ b/src/renderer/components/+user-management/+role-bindings/dialog.tsx @@ -91,17 +91,15 @@ export class RoleBindingDialog extends React.Component { const serviceAccounts = Array.from(this.selectedAccounts, sa => ({ name: sa.getName(), kind: "ServiceAccount" as const, - namespace: this.bindingNamespace, + namespace: sa.getNs(), })); const users = Array.from(this.selectedUsers, user => ({ name: user, - kind: "User" as const, - namespace: this.bindingNamespace, + kind: "User" as const })); const groups = Array.from(this.selectedGroups, group => ({ name: group, - kind: "Group" as const, - namespace: this.bindingNamespace, + kind: "Group" as const })); return [ diff --git a/src/renderer/components/cluster-manager/cluster-manager.scss b/src/renderer/components/cluster-manager/cluster-manager.scss index da31c2a07b..dddbb1a5e5 100644 --- a/src/renderer/components/cluster-manager/cluster-manager.scss +++ b/src/renderer/components/cluster-manager/cluster-manager.scss @@ -35,6 +35,10 @@ position: relative; display: flex; flex-direction: column; + + > * { + z-index: 1; + } } .HotbarMenu { diff --git a/src/renderer/initializers/index.ts b/src/renderer/initializers/index.ts index c9370d5a82..03f32f1a9d 100644 --- a/src/renderer/initializers/index.ts +++ b/src/renderer/initializers/index.ts @@ -27,3 +27,4 @@ export * from "./registries"; export * from "./welcome-menu-registry"; export * from "./workloads-overview-detail-registry"; export * from "./catalog"; +export * from "./ipc"; diff --git a/src/renderer/initializers/ipc.ts b/src/renderer/initializers/ipc.ts new file mode 100644 index 0000000000..fedb007d9b --- /dev/null +++ b/src/renderer/initializers/ipc.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * 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 { ipcRendererOn } from "../../common/ipc"; +import { ExtensionLoader } from "../../extensions/extension-loader"; +import type { LensRendererExtension } from "../../extensions/lens-renderer-extension"; + +export function initIpcRendererListeners() { + ipcRendererOn("extension:navigate", (event, extId: string, pageId ?: string, params?: Record) => { + ExtensionLoader.getInstance().getInstanceById(extId).navigate(pageId, params); + }); +} diff --git a/src/renderer/initializers/registries.ts b/src/renderer/initializers/registries.ts index 08594d41c5..1d455a0bcc 100644 --- a/src/renderer/initializers/registries.ts +++ b/src/renderer/initializers/registries.ts @@ -32,7 +32,6 @@ export function initRegistries() { registries.KubeObjectDetailRegistry.createInstance(); registries.KubeObjectMenuRegistry.createInstance(); registries.KubeObjectStatusRegistry.createInstance(); - registries.PageMenuRegistry.createInstance(); registries.StatusBarRegistry.createInstance(); registries.WelcomeMenuRegistry.createInstance(); registries.WorkloadsOverviewDetailRegistry.createInstance(); diff --git a/src/renderer/kube-object.store.ts b/src/renderer/kube-object.store.ts index 0c9f8688a2..62dd1cb117 100644 --- a/src/renderer/kube-object.store.ts +++ b/src/renderer/kube-object.store.ts @@ -280,7 +280,7 @@ export abstract class KubeObjectStore extends ItemSt async update(item: T, data: Partial): Promise { const newItem = await item.update(data); - + ensureObjectSelfLink(this.api, newItem); const index = this.items.findIndex(item => item.getId() === newItem.getId()); @@ -332,6 +332,10 @@ export abstract class KubeObjectStore extends ItemSt } private watchNamespace(namespace: string, abortController: AbortController) { + if (!this.api.getResourceVersion(namespace)) { + return; + } + let timedRetry: NodeJS.Timeout; const watch = () => this.api.watch({ namespace,