From 526bdaaed8260e2955a30749f731283d25263399 Mon Sep 17 00:00:00 2001 From: Alexandre Rousseau Date: Mon, 23 Dec 2024 11:07:55 +0100 Subject: [PATCH] chore(ui): improve icon fetching. WF-141 --- .../builder/sidebar/BuilderSidebarToolkit.vue | 33 ++++------ .../components/core/content/CoreChatbot.vue | 2 +- .../shared/SharedImgWithFallback.spec.ts | 37 +++++++++++ .../shared/SharedImgWithFallback.vue | 31 +++++++++ .../workflows/abstract/WorkflowsNode.vue | 38 +++-------- .../composables/useAssetContentType.spec.ts | 65 +++++++++++++++++++ src/ui/src/composables/useAssetContentType.ts | 29 +++++++++ src/ui/src/utils/url.spec.ts | 22 +++++++ src/ui/src/utils/url.ts | 14 ++++ 9 files changed, 219 insertions(+), 52 deletions(-) create mode 100644 src/ui/src/components/shared/SharedImgWithFallback.spec.ts create mode 100644 src/ui/src/components/shared/SharedImgWithFallback.vue create mode 100644 src/ui/src/composables/useAssetContentType.spec.ts create mode 100644 src/ui/src/composables/useAssetContentType.ts create mode 100644 src/ui/src/utils/url.spec.ts create mode 100644 src/ui/src/utils/url.ts diff --git a/src/ui/src/builder/sidebar/BuilderSidebarToolkit.vue b/src/ui/src/builder/sidebar/BuilderSidebarToolkit.vue index d9bc28bfc..dcd447b8c 100644 --- a/src/ui/src/builder/sidebar/BuilderSidebarToolkit.vue +++ b/src/ui/src/builder/sidebar/BuilderSidebarToolkit.vue @@ -23,19 +23,10 @@ @dragend="handleDragEnd($event)" @dragstart="handleDragStart($event, tool.type)" > -
{{ tool.name }}
@@ -54,12 +45,13 @@ import { import injectionKeys from "@/injectionKeys"; import { useDragDropComponent } from "../useDragDropComponent"; import { Component } from "@/writerTypes"; +import SharedImgWithFallback from "@/components/shared/SharedImgWithFallback.vue"; +import { convertAbsolutePathtoFullURL } from "@/utils/url"; const wf = inject(injectionKeys.core); const wfbm = inject(injectionKeys.builderManager); const { removeInsertionCandidacy } = useDragDropComponent(wf); const query = ref(""); -const isImageFallback = ref>({}); const displayedCategories = [ "Layout", @@ -114,16 +106,6 @@ function getRelevantToolsInCategory(categoryId: string) { return queryApplied; } -function handleImageError( - ev: Event, - type: Component["type"], - categoryId: string, -) { - isImageFallback.value[type] = true; // Prevent calling more than once - const imageEl = ev.target as HTMLImageElement; - imageEl.src = `./../../../../components/category_${categoryId}.svg`; -} - function handleDragStart(ev: DragEvent, type: Component["type"]) { wfbm.setSelection(null); ev.dataTransfer.setData(`application/json;writer=${type},`, "{}"); @@ -133,6 +115,13 @@ function handleDragEnd(ev: DragEvent) { removeInsertionCandidacy(ev); } +function getToolIcons(tool: ReturnType[0]) { + return [ + `/components/${tool.type}.svg`, + `/components/category_${tool.category}.svg`, + ].map((p) => convertAbsolutePathtoFullURL(p)); +} + watch(activeToolkit, () => { query.value = ""; }); diff --git a/src/ui/src/components/core/content/CoreChatbot.vue b/src/ui/src/components/core/content/CoreChatbot.vue index 521bfa16c..0cba76b74 100644 --- a/src/ui/src/components/core/content/CoreChatbot.vue +++ b/src/ui/src/components/core/content/CoreChatbot.vue @@ -401,7 +401,7 @@ function scrollToBottom() { } const encodeFile = async (file: File) => { - var reader = new FileReader(); + const reader = new FileReader(); reader.readAsDataURL(file); return new Promise((resolve, reject) => { diff --git a/src/ui/src/components/shared/SharedImgWithFallback.spec.ts b/src/ui/src/components/shared/SharedImgWithFallback.spec.ts new file mode 100644 index 000000000..846fc944f --- /dev/null +++ b/src/ui/src/components/shared/SharedImgWithFallback.spec.ts @@ -0,0 +1,37 @@ +import { describe, it, expect, vi, beforeEach, Mock } from "vitest"; +import SharedImgWithFallback from "./SharedImgWithFallback.vue"; +import { flushPromises, shallowMount } from "@vue/test-utils"; + +describe("SharedImgWithFallback", () => { + let fetch: Mock; + + beforeEach(() => { + fetch = vi.fn().mockResolvedValue({ + ok: true, + headers: new Map([["Content-Type", "image/png"]]), + }); + global.fetch = fetch; + }); + + it("should use the last image because the first two are not valid", async () => { + fetch + .mockRejectedValueOnce(new Error()) + .mockResolvedValueOnce({ + ok: true, + headers: new Map([["Content-Type", "text/html"]]), + }) + .mockResolvedValue({ + ok: true, + headers: new Map([["Content-Type", "image/png"]]), + }); + + const wrapper = shallowMount(SharedImgWithFallback, { + props: { urls: ["/img1.svg", "/img2.svg", "/img3.svg"] }, + }); + expect(wrapper.get("img").attributes().src).toBe(""); + + await flushPromises(); + + expect(wrapper.get("img").attributes().src).toBe("/img3.svg"); + }); +}); diff --git a/src/ui/src/components/shared/SharedImgWithFallback.vue b/src/ui/src/components/shared/SharedImgWithFallback.vue new file mode 100644 index 000000000..d4b0d7b47 --- /dev/null +++ b/src/ui/src/components/shared/SharedImgWithFallback.vue @@ -0,0 +1,31 @@ + + + diff --git a/src/ui/src/components/workflows/abstract/WorkflowsNode.vue b/src/ui/src/components/workflows/abstract/WorkflowsNode.vue index 5db673f1a..757e4ec81 100644 --- a/src/ui/src/components/workflows/abstract/WorkflowsNode.vue +++ b/src/ui/src/components/workflows/abstract/WorkflowsNode.vue @@ -1,7 +1,7 @@