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
21 changes: 20 additions & 1 deletion src/lib/components/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@
let {
open = $bindable(false),
children,
variant = 'default',
class: className = ''
}: {
open: boolean;
children: import('svelte').Snippet;
/**
* - `default` — DaisyUI's centred `modal`, paired with a `modal-box` child.
* - `fullscreen` — edge-to-edge sheet; the child owns the whole viewport.
*/
variant?: 'default' | 'fullscreen';
/** Extra classes, appended to the variant's own. */
class?: string;
} = $props();

const variantClass = {
default: 'modal',
fullscreen: 'bg-base-100 fixed inset-0 z-40 size-full max-h-full max-w-full p-0'
} as const;

const dialogClass = $derived(`${variantClass[variant]} ${className}`.trim());

let dialogEl = $state<HTMLDialogElement | undefined>(undefined);

// Sync the `open` prop with the native <dialog> open/close state.
Expand All @@ -34,7 +48,12 @@
}
</script>

<dialog bind:this={dialogEl} class={className} onclose={handleClose} onclick={handleBackdropClick}>
<dialog
bind:this={dialogEl}
class={dialogClass}
onclose={handleClose}
onclick={handleBackdropClick}
>
{#if open}
{@render children()}
{/if}
Expand Down
24 changes: 4 additions & 20 deletions src/lib/components/TabBar.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import IconClose from 'virtual:icons/material-symbols/close';
import IconAdd from 'virtual:icons/material-symbols/add';

interface TabItem {
id: string;
Expand Down Expand Up @@ -177,16 +179,7 @@
aria-label={m.trino_tab_close({ name: item.label })}
onclick={() => onClose?.(item.id)}
>
<svg
class="h-3 w-3"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"><path d="M18 6 6 18" /><path d="m6 6 12 12" /></svg
>
<IconClose class="h-3 w-3" aria-hidden="true" />
</button>
{/if}
</div>
Expand All @@ -203,16 +196,7 @@
requestAnimationFrame(() => focusTab(activeId));
}}
>
<svg
class="h-4 w-4"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"><path d="M12 5v14" /><path d="M5 12h14" /></svg
>
<IconAdd class="h-4 w-4" aria-hidden="true" />
</button>
{/if}
</div>
15 changes: 2 additions & 13 deletions src/lib/components/catalog/CatalogBrowser.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { untrack } from 'svelte';
import { SvelteSet } from 'svelte/reactivity';
import * as m from '$lib/paraglide/messages.js';
import IconRefresh from 'virtual:icons/material-symbols/refresh';
import CatalogTree from './CatalogTree.svelte';
import type { TreeNode } from './types.js';

Expand Down Expand Up @@ -267,19 +268,7 @@
onclick={handleRefresh}
disabled={catalogsLoading}
>
<svg
class="h-3.5 w-3.5"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
<IconRefresh class="h-3.5 w-3.5" aria-hidden="true" />
</button>
</div>
<div class="min-h-0 flex-1 overflow-auto p-2">
Expand Down
108 changes: 15 additions & 93 deletions src/lib/components/catalog/CatalogTree.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import IconChevronRight from 'virtual:icons/material-symbols/chevron-right';
import IconCatalog from 'virtual:icons/material-symbols/database-outline';
import IconSchema from 'virtual:icons/material-symbols/folder-outline';
import IconTable from 'virtual:icons/material-symbols/table-outline';
import IconView from 'virtual:icons/material-symbols/visibility-outline';
import IconMaterializedView from 'virtual:icons/material-symbols/preview-outline';
import IconColumn from 'virtual:icons/material-symbols/circle';
import type { TreeNode } from './types.js';
import CatalogTree from './CatalogTree.svelte';

Expand Down Expand Up @@ -51,110 +58,25 @@
</script>

{#snippet chevronIcon(isOpen: boolean)}
<svg
<IconChevronRight
class="h-3.5 w-3.5 shrink-0 transition-transform duration-150 {isOpen ? 'rotate-90' : ''}"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="m9 5 7 7-7 7" />
</svg>
/>
{/snippet}

{#snippet nodeIcon(type: string)}
{#if type === 'catalog'}
<svg
class="text-base-content/50 h-4 w-4 shrink-0"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<ellipse cx="12" cy="5" rx="9" ry="3" />
<path d="M3 5v14c0 1.66 4.03 3 9 3s9-1.34 9-3V5" />
<path d="M3 12c0 1.66 4.03 3 9 3s9-1.34 9-3" />
</svg>
<IconCatalog class="text-base-content/50 h-4 w-4 shrink-0" aria-hidden="true" />
{:else if type === 'schema'}
<svg
class="text-base-content/50 h-4 w-4 shrink-0"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
/>
</svg>
<IconSchema class="text-base-content/50 h-4 w-4 shrink-0" aria-hidden="true" />
{:else if type === 'table'}
<svg
class="text-base-content/50 h-4 w-4 shrink-0"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect x="3" y="3" width="18" height="18" rx="2" />
<path d="M3 9h18" />
<path d="M3 15h18" />
<path d="M9 3v18" />
</svg>
<IconTable class="text-base-content/50 h-4 w-4 shrink-0" aria-hidden="true" />
{:else if type === 'view'}
<svg
class="text-base-content/50 h-4 w-4 shrink-0"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"
/>
<circle cx="12" cy="12" r="3" />
</svg>
<IconView class="text-base-content/50 h-4 w-4 shrink-0" aria-hidden="true" />
{:else if type === 'materialized_view'}
<svg
class="text-base-content/50 h-4 w-4 shrink-0"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"
/>
<circle cx="12" cy="12" r="3" />
<path d="M12 2v4" />
<path d="M12 18v4" />
</svg>
<IconMaterializedView class="text-base-content/50 h-4 w-4 shrink-0" aria-hidden="true" />
{:else}
<svg
class="text-base-content/40 h-3 w-3 shrink-0"
aria-hidden="true"
viewBox="0 0 24 24"
fill="currentColor"
>
<circle cx="12" cy="12" r="4" />
</svg>
<IconColumn class="text-base-content/40 h-3 w-3 shrink-0" aria-hidden="true" />
{/if}
{/snippet}

Expand Down
8 changes: 2 additions & 6 deletions src/lib/components/storage/DeleteConnectionModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import Modal from '$lib/components/Modal.svelte';
import * as m from '$lib/paraglide/messages.js';
import type { SavedConnection } from '$lib/storage/connection-storage.js';
import { connectionLabel } from '$lib/storage/display-helpers.js';

interface Props {
open: boolean;
Expand All @@ -16,11 +17,6 @@

let copiedField: string | null = $state(null);

function connectionLabel(conn: SavedConnection): string {
if (conn.name) return conn.name;
return conn.port ? `${conn.host}:${conn.port}` : conn.host;
}

function copyField(value: string, field: string) {
navigator.clipboard.writeText(value);
copiedField = field;
Expand All @@ -45,7 +41,7 @@
}
</script>

<Modal bind:open class="modal">
<Modal bind:open>
<div class="modal-box max-w-lg">
{#if connection}
<p class="text-base-content mb-4 font-medium">
Expand Down
15 changes: 7 additions & 8 deletions src/lib/components/storage/landing/RecentItems.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
import IconStorage from 'virtual:icons/material-symbols/storage';
import IconFolderOutline from 'virtual:icons/material-symbols/folder-outline';
import * as m from '$lib/paraglide/messages.js';
import { formatFileSize } from '$lib/storage/utils.js';
import { formatFileSize, keyToName } from '$lib/storage/utils.js';
import { getStorageState } from '$lib/storage/context.js';
import {
fileName,
fileHref,
fileLocation,
locationHref,
locationName,
locationLabel,
locationPath
} from '$lib/storage/display-helpers.js';
import PreviewModal from '$lib/components/storage/modals/PreviewModal.svelte';
Expand Down Expand Up @@ -63,7 +62,7 @@
<td>
<div class="flex items-center gap-2">
<IconDescriptionOutline class="text-primary size-4 shrink-0" aria-hidden="true" />
<span class="font-medium">{fileName(file.key)}</span>
<span class="font-medium">{keyToName(file.key)}</span>
</div>
</td>
<td>
Expand All @@ -88,7 +87,7 @@
<div class="tooltip tooltip-left" data-tip={m.storage_recent_preview_file()}>
<button
class="btn btn-ghost btn-xs"
aria-label="{m.storage_recent_preview_file()} — {fileName(file.key)}"
aria-label="{m.storage_recent_preview_file()} — {keyToName(file.key)}"
onclick={() => openPreview(file.bucket, file.key)}
>
<IconPreviewOutline class="size-3.5" aria-hidden="true" />
Expand All @@ -100,7 +99,7 @@
href={fileHref(file)}
data-sveltekit-preload-data="off"
class="btn btn-ghost btn-xs"
aria-label="{m.storage_recent_open_folder()} — {fileName(file.key)}"
aria-label="{m.storage_recent_open_folder()} — {keyToName(file.key)}"
>
<!-- eslint-enable svelte/no-navigation-without-resolve -->
<IconFolderOpenOutline class="size-3.5" aria-hidden="true" />
Expand Down Expand Up @@ -138,7 +137,7 @@
<a
href={locationHref(loc)}
data-sveltekit-preload-data="off"
class="hover:text-primary font-medium">{locationName(loc)}</a
class="hover:text-primary font-medium">{locationLabel(loc)}</a
>
<!-- eslint-enable svelte/no-navigation-without-resolve -->
</div>
Expand All @@ -164,7 +163,7 @@
href={locationHref(loc)}
data-sveltekit-preload-data="off"
class="btn btn-ghost btn-xs"
aria-label="{m.storage_recent_go_to_location()} — {locationName(loc)}"
aria-label="{m.storage_recent_go_to_location()} — {locationLabel(loc)}"
>
<!-- eslint-enable svelte/no-navigation-without-resolve -->
<IconArrowForward class="size-3.5" aria-hidden="true" />
Expand Down
5 changes: 3 additions & 2 deletions src/lib/components/storage/modals/DeleteConfirmModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import IconDeleteForever from 'virtual:icons/material-symbols/delete-forever';
import IconWarningRounded from 'virtual:icons/material-symbols/warning-rounded';
import * as m from '$lib/paraglide/messages.js';
import { keyToName } from '$lib/storage/utils.js';

interface Props {
open: boolean;
Expand All @@ -14,11 +15,11 @@
let { open = $bindable(), keys, onConfirm, onCancel }: Props = $props();

const count = $derived(keys.length);
const firstName = $derived(keys[0]?.split('/').filter(Boolean).pop() ?? '');
const firstName = $derived(keys[0] ? keyToName(keys[0]) : '');
const hasDirectories = $derived(keys.some((k) => k.endsWith('/')));
</script>

<Modal bind:open class="modal">
<Modal bind:open>
<div class="modal-box {hasDirectories ? 'max-w-md' : 'max-w-sm'}">
<h3 class="text-error mb-3 flex items-center gap-2 text-lg font-bold">
<IconDeleteForever class="size-5 shrink-0" aria-hidden="true" />
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/storage/modals/PreviewModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@
}
</script>

<Modal bind:open class="modal">
<Modal bind:open>
<div
class="modal-box flex flex-col p-0 transition-none
{maximized ? 'h-dvh max-h-dvh w-screen max-w-none rounded-none' : 'w-full max-w-5xl'}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import IconCheck from 'virtual:icons/material-symbols/check';
import IconCheckCircle from 'virtual:icons/material-symbols/check-circle';
import * as m from '$lib/paraglide/messages.js';
import { keyToName } from '$lib/storage/utils.js';
import type { FileEntry, Resolution } from './types.js';

interface Props {
Expand All @@ -17,7 +18,7 @@

const uid = $props.id();

let nameOnly = $derived(entry.targetKey.split('/').at(-1) ?? entry.file.name);
let nameOnly = $derived(keyToName(entry.targetKey) || entry.file.name);
let badRename = $derived(
entry.resolution === 'rename' &&
(entry.customName.trim() === '' || entry.customName.trim() === entry.file.name)
Expand Down
Loading
Loading