mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-08 00:03:07 +00:00
* fix(frontend): scope raw-app/flow/script editors to the session workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): scope flow and script editor operations to the session workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): scope flow preview, inline-script creation and datatable schema to the session workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review — thread session workspace through flow resource pickers, script fetch, preview cancel/recording and path collision check Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Claude review — pass session workspace to preview FlowStatusViewer and align FlowChatManager guards Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Pi review — show acting workspace in script-not-found message and fetch picked script from it in EditorBar Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 2 — thread session workspace into flow step test, raw-app inline runnable, inline editor toolbars and MCP OAuth path Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 3 — thread session workspace into dynamic-input helpers and the flow-preview argument side panel (history/saved-inputs/captures) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 4 — thread session workspace into nested flow/script drawers, flow chat inputs and the flow input side tabs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 5 — thread session workspace into script-module fork/reload and key the raw-app schema cache by workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 6 — key the DB manager schema cache by acting workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 7 — thread session workspace into resource-valued arg pickers and the editor variable/resource helper drawers Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): scope the flow asset explorer's ResourceEditorDrawer to the acting workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: thread acting workspace through flow asset explore controls Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: thread acting workspace through SQL REPL, secret args, helper forms, S3 inputs, saved inputs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
125 lines
3.9 KiB
Svelte
125 lines
3.9 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,
|
|
workspace = undefined
|
|
}: {
|
|
asset: Asset
|
|
_resourceMetadata?: { resource_type?: string }
|
|
s3FilePicker?: S3FilePicker
|
|
onClick?: () => void
|
|
class?: string
|
|
noText?: boolean
|
|
buttonVariant?: ButtonType.Variant
|
|
btnClasses?: string
|
|
disabled?: boolean
|
|
/** Workspace the explored asset lives in; defaults to the nav workspace. */
|
|
workspace?: string
|
|
} = $props()
|
|
|
|
let dbManagerDrawer = $derived(globalDbManagerDrawer.val)
|
|
let ws = $derived(workspace ?? $workspaceStore)
|
|
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
|
|
},
|
|
ws
|
|
)
|
|
} else if (asset.kind === 's3object' && isS3Uri(assetUri)) {
|
|
s3FilePicker?.open(assetUri)
|
|
} else if (asset.kind === 'volume') {
|
|
const storage = (await VolumeService.getVolumeStorage({ workspace: ws! })) ?? undefined
|
|
s3FilePicker?.open({ s3: `volumes/${ws}/${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 }, ws)
|
|
} 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
|
|
},
|
|
ws
|
|
)
|
|
}
|
|
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>
|