This commit is contained in:
jarek committed 2026-02-16 08:46:56 +01:00
1 parent d83ca684d7
commit 8ee4fe4d68
49 files changed
+2126 -261

No files matched your search

+21 -12
View File
@@ -7,7 +7,7 @@
import CodeEditor, { type VariableMarker } from '$lib/components/CodeEditor.svelte';
import StackEnvVarsPanel from '$lib/components/StackEnvVarsPanel.svelte';
import { type EnvVar, type ValidationResult } from '$lib/components/StackEnvVarsEditor.svelte';
import { Layers, Save, Play, Code, GitGraph, Loader2, AlertCircle, X, Sun, Moon, TriangleAlert, GripVertical, FolderOpen, Copy, Check, MapPin, ArrowRight, ArrowDown, Info, Box, FolderSync } from 'lucide-svelte';
import { Layers, Save, Play, Code, GitGraph, Loader2, AlertCircle, X, Sun, Moon, TriangleAlert, GripVertical, FolderOpen, Copy, Check, XCircle, MapPin, ArrowRight, ArrowDown, Info, Box, FolderSync } from 'lucide-svelte';
import type { Component } from 'svelte';
import FilesystemBrowser from './FilesystemBrowser.svelte';
import PathBarItem from './PathBarItem.svelte';
@@ -17,6 +17,7 @@
import { currentEnvironment, appendEnvParam } from '$lib/stores/environment';
import { appSettings } from '$lib/stores/settings';
import { focusFirstInput } from '$lib/utils';
import { copyToClipboard } from '$lib/utils/clipboard';
import * as Alert from '$lib/components/ui/alert';
import { ErrorDialog } from '$lib/components/ui/error-dialog';
import ComposeGraphViewer from './ComposeGraphViewer.svelte';
@@ -89,9 +90,9 @@
// UI state
let composePathCopied = $state(false);
let envPathCopied = $state(false);
let composeContentCopied = $state(false);
let composePathCopied = $state<'ok' | 'error' | null>(null);
let envPathCopied = $state<'ok' | 'error' | null>(null);
let composeContentCopied = $state<'ok' | 'error' | null>(null);
let needsFileLocation = $state(false);
// Container info for untracked stacks
@@ -326,11 +327,11 @@
}
// Generic copy function that returns a reset callback
function copyToClipboard(text: string | null, setCopied: (v: boolean) => void) {
async function copyText(text: string | null, setCopied: (v: 'ok' | 'error' | null) => void) {
if (text) {
navigator.clipboard.writeText(text);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
const ok = await copyToClipboard(text);
setCopied(ok ? 'ok' : 'error');
setTimeout(() => setCopied(null), 2000);
}
}
@@ -1463,7 +1464,7 @@ services:
path={workingComposePath || null}
placeholder="/path/to/compose.yaml"
copied={composePathCopied}
onCopy={() => copyToClipboard(workingComposePath, (v) => composePathCopied = v)}
onCopy={() => copyText(workingComposePath, (v) => composePathCopied = v)}
onBrowse={openComposeBrowser}
onChangeLocation={mode === 'edit' && !needsFileLocation ? openChangeLocationBrowser : undefined}
defaultText={mode === 'create' ? 'Enter stack name above' : 'Not specified'}
@@ -1480,7 +1481,7 @@ services:
selectedPath={workingEnvPath || suggestedEnvPath || ''}
placeholder="/path/to/.env (optional)"
copied={envPathCopied}
onCopy={() => copyToClipboard(displayEnvPath, (v) => envPathCopied = v)}
onCopy={() => copyText(displayEnvPath, (v) => envPathCopied = v)}
onBrowse={openEnvBrowser}
isEditable={true}
isCustom={!!workingEnvPath}
@@ -1525,10 +1526,18 @@ services:
variant="ghost"
size="sm"
class="h-6 px-2 text-xs text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200"
onclick={() => copyToClipboard(composeContent, (v) => composeContentCopied = v)}
onclick={() => copyText(composeContent, (v) => composeContentCopied = v)}
disabled={!composeContent}
>
{#if composeContentCopied}
{#if composeContentCopied === 'error'}
<Tooltip.Root open>
<Tooltip.Trigger>
<XCircle class="w-3 h-3 text-red-500" />
</Tooltip.Trigger>
<Tooltip.Content>Copy requires HTTPS</Tooltip.Content>
</Tooltip.Root>
Failed
{:else if composeContentCopied === 'ok'}
<Check class="w-3 h-3 text-green-500" />
Copied
{:else}