diff --git a/src/features/preferences/renderer/preference-items/terminal/copy-paste-from-terminal/copy-paste-from-terminal-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/terminal/copy-paste-from-terminal/copy-paste-from-terminal-preference-item.injectable.ts new file mode 100644 index 0000000000..61dcc3dd40 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/copy-paste-from-terminal/copy-paste-from-terminal-preference-item.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../../preference-item-injection-token"; +import { CopyPasteFromTerminal } from "./copy-paste-from-terminal"; + +const copyPasteFromTerminalPreferenceItemInjectable = getInjectable({ + id: "copy-paste-from-terminal-preference-item", + + instantiate: () => ({ + kind: "item" as const, + id: "copy-paste-from-terminal-preference-item", + parentId: "terminal-page", + orderNumber: 20, + Component: CopyPasteFromTerminal, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default copyPasteFromTerminalPreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/terminal/copy-paste-from-terminal/copy-paste-from-terminal.tsx b/src/features/preferences/renderer/preference-items/terminal/copy-paste-from-terminal/copy-paste-from-terminal.tsx new file mode 100644 index 0000000000..50a63d2c66 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/copy-paste-from-terminal/copy-paste-from-terminal.tsx @@ -0,0 +1,42 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import { SubTitle } from "../../../../../../renderer/components/layout/sub-title"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import type { UserStore } from "../../../../../../common/user-store"; +import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable"; +import { observer } from "mobx-react"; +import { Switch } from "../../../../../../renderer/components/switch"; + +interface Dependencies { + userStore: UserStore; +} + +const NonInjectedCopyPasteFromTerminal = observer( + ({ userStore }: Dependencies) => { + + return ( +
+ + userStore.terminalCopyOnSelect = !userStore.terminalCopyOnSelect} + > + Copy on select and paste on right-click + +
+ ); + }, +); + +export const CopyPasteFromTerminal = withInjectables( + NonInjectedCopyPasteFromTerminal, + + { + getProps: (di) => ({ + userStore: di.inject(userStoreInjectable), + }), + }, +); diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-font-family/terminal-font-family-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/terminal/terminal-font-family/terminal-font-family-preference-item.injectable.ts new file mode 100644 index 0000000000..7d016f8603 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-font-family/terminal-font-family-preference-item.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../../preference-item-injection-token"; +import { TerminalFontFamily } from "./terminal-font-family"; + +const terminalFontFamilyPreferenceItemInjectable = getInjectable({ + id: "terminal-font-family-preference-item", + + instantiate: () => ({ + kind: "item" as const, + id: "terminal-font-family-preference-item", + parentId: "terminal-page", + orderNumber: 40, + Component: TerminalFontFamily, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default terminalFontFamilyPreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-font-family/terminal-font-family.tsx b/src/features/preferences/renderer/preference-items/terminal/terminal-font-family/terminal-font-family.tsx new file mode 100644 index 0000000000..14bc5efacd --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-font-family/terminal-font-family.tsx @@ -0,0 +1,70 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import { SubTitle } from "../../../../../../renderer/components/layout/sub-title"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import type { UserStore } from "../../../../../../common/user-store"; +import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable"; +import { observer } from "mobx-react"; +import type { SelectOption } from "../../../../../../renderer/components/select"; +import { Select } from "../../../../../../renderer/components/select"; +import type { Logger } from "../../../../../../common/logger"; +import { action } from "mobx"; +import loggerInjectable from "../../../../../../common/logger.injectable"; + +interface Dependencies { + userStore: UserStore; + logger: Logger; +} + +const NonInjectedTerminalFontFamily = observer( + ({ userStore, logger }: Dependencies) => { + + // fonts must be declared in `fonts.scss` and at `template.html` (if early-preloading required) + const supportedCustomFonts: SelectOption[] = [ + "RobotoMono", "Anonymous Pro", "IBM Plex Mono", "JetBrains Mono", "Red Hat Mono", + "Source Code Pro", "Space Mono", "Ubuntu Mono", + ].map(customFont => { + const { fontFamily, fontSize } = userStore.terminalConfig; + + return { + label: {customFont}, + value: customFont, + isSelected: fontFamily === customFont, + }; + }); + + const onFontFamilyChange = action(({ value: fontFamily }: SelectOption) => { + logger.info(`setting terminal font to ${fontFamily}`); + + userStore.terminalConfig.fontFamily = fontFamily; // save to external storage + }); + + + return ( +
+ + userStore.terminalConfig.fontSize = Number(value)} + /> + + ); + }, +); + +export const TerminalFontSize = withInjectables( + NonInjectedTerminalFontSize, + + { + getProps: (di) => ({ + userStore: di.inject(userStoreInjectable), + }), + }, +); diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-page-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/terminal/terminal-page-preference-item.injectable.ts new file mode 100644 index 0000000000..93c9b3892e --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-page-preference-item.injectable.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../preference-item-injection-token"; +import { TerminalPage } from "./terminal-page"; +import { HorizontalLine } from "../../../../../renderer/components/+preferences/horizontal-line/horizontal-line"; + +const terminalPagePreferenceItemInjectable = getInjectable({ + id: "terminal-preference-page", + + instantiate: () => ({ + kind: "page" as const, + id: "terminal-page", + parentId: "terminal-tab", + orderNumber: 0, + Component: TerminalPage, + childrenSeparator: HorizontalLine, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default terminalPagePreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-page.tsx b/src/features/preferences/renderer/preference-items/terminal/terminal-page.tsx new file mode 100644 index 0000000000..a58be193ab --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-page.tsx @@ -0,0 +1,14 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import type { PreferenceItemComponent } from "../preference-item-injection-token"; + +export const TerminalPage: PreferenceItemComponent = ({ children }) => ( +
+

Terminal

+ + {children} +
+); diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-preference-tab.injectable.ts b/src/features/preferences/renderer/preference-items/terminal/terminal-preference-tab.injectable.ts new file mode 100644 index 0000000000..4654e54c90 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-preference-tab.injectable.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../preference-item-injection-token"; + +const terminalPreferenceTabInjectable = getInjectable({ + id: "terminal-preference-tab", + + instantiate: () => ({ + kind: "tab" as const, + id: "terminal-tab", + pathId: "terminal", + parentId: "preference-tabs" as const, + testId: "terminal-preferences-page", + label: "Terminal", + orderNumber: 20, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default terminalPreferenceTabInjectable; diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-shell-path/terminal-shell-path-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/terminal/terminal-shell-path/terminal-shell-path-preference-item.injectable.ts new file mode 100644 index 0000000000..ef0cd88fa7 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-shell-path/terminal-shell-path-preference-item.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../../preference-item-injection-token"; +import { TerminalShellPath } from "./terminal-shell-path"; + +const terminalShellPathPreferenceItemInjectable = getInjectable({ + id: "terminal-shell-path-preference-item", + + instantiate: () => ({ + kind: "item" as const, + id: "terminal-shell-path", + parentId: "terminal-page", + orderNumber: 10, + Component: TerminalShellPath, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default terminalShellPathPreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-shell-path/terminal-shell-path.tsx b/src/features/preferences/renderer/preference-items/terminal/terminal-shell-path/terminal-shell-path.tsx new file mode 100644 index 0000000000..df8529c994 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-shell-path/terminal-shell-path.tsx @@ -0,0 +1,46 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import { SubTitle } from "../../../../../../renderer/components/layout/sub-title"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import type { UserStore } from "../../../../../../common/user-store"; +import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable"; +import { observer } from "mobx-react"; +import { Input } from "../../../../../../renderer/components/input"; +import defaultShellInjectable from "../../../../../../renderer/components/+preferences/default-shell.injectable"; + +interface Dependencies { + userStore: UserStore; + defaultShell: string; +} + +const NonInjectedTerminalShellPath = observer( + ({ userStore, defaultShell }: Dependencies) => { + + return ( +
+ + userStore.shell = value} + /> +
+ + ); + }, +); + +export const TerminalShellPath = withInjectables( + NonInjectedTerminalShellPath, + + { + getProps: (di) => ({ + userStore: di.inject(userStoreInjectable), + defaultShell: di.inject(defaultShellInjectable), + }), + }, +); diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-theme/terminal-theme-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/terminal/terminal-theme/terminal-theme-preference-item.injectable.ts new file mode 100644 index 0000000000..d292be0747 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-theme/terminal-theme-preference-item.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../../preference-item-injection-token"; +import { TerminalTheme } from "./terminal-theme"; + +const terminalThemePreferenceItemInjectable = getInjectable({ + id: "terminal-theme", + + instantiate: () => ({ + kind: "item" as const, + id: "terminal-theme", + parentId: "terminal-page", + orderNumber: 30, + Component: TerminalTheme, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default terminalThemePreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/terminal/terminal-theme/terminal-theme.tsx b/src/features/preferences/renderer/preference-items/terminal/terminal-theme/terminal-theme.tsx new file mode 100644 index 0000000000..c7819bacec --- /dev/null +++ b/src/features/preferences/renderer/preference-items/terminal/terminal-theme/terminal-theme.tsx @@ -0,0 +1,58 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import { SubTitle } from "../../../../../../renderer/components/layout/sub-title"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import type { UserStore } from "../../../../../../common/user-store"; +import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable"; +import { observer } from "mobx-react"; +import { Select } from "../../../../../../renderer/components/select"; +import themeStoreInjectable from "../../../../../../renderer/themes/store.injectable"; +import type { ThemeStore } from "../../../../../../renderer/themes/store"; + +interface Dependencies { + userStore: UserStore; + themeStore: ThemeStore; +} + +const NonInjectedTerminalTheme = observer( + ({ userStore, themeStore }: Dependencies) => { + + const themeOptions = [ + { + value: "", // TODO: replace with a sentinal value that isn't string (and serialize it differently) + label: "Match Lens Theme", + }, + ...Array.from(themeStore.themes, ([themeId, { name }]) => ({ + value: themeId, + label: name, + })), + ]; + + return ( +
+ +