diff --git a/frontend/src/components/App/icons.ts b/frontend/src/components/App/icons.ts
index b2fa0780dd5..dce03b1c21a 100644
--- a/frontend/src/components/App/icons.ts
+++ b/frontend/src/components/App/icons.ts
@@ -423,6 +423,9 @@ const mdiIcons = {
'content-copy': {
body: '\u003Cpath fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12z"/\u003E',
},
+ 'content-paste': {
+ body: '\u003Cpath fill="currentColor" d="M19 20H5V4h2v3h10V4h2m-7-2a1 1 0 0 1 1 1a1 1 0 0 1-1 1a1 1 0 0 1-1-1a1 1 0 0 1 1-1m7 0h-4.18C14.4.84 13.3 0 12 0S9.6.84 9.18 2H5a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2"/\u003E',
+ },
'arrow-left': {
body: '\u003Cpath fill="currentColor" d="M20 11v2H8l5.5 5.5l-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5L8 11z"/\u003E',
},
diff --git a/frontend/src/components/common/Terminal.tsx b/frontend/src/components/common/Terminal.tsx
index 4f1cf88216f..c6ccb9e5ee3 100644
--- a/frontend/src/components/common/Terminal.tsx
+++ b/frontend/src/components/common/Terminal.tsx
@@ -15,11 +15,15 @@
*/
import '@xterm/xterm/css/xterm.css';
+import { Icon } from '@iconify/react';
import Box from '@mui/material/Box';
import { DialogProps } from '@mui/material/Dialog';
import DialogContent from '@mui/material/DialogContent';
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
+import ListItemIcon from '@mui/material/ListItemIcon';
+import ListItemText from '@mui/material/ListItemText';
+import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import Select from '@mui/material/Select';
import { FitAddon } from '@xterm/addon-fit';
@@ -68,6 +72,11 @@ export default function Terminal(props: TerminalProps) {
available: getAvailableShells(),
currentIdx: 0,
});
+ const [contextMenu, setContextMenu] = React.useState<{
+ mouseX: number;
+ mouseY: number;
+ hasSelection: boolean;
+ } | null>(null);
const { t } = useTranslation(['translation', 'glossary']);
function getDefaultContainer() {
@@ -369,6 +378,46 @@ export default function Terminal(props: TerminalProps) {
setContainer(event.target.value);
}
+ const handleContextMenu = (event: React.MouseEvent) => {
+ event.preventDefault();
+ const hasSelection = !!xtermRef.current?.xterm.getSelection();
+ setContextMenu({
+ mouseX: event.clientX + 2,
+ mouseY: event.clientY - 6,
+ hasSelection,
+ });
+ };
+
+ const handleContextMenuClose = () => {
+ setContextMenu(null);
+ };
+
+ const handleCopy = async () => {
+ if (xtermRef.current) {
+ const selection = xtermRef.current.xterm.getSelection();
+ if (selection) {
+ try {
+ await navigator.clipboard.writeText(selection);
+ } catch (err) {
+ console.error('Failed to copy text: ', err);
+ }
+ }
+ }
+ handleContextMenuClose();
+ };
+
+ const handlePaste = async () => {
+ if (xtermRef.current) {
+ try {
+ const text = await navigator.clipboard.readText();
+ send(0, text);
+ } catch (err) {
+ console.error('Failed to paste text: ', err);
+ }
+ }
+ handleContextMenuClose();
+ };
+
function isSuccessfulExitError(channel: number, text: string): boolean {
// Linux container Error
if (channel === 3) {
@@ -479,8 +528,34 @@ export default function Terminal(props: TerminalProps) {
setTerminalContainerRef(x)}
- style={{ flex: 1, display: 'flex', flexDirection: 'column-reverse' }}
+ onContextMenu={handleContextMenu}
+ style={{
+ flex: 1,
+ display: 'flex',
+ flexDirection: 'column-reverse',
+ }}
/>
+
);
diff --git a/frontend/src/i18n/locales/de/translation.json b/frontend/src/i18n/locales/de/translation.json
index 813048be994..a7e3702fe11 100644
--- a/frontend/src/i18n/locales/de/translation.json
+++ b/frontend/src/i18n/locales/de/translation.json
@@ -400,6 +400,7 @@
"Failed to run \"{{ command }}\"": "Ausführung von \"{{ command }}\" fehlgeschlagen",
"Trying to attach to the container {{ container }}…": "Versuche, an den Container {{ container }} anzuhängen…",
"Trying to run \"{{command}}\"…": "Versuche, \"{{command}}\" auszuführen…",
+ "Paste": "Einfügen",
"Attach: {{ itemName }}": "",
"Terminal: {{ itemName }}": "",
"Timezone": "Zeitzone",
diff --git a/frontend/src/i18n/locales/en/translation.json b/frontend/src/i18n/locales/en/translation.json
index b7e3c1713ea..a4c8be8ba82 100644
--- a/frontend/src/i18n/locales/en/translation.json
+++ b/frontend/src/i18n/locales/en/translation.json
@@ -400,6 +400,7 @@
"Failed to run \"{{ command }}\"": "Failed to run \"{{ command }}\"",
"Trying to attach to the container {{ container }}…": "Trying to attach to the container {{ container }}…",
"Trying to run \"{{command}}\"…": "Trying to run \"{{command}}\"…",
+ "Paste": "Paste",
"Attach: {{ itemName }}": "Attach: {{ itemName }}",
"Terminal: {{ itemName }}": "Terminal: {{ itemName }}",
"Timezone": "Timezone",
diff --git a/frontend/src/i18n/locales/es/translation.json b/frontend/src/i18n/locales/es/translation.json
index e202c7f01e5..a7b28d1c249 100644
--- a/frontend/src/i18n/locales/es/translation.json
+++ b/frontend/src/i18n/locales/es/translation.json
@@ -403,6 +403,7 @@
"Failed to run \"{{ command }}\"": "Fallo al ejecutar \"{{ command }}\"",
"Trying to attach to the container {{ container }}…": "Intentando adjuntarse al contenedor {{ container }}…",
"Trying to run \"{{command}}\"…": "Intentando ejecutar \"{{command}}\"…",
+ "Paste": "Pegar",
"Attach: {{ itemName }}": "",
"Terminal: {{ itemName }}": "",
"Timezone": "Huso horario",
diff --git a/frontend/src/i18n/locales/fr/translation.json b/frontend/src/i18n/locales/fr/translation.json
index 12429e6367e..a599cf07ba1 100644
--- a/frontend/src/i18n/locales/fr/translation.json
+++ b/frontend/src/i18n/locales/fr/translation.json
@@ -403,6 +403,7 @@
"Failed to run \"{{ command }}\"": "Échec de l'exécution de \"{commande }}\"",
"Trying to attach to the container {{ container }}…": "Tentative de connexion au conteneur {{ container }}…",
"Trying to run \"{{command}}\"…": "Essayer d'exécuter \"{{command}}\"…",
+ "Paste": "Coller",
"Attach: {{ itemName }}": "",
"Terminal: {{ itemName }}": "",
"Timezone": "Fuseau horaire",
diff --git a/frontend/src/i18n/locales/hi/translation.json b/frontend/src/i18n/locales/hi/translation.json
index c211c4f70fc..33b3acb2317 100644
--- a/frontend/src/i18n/locales/hi/translation.json
+++ b/frontend/src/i18n/locales/hi/translation.json
@@ -400,6 +400,7 @@
"Failed to run \"{{ command }}\"": "\"{{ command }}\" चलाने में विफल",
"Trying to attach to the container {{ container }}…": "कंटेनर {{ container }} से जुड़ने का प्रयास कर रहे हैं…",
"Trying to run \"{{command}}\"…": "\"{{command}}\" चलाने का प्रयास कर रहे हैं…",
+ "Paste": "पेस्ट करें",
"Attach: {{ itemName }}": "जोड़ें: {{ itemName }}",
"Terminal: {{ itemName }}": "टर्मिनल: {{ itemName }}",
"Timezone": "समय क्षेत्र",
diff --git a/frontend/src/i18n/locales/it/translation.json b/frontend/src/i18n/locales/it/translation.json
index 5345b0abbc7..16508329c03 100644
--- a/frontend/src/i18n/locales/it/translation.json
+++ b/frontend/src/i18n/locales/it/translation.json
@@ -403,6 +403,7 @@
"Failed to run \"{{ command }}\"": "Impossibile eseguire \"{{ command }}\"",
"Trying to attach to the container {{ container }}…": "Tentativo di collegamento al container {{ container }}…",
"Trying to run \"{{command}}\"…": "Sto tentando di eseguire \"{{command}}\"…",
+ "Paste": "Incolla",
"Attach: {{ itemName }}": "Collega: {{ itemName }}",
"Terminal: {{ itemName }}": "Terminale: {{ itemName }}",
"Timezone": "Fuso orario",
diff --git a/frontend/src/i18n/locales/ja/translation.json b/frontend/src/i18n/locales/ja/translation.json
index 5aae17befc1..2faf9840db7 100644
--- a/frontend/src/i18n/locales/ja/translation.json
+++ b/frontend/src/i18n/locales/ja/translation.json
@@ -397,6 +397,7 @@
"Failed to run \"{{ command }}\"": "\"{{ command }}\" の実行に失敗しました",
"Trying to attach to the container {{ container }}…": "コンテナー {{ container }} にアタッチしようとしています…",
"Trying to run \"{{command}}\"…": "\"{{command}}\" を実行しようとしています…",
+ "Paste": "貼り付け",
"Attach: {{ itemName }}": "アタッチ: {{ itemName }}",
"Terminal: {{ itemName }}": "ターミナル: {{ itemName }}",
"Timezone": "タイムゾーン",
diff --git a/frontend/src/i18n/locales/ko/translation.json b/frontend/src/i18n/locales/ko/translation.json
index 6f4758bf423..60e978d3f72 100644
--- a/frontend/src/i18n/locales/ko/translation.json
+++ b/frontend/src/i18n/locales/ko/translation.json
@@ -397,6 +397,7 @@
"Failed to run \"{{ command }}\"": "\"{{ command }}\" 실행에 실패했습니다.",
"Trying to attach to the container {{ container }}…": "컨테이너 {{ container }}에 연결을 시도 중…",
"Trying to run \"{{command}}\"…": "\"{{command}}\" 실행 중…",
+ "Paste": "붙여넣기",
"Attach: {{ itemName }}": "연결: {{ itemName }}",
"Terminal: {{ itemName }}": "터미널: {{ itemName }}",
"Timezone": "시간대",
diff --git a/frontend/src/i18n/locales/pt/translation.json b/frontend/src/i18n/locales/pt/translation.json
index 1685951605f..acca5d8a3c4 100644
--- a/frontend/src/i18n/locales/pt/translation.json
+++ b/frontend/src/i18n/locales/pt/translation.json
@@ -403,6 +403,7 @@
"Failed to run \"{{ command }}\"": "Falha ao executar \"{{ command }}\"",
"Trying to attach to the container {{ container }}…": "A tentar anexar ao container {{ container }}…",
"Trying to run \"{{command}}\"…": "A tentar executar \"{{command}}\"…",
+ "Paste": "Colar",
"Attach: {{ itemName }}": "",
"Terminal: {{ itemName }}": "",
"Timezone": "Fuso horário",
diff --git a/frontend/src/i18n/locales/ta/translation.json b/frontend/src/i18n/locales/ta/translation.json
index eb9b23e6f7e..263245a675f 100644
--- a/frontend/src/i18n/locales/ta/translation.json
+++ b/frontend/src/i18n/locales/ta/translation.json
@@ -400,6 +400,7 @@
"Failed to run \"{{ command }}\"": "\"{{ command }}\"-ஐ இயக்குவதில் தோல்வி",
"Trying to attach to the container {{ container }}…": "{{ container }} கண்டெய்னருடன் இணைக்க முயற்சிக்கிறது...",
"Trying to run \"{{command}}\"…": "\"{{command}}\"-ஐ இயக்க முயற்சிக்கிறது...",
+ "Paste": "ஒட்டு",
"Attach: {{ itemName }}": "அட்டாச்: {{ itemName }}",
"Terminal: {{ itemName }}": "டெர்மினல்: {{ itemName }}",
"Timezone": "டைம்ஸோன்",
diff --git a/frontend/src/i18n/locales/zh-tw/translation.json b/frontend/src/i18n/locales/zh-tw/translation.json
index 2e9325cf72e..15db38f056e 100644
--- a/frontend/src/i18n/locales/zh-tw/translation.json
+++ b/frontend/src/i18n/locales/zh-tw/translation.json
@@ -397,6 +397,7 @@
"Failed to run \"{{ command }}\"": "執行 \"{{ command }}\" 失敗",
"Trying to attach to the container {{ container }}…": "嘗試附加到容器 {{ container }}…",
"Trying to run \"{{command}}\"…": "嘗試執行 \"{{command}}\"…",
+ "Paste": "貼上",
"Attach: {{ itemName }}": "附加:{{ itemName }}",
"Terminal: {{ itemName }}": "終端:{{ itemName }}",
"Timezone": "時區",
diff --git a/frontend/src/i18n/locales/zh/translation.json b/frontend/src/i18n/locales/zh/translation.json
index e84b098a5af..66f5aa3ca41 100644
--- a/frontend/src/i18n/locales/zh/translation.json
+++ b/frontend/src/i18n/locales/zh/translation.json
@@ -397,6 +397,7 @@
"Failed to run \"{{ command }}\"": "执行 \"{{ command }}\" 失败",
"Trying to attach to the container {{ container }}…": "尝试附加到容器 {{ container }}…",
"Trying to run \"{{command}}\"…": "尝试执行 \"{{command}}\"…",
+ "Paste": "粘贴",
"Attach: {{ itemName }}": "附加:{{ itemName }}",
"Terminal: {{ itemName }}": "终端:{{ itemName }}",
"Timezone": "时区",