Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions frontend/src/components/App/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
},
Expand Down
77 changes: 76 additions & 1 deletion frontend/src/components/common/Terminal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -479,8 +528,34 @@ export default function Terminal(props: TerminalProps) {
<div
id="xterm-container"
ref={x => setTerminalContainerRef(x)}
style={{ flex: 1, display: 'flex', flexDirection: 'column-reverse' }}
onContextMenu={handleContextMenu}
style={{
flex: 1,
display: 'flex',
flexDirection: 'column-reverse',
}}
/>
<Menu
open={contextMenu !== null}
onClose={handleContextMenuClose}
anchorReference="anchorPosition"
anchorPosition={
contextMenu !== null ? { top: contextMenu.mouseY, left: contextMenu.mouseX } : undefined
}
>
<MenuItem onClick={handleCopy} disabled={!contextMenu?.hasSelection}>
<ListItemIcon>
<Icon icon="mdi:content-copy" />
</ListItemIcon>
<ListItemText>{t('translation|Copy')}</ListItemText>
</MenuItem>
<MenuItem onClick={handlePaste}>
<ListItemIcon>
<Icon icon="mdi:content-paste" />
</ListItemIcon>
<ListItemText>{t('translation|Paste')}</ListItemText>
</MenuItem>
</Menu>
</Box>
</DialogContent>
);
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/hi/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "समय क्षेत्र",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/it/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/ja/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "タイムゾーン",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/ko/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "시간대",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/pt/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/ta/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "டைம்ஸோன்",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/zh-tw/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "時區",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/zh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "时区",
Expand Down
Loading