forked from tsai/budibase
13 changed files with 231 additions and 1 deletions
@ -0,0 +1,33 @@ |
|||||
|
<script> |
||||
|
import { Select, Label } from "@budibase/bbui" |
||||
|
import { currentAsset } from "builderStore" |
||||
|
import { findAllMatchingComponents } from "builderStore/componentUtils" |
||||
|
|
||||
|
export let parameters |
||||
|
|
||||
|
$: components = findAllMatchingComponents($currentAsset.props, component => |
||||
|
component._component.endsWith("s3upload") |
||||
|
) |
||||
|
</script> |
||||
|
|
||||
|
<div class="root"> |
||||
|
<Label small>S3 Upload Component</Label> |
||||
|
<Select |
||||
|
bind:value={parameters.componentId} |
||||
|
options={components} |
||||
|
getOptionLabel={x => x._instanceName} |
||||
|
getOptionValue={x => x._id} |
||||
|
/> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.root { |
||||
|
display: grid; |
||||
|
column-gap: var(--spacing-l); |
||||
|
row-gap: var(--spacing-s); |
||||
|
grid-template-columns: 120px 1fr; |
||||
|
align-items: center; |
||||
|
max-width: 400px; |
||||
|
margin: 0 auto; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,15 @@ |
|||||
|
<script> |
||||
|
import { Select } from "@budibase/bbui" |
||||
|
import { datasources } from "stores/backend" |
||||
|
|
||||
|
export let value = null |
||||
|
|
||||
|
$: dataSources = $datasources.list |
||||
|
.filter(ds => ds.source === "S3") |
||||
|
.map(ds => ({ |
||||
|
label: ds.name, |
||||
|
value: ds._id, |
||||
|
})) |
||||
|
</script> |
||||
|
|
||||
|
<Select options={dataSources} {value} on:change /> |
||||
@ -0,0 +1,79 @@ |
|||||
|
<script> |
||||
|
import Field from "./Field.svelte" |
||||
|
import { CoreDropzone } from "@budibase/bbui" |
||||
|
import { getContext, onMount, onDestroy } from "svelte" |
||||
|
|
||||
|
export let dataSource |
||||
|
export let bucket |
||||
|
export let field |
||||
|
export let label |
||||
|
export let disabled = false |
||||
|
export let validation |
||||
|
|
||||
|
let fieldState |
||||
|
let fieldApi |
||||
|
|
||||
|
const { API, notificationStore, uploadStore } = getContext("sdk") |
||||
|
const component = getContext("component") |
||||
|
const formContext = getContext("form") |
||||
|
|
||||
|
// 5GB cap per item sent via S3 REST API |
||||
|
const MaxFileSize = 1000000000 * 5 |
||||
|
|
||||
|
let file |
||||
|
|
||||
|
const handleFileTooLarge = () => { |
||||
|
notificationStore.actions.warning( |
||||
|
"Files cannot exceed 5GB. Please try again with a smaller file." |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
const processFiles = async fileList => { |
||||
|
// let data = new FormData() |
||||
|
// for (let i = 0; i < fileList.length; i++) { |
||||
|
// data.append("file", fileList[i]) |
||||
|
// } |
||||
|
// return await API.uploadAttachment(data, formContext?.dataSource?.tableId) |
||||
|
file = fileList[0] |
||||
|
console.log("processing", fileList) |
||||
|
return [] |
||||
|
} |
||||
|
|
||||
|
const upload = async () => { |
||||
|
console.log("UPLOADING!!!") |
||||
|
} |
||||
|
|
||||
|
onMount(() => { |
||||
|
uploadStore.actions.registerFileUpload($component.id, upload) |
||||
|
}) |
||||
|
|
||||
|
onDestroy(() => { |
||||
|
uploadStore.actions.unregisterFileUpload($component.id) |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<Field |
||||
|
{label} |
||||
|
{field} |
||||
|
{disabled} |
||||
|
{validation} |
||||
|
type="s3upload" |
||||
|
bind:fieldState |
||||
|
bind:fieldApi |
||||
|
defaultValue={[]} |
||||
|
> |
||||
|
{#if fieldState} |
||||
|
<CoreDropzone |
||||
|
value={fieldState.value} |
||||
|
disabled={fieldState.disabled} |
||||
|
error={fieldState.error} |
||||
|
on:change={e => { |
||||
|
fieldApi.setValue(e.detail) |
||||
|
}} |
||||
|
{processFiles} |
||||
|
{handleFileTooLarge} |
||||
|
maximum={1} |
||||
|
fileSizeLimit={MaxFileSize} |
||||
|
/> |
||||
|
{/if} |
||||
|
</Field> |
||||
@ -0,0 +1,42 @@ |
|||||
|
import { writable, get } from "svelte/store" |
||||
|
|
||||
|
export const createUploadStore = () => { |
||||
|
const store = writable([]) |
||||
|
|
||||
|
// Registers a new file upload component
|
||||
|
const registerFileUpload = (componentId, callback) => { |
||||
|
if (!componentId || !callback) { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
store.update(state => { |
||||
|
state.push({ |
||||
|
componentId, |
||||
|
callback, |
||||
|
}) |
||||
|
return state |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// Unregisters a file upload component
|
||||
|
const unregisterFileUpload = componentId => { |
||||
|
store.update(state => state.filter(c => c.componentId !== componentId)) |
||||
|
} |
||||
|
|
||||
|
// Processes a file upload for a given component ID
|
||||
|
const processFileUpload = async componentId => { |
||||
|
if (!componentId) { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
const component = get(store).find(c => c.componentId === componentId) |
||||
|
await component?.callback() |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
subscribe: store.subscribe, |
||||
|
actions: { registerFileUpload, unregisterFileUpload, processFileUpload }, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export const uploadStore = createUploadStore() |
||||
Loading…
Reference in new issue