mirror of https://github.com/halo-dev/halo
feat: allow switching editors while editing a post (#4180)
#### What type of PR is this? /area console /kind feature /milestone 2.8.x #### What this PR does / why we need it: 支持在编辑文章时切换编辑器,不再限制仅新建时允许切换。但需要注意的是,目前只支持同类型的编辑器切换(rawType)。 #### Which issue(s) this PR fixes: Fixes #4176 #### Special notes for your reviewer: 测试方式: 1. 安装多个编辑器插件,可以在 https://github.com/halo-sigs/awesome-halo 中查找。 2. 测试在新建文章时是否能够正常切换编辑器。 3. 测试在修改文章时能够正常切换同类型的编辑器。 #### Does this PR introduce a user-facing change? ```release-note Console 端编辑文章时允许同类型的编辑器切换。 ```pull/4179/head^2
parent
5a0e202847
commit
e6f31759a0
|
@ -2,13 +2,15 @@
|
||||||
import { DropdownContextInjectionKey } from "./symbols";
|
import { DropdownContextInjectionKey } from "./symbols";
|
||||||
import { inject } from "vue";
|
import { inject } from "vue";
|
||||||
|
|
||||||
withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
type: "default" | "danger";
|
type: "default" | "danger";
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
selected: false,
|
selected: false,
|
||||||
|
disabled: false,
|
||||||
type: "default",
|
type: "default",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -20,6 +22,10 @@ const emit = defineEmits<{
|
||||||
const { hide } = inject(DropdownContextInjectionKey) || {};
|
const { hide } = inject(DropdownContextInjectionKey) || {};
|
||||||
|
|
||||||
function onClick(e: MouseEvent) {
|
function onClick(e: MouseEvent) {
|
||||||
|
if (props.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
hide?.();
|
hide?.();
|
||||||
emit("click", e);
|
emit("click", e);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +34,10 @@ function onClick(e: MouseEvent) {
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="dropdown-item-wrapper"
|
class="dropdown-item-wrapper"
|
||||||
:class="[`dropdown-item-wrapper--${type}${selected ? '--selected' : ''}`]"
|
:class="[
|
||||||
|
`dropdown-item-wrapper--${type}${selected ? '--selected' : ''}`,
|
||||||
|
{ 'dropdown-item-wrapper--disabled': disabled },
|
||||||
|
]"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@click="onClick"
|
@click="onClick"
|
||||||
|
@ -62,5 +71,9 @@ function onClick(e: MouseEvent) {
|
||||||
@apply bg-red-50 text-red-700;
|
@apply bg-red-50 text-red-700;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
@apply opacity-70 cursor-not-allowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -13,9 +13,11 @@ import {
|
||||||
withDefaults(
|
withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
provider?: EditorProvider;
|
provider?: EditorProvider;
|
||||||
|
allowForcedSelect: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
provider: undefined,
|
provider: undefined,
|
||||||
|
allowForcedSelect: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -42,6 +44,11 @@ const { editorProviders } = useEditorExtensionPoints();
|
||||||
v-for="(editorProvider, index) in editorProviders"
|
v-for="(editorProvider, index) in editorProviders"
|
||||||
:key="index"
|
:key="index"
|
||||||
:selected="provider?.name === editorProvider.name"
|
:selected="provider?.name === editorProvider.name"
|
||||||
|
:disabled="
|
||||||
|
!allowForcedSelect &&
|
||||||
|
provider?.rawType.toLowerCase() !==
|
||||||
|
editorProvider.rawType.toLowerCase()
|
||||||
|
"
|
||||||
@click="emit('select', editorProvider)"
|
@click="emit('select', editorProvider)"
|
||||||
>
|
>
|
||||||
<template #prefix-icon>
|
<template #prefix-icon>
|
||||||
|
|
|
@ -10,3 +10,9 @@ export enum rbacAnnotations {
|
||||||
DISPLAY_NAME = "rbac.authorization.halo.run/display-name",
|
DISPLAY_NAME = "rbac.authorization.halo.run/display-name",
|
||||||
DEPENDENCIES = "rbac.authorization.halo.run/dependencies",
|
DEPENDENCIES = "rbac.authorization.halo.run/dependencies",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// content
|
||||||
|
|
||||||
|
export enum contentAnnotations {
|
||||||
|
PREFERRED_EDITOR = "content.halo.run/preferred-editor",
|
||||||
|
}
|
||||||
|
|
|
@ -36,22 +36,31 @@ import { useLocalStorage } from "@vueuse/core";
|
||||||
import EditorProviderSelector from "@/components/dropdown-selector/EditorProviderSelector.vue";
|
import EditorProviderSelector from "@/components/dropdown-selector/EditorProviderSelector.vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import UrlPreviewModal from "@/components/preview/UrlPreviewModal.vue";
|
import UrlPreviewModal from "@/components/preview/UrlPreviewModal.vue";
|
||||||
|
import { contentAnnotations } from "@/constants/annotations";
|
||||||
|
import { usePageUpdateMutate } from "./composables/use-page-update-mutate";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { mutateAsync: singlePageUpdateMutate } = usePageUpdateMutate();
|
||||||
|
|
||||||
// Editor providers
|
// Editor providers
|
||||||
const { editorProviders } = useEditorExtensionPoints();
|
const { editorProviders } = useEditorExtensionPoints();
|
||||||
const currentEditorProvider = ref<EditorProvider>();
|
const currentEditorProvider = ref<EditorProvider>();
|
||||||
const storedEditorProviderName = useLocalStorage("editor-provider-name", "");
|
const storedEditorProviderName = useLocalStorage("editor-provider-name", "");
|
||||||
|
|
||||||
const handleChangeEditorProvider = (provider: EditorProvider) => {
|
const handleChangeEditorProvider = async (provider: EditorProvider) => {
|
||||||
currentEditorProvider.value = provider;
|
currentEditorProvider.value = provider;
|
||||||
storedEditorProviderName.value = provider.name;
|
storedEditorProviderName.value = provider.name;
|
||||||
formState.value.page.metadata.annotations = {
|
formState.value.page.metadata.annotations = {
|
||||||
"content.halo.run/preferred-editor": provider.name,
|
...formState.value.page.metadata.annotations,
|
||||||
|
[contentAnnotations.PREFERRED_EDITOR]: provider.name,
|
||||||
};
|
};
|
||||||
formState.value.content.rawType = provider.rawType;
|
formState.value.content.rawType = provider.rawType;
|
||||||
|
|
||||||
|
if (isUpdateMode.value) {
|
||||||
|
const { data } = await singlePageUpdateMutate(formState.value.page);
|
||||||
|
formState.value.page = data;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// SinglePage form
|
// SinglePage form
|
||||||
|
@ -223,7 +232,7 @@ const handleFetchContent = async () => {
|
||||||
(provider) =>
|
(provider) =>
|
||||||
provider.name ===
|
provider.name ===
|
||||||
formState.value.page.metadata.annotations?.[
|
formState.value.page.metadata.annotations?.[
|
||||||
"content.halo.run/preferred-editor"
|
contentAnnotations.PREFERRED_EDITOR
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
const provider =
|
const provider =
|
||||||
|
@ -235,16 +244,10 @@ const handleFetchContent = async () => {
|
||||||
currentEditorProvider.value = provider;
|
currentEditorProvider.value = provider;
|
||||||
formState.value.page.metadata.annotations = {
|
formState.value.page.metadata.annotations = {
|
||||||
...formState.value.page.metadata.annotations,
|
...formState.value.page.metadata.annotations,
|
||||||
"content.halo.run/preferred-editor": provider.name,
|
[contentAnnotations.PREFERRED_EDITOR]: provider.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data } =
|
const { data } = await singlePageUpdateMutate(formState.value.page);
|
||||||
await apiClient.extension.singlePage.updatecontentHaloRunV1alpha1SinglePage(
|
|
||||||
{
|
|
||||||
name: formState.value.page.metadata.name,
|
|
||||||
singlePage: formState.value.page,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
formState.value.page = data;
|
formState.value.page = data;
|
||||||
} else {
|
} else {
|
||||||
|
@ -258,6 +261,9 @@ const handleFetchContent = async () => {
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
router.back();
|
router.back();
|
||||||
},
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
router.back();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
@ -315,7 +321,7 @@ onMounted(async () => {
|
||||||
formState.value.content.rawType = provider.rawType;
|
formState.value.content.rawType = provider.rawType;
|
||||||
}
|
}
|
||||||
formState.value.page.metadata.annotations = {
|
formState.value.page.metadata.annotations = {
|
||||||
"content.halo.run/preferred-editor": provider.name,
|
[contentAnnotations.PREFERRED_EDITOR]: provider.name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,8 +372,9 @@ const handlePreview = async () => {
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<VSpace>
|
<VSpace>
|
||||||
<EditorProviderSelector
|
<EditorProviderSelector
|
||||||
v-if="editorProviders.length > 1 && !isUpdateMode"
|
v-if="editorProviders.length > 1"
|
||||||
:provider="currentEditorProvider"
|
:provider="currentEditorProvider"
|
||||||
|
:allow-forced-select="!isUpdateMode"
|
||||||
@select="handleChangeEditorProvider"
|
@select="handleChangeEditorProvider"
|
||||||
/>
|
/>
|
||||||
<VButton
|
<VButton
|
||||||
|
|
|
@ -17,8 +17,8 @@ import { toDatetimeLocal, toISOString } from "@/utils/date";
|
||||||
import { submitForm } from "@formkit/core";
|
import { submitForm } from "@formkit/core";
|
||||||
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
||||||
import useSlugify from "@/composables/use-slugify";
|
import useSlugify from "@/composables/use-slugify";
|
||||||
import { useMutation } from "@tanstack/vue-query";
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { usePageUpdateMutate } from "../composables/use-page-update-mutate";
|
||||||
|
|
||||||
const initialFormState: SinglePage = {
|
const initialFormState: SinglePage = {
|
||||||
spec: {
|
spec: {
|
||||||
|
@ -117,37 +117,7 @@ const handlePublishClick = () => {
|
||||||
// Fix me:
|
// Fix me:
|
||||||
// Force update post settings,
|
// Force update post settings,
|
||||||
// because currently there may be errors caused by changes in version due to asynchronous processing.
|
// because currently there may be errors caused by changes in version due to asynchronous processing.
|
||||||
const { mutateAsync: singlePageUpdateMutate } = useMutation({
|
const { mutateAsync: singlePageUpdateMutate } = usePageUpdateMutate();
|
||||||
mutationKey: ["singlePage-update"],
|
|
||||||
mutationFn: async (page: SinglePage) => {
|
|
||||||
const { data: latestSinglePage } =
|
|
||||||
await apiClient.extension.singlePage.getcontentHaloRunV1alpha1SinglePage({
|
|
||||||
name: page.metadata.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
return apiClient.extension.singlePage.updatecontentHaloRunV1alpha1SinglePage(
|
|
||||||
{
|
|
||||||
name: page.metadata.name,
|
|
||||||
singlePage: {
|
|
||||||
...latestSinglePage,
|
|
||||||
spec: page.spec,
|
|
||||||
metadata: {
|
|
||||||
...latestSinglePage.metadata,
|
|
||||||
annotations: page.metadata.annotations,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
mute: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
retry: 3,
|
|
||||||
onError: (error) => {
|
|
||||||
console.error("Failed to update post", error);
|
|
||||||
Toast.error(t("core.common.toast.server_internal_error"));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
annotationsFormRef.value?.handleSubmit();
|
annotationsFormRef.value?.handleSubmit();
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { apiClient } from "@/utils/api-client";
|
||||||
|
import { useMutation } from "@tanstack/vue-query";
|
||||||
|
import type { SinglePage } from "@halo-dev/api-client";
|
||||||
|
import { Toast } from "@halo-dev/components";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
export function usePageUpdateMutate() {
|
||||||
|
const { t } = useI18n();
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ["singlePage-update"],
|
||||||
|
mutationFn: async (page: SinglePage) => {
|
||||||
|
const { data: latestSinglePage } =
|
||||||
|
await apiClient.extension.singlePage.getcontentHaloRunV1alpha1SinglePage(
|
||||||
|
{
|
||||||
|
name: page.metadata.name,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return apiClient.extension.singlePage.updatecontentHaloRunV1alpha1SinglePage(
|
||||||
|
{
|
||||||
|
name: page.metadata.name,
|
||||||
|
singlePage: {
|
||||||
|
...latestSinglePage,
|
||||||
|
spec: page.spec,
|
||||||
|
metadata: {
|
||||||
|
...latestSinglePage.metadata,
|
||||||
|
annotations: page.metadata.annotations,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mute: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
retry: 3,
|
||||||
|
onError: (error) => {
|
||||||
|
console.error("Failed to update post", error);
|
||||||
|
Toast.error(t("core.common.toast.server_internal_error"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
|
@ -36,22 +36,33 @@ import { useLocalStorage } from "@vueuse/core";
|
||||||
import EditorProviderSelector from "@/components/dropdown-selector/EditorProviderSelector.vue";
|
import EditorProviderSelector from "@/components/dropdown-selector/EditorProviderSelector.vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import UrlPreviewModal from "@/components/preview/UrlPreviewModal.vue";
|
import UrlPreviewModal from "@/components/preview/UrlPreviewModal.vue";
|
||||||
|
import { usePostUpdateMutate } from "./composables/use-post-update-mutate";
|
||||||
|
import { contentAnnotations } from "@/constants/annotations";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { mutateAsync: postUpdateMutate } = usePostUpdateMutate();
|
||||||
|
|
||||||
// Editor providers
|
// Editor providers
|
||||||
const { editorProviders } = useEditorExtensionPoints();
|
const { editorProviders } = useEditorExtensionPoints();
|
||||||
const currentEditorProvider = ref<EditorProvider>();
|
const currentEditorProvider = ref<EditorProvider>();
|
||||||
const storedEditorProviderName = useLocalStorage("editor-provider-name", "");
|
const storedEditorProviderName = useLocalStorage("editor-provider-name", "");
|
||||||
|
|
||||||
const handleChangeEditorProvider = (provider: EditorProvider) => {
|
const handleChangeEditorProvider = async (provider: EditorProvider) => {
|
||||||
currentEditorProvider.value = provider;
|
currentEditorProvider.value = provider;
|
||||||
storedEditorProviderName.value = provider.name;
|
storedEditorProviderName.value = provider.name;
|
||||||
|
|
||||||
formState.value.post.metadata.annotations = {
|
formState.value.post.metadata.annotations = {
|
||||||
"content.halo.run/preferred-editor": provider.name,
|
...formState.value.post.metadata.annotations,
|
||||||
|
[contentAnnotations.PREFERRED_EDITOR]: provider.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
formState.value.content.rawType = provider.rawType;
|
formState.value.content.rawType = provider.rawType;
|
||||||
|
|
||||||
|
if (isUpdateMode.value) {
|
||||||
|
const { data } = await postUpdateMutate(formState.value.post);
|
||||||
|
formState.value.post = data;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Post form
|
// Post form
|
||||||
|
@ -230,7 +241,7 @@ const handleFetchContent = async () => {
|
||||||
(provider) =>
|
(provider) =>
|
||||||
provider.name ===
|
provider.name ===
|
||||||
formState.value.post.metadata.annotations?.[
|
formState.value.post.metadata.annotations?.[
|
||||||
"content.halo.run/preferred-editor"
|
contentAnnotations.PREFERRED_EDITOR
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -245,14 +256,10 @@ const handleFetchContent = async () => {
|
||||||
|
|
||||||
formState.value.post.metadata.annotations = {
|
formState.value.post.metadata.annotations = {
|
||||||
...formState.value.post.metadata.annotations,
|
...formState.value.post.metadata.annotations,
|
||||||
"content.halo.run/preferred-editor": provider.name,
|
[contentAnnotations.PREFERRED_EDITOR]: provider.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data } =
|
const { data } = await postUpdateMutate(formState.value.post);
|
||||||
await apiClient.extension.post.updatecontentHaloRunV1alpha1Post({
|
|
||||||
name: formState.value.post.metadata.name,
|
|
||||||
post: formState.value.post,
|
|
||||||
});
|
|
||||||
|
|
||||||
formState.value.post = data;
|
formState.value.post = data;
|
||||||
} else {
|
} else {
|
||||||
|
@ -266,6 +273,9 @@ const handleFetchContent = async () => {
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
router.back();
|
router.back();
|
||||||
},
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
router.back();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +339,7 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
formState.value.post.metadata.annotations = {
|
formState.value.post.metadata.annotations = {
|
||||||
"content.halo.run/preferred-editor": provider.name,
|
[contentAnnotations.PREFERRED_EDITOR]: provider.name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
handleResetCache();
|
handleResetCache();
|
||||||
|
@ -379,8 +389,9 @@ const handlePreview = async () => {
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<VSpace>
|
<VSpace>
|
||||||
<EditorProviderSelector
|
<EditorProviderSelector
|
||||||
v-if="editorProviders.length > 1 && !isUpdateMode"
|
v-if="editorProviders.length > 1"
|
||||||
:provider="currentEditorProvider"
|
:provider="currentEditorProvider"
|
||||||
|
:allow-forced-select="!isUpdateMode"
|
||||||
@select="handleChangeEditorProvider"
|
@select="handleChangeEditorProvider"
|
||||||
/>
|
/>
|
||||||
<VButton
|
<VButton
|
||||||
|
|
|
@ -17,8 +17,8 @@ import { toDatetimeLocal, toISOString } from "@/utils/date";
|
||||||
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
||||||
import { submitForm } from "@formkit/core";
|
import { submitForm } from "@formkit/core";
|
||||||
import useSlugify from "@/composables/use-slugify";
|
import useSlugify from "@/composables/use-slugify";
|
||||||
import { useMutation } from "@tanstack/vue-query";
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { usePostUpdateMutate } from "../composables/use-post-update-mutate";
|
||||||
|
|
||||||
const initialFormState: Post = {
|
const initialFormState: Post = {
|
||||||
spec: {
|
spec: {
|
||||||
|
@ -117,37 +117,7 @@ const handlePublishClick = () => {
|
||||||
// Fix me:
|
// Fix me:
|
||||||
// Force update post settings,
|
// Force update post settings,
|
||||||
// because currently there may be errors caused by changes in version due to asynchronous processing.
|
// because currently there may be errors caused by changes in version due to asynchronous processing.
|
||||||
const { mutateAsync: postUpdateMutate } = useMutation({
|
const { mutateAsync: postUpdateMutate } = usePostUpdateMutate();
|
||||||
mutationKey: ["post-update"],
|
|
||||||
mutationFn: async (post: Post) => {
|
|
||||||
const { data: latestPost } =
|
|
||||||
await apiClient.extension.post.getcontentHaloRunV1alpha1Post({
|
|
||||||
name: post.metadata.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
return apiClient.extension.post.updatecontentHaloRunV1alpha1Post(
|
|
||||||
{
|
|
||||||
name: post.metadata.name,
|
|
||||||
post: {
|
|
||||||
...latestPost,
|
|
||||||
spec: post.spec,
|
|
||||||
metadata: {
|
|
||||||
...latestPost.metadata,
|
|
||||||
annotations: post.metadata.annotations,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
mute: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
retry: 3,
|
|
||||||
onError: (error) => {
|
|
||||||
console.error("Failed to update post", error);
|
|
||||||
Toast.error(t("core.common.toast.server_internal_error"));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
annotationsFormRef.value?.handleSubmit();
|
annotationsFormRef.value?.handleSubmit();
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { useMutation } from "@tanstack/vue-query";
|
||||||
|
import type { Post } from "@halo-dev/api-client";
|
||||||
|
import { apiClient } from "@/utils/api-client";
|
||||||
|
import { Toast } from "@halo-dev/components";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
export function usePostUpdateMutate() {
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ["post-update"],
|
||||||
|
mutationFn: async (post: Post) => {
|
||||||
|
const { data: latestPost } =
|
||||||
|
await apiClient.extension.post.getcontentHaloRunV1alpha1Post({
|
||||||
|
name: post.metadata.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
return await apiClient.extension.post.updatecontentHaloRunV1alpha1Post(
|
||||||
|
{
|
||||||
|
name: post.metadata.name,
|
||||||
|
post: {
|
||||||
|
...latestPost,
|
||||||
|
spec: post.spec,
|
||||||
|
metadata: {
|
||||||
|
...latestPost.metadata,
|
||||||
|
annotations: post.metadata.annotations,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mute: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
retry: 3,
|
||||||
|
onError: (error) => {
|
||||||
|
console.error("Failed to update post", error);
|
||||||
|
Toast.error(t("core.common.toast.server_internal_error"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue