Files
windmill/frontend/src/lib/components/ExploreAssetButton.svelte
T
Diego ImbertandClaude Opus 4.8 3eeccaf968 feat: add ducklake schema support to the database manager (#9633)
* feat: add ducklake schema support to the database manager

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat: support schema in wmill.ducklake("name:schema") template helper

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: preserve schema when parsing ducklake asset/favorite paths

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: regenerate system prompts for ducklake schema syntax doc

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 17:23:14 +00:00

116 lines
3.7 KiB
Svelte

<script module lang="ts">
export function assetCanBeExplored(
asset: Asset,
_resourceMetadata?: { resource_type?: string }
): boolean {
return (
asset.kind === 'ducklake' ||
asset.kind === 'datatable' ||
asset.kind === 's3object' ||
asset.kind === 'volume' ||
(asset.kind === 'resource' && isDbType(_resourceMetadata?.resource_type))
)
}
</script>
<script lang="ts">
import { isDbType } from '$lib/components/dbTypes'
import { formatAsset, type Asset } from '$lib/components/assets/lib'
import { Button, ButtonType } from '$lib/components/common'
import S3FilePicker from '$lib/components/S3FilePicker.svelte'
import { VolumeService } from '$lib/gen'
import { globalDbManagerDrawer, userStore, workspaceStore } from '$lib/stores'
import { isS3Uri } from '$lib/utils'
import { Database, File, HardDriveIcon } from 'lucide-svelte'
import DucklakeIcon from './icons/DucklakeIcon.svelte'
const {
asset,
_resourceMetadata,
s3FilePicker,
onClick,
class: className = '',
noText = false,
buttonVariant = 'default',
btnClasses = '',
disabled = false
}: {
asset: Asset
_resourceMetadata?: { resource_type?: string }
s3FilePicker?: S3FilePicker
onClick?: () => void
class?: string
noText?: boolean
buttonVariant?: ButtonType.Variant
btnClasses?: string
disabled?: boolean
} = $props()
let dbManagerDrawer = $derived(globalDbManagerDrawer.val)
const assetUri = $derived(formatAsset(asset))
</script>
<Button
disabled={$userStore?.operator || disabled}
unifiedSize={'md'}
variant={buttonVariant}
wrapperClasses={className}
iconOnly={noText}
{btnClasses}
on:click={async () => {
if (asset.kind === 'resource' && isDbType(_resourceMetadata?.resource_type)) {
let [resourcePath, specificTable] = asset.path.split('?table=')
dbManagerDrawer?.openDrawer({
type: 'database',
resourceType: _resourceMetadata.resource_type,
resourcePath,
specificTable
})
} else if (asset.kind === 's3object' && isS3Uri(assetUri)) {
s3FilePicker?.open(assetUri)
} else if (asset.kind === 'volume') {
const storage =
(await VolumeService.getVolumeStorage({ workspace: $workspaceStore! })) ?? undefined
s3FilePicker?.open({ s3: `volumes/${$workspaceStore}/${asset.path}/`, storage })
} else if (asset.kind === 'ducklake') {
let ducklake = asset.path.split('/')[0]
let specificTableSplit = asset.path.split('/')[1]?.split('.') as string[] | undefined
let [specificSchema, specificTable] =
specificTableSplit?.length === 2
? [specificTableSplit[0], specificTableSplit[1]]
: [undefined, specificTableSplit?.[0]]
dbManagerDrawer?.openDrawer({ type: 'ducklake', ducklake, specificSchema, specificTable })
} else if (asset.kind === 'datatable') {
let datatable = asset.path.split('/')[0]
let specificTableSplit = asset.path.split('/')[1]?.split('.') as string[] | undefined
let [specificSchema, specificTable] =
specificTableSplit?.length === 2
? [specificTableSplit[0], specificTableSplit[1]]
: [undefined, specificTableSplit?.[0]]
dbManagerDrawer?.openDrawer({
type: 'database',
resourceType: 'postgresql',
resourcePath: `datatable://${datatable}`,
specificTable,
specificSchema
})
}
onClick?.()
}}
endIcon={asset.kind === 's3object'
? { icon: File }
: asset.kind === 'resource' || asset.kind === 'datatable'
? { icon: Database }
: asset.kind === 'ducklake'
? { icon: DucklakeIcon }
: asset.kind === 'volume'
? { icon: HardDriveIcon }
: undefined}
>
{#if asset.kind === 's3object' || asset.kind === 'volume'}
<span class:hidden={noText}>Explore</span>
{:else if asset.kind === 'resource' || asset.kind === 'ducklake' || asset.kind === 'datatable'}
<span class:hidden={noText}>Manage</span>
{/if}
</Button>