From 918cf926f59097642071f4b88467cc99a1ccd819 Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Fri, 2 May 2025 19:23:41 +0000 Subject: [PATCH 1/6] fix: error words improvement, pass resourceConfig --- custom/uploader.vue | 2 +- index.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/custom/uploader.vue b/custom/uploader.vue index e95a6e3..36a0533 100644 --- a/custom/uploader.vue +++ b/custom/uploader.vue @@ -273,7 +273,7 @@ const onFileChange = async (e) => { }); if (!success) { adminforth.alert({ - messageHtml: `
${t('Sorry but the file was not uploaded because of S3 Request Error:')}
+ messageHtml: `
${t('Sorry but the file was not uploaded because of internal storage Request Error:')}
${
           xhr.responseText.replace(//g, '>')
         }
`, diff --git a/index.ts b/index.ts index b284627..6c83752 100644 --- a/index.ts +++ b/index.ts @@ -14,6 +14,8 @@ export default class UploadPlugin extends AdminForthPlugin { totalCalls: number; totalDuration: number; + resourceConfig: AdminForthResource; + constructor(options: PluginOptions) { super(options, import.meta.url); this.options = options; @@ -28,7 +30,8 @@ export default class UploadPlugin extends AdminForthPlugin { } async setupLifecycleRule() { - this.options.storageAdapter.setupLifecycle(); + const adapterUserUniqueRepresentation = `${this.resourceConfig.resourceId}-${this.pluginInstanceId}`; + this.options.storageAdapter.setupLifecycle(adapterUserUniqueRepresentation); } async genPreviewUrl(record: any) { @@ -43,6 +46,7 @@ export default class UploadPlugin extends AdminForthPlugin { async modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource) { super.modifyResourceConfig(adminforth, resourceConfig); + this.resourceConfig = resourceConfig; // after column to store the path of the uploaded file, add new VirtualColumn, // show only in edit and create views // use component uploader.vue From 6cf3c7420d4047a0830abe31d28ac29fb0ce3033 Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Sun, 4 May 2025 13:56:14 +0000 Subject: [PATCH 2/6] fix: allow attachFiles to be an async function. Might allow to predownload files or use in conjhunction with adapter.getKeyAsDataURL() --- index.ts | 2 +- types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.ts b/index.ts index 6c83752..3fb70f0 100644 --- a/index.ts +++ b/index.ts @@ -365,7 +365,7 @@ export default class UploadPlugin extends AdminForthPlugin { return { error: `Record with id ${recordId} not found` }; } - attachmentFiles = this.options.generation.attachFiles({ record, adminUser }); + attachmentFiles = await this.options.generation.attachFiles({ record, adminUser }); // if files is not array, make it array if (!Array.isArray(attachmentFiles)) { attachmentFiles = [attachmentFiles]; diff --git a/types.ts b/types.ts index 08ad927..b3efd5c 100644 --- a/types.ts +++ b/types.ts @@ -131,7 +131,7 @@ export type PluginOptions = { attachFiles?: ({ record, adminUser }: { record: any, adminUser: AdminUser, - }) => string[], + }) => string[] | Promise, /** From 14c44865781d8ceca9d442b47392556bca8afb1f Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Sun, 4 May 2025 13:58:12 +0000 Subject: [PATCH 3/6] fix: preview field: instead of always guessing content type based on url, do a HEAD to upstream which can return correct value from metadata even if URL has file without extension. Both ways are cross-fallback so if any of them will not work other one will do a best to display image correctly --- custom/preview.vue | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/custom/preview.vue b/custom/preview.vue index 75541a0..6300b52 100644 --- a/custom/preview.vue +++ b/custom/preview.vue @@ -71,6 +71,30 @@ const props = defineProps({ meta: Object, }) +const trueContentType = ref(null); + +onMounted(async () => { + // try to get HEAD request + try { + const response = await fetch(url.value, { + method: 'HEAD', + }); + const ct = response.headers.get('Content-Type'); + if (ct) { + trueContentType.value = ct; + } + } catch (e) { + console.error('fetch error for getting content type, please check CORS allowed for HEAD request', e); + } +}); + +const contentType = computed(() => { + if (trueContentType.value) { + return trueContentType.value; + } + return guessedContentType.value; +}); + const route = useRoute(); const url = computed(() => { return props.record[`previewUrl_${props.meta.pluginInstanceId}`]; @@ -95,11 +119,11 @@ const minWidth = computed(() => { }); // since we have no way to know the content type of the file, we will try to guess it from extension // for better experience probably we should check whether user saves content type in the database and use it here -const contentType = computed(() => { +const guessedContentType = computed(() => { if (!url.value) { return null; } - const u = new URL(url.value); + const u = new URL(url.value, url.value.startsWith('http') ? undefined : location.origin); return guessContentType(u.pathname); }); From a4f5f3a9e5fb2b6c3d23f30d3eae9a9b03bc17c2 Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Sun, 4 May 2025 14:01:55 +0000 Subject: [PATCH 4/6] fix: preview put zoom on preview when content type or url changes --- custom/preview.vue | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/custom/preview.vue b/custom/preview.vue index 6300b52..c5e64a6 100644 --- a/custom/preview.vue +++ b/custom/preview.vue @@ -58,7 +58,7 @@ } */ \ No newline at end of file From 4a706f96d01a700ae3aba0563c48e0acd37bff08 Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Sun, 4 May 2025 14:03:13 +0000 Subject: [PATCH 5/6] fix: preview put zoom on preview when content type or url changes --- custom/preview.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom/preview.vue b/custom/preview.vue index c5e64a6..4080b14 100644 --- a/custom/preview.vue +++ b/custom/preview.vue @@ -141,7 +141,8 @@ function guessContentType(url) { } -watch([url, contentType], async ([url, contentType]) => { +watch([contentType], async ([contentType]) => { + // since content type might change after true guessing (HEAD request might be slow) we need to try initializing zoom again if (zoom.value) { zoom.value.detach(); } From 7c4dcb0048788b526b8a559fa1682910b03be846 Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Sun, 4 May 2025 19:59:18 +0000 Subject: [PATCH 6/6] rebuild --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6367e67..14795c1 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,4 @@ Allows to upload files to Amazon S3 bucket from adminforth application. -## For usage, see [AdminForth Upload Documentation](https://adminforth.dev/docs/tutorial/Plugins/upload/) \ No newline at end of file +## For usage, see [AdminForth Upload Documentation](https://adminforth.dev/docs/tutorial/Plugins/upload/)