feat(app builder): adding downloadFile frontend helper

This commit is contained in:
Alexander Petric
2024-10-08 17:38:11 -04:00
parent e44decb9c2
commit ffce571117
6 changed files with 55 additions and 1 deletions
@@ -31,6 +31,7 @@
| 'open'
| 'close'
| 'clearFiles'
| 'downloadFile'
configuration: {
gotoUrl: { url: (() => string) | string | undefined; newTab: boolean | undefined }
setTab: {
@@ -61,6 +62,10 @@
clearFiles?: {
id: string | undefined
}
downloadFile?: {
id: string | undefined
fileName: string | undefined
}
}
}
| undefined
@@ -235,6 +240,15 @@
$componentControl[id].clearFiles?.()
break
}
case 'downloadFile': {
const id = sideEffect?.configuration?.downloadFile?.id
const fileName = sideEffect?.configuration?.downloadFile?.fileName
if (!id || !fileName) return
$componentControl[id].downloadFile?.(fileName)
break
}
default:
break
}
@@ -25,7 +25,7 @@ function create_context_function_template(
) {
let hasReturnAsLastLine = noReturn || eval_string.split('\n').some((x) => x.startsWith('return '))
return `
return async function (context, state, createProxy, goto, setTab, recompute, getAgGrid, setValue, setSelectedIndex, openModal, closeModal, open, close, validate, invalidate, validateAll, clearFiles, showToast, waitJob, askNewResource) {
return async function (context, state, createProxy, goto, setTab, recompute, getAgGrid, setValue, setSelectedIndex, openModal, closeModal, open, close, validate, invalidate, validateAll, clearFiles, downloadFile, showToast, waitJob, askNewResource) {
"use strict";
${
contextKeys && contextKeys.length > 0
@@ -61,6 +61,7 @@ type WmFunctor = (
invalidate,
validateAll,
clearFiles,
downloadFile,
showToast,
waitJob,
askNewResource
@@ -111,6 +112,7 @@ export async function eval_like(
invalidate?: (key: string, error: string) => void
validateAll?: () => void
clearFiles?: () => void
downloadFile?: (fileName: string) => void
showToast?: (message: string, error?: boolean) => void
waitJob?: (jobId: string) => void
askNewResource?: () => void
@@ -231,6 +233,9 @@ export async function eval_like(
(id) => {
controlComponents[id]?.clearFiles?.()
},
(id, fileName) => {
controlComponents[id]?.downloadFile?.(fileName)
},
(message, error) => {
sendUserToast(message, error)
},
@@ -48,6 +48,9 @@
$componentControl[id] = {
clearFiles: () => {
fileInput?.clearFiles()
},
downloadFile: (fileName: string) => {
fileInput?.downloadFile(fileName)
}
}
@@ -261,6 +261,7 @@ export type AppViewerContext = {
invalidate?: (key: string, error: string) => void
validateAll?: () => void
clearFiles?: () => void
downloadFile?: (fileName: string) => void
showToast?: (message: string, error?: boolean) => void
recompute?: () => void
askNewResource?: () => void
@@ -281,6 +281,12 @@ declare function validateAll(id: string): void;
*/
declare function clearFiles(id: string): void;
/** Download a file from a file input component
* @param id component's id
* @param fileName name of the file to download
*/
declare function downloadFile(id: string, fileName: string): void;
/** Display a toast message
* @param message message to display
*/
@@ -121,6 +121,31 @@
files = undefined
dispatchChange()
}
export function downloadFile(fileName: string) {
if (!files) {
console.error('Trying to download a file: No files uploaded');
return;
}
const file = files.find(f => f.name === fileName);
if (!file) {
console.error(`Trying to download a file: File "${fileName}" doesn't exist`);
return;
}
const url = URL.createObjectURL(file);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
// Delay revoking the object URL to ensure the download works
setTimeout(() => {
URL.revokeObjectURL(url);
}, 100);
}
</script>
<button