From b1beb7b71b3e0bc8e9338a8a8dcab87bffaefbe5 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 26 Jan 2025 14:55:22 -0600 Subject: [PATCH] fix: adjust color paste on terminal --- .../settings/web-server/terminal.tsx | 11 +- apps/dokploy/package.json | 1 + apps/dokploy/styles/globals.css | 317 +++++++++--------- pnpm-lock.yaml | 18 + 4 files changed, 188 insertions(+), 159 deletions(-) diff --git a/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx b/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx index 402ce57d..a82afa28 100644 --- a/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx +++ b/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx @@ -6,6 +6,7 @@ import "@xterm/xterm/css/xterm.css"; import { AttachAddon } from "@xterm/addon-attach"; import { useTheme } from "next-themes"; import { getLocalServerData } from "./local-server-config"; +import { ClipboardAddon } from "@xterm/addon-clipboard"; interface Props { id: string; @@ -32,15 +33,15 @@ export const Terminal: React.FC = ({ id, serverId }) => { lineHeight: 1.4, convertEol: true, theme: { - cursor: resolvedTheme === "light" ? "#000000" : "#FFFFFF", - background: resolvedTheme === "light" ? "#FFFFFF" : "rgba(0, 0, 0, 0.9)", - foreground: resolvedTheme === "light" ? "#000000" : "#FFFFFF", - selectionForeground: resolvedTheme === "light" ? "#000000" : "#FFFFFF", + cursor: resolvedTheme === "light" ? "#000000" : "transparent", + background: "rgba(0, 0, 0, 0)", + foreground: "currentColor", }, allowTransparency: true, screenReaderMode: true, scrollback: 1000, }); + const addonFit = new FitAddon(); const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; @@ -58,6 +59,8 @@ export const Terminal: React.FC = ({ id, serverId }) => { const ws = new WebSocket(wsUrl); const addonAttach = new AttachAddon(ws); + const clipboardAddon = new ClipboardAddon(); + term.loadAddon(clipboardAddon); // @ts-ignore term.open(termRef.current); diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index 5166c2f9..23be9df3 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -75,6 +75,7 @@ "@uiw/react-codemirror": "^4.22.1", "@xterm/addon-attach": "0.10.0", "@xterm/xterm": "^5.4.0", + "@xterm/addon-clipboard": "0.1.0", "adm-zip": "^0.5.14", "bcrypt": "5.1.1", "bullmq": "5.4.2", diff --git a/apps/dokploy/styles/globals.css b/apps/dokploy/styles/globals.css index 7b7977b9..860c0632 100644 --- a/apps/dokploy/styles/globals.css +++ b/apps/dokploy/styles/globals.css @@ -3,235 +3,242 @@ @tailwind utilities; @layer base { - :root { - --background: 0 0% 100%; - --foreground: 240 10% 3.9%; + :root { + --terminal-paste: rgba(0, 0, 0, 0.2); + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; - --card: 0 0% 100%; - --card-foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; - --popover: 0 0% 100%; - --popover-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; - --primary: 240 5.9% 10%; - --primary-foreground: 0 0% 98%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; - --secondary: 240 4.8% 95.9%; - --secondary-foreground: 240 5.9% 10%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; - --muted: 240 4.8% 95.9%; - --muted-foreground: 240 3.8% 46.1%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; - --accent: 240 4.8% 95.9%; - --accent-foreground: 240 5.9% 10%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; - --destructive: 0 84.2% 50.2%; - --destructive-foreground: 0 0% 98%; + --destructive: 0 84.2% 50.2%; + --destructive-foreground: 0 0% 98%; - --border: 240 5.9% 90%; - --input: 240 5.9% 90%; - --ring: 240 10% 3.9%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 10% 3.9%; - --radius: 0.5rem; - --overlay: rgba(0, 0, 0, 0.2); + --radius: 0.5rem; + --overlay: rgba(0, 0, 0, 0.2); - --chart-1: 173 58% 39%; - --chart-2: 12 76% 61%; - --chart-3: 197 37% 24%; - --chart-4: 43 74% 66%; - --chart-5: 27 87% 67%; - --sidebar-background: 0 0% 98%; - --sidebar-foreground: 240 5.3% 26.1%; - --sidebar-primary: 240 5.9% 10%; - --sidebar-primary-foreground: 0 0% 98%; - --sidebar-accent: 240 4.8% 95.9%; - --sidebar-accent-foreground: 240 5.9% 10%; - --sidebar-border: 220 13% 91%; - --sidebar-ring: 217.2 91.2% 59.8%; - } + --chart-1: 173 58% 39%; + --chart-2: 12 76% 61%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + --sidebar-background: 0 0% 98%; + --sidebar-foreground: 240 5.3% 26.1%; + --sidebar-primary: 240 5.9% 10%; + --sidebar-primary-foreground: 0 0% 98%; + --sidebar-accent: 240 4.8% 95.9%; + --sidebar-accent-foreground: 240 5.9% 10%; + --sidebar-border: 220 13% 91%; + --sidebar-ring: 217.2 91.2% 59.8%; + } - .dark { - --background: 0 0% 0%; - --foreground: 0 0% 98%; + .dark { + --terminal-paste: rgba(255, 255, 255, 0.2); + --background: 0 0% 0%; + --foreground: 0 0% 98%; - --card: 240 4% 10%; - --card-foreground: 0 0% 98%; + --card: 240 4% 10%; + --card-foreground: 0 0% 98%; - --popover: 240 10% 3.9%; - --popover-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; - --primary: 0 0% 98%; - --primary-foreground: 240 5.9% 10%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; - --secondary: 240 3.7% 15.9%; - --secondary-foreground: 0 0% 98%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; - --muted: 240 4% 10%; - --muted-foreground: 240 5% 64.9%; + --muted: 240 4% 10%; + --muted-foreground: 240 5% 64.9%; - --accent: 240 3.7% 15.9%; - --accent-foreground: 0 0% 98%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; - --destructive: 0 84.2% 50.2%; - --destructive-foreground: 0 0% 98%; + --destructive: 0 84.2% 50.2%; + --destructive-foreground: 0 0% 98%; - --border: 240 3.7% 15.9%; - --input: 240 4% 10%; - --ring: 240 4.9% 83.9%; + --border: 240 3.7% 15.9%; + --input: 240 4% 10%; + --ring: 240 4.9% 83.9%; - --overlay: rgba(0, 0, 0, 0.5); + --overlay: rgba(0, 0, 0, 0.5); - --chart-1: 220 70% 50%; - --chart-5: 160 60% 45%; - --chart-3: 30 80% 55%; - --chart-4: 280 65% 60%; - --chart-2: 340 75% 55%; - --sidebar-background: 240 5.9% 10%; - --sidebar-foreground: 240 4.8% 95.9%; - --sidebar-primary: 224.3 76.3% 48%; - --sidebar-primary-foreground: 0 0% 100%; - --sidebar-accent: 240 3.7% 15.9%; - --sidebar-accent-foreground: 240 4.8% 95.9%; - --sidebar-border: 240 3.7% 15.9%; - --sidebar-ring: 217.2 91.2% 59.8%; - } + --chart-1: 220 70% 50%; + --chart-5: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-2: 340 75% 55%; + --sidebar-background: 240 5.9% 10%; + --sidebar-foreground: 240 4.8% 95.9%; + --sidebar-primary: 224.3 76.3% 48%; + --sidebar-primary-foreground: 0 0% 100%; + --sidebar-accent: 240 3.7% 15.9%; + --sidebar-accent-foreground: 240 4.8% 95.9%; + --sidebar-border: 240 3.7% 15.9%; + --sidebar-ring: 217.2 91.2% 59.8%; + } } @layer base { - * { - @apply border-border; - } + * { + @apply border-border; + } - body { - @apply bg-background text-foreground; - } + body { + @apply bg-background text-foreground; + } - /* Custom scrollbar styling */ - ::-webkit-scrollbar { - width: 0.3125rem; - } + /* Custom scrollbar styling */ + ::-webkit-scrollbar { + width: 0.3125rem; + } - ::-webkit-scrollbar-track { - background: transparent; - } + ::-webkit-scrollbar-track { + background: transparent; + } - ::-webkit-scrollbar-thumb { - background: hsl(var(--border)); - border-radius: 0.3125rem; - } + ::-webkit-scrollbar-thumb { + background: hsl(var(--border)); + border-radius: 0.3125rem; + } - * { - scrollbar-width: thin; - scrollbar-color: hsl(var(--border)) transparent; - } + * { + scrollbar-width: thin; + scrollbar-color: hsl(var(--border)) transparent; + } } .xterm-viewport { - border-radius: 0.75rem /* 12px */ !important; + border-radius: 0.75rem /* 12px */ !important; } .xterm .xterm-viewport { - overflow-y: auto !important; + overflow-y: auto !important; } .xterm .xterm-screen { - overflow: hidden; + overflow: hidden; } @layer utilities { - /* Chrome, Safari and Opera */ - .no-scrollbar::-webkit-scrollbar { - display: none; - } + /* Chrome, Safari and Opera */ + .no-scrollbar::-webkit-scrollbar { + display: none; + } - .no-scrollbar { - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ - } + .no-scrollbar { + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ + } } /* Codemirror */ .cm-editor { - @apply w-full h-full rounded-md overflow-hidden border border-solid border-border outline-none; + @apply w-full h-full rounded-md overflow-hidden border border-solid border-border outline-none; } .cm-editor .cm-scroller { - font-family: inherit; - line-height: inherit; + font-family: inherit; + line-height: inherit; } .cm-editor.cm-focused { - @apply outline-none; + @apply outline-none; } /* fix: placeholder bg */ .cm-editor .cm-activeLine:has(.cm-placeholder) { - background-color: transparent; + background-color: transparent; } .compose-file-editor .cm-editor { - @apply min-h-[25rem]; + @apply min-h-[25rem]; } @keyframes heartbeat { - 0% { - transform: scale(1); - opacity: 0.7; - } - 25% { - transform: scale(1.1); - opacity: 1; - } - 50% { - transform: scale(1); - opacity: 0.7; - } - 75% { - transform: scale(1.1); - opacity: 1; - } - 100% { - transform: scale(1); - opacity: 0.7; - } + 0% { + transform: scale(1); + opacity: 0.7; + } + 25% { + transform: scale(1.1); + opacity: 1; + } + 50% { + transform: scale(1); + opacity: 0.7; + } + 75% { + transform: scale(1.1); + opacity: 1; + } + 100% { + transform: scale(1); + opacity: 0.7; + } } .animate-heartbeat { - animation: heartbeat 2.5s infinite; + animation: heartbeat 2.5s infinite; } @media (prefers-color-scheme: dark) { - .swagger-ui { - background-color: white; - } + .swagger-ui { + background-color: white; + } - .swagger-ui .info { - margin: 0px !important; - padding-top: 1rem !important; - } + .swagger-ui .info { + margin: 0px !important; + padding-top: 1rem !important; + } } /* Docker Logs Scrollbar */ @layer utilities { - .custom-logs-scrollbar { - scrollbar-width: thin; - scrollbar-color: hsl(var(--muted-foreground)) transparent; - } + .custom-logs-scrollbar { + scrollbar-width: thin; + scrollbar-color: hsl(var(--muted-foreground)) transparent; + } - .custom-logs-scrollbar::-webkit-scrollbar { - width: 8px; - height: 8px; - } + .custom-logs-scrollbar::-webkit-scrollbar { + width: 8px; + height: 8px; + } - .custom-logs-scrollbar::-webkit-scrollbar-track { - background: transparent; - } + .custom-logs-scrollbar::-webkit-scrollbar-track { + background: transparent; + } - .custom-logs-scrollbar::-webkit-scrollbar-thumb { - background-color: hsl(var(--muted-foreground) / 0.3); - border-radius: 20px; - } + .custom-logs-scrollbar::-webkit-scrollbar-thumb { + background-color: hsl(var(--muted-foreground) / 0.3); + border-radius: 20px; + } - .custom-logs-scrollbar::-webkit-scrollbar-thumb:hover { - background-color: hsl(var(--muted-foreground) / 0.5); - } + .custom-logs-scrollbar::-webkit-scrollbar-thumb:hover { + background-color: hsl(var(--muted-foreground) / 0.5); + } +} + +.xterm-bg-257.xterm-fg-257 { + background-color: var(--terminal-paste) !important; + color: currentColor !important; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6341be34..c2167677 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -217,6 +217,9 @@ importers: '@xterm/addon-attach': specifier: 0.10.0 version: 0.10.0(@xterm/xterm@5.5.0) + '@xterm/addon-clipboard': + specifier: 0.1.0 + version: 0.1.0(@xterm/xterm@5.5.0) '@xterm/xterm': specifier: ^5.4.0 version: 5.5.0 @@ -3503,6 +3506,11 @@ packages: peerDependencies: '@xterm/xterm': ^5.0.0 + '@xterm/addon-clipboard@0.1.0': + resolution: {integrity: sha512-zdoM7p53T5sv/HbRTyp4hY0kKmEQ3MZvAvEtiXqNIHc/JdpqwByCtsTaQF5DX2n4hYdXRPO4P/eOS0QEhX1nPw==} + peerDependencies: + '@xterm/xterm': ^5.4.0 + '@xterm/xterm@5.5.0': resolution: {integrity: sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==} @@ -5011,6 +5019,9 @@ packages: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} + js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + js-beautify@1.15.1: resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==} engines: {node: '>=14'} @@ -9894,6 +9905,11 @@ snapshots: dependencies: '@xterm/xterm': 5.5.0 + '@xterm/addon-clipboard@0.1.0(@xterm/xterm@5.5.0)': + dependencies: + '@xterm/xterm': 5.5.0 + js-base64: 3.7.7 + '@xterm/xterm@5.5.0': {} '@xtuc/ieee754@1.2.0': {} @@ -11410,6 +11426,8 @@ snapshots: joycon@3.1.1: {} + js-base64@3.7.7: {} + js-beautify@1.15.1: dependencies: config-chain: 1.1.13