From f589987e19993408acadb7b67b265408cbc5c597 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Wed, 4 Aug 2021 15:47:51 +0300 Subject: [PATCH] Kubeconfig syncs from Catalog Signed-off-by: Alex Andreev --- .../catalog-entities/kubernetes-cluster.ts | 24 +---- src/common/catalog/catalog-entity.ts | 1 + src/common/user-store/user-store.ts | 2 +- src/common/utils/extended-map.ts | 6 ++ src/renderer/bootstrap.tsx | 1 + .../+catalog/catalog-add-button.tsx | 9 +- .../+preferences/kubeconfig-syncs.tsx | 60 ++++-------- .../+preferences/kubectl-binaries.tsx | 4 +- .../components/path-picker/path-picker.tsx | 80 ++++++++++++++++ .../catalog-category-registry.tsx | 95 +++++++++++++++++++ src/renderer/initializers/index.ts | 1 + 11 files changed, 217 insertions(+), 66 deletions(-) create mode 100644 src/renderer/components/path-picker/path-picker.tsx create mode 100644 src/renderer/initializers/catalog-category-registry.tsx diff --git a/src/common/catalog-entities/kubernetes-cluster.ts b/src/common/catalog-entities/kubernetes-cluster.ts index 2e8fdccf04..14a584ee8c 100644 --- a/src/common/catalog-entities/kubernetes-cluster.ts +++ b/src/common/catalog-entities/kubernetes-cluster.ts @@ -20,12 +20,11 @@ */ import { catalogCategoryRegistry } from "../catalog/catalog-category-registry"; -import { CatalogEntity, CatalogEntityActionContext, CatalogEntityAddMenuContext, CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; +import { CatalogEntity, CatalogEntityActionContext, CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; import { clusterActivateHandler, clusterDeleteHandler, clusterDisconnectHandler } from "../cluster-ipc"; import { ClusterStore } from "../cluster-store"; import { requestMain } from "../ipc"; import { CatalogCategory, CatalogCategorySpec } from "../catalog"; -import { addClusterURL } from "../routes"; import { app } from "electron"; import type { CatalogEntitySpec } from "../catalog/catalog-entity"; import { HotbarStore } from "../hotbar-store"; @@ -43,7 +42,6 @@ export interface KubernetesClusterPrometheusMetrics { export interface KubernetesClusterSpec extends CatalogEntitySpec { kubeconfigPath: string; kubeconfigContext: string; - accessibleNamespaces?: string[]; metrics?: { source: string; prometheus?: KubernetesClusterPrometheusMetrics; @@ -149,7 +147,7 @@ export class KubernetesCluster extends CatalogEntity { - ctx.menuItems.push({ - icon: "text_snippet", - title: "Add from kubeconfig", - onClick: () => { - ctx.navigate(addClusterURL()); - } - }); - }); - } } -catalogCategoryRegistry.add(new KubernetesClusterCategory()); +export const kubernetesClusterCategory = new KubernetesClusterCategory(); + +catalogCategoryRegistry.add(kubernetesClusterCategory); diff --git a/src/common/catalog/catalog-entity.ts b/src/common/catalog/catalog-entity.ts index bc3e360a7b..7b9db2f0ff 100644 --- a/src/common/catalog/catalog-entity.ts +++ b/src/common/catalog/catalog-entity.ts @@ -123,6 +123,7 @@ export interface CatalogEntityContextMenu { export interface CatalogEntityAddMenu extends CatalogEntityContextMenu { icon: string; + defaultAction?: boolean; } export interface CatalogEntitySettingsMenu { diff --git a/src/common/user-store/user-store.ts b/src/common/user-store/user-store.ts index 7121357671..9cc5cd06e9 100644 --- a/src/common/user-store/user-store.ts +++ b/src/common/user-store/user-store.ts @@ -213,6 +213,6 @@ export class UserStore extends BaseStore /* implements UserStore * Getting default directory to download kubectl binaries * @returns string */ -export function getDefaultKubectlPath(): string { +export function getDefaultKubectlDownloadPath(): string { return path.join((app || remote.app).getPath("userData"), "binaries"); } diff --git a/src/common/utils/extended-map.ts b/src/common/utils/extended-map.ts index bd29cbbfe0..46621194e2 100644 --- a/src/common/utils/extended-map.ts +++ b/src/common/utils/extended-map.ts @@ -21,6 +21,12 @@ import { action, ObservableMap } from "mobx"; +export function multiSet(map: Map, newEntries: [T, V][]): void { + for (const [key, val] of newEntries) { + map.set(key, val); + } +} + export class ExtendedMap extends Map { static new(entries?: readonly (readonly [K, V])[] | null): ExtendedMap { return new ExtendedMap(entries); diff --git a/src/renderer/bootstrap.tsx b/src/renderer/bootstrap.tsx index 87c30dba59..3e7daa5404 100644 --- a/src/renderer/bootstrap.tsx +++ b/src/renderer/bootstrap.tsx @@ -81,6 +81,7 @@ export async function bootstrap(App: AppComponent) { initializers.initWelcomeMenuRegistry(); initializers.initWorkloadsOverviewDetailRegistry(); initializers.initCatalogEntityDetailRegistry(); + initializers.initCatalogCategoryRegistryEntries(); initializers.initCatalog(); initializers.initIpcRendererListeners(); diff --git a/src/renderer/components/+catalog/catalog-add-button.tsx b/src/renderer/components/+catalog/catalog-add-button.tsx index 25cd43239f..37b16dab6b 100644 --- a/src/renderer/components/+catalog/catalog-add-button.tsx +++ b/src/renderer/components/+catalog/catalog-add-button.tsx @@ -73,9 +73,10 @@ export class CatalogAddButton extends React.Component { @boundMethod onButtonClick() { - if (this.menuItems.length == 1) { - this.menuItems[0].onClick(); - } + const defaultAction = this.menuItems.find(item => item.defaultAction)?.onClick; + const clickAction = defaultAction || (this.menuItems.length === 1 ? this.menuItems[0].onClick : null); + + clickAction?.(); } render() { @@ -97,7 +98,7 @@ export class CatalogAddButton extends React.Component { { this.menuItems.map((menuItem, index) => { return } + icon={} tooltipTitle={menuItem.title} onClick={() => menuItem.onClick()} TooltipClasses={{ diff --git a/src/renderer/components/+preferences/kubeconfig-syncs.tsx b/src/renderer/components/+preferences/kubeconfig-syncs.tsx index c1e049cbde..c09113aac1 100644 --- a/src/renderer/components/+preferences/kubeconfig-syncs.tsx +++ b/src/renderer/components/+preferences/kubeconfig-syncs.tsx @@ -20,19 +20,17 @@ */ import React from "react"; -import { remote } from "electron"; import { Avatar, IconButton, List, ListItem, ListItemAvatar, ListItemSecondaryAction, ListItemText, Paper } from "@material-ui/core"; import { Description, Folder, Delete, HelpOutline } from "@material-ui/icons"; import { action, computed, observable, reaction, makeObservable } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import fse from "fs-extra"; import { KubeconfigSyncEntry, KubeconfigSyncValue, UserStore } from "../../../common/user-store"; -import { Button } from "../button"; -import { SubTitle } from "../layout/sub-title"; import { Spinner } from "../spinner"; import logger from "../../../main/logger"; -import { iter } from "../../utils"; +import { iter, multiSet } from "../../utils"; import { isWindows } from "../../../common/vars"; +import { PathPicker } from "../path-picker/path-picker"; interface SyncInfo { type: "file" | "folder" | "unknown"; @@ -70,7 +68,9 @@ async function getMapEntry({ filePath, ...data}: KubeconfigSyncEntry): Promise<[ } } -type SelectPathOptions = ("openFile" | "openDirectory")[]; +export async function getAllEntries(filePaths: string[]): Promise<[string, Value][]> { + return Promise.all(filePaths.map(filePath => getMapEntry({ filePath }))); +} @observer export class KubeconfigSyncs extends React.Component { @@ -109,24 +109,7 @@ export class KubeconfigSyncs extends React.Component { } @action - async openDialog(message: string, actions: SelectPathOptions) { - const { dialog, BrowserWindow } = remote; - const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), { - properties: ["showHiddenFiles", "multiSelections", ...actions], - message, - buttonLabel: "Sync", - }); - - if (canceled) { - return; - } - - const newEntries = await Promise.all(filePaths.map(filePath => getMapEntry({ filePath }))); - - for (const [filePath, info] of newEntries) { - this.syncs.set(filePath, info); - } - } + onPick = async (filePaths: string[]) => multiSet(this.syncs, await getAllEntries(filePaths)); renderEntryIcon(entry: Entry) { switch (entry.info.type) { @@ -188,27 +171,30 @@ export class KubeconfigSyncs extends React.Component { if (isWindows) { return (
-
); } return ( -