fix: saving settings in theme preview returns to homepage (#6447)

#### What type of PR is this?

/kind bug
/area ui
/milestone 2.19.x

#### What this PR does / why we need it:

此 PR 将主题预览及文章预览的 `iframe` 由 srcdoc 改为使用 src 加载。用于解决在主题预览时,如果点击保存设置,会导致主题端页面跳转至首页。

#### How to test it?

1. 打开主题预览界面。
2. 打开非首页的页面。
3. 点击保存配置。查看此时刷新页面后是否不再回到首页。

同时需要测试 #4047 中的场景是否还会再发生。

#### Which issue(s) this PR fixes:

Fixes #6371 

#### Does this PR introduce a user-facing change?
```release-note
解决预览主题时保存设置,页面会跳转至首页的问题。
```
pull/6453/head
Takagi 2024-08-08 16:20:38 +08:00 committed by GitHub
parent 40386557a7
commit 6cfc92b29e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 13 additions and 45 deletions

View File

@ -7,7 +7,7 @@ import type {
SettingForm, SettingForm,
Theme, Theme,
} from "@halo-dev/api-client"; } from "@halo-dev/api-client";
import { axiosInstance, consoleApiClient } from "@halo-dev/api-client"; import { consoleApiClient } from "@halo-dev/api-client";
import { import {
IconArrowLeft, IconArrowLeft,
IconComputer, IconComputer,
@ -54,6 +54,7 @@ interface SettingTab {
const { activatedTheme } = storeToRefs(useThemeStore()); const { activatedTheme } = storeToRefs(useThemeStore());
const previewFrame = ref<HTMLIFrameElement | null>(null);
const themesVisible = ref(false); const themesVisible = ref(false);
const switching = ref(false); const switching = ref(false);
const selectedTheme = ref<Theme>(); const selectedTheme = ref<Theme>();
@ -99,26 +100,6 @@ const modalTitle = computed(() => {
}); });
}); });
const {
data: previewHTML,
isLoading,
refetch: refetchPreviewHTML,
} = useQuery({
queryKey: ["site-preview", previewUrl],
queryFn: async () => {
const { data } = await axiosInstance.get(previewUrl.value, {
headers: {
Accept: "text/html",
"Cache-Control": "no-cache",
Pragma: "no-cache",
Expires: "0",
},
});
return data;
},
enabled: computed(() => !!previewUrl.value),
});
// theme settings // theme settings
const saving = ref(false); const saving = ref(false);
const settingTabs = ref<SettingTab[]>([] as SettingTab[]); const settingTabs = ref<SettingTab[]>([] as SettingTab[]);
@ -169,6 +150,10 @@ const { formSchema, configMapFormData, convertToSave } = useSettingFormConvert(
activeSettingTab activeSettingTab
); );
const handleRefresh = () => {
previewFrame.value?.contentWindow?.location.reload();
};
const handleSaveConfigMap = async () => { const handleSaveConfigMap = async () => {
saving.value = true; saving.value = true;
@ -190,7 +175,7 @@ const handleSaveConfigMap = async () => {
saving.value = false; saving.value = false;
refetchPreviewHTML(); handleRefresh();
}; };
const handleOpenSettings = (theme?: Theme) => { const handleOpenSettings = (theme?: Theme) => {
@ -271,7 +256,7 @@ const iframeClasses = computed(() => {
content: $t('core.common.buttons.refresh'), content: $t('core.common.buttons.refresh'),
delay: 300, delay: 300,
}" }"
@click="refetchPreviewHTML()" @click="handleRefresh()"
> >
<IconRefreshLine /> <IconRefreshLine />
</span> </span>
@ -422,12 +407,13 @@ const iframeClasses = computed(() => {
<div <div
class="flex h-full flex-1 items-center justify-center transition-all duration-300" class="flex h-full flex-1 items-center justify-center transition-all duration-300"
> >
<VLoading v-if="isLoading" /> <VLoading v-if="!previewUrl" />
<iframe <iframe
v-else v-else
ref="previewFrame"
class="border-none transition-all duration-500" class="border-none transition-all duration-500"
:class="iframeClasses" :class="iframeClasses"
:srcdoc="previewHTML" :src="previewUrl"
></iframe> ></iframe>
</div> </div>
</div> </div>

View File

@ -1,5 +1,4 @@
<script lang="ts" setup> <script lang="ts" setup>
import { axiosInstance } from "@halo-dev/api-client";
import { import {
IconComputer, IconComputer,
IconLink, IconLink,
@ -9,7 +8,6 @@ import {
VModal, VModal,
VTabbar, VTabbar,
} from "@halo-dev/components"; } from "@halo-dev/components";
import { useQuery } from "@tanstack/vue-query";
import { computed, markRaw, ref, toRefs } from "vue"; import { computed, markRaw, ref, toRefs } from "vue";
const props = withDefaults( const props = withDefaults(
@ -54,22 +52,6 @@ const iframeClasses = computed(() => {
} }
return "w-96 h-[50rem] ring-2 rounded ring-gray-300"; return "w-96 h-[50rem] ring-2 rounded ring-gray-300";
}); });
const { data: html, isLoading } = useQuery({
queryKey: ["url-preview", url],
queryFn: async () => {
const { data } = await axiosInstance.get(url.value, {
headers: {
Accept: "text/html",
"Cache-Control": "no-cache",
Pragma: "no-cache",
Expires: "0",
},
});
return data;
},
enabled: computed(() => !!url.value),
});
</script> </script>
<template> <template>
<VModal <VModal
@ -96,12 +78,12 @@ const { data: html, isLoading } = useQuery({
</span> </span>
</template> </template>
<div class="flex h-full items-center justify-center"> <div class="flex h-full items-center justify-center">
<VLoading v-if="isLoading" /> <VLoading v-if="!url" />
<iframe <iframe
v-else v-else
class="border-none transition-all duration-500" class="border-none transition-all duration-500"
:class="iframeClasses" :class="iframeClasses"
:srcdoc="html" :src="url"
></iframe> ></iframe>
</div> </div>
</VModal> </VModal>