refactor: logic of singlePage setting modal (#5968)

#### What type of PR is this?

/area ui
/kind improvement
/milestone 2.16.x

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

优化页面设置弹窗的显示逻辑,改为在未打开弹窗组件的时候不渲染组件,减少不必要的请求。

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

#### Does this PR introduce a user-facing change?

```release-note
优化页面设置弹窗的显示逻辑,减少不必要的请求。
```
pull/5975/head
Ryan Wang 2024-05-23 11:02:49 +08:00 committed by GitHub
parent 5a3c9f0601
commit c51f2f4d4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 61 deletions

View File

@ -319,7 +319,6 @@ const onSettingSaved = (page: SinglePage) => {
} }
formState.value.page = page; formState.value.page = page;
settingModal.value = false;
if (!isUpdateMode.value) { if (!isUpdateMode.value) {
handleSave(); handleSave();
@ -328,7 +327,6 @@ const onSettingSaved = (page: SinglePage) => {
const onSettingPublished = (singlePage: SinglePage) => { const onSettingPublished = (singlePage: SinglePage) => {
formState.value.page = singlePage; formState.value.page = singlePage;
settingModal.value = false;
handlePublish(); handlePublish();
}; };
@ -426,10 +424,11 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) {
<template> <template>
<SinglePageSettingModal <SinglePageSettingModal
v-model:visible="settingModal" v-if="settingModal"
:single-page="formState.page" :single-page="formState.page"
:publish-support="!isUpdateMode" :publish-support="!isUpdateMode"
:only-emit="!isUpdateMode" :only-emit="!isUpdateMode"
@close="settingModal = false"
@saved="onSettingSaved" @saved="onSettingSaved"
@published="onSettingPublished" @published="onSettingPublished"
/> />

View File

@ -1,22 +1,23 @@
<script lang="ts" setup> <script lang="ts" setup>
import { import {
Dialog,
IconAddCircle,
IconArrowLeft, IconArrowLeft,
IconArrowRight, IconArrowRight,
IconAddCircle,
IconRefreshLine,
IconPages, IconPages,
IconRefreshLine,
Toast,
VButton, VButton,
VCard, VCard,
VPagination,
VSpace,
Dialog,
VEmpty, VEmpty,
VLoading, VLoading,
VPageHeader, VPageHeader,
Toast, VPagination,
VSpace,
} from "@halo-dev/components"; } from "@halo-dev/components";
import SinglePageSettingModal from "./components/SinglePageSettingModal.vue"; import SinglePageSettingModal from "./components/SinglePageSettingModal.vue";
import { computed, ref, watch } from "vue"; import type { Ref } from "vue";
import { computed, provide, ref, watch } from "vue";
import type { ListedSinglePage, SinglePage } from "@halo-dev/api-client"; import type { ListedSinglePage, SinglePage } from "@halo-dev/api-client";
import { apiClient } from "@/utils/api-client"; import { apiClient } from "@/utils/api-client";
import { singlePageLabels } from "@/constants/labels"; import { singlePageLabels } from "@/constants/labels";
@ -24,8 +25,6 @@ import { useQuery } from "@tanstack/vue-query";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import UserFilterDropdown from "@/components/filter/UserFilterDropdown.vue"; import UserFilterDropdown from "@/components/filter/UserFilterDropdown.vue";
import SinglePageListItem from "./components/SinglePageListItem.vue"; import SinglePageListItem from "./components/SinglePageListItem.vue";
import { provide } from "vue";
import type { Ref } from "vue";
import { useRouteQuery } from "@vueuse/router"; import { useRouteQuery } from "@vueuse/router";
const { t } = useI18n(); const { t } = useI18n();
@ -156,6 +155,7 @@ const handleOpenSettingModal = async (singlePage: SinglePage) => {
const onSettingModalClose = () => { const onSettingModalClose = () => {
selectedSinglePage.value = undefined; selectedSinglePage.value = undefined;
settingModal.value = false;
refetch(); refetch();
}; };
@ -271,7 +271,7 @@ watch(selectedPageNames, (newValue) => {
<template> <template>
<SinglePageSettingModal <SinglePageSettingModal
v-model:visible="settingModal" v-if="settingModal"
:single-page="selectedSinglePage" :single-page="selectedSinglePage"
@close="onSettingModalClose" @close="onSettingModalClose"
> >

View File

@ -6,7 +6,7 @@ import {
VModal, VModal,
VSpace, VSpace,
} from "@halo-dev/components"; } from "@halo-dev/components";
import { computed, nextTick, ref, toRaw, watch } from "vue"; import { computed, nextTick, ref, watch } from "vue";
import type { SinglePage } from "@halo-dev/api-client"; import type { SinglePage } from "@halo-dev/api-client";
import { cloneDeep } from "lodash-es"; import { cloneDeep } from "lodash-es";
import { apiClient } from "@/utils/api-client"; import { apiClient } from "@/utils/api-client";
@ -21,7 +21,28 @@ import { useI18n } from "vue-i18n";
import { usePageUpdateMutate } from "../composables/use-page-update-mutate"; import { usePageUpdateMutate } from "../composables/use-page-update-mutate";
import { FormType } from "@/types/slug"; import { FormType } from "@/types/slug";
const initialFormState: SinglePage = { const props = withDefaults(
defineProps<{
singlePage?: SinglePage;
publishSupport?: boolean;
onlyEmit?: boolean;
}>(),
{
singlePage: undefined,
publishSupport: true,
onlyEmit: false,
}
);
const emit = defineEmits<{
(event: "close"): void;
(event: "saved", singlePage: SinglePage): void;
(event: "published", singlePage: SinglePage): void;
}>();
const { t } = useI18n();
const formState = ref<SinglePage>({
spec: { spec: {
title: "", title: "",
slug: "", slug: "",
@ -45,49 +66,15 @@ const initialFormState: SinglePage = {
metadata: { metadata: {
name: randomUUID(), name: randomUUID(),
}, },
}; });
const modal = ref();
const props = withDefaults(
defineProps<{
visible: boolean;
singlePage?: SinglePage;
publishSupport?: boolean;
onlyEmit?: boolean;
}>(),
{
visible: false,
singlePage: undefined,
publishSupport: true,
onlyEmit: false,
}
);
const emit = defineEmits<{
(event: "update:visible", visible: boolean): void;
(event: "close"): void;
(event: "saved", singlePage: SinglePage): void;
(event: "published", singlePage: SinglePage): void;
}>();
const { t } = useI18n();
const formState = ref<SinglePage>(cloneDeep(initialFormState));
const saving = ref(false); const saving = ref(false);
const publishing = ref(false); const publishing = ref(false);
const publishCanceling = ref(false); const publishCanceling = ref(false);
const submitType = ref<"publish" | "save">(); const submitType = ref<"publish" | "save">();
const publishTime = ref<string | undefined>(undefined); const publishTime = ref<string | undefined>(undefined);
const isUpdateMode = computed(() => { const isUpdateMode = !!props.singlePage;
return !!formState.value.metadata.creationTimestamp;
});
const onVisibleChange = (visible: boolean) => {
emit("update:visible", visible);
if (!visible) {
emit("close");
}
};
const annotationsFormRef = ref<InstanceType<typeof AnnotationsForm>>(); const annotationsFormRef = ref<InstanceType<typeof AnnotationsForm>>();
@ -138,13 +125,14 @@ const handleSave = async () => {
if (props.onlyEmit) { if (props.onlyEmit) {
emit("saved", formState.value); emit("saved", formState.value);
modal.value.close();
return; return;
} }
try { try {
saving.value = true; saving.value = true;
const { data } = isUpdateMode.value const { data } = isUpdateMode
? await singlePageUpdateMutate(formState.value) ? await singlePageUpdateMutate(formState.value)
: await apiClient.extension.singlePage.createcontentHaloRunV1alpha1SinglePage( : await apiClient.extension.singlePage.createcontentHaloRunV1alpha1SinglePage(
{ {
@ -155,7 +143,7 @@ const handleSave = async () => {
formState.value = data; formState.value = data;
emit("saved", data); emit("saved", data);
onVisibleChange(false); modal.value.close();
Toast.success(t("core.common.toast.save_success")); Toast.success(t("core.common.toast.save_success"));
} catch (error) { } catch (error) {
@ -182,6 +170,7 @@ const handlePublish = async () => {
if (props.onlyEmit) { if (props.onlyEmit) {
emit("published", formState.value); emit("published", formState.value);
modal.value.close();
return; return;
} }
@ -206,7 +195,7 @@ const handlePublish = async () => {
emit("published", data); emit("published", data);
onVisibleChange(false); modal.value.close();
Toast.success(t("core.common.toast.publish_success")); Toast.success(t("core.common.toast.publish_success"));
} catch (error) { } catch (error) {
@ -238,7 +227,7 @@ const handleUnpublish = async () => {
formState.value = data; formState.value = data;
onVisibleChange(false); modal.value.close();
Toast.success(t("core.common.toast.cancel_publish_success")); Toast.success(t("core.common.toast.cancel_publish_success"));
} catch (error) { } catch (error) {
@ -252,7 +241,7 @@ watch(
() => props.singlePage, () => props.singlePage,
(value) => { (value) => {
if (value) { if (value) {
formState.value = toRaw(value); formState.value = cloneDeep(value);
publishTime.value = toDatetimeLocal(formState.value.spec.publishTime); publishTime.value = toDatetimeLocal(formState.value.spec.publishTime);
} }
}, },
@ -282,18 +271,18 @@ const { handleGenerateSlug } = useSlugify(
formState.value.spec.slug = value; formState.value.spec.slug = value;
}, },
}), }),
computed(() => !isUpdateMode.value), computed(() => !isUpdateMode),
FormType.SINGLE_PAGE FormType.SINGLE_PAGE
); );
</script> </script>
<template> <template>
<VModal <VModal
:visible="visible" ref="modal"
:width="700" :width="700"
:title="$t('core.page.settings.title')" :title="$t('core.page.settings.title')"
:centered="false" :centered="false"
@update:visible="onVisibleChange" @close="emit('close')"
> >
<template #actions> <template #actions>
<slot name="actions"></slot> <slot name="actions"></slot>
@ -492,7 +481,7 @@ const { handleGenerateSlug } = useSlugify(
<VButton :loading="saving" type="secondary" @click="handleSaveClick"> <VButton :loading="saving" type="secondary" @click="handleSaveClick">
{{ $t("core.common.buttons.save") }} {{ $t("core.common.buttons.save") }}
</VButton> </VButton>
<VButton type="default" @click="onVisibleChange(false)"> <VButton type="default" @click="modal.close()">
{{ $t("core.common.buttons.close") }} {{ $t("core.common.buttons.close") }}
</VButton> </VButton>
</VSpace> </VSpace>