feat: array of s3 objects in input maker

This commit is contained in:
Ruben Fiszel
2025-05-29 16:35:03 +02:00
parent f16149f777
commit 13823edf3d
5 changed files with 144 additions and 65 deletions

View File

@@ -573,6 +573,30 @@
}}
/>
</div>
{:else if itemsType?.type == 'object' && itemsType?.resourceType == 's3object'}
<div class="w-full">
<FileUpload
{appPath}
computeForceViewerPolicies={computeS3ForceViewerPolicies}
{workspace}
allowMultiple={true}
randomFileKey={true}
on:addition={(evt) => {
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}
/>
</div>
{:else}
<div class="w-full">
{#key redraw}

View File

@@ -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 @@
<option value="string"> Items are strings</option>
<option value="enum">Items are strings from an enum</option>
{#if originalType != 'string[]'}
<option value="s3object">Items are S3 objects</option>
<option value="object"> Items are objects (JSON)</option>
<option value="resource"> Items are resources</option>
<option value="number">Items are numbers</option>

View File

@@ -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)}
<div class="w-full border-dashed border-t-2 text-2xs pt-1 text-tertiary mt-2">
Default file: <span class="text-blue-500">{defaultFile}</span>
</div>

View File

@@ -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<FileUploadData[]> = 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<FileUploadData[]>
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}<br />(Disabled){/if}
</FileInput>
{/if}
{#if initialValue?.s3 && $fileUploads.length == 0}
{#if initialS3 && initialS3.length > 0 && $fileUploads.length == 0}
<div class="flex flex-row gap-1 items-center p-1">
<span class="text-sm">
File currently selected: {initialValue?.s3}
File currently selected: {initialS3?.join(', ')}
</span>
</div>
{/if}

View File

@@ -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}
</div>
{/if}
{#if keys.length > 0}
{#if !fullyCollapsed}
<span>