From 533f0cfa667da57b0d301db90c837da246553cc3 Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Thu, 25 May 2023 22:40:18 +0800 Subject: [PATCH] feat: prompt to upgrade theme when installing existing theme (#3970) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind feature /area console /milestone 2.6.x #### What this PR does / why we need it: 支持在安装已存在主题时提示是否升级主题。 image image #### Which issue(s) this PR fixes: Fixes #3969 #### Special notes for your reviewer: 测试方式: 1. 通过本地上传和远程下载的方式重复安装某个主题,观察是否可以正常提示升级以及测试升级是否正常。 #### Does this PR introduce a user-facing change? ```release-note Console 端支持安装已存在主题时提示升级主题。 ``` --- console/src/locales/en.yaml | 4 + console/src/locales/zh-CN.yaml | 4 + console/src/locales/zh-TW.yaml | 4 + .../themes/components/ThemeListModal.vue | 1 - .../themes/components/ThemeUploadModal.vue | 89 ++++++++++++++++++- 5 files changed, 97 insertions(+), 5 deletions(-) diff --git a/console/src/locales/en.yaml b/console/src/locales/en.yaml index 17160f20b..7c22a840d 100644 --- a/console/src/locales/en.yaml +++ b/console/src/locales/en.yaml @@ -606,6 +606,10 @@ core: titles: install: Install theme upgrade: Upgrade theme ({display_name}) + operations: + existed_during_installation: + title: The theme already exists. + description: The currently installed theme already exists, do you want to upgrade? tabs: local: Local remote: diff --git a/console/src/locales/zh-CN.yaml b/console/src/locales/zh-CN.yaml index 9beca1fbf..0257ce192 100644 --- a/console/src/locales/zh-CN.yaml +++ b/console/src/locales/zh-CN.yaml @@ -606,6 +606,10 @@ core: titles: install: 安装主题 upgrade: 升级主题({display_name}) + operations: + existed_during_installation: + title: 主题已存在 + description: 当前安装的主题已存在,是否升级? tabs: local: 本地上传 remote: diff --git a/console/src/locales/zh-TW.yaml b/console/src/locales/zh-TW.yaml index 3a10d16d8..81e55a4e5 100644 --- a/console/src/locales/zh-TW.yaml +++ b/console/src/locales/zh-TW.yaml @@ -606,6 +606,10 @@ core: titles: install: 安裝主題 upgrade: 升級主題({display_name}) + operations: + existed_during_installation: + title: 主題已存在 + description: 當前安裝的主題已存在,是否升級? tabs: local: 本地上傳 remote: diff --git a/console/src/modules/interface/themes/components/ThemeListModal.vue b/console/src/modules/interface/themes/components/ThemeListModal.vue index be1b78510..099a555ea 100644 --- a/console/src/modules/interface/themes/components/ThemeListModal.vue +++ b/console/src/modules/interface/themes/components/ThemeListModal.vue @@ -356,7 +356,6 @@ watch( v-if="visible" v-model:visible="themeUploadVisible" :upgrade-theme="themeToUpgrade" - @close="refetch" /> -import { Toast, VButton, VModal, VTabItem, VTabs } from "@halo-dev/components"; +import { + Dialog, + Toast, + VButton, + VModal, + VTabItem, + VTabs, +} from "@halo-dev/components"; import UppyUpload from "@/components/upload/UppyUpload.vue"; import { computed, ref, watch, nextTick } from "vue"; import type { Theme } from "@halo-dev/api-client"; @@ -9,6 +16,8 @@ import { useThemeStore } from "@/stores/theme"; import { apiClient } from "@/utils/api-client"; import { useRouteQuery } from "@vueuse/router"; import { submitForm } from "@formkit/core"; +import type { ErrorResponse } from "@uppy/core"; +import type { UppyFile } from "@uppy/utils"; const { t } = useI18n(); const queryClient = useQueryClient(); @@ -83,6 +92,71 @@ const onUploaded = () => { handleVisibleChange(false); }; +interface ThemeInstallationErrorResponse { + detail: string; + instance: string; + themeName: string; + requestId: string; + status: number; + timestamp: string; + title: string; + type: string; +} + +const THEME_ALREADY_EXISTS_TYPE = "https://halo.run/probs/theme-alreay-exists"; + +const onError = (file: UppyFile, response: ErrorResponse) => { + const body = response.body as ThemeInstallationErrorResponse; + + if (body.type === THEME_ALREADY_EXISTS_TYPE) { + handleCatchExistsException(body, file.data as File); + } +}; + +const handleCatchExistsException = async ( + error: ThemeInstallationErrorResponse, + file?: File +) => { + Dialog.info({ + title: t( + "core.theme.upload_modal.operations.existed_during_installation.title" + ), + description: t( + "core.theme.upload_modal.operations.existed_during_installation.description" + ), + confirmText: t("core.common.buttons.confirm"), + cancelText: t("core.common.buttons.cancel"), + onConfirm: async () => { + if (activeTabId.value === "local") { + if (!file) { + throw new Error("File is required"); + } + + await apiClient.theme.upgradeTheme({ + name: error.themeName, + file: file, + }); + } else if (activeTabId.value === "remote") { + await apiClient.theme.upgradeThemeFromUri({ + name: error.themeName, + upgradeFromUriRequest: { + uri: remoteDownloadUrl.value, + }, + }); + } else { + throw new Error("Unknown tab id"); + } + + Toast.success(t("core.common.toast.upgrade_success")); + + queryClient.invalidateQueries({ queryKey: ["themes"] }); + themeStore.fetchActivatedTheme(); + + handleVisibleChange(false); + }, + }); +}; + // remote download const activeTabId = ref("local"); const remoteDownloadUrl = ref(""); @@ -120,10 +194,16 @@ const handleDownloadTheme = async () => { handleVisibleChange(false); - routeRemoteDownloadUrl.value = null; - } catch (error) { - console.log("Failed to download theme", error); + // eslint-disable-next-line + } catch (error: any) { + const data = error?.response.data as ThemeInstallationErrorResponse; + if (data?.type === THEME_ALREADY_EXISTS_TYPE) { + handleCatchExistsException(data); + } + + console.error("Failed to download theme", error); } finally { + routeRemoteDownloadUrl.value = null; downloading.value = false; } }; @@ -164,6 +244,7 @@ watch( :endpoint="endpoint" auto-proceed @uploaded="onUploaded" + @error="onError" />