mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Add terminal tabs with read-only main terminal
This commit is contained in:
@@ -170,4 +170,5 @@ export class Synapse {
|
||||
}
|
||||
}
|
||||
|
||||
export const synapse = new Synapse('wss://terminal.appwrite.torsten.work');
|
||||
export const endpoint = 'wss://terminal.appwrite.torsten.work';
|
||||
export const synapse = new Synapse(endpoint);
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
type Props = {
|
||||
height: number;
|
||||
synapse: Synapse;
|
||||
readonly?: boolean;
|
||||
};
|
||||
let { height, synapse }: Props = $props();
|
||||
let { height, synapse, readonly = false }: Props = $props();
|
||||
|
||||
const terminal: Action = (node) => {
|
||||
const init = async () => {
|
||||
@@ -26,7 +27,12 @@
|
||||
const fitAddon = new FitAddon();
|
||||
term.loadAddon(fitAddon);
|
||||
term.open(node);
|
||||
term.onKey(({ key }) => {
|
||||
term.onKey(({ key, domEvent }) => {
|
||||
if (readonly) {
|
||||
domEvent.preventDefault();
|
||||
domEvent.stopPropagation();
|
||||
return;
|
||||
}
|
||||
synapse.dispatch('terminal', {
|
||||
operation: 'createCommand',
|
||||
params: {
|
||||
|
||||
@@ -25,11 +25,12 @@
|
||||
saveTerminalHeightToPrefs,
|
||||
saveTerminalOpenToPrefs
|
||||
} from '$lib/helpers/studioLayout';
|
||||
import { synapse } from '$lib/components/studio/synapse.svelte';
|
||||
import { endpoint, Synapse, synapse } from '$lib/components/studio/synapse.svelte';
|
||||
import { showChat } from '$lib/stores/chat';
|
||||
import { default as IconChatLayout } from '../assets/chat-layout.svelte';
|
||||
import { filesystem } from '$lib/components/editor/filesystem';
|
||||
import { InputSelect } from '$lib/elements/forms/index.js';
|
||||
import { SvelteMap } from 'svelte/reactivity';
|
||||
|
||||
const { children } = $props();
|
||||
|
||||
@@ -51,6 +52,10 @@
|
||||
hasChildren: true
|
||||
}
|
||||
];
|
||||
const mainTerminalId = Symbol();
|
||||
const terminals = new SvelteMap<symbol, Synapse>();
|
||||
let currentTerminal: symbol = $state(mainTerminalId);
|
||||
|
||||
synapse.dispatch('synapse', {
|
||||
operation: 'updateWorkDir',
|
||||
params: {
|
||||
@@ -132,6 +137,12 @@
|
||||
$previewFrameRef.style.pointerEvents = '';
|
||||
}
|
||||
}
|
||||
|
||||
function createTerminal() {
|
||||
const symbol = Symbol();
|
||||
terminals.set(symbol, new Synapse(endpoint));
|
||||
currentTerminal = symbol;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Layout.Stack
|
||||
@@ -196,7 +207,33 @@
|
||||
<Icon icon={IconChevronDoubleUp} color="--fgcolor-neutral-tertiary" />
|
||||
</Layout.Stack>
|
||||
</summary>
|
||||
<Terminal height={terminalHeight} {synapse}></Terminal>
|
||||
<Layout.Stack>
|
||||
<Tabs let:root>
|
||||
<Tab
|
||||
{root}
|
||||
selected={currentTerminal === mainTerminalId}
|
||||
on:click={() => (currentTerminal = mainTerminalId)}>
|
||||
Imagine
|
||||
</Tab>
|
||||
{#each terminals as [symbol] (symbol)}
|
||||
<Tab
|
||||
{root}
|
||||
on:click={() => (currentTerminal = symbol)}
|
||||
selected={currentTerminal === symbol}>
|
||||
Terminal
|
||||
</Tab>
|
||||
{/each}
|
||||
<Tab {root} on:click={createTerminal}>+</Tab>
|
||||
</Tabs>
|
||||
</Layout.Stack>
|
||||
<div style:display={currentTerminal === mainTerminalId ? 'contents' : 'none'}>
|
||||
<Terminal height={terminalHeight} {synapse} readonly></Terminal>
|
||||
</div>
|
||||
{#each terminals as [symbol, synapse] (symbol)}
|
||||
<div style:display={currentTerminal === symbol ? 'contents' : 'none'}>
|
||||
<Terminal height={terminalHeight} {synapse}></Terminal>
|
||||
</div>
|
||||
{/each}
|
||||
</details>
|
||||
</aside>
|
||||
</Layout.Stack>
|
||||
|
||||
Reference in New Issue
Block a user