/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import React, { useEffect, useState } from "react"; import { observer } from "mobx-react"; import type { Cluster } from "../../../../common/cluster/cluster"; import { Input } from "../../input"; import { SubTitle } from "../../layout/sub-title"; import type { ShowNotification } from "../../notifications"; import { Icon } from "../../icon"; import { PathPicker } from "../../path-picker"; import { isWindows } from "../../../../common/vars"; import { withInjectables } from "@ogre-tools/injectable-react"; import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable"; import type { ValidateDirectory } from "../../../../common/fs/validate-directory.injectable"; import validateDirectoryInjectable from "../../../../common/fs/validate-directory.injectable"; import type { ResolveTilde } from "../../../../common/path/resolve-tilde.injectable"; import resolveTildeInjectable from "../../../../common/path/resolve-tilde.injectable"; import Gutter from "../../gutter/gutter"; export interface ClusterLocalTerminalSettingProps { cluster: Cluster; } interface Dependencies { showErrorNotification: ShowNotification; validateDirectory: ValidateDirectory; resolveTilde: ResolveTilde; } const NonInjectedClusterLocalTerminalSetting = observer(({ cluster, showErrorNotification, validateDirectory, resolveTilde, }: Dependencies & ClusterLocalTerminalSettingProps) => { if (!cluster) { return null; } const [directory, setDirectory] = useState(cluster.preferences?.terminalCWD || ""); const [defaultNamespace, setDefaultNamespaces] = useState(cluster.preferences?.defaultNamespace || ""); const [placeholderDefaultNamespace, setPlaceholderDefaultNamespace] = useState("default"); useEffect(() => { (async () => { const kubeconfig = await cluster.getKubeconfig(); const { namespace } = kubeconfig.getContextObject(cluster.contextName) ?? {}; if (namespace) { setPlaceholderDefaultNamespace(namespace); } })(); setDirectory(cluster.preferences?.terminalCWD || ""); setDefaultNamespaces(cluster.preferences?.defaultNamespace || ""); }, [cluster]); const commitDirectory = async (directory: string) => { cluster.preferences ??= {}; if (!directory) { cluster.preferences.terminalCWD = undefined; } else { const dir = resolveTilde(directory); const result = await validateDirectory(dir); if (!result.callWasSuccessful) { showErrorNotification( <> Terminal Working Directory

{"Your changes were not saved because "} {result.error}

, ); } else { cluster.preferences.terminalCWD = dir; setDirectory(dir); } } }; const commitDefaultNamespace = () => { cluster.preferences ??= {}; cluster.preferences.defaultNamespace = defaultNamespace || undefined; }; const setAndCommitDirectory = (newPath: string) => { setDirectory(newPath); commitDirectory(newPath); }; const openFilePicker = () => { PathPicker.pick({ label: "Choose Working Directory", buttonLabel: "Pick", properties: ["openDirectory", "showHiddenFiles"], onPick: ([directory]) => setAndCommitDirectory(directory), }); }; return ( <>
commitDirectory(directory)} placeholder={isWindows ? "$USERPROFILE" : "$HOME"} iconRight={( <> { directory && ( setAndCommitDirectory("")} smallest style={{ marginRight: "var(--margin)" }} /> ) } )} /> An explicit start path where the terminal will be launched, {" "} this is used as the current working directory (cwd) for the shell process.
Default namespace used for kubectl.
); }); export const ClusterLocalTerminalSetting = withInjectables(NonInjectedClusterLocalTerminalSetting, { getProps: (di, props) => ({ ...props, showErrorNotification: di.inject(showErrorNotificationInjectable), validateDirectory: di.inject(validateDirectoryInjectable), resolveTilde: di.inject(resolveTildeInjectable), }), });