diff --git a/frontend/src/lib/components/ArgInput.svelte b/frontend/src/lib/components/ArgInput.svelte index 80b0388df1..2f4a9af993 100644 --- a/frontend/src/lib/components/ArgInput.svelte +++ b/frontend/src/lib/components/ArgInput.svelte @@ -573,6 +573,30 @@ }} /> + {:else if itemsType?.type == 'object' && itemsType?.resourceType == 's3object'} +
+ { + value = [ + ...value, + { + s3: evt.detail?.path ?? '', + filename: evt.detail?.filename ?? '' + } + ] + }} + on:deletion={(evt) => { + value = value.filter((v) => v.s3 !== evt.detail?.path) + }} + defaultValue={defaultValue?.map((v) => v.s3)} + initialValue={value} + /> +
{:else}
{#key redraw} diff --git a/frontend/src/lib/components/ArrayTypeNarrowing.svelte b/frontend/src/lib/components/ArrayTypeNarrowing.svelte index 89285414de..3694b021b7 100644 --- a/frontend/src/lib/components/ArrayTypeNarrowing.svelte +++ b/frontend/src/lib/components/ArrayTypeNarrowing.svelte @@ -21,9 +21,19 @@ } | undefined - let selected: 'string' | 'number' | 'object' | 'bytes' | 'enum' | 'resource' | undefined = + let selected: + | 'string' + | 'number' + | 'object' + | 'bytes' + | 'enum' + | 'resource' + | 's3object' + | undefined = itemsType?.type != 'string' - ? itemsType?.type + ? itemsType?.type == 'object' && itemsType?.resourceType == 's3object' + ? 's3object' + : itemsType?.type : Array.isArray(itemsType?.enum) ? 'enum' : itemsType?.contentEncoding == 'base64' @@ -62,6 +72,8 @@ itemsType = { type: 'string', contentEncoding: 'base64' } } else if (selected == 'resource') { itemsType = { type: 'resource', resourceType: itemsType?.resourceType } + } else if (selected == 's3object') { + itemsType = { type: 'object', resourceType: 's3object' } } else { itemsType = undefined } @@ -71,6 +83,7 @@ {#if originalType != 'string[]'} + diff --git a/frontend/src/lib/components/common/fileInput/FileInput.svelte b/frontend/src/lib/components/common/fileInput/FileInput.svelte index 0212f5f534..77d9b308d8 100644 --- a/frontend/src/lib/components/common/fileInput/FileInput.svelte +++ b/frontend/src/lib/components/common/fileInput/FileInput.svelte @@ -18,7 +18,7 @@ export let iconSize = 36 export let returnFileNames = false export let submittedText: string | undefined = undefined - export let defaultFile: string | undefined = undefined + export let defaultFile: string | string[] | undefined = undefined export let disabled: boolean | undefined = undefined export let folderOnly = false @@ -160,9 +160,8 @@ files = files if (convertTo && files) { const promises = files.map(convertFile) - let converted: ConvertedFile[] | { name: string; data: ConvertedFile }[] = await Promise.all( - promises - ) + let converted: ConvertedFile[] | { name: string; data: ConvertedFile }[] = + await Promise.all(promises) if (returnFileNames) { converted = converted.map((c, i) => ({ name: files![i].name, data: c })) } @@ -239,7 +238,7 @@ {multiple} {...$$restProps} /> - {#if defaultFile} + {#if defaultFile && (!Array.isArray(defaultFile) || defaultFile.length > 0)}
Default file: {defaultFile}
diff --git a/frontend/src/lib/components/common/fileUpload/FileUpload.svelte b/frontend/src/lib/components/common/fileUpload/FileUpload.svelte index 9e5180b76c..44f2a7d8d6 100644 --- a/frontend/src/lib/components/common/fileUpload/FileUpload.svelte +++ b/frontend/src/lib/components/common/fileUpload/FileUpload.svelte @@ -12,69 +12,111 @@ import { createEventDispatcher, onDestroy } from 'svelte' import { emptyString } from '$lib/utils' - export let acceptedFileTypes: string[] | undefined = ['*'] - export let allowMultiple: boolean = true - export let allowDelete = true - export let folderOnly = false - export let containerText: string = folderOnly - ? 'Drag and drop a folder here or click to browse' - : allowMultiple - ? 'Drag and drop files here or click to browse' - : 'Drag and drop a file here or click to browse' - export let customResourcePath: string | undefined = undefined - export let customResourceType: 's3' | 'azure_blob' | undefined = undefined // when customResourcePath is provided, this should be provided as well. Will default to S3 if not - export let customClass: string = '' - export let customStyle: string = '' - export let randomFileKey: boolean = false - export let pathTransformer: any = undefined // function taking as input {file: File} and returning a string - export let forceDisplayUploads: boolean = false - export let defaultValue: string | undefined = undefined - export let workspace: string | undefined = undefined - export let fileUploads: Writable = writable([]) - export let appPath: string | undefined = undefined - export let disabled = false - export let iconSize: number | undefined = undefined - export let initialValue: - | { - s3: string - filename: string - } - | undefined = undefined - - init() - - function init() { - if (initialValue?.s3) { - if (!$fileUploads.find((fileUpload) => fileUpload.path === initialValue?.s3)) { - $fileUploads = [ - ...$fileUploads, - { - name: initialValue.filename, - size: 0, - progress: 100, - path: initialValue?.s3 - } - ] - } - } + interface Props { + acceptedFileTypes?: string[] | undefined + allowMultiple?: boolean + allowDelete?: boolean + folderOnly?: boolean + containerText?: string + customResourcePath?: string | undefined + customResourceType?: 's3' | 'azure_blob' | undefined // when customResourcePath is provided, this should be provided as well. Will default to S3 if not + customClass?: string + customStyle?: string + randomFileKey?: boolean + pathTransformer?: any // function taking as input {file: File} and returning a string + forceDisplayUploads?: boolean + defaultValue?: string | string[] | undefined + workspace?: string | undefined + fileUploads?: Writable + appPath?: string | undefined + disabled?: boolean + iconSize?: number | undefined + initialValue?: + | { + s3: string + filename: string + } + | { + s3: string + filename: string + }[] + | undefined + computeForceViewerPolicies?: + | (() => + | { + allowed_resources: string[] + allow_user_resources: boolean + allow_workspace_resource: boolean + file_key_regex: string + } + | undefined) + | undefined } - export let computeForceViewerPolicies: - | (() => - | { - allowed_resources: string[] - allow_user_resources: boolean - allow_workspace_resource: boolean - file_key_regex: string - } - | undefined) - | undefined = undefined + let { + acceptedFileTypes = ['*'], + allowMultiple = true, + allowDelete = true, + folderOnly = false, + containerText = folderOnly + ? 'Drag and drop a folder here or click to browse' + : allowMultiple + ? 'Drag and drop files here or click to browse' + : 'Drag and drop a file here or click to browse', + customResourcePath = undefined, + customResourceType = undefined, + customClass = '', + customStyle = '', + randomFileKey = false, + pathTransformer = undefined, + forceDisplayUploads = $bindable(false), + defaultValue = undefined, + workspace = undefined, + fileUploads = writable([]), + appPath = undefined, + disabled = false, + iconSize = undefined, + initialValue = undefined, + computeForceViewerPolicies = undefined + }: Props = $props() const dispatch = createEventDispatcher<{ addition: { path?: string; filename?: string } deletion: { path: string } }>() + let initialS3 = $derived( + Array.isArray(initialValue) + ? initialValue?.map((v) => v.s3) + : initialValue?.s3 + ? [initialValue?.s3] + : undefined + ) + init() + + function init() { + if (initialS3) { + function transform(initialValue: { s3: string; filename: string }) { + return { + name: initialValue.filename, + size: 0, + progress: 100, + path: initialValue?.s3 + } + } + for (const s3 of initialS3) { + if (!$fileUploads.find((fileUpload) => fileUpload.path === s3)) { + let initialFileUploads = initialValue + ? Array.isArray(initialValue) + ? initialValue.map(transform) + : [transform(initialValue)] + : [] + $fileUploads = [...$fileUploads, ...initialFileUploads] + } + } + } + } + type FileUploadData = { name: string size: number @@ -554,10 +596,10 @@ {containerText}{#if disabled}
(Disabled){/if} {/if} - {#if initialValue?.s3 && $fileUploads.length == 0} + {#if initialS3 && initialS3.length > 0 && $fileUploads.length == 0}
- File currently selected: {initialValue?.s3} + File currently selected: {initialS3?.join(', ')}
{/if} diff --git a/frontend/src/lib/components/propertyPicker/ObjectViewer.svelte b/frontend/src/lib/components/propertyPicker/ObjectViewer.svelte index c9f4fec930..97d541a673 100644 --- a/frontend/src/lib/components/propertyPicker/ObjectViewer.svelte +++ b/frontend/src/lib/components/propertyPicker/ObjectViewer.svelte @@ -34,7 +34,7 @@ level = 0, currentPath = '', pureViewer = false, - collapsed = $bindable((level != 0 && level % 3 == 0) || Array.isArray(json)), + collapsed = $bindable((level != 0 && level % 3 == 0) || (Array.isArray(json) && level != 0)), rawKey = false, topBrackets = false, allowCopy = true, @@ -205,6 +205,7 @@ {/if}
{/if} + {#if keys.length > 0} {#if !fullyCollapsed}