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'}
+
{#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}