mirror of https://github.com/halo-dev/halo
feat: add upgrade plugin support (halo-dev/console#663)
#### What type of PR is this? /kind feature /milestone 2.0 #### What this PR does / why we need it: 支持插件升级,适配 https://github.com/halo-dev/halo/pull/2624 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/2551 #### Screenshots: <img width="1663" alt="image" src="https://user-images.githubusercontent.com/21301288/197682557-7e37895e-a6b5-43d6-8d40-2a1c899b9ce1.png"> <img width="1662" alt="image" src="https://user-images.githubusercontent.com/21301288/197682572-4db39f09-efda-4928-9a6d-8593c7c0c790.png"> #### Special notes for your reviewer: 测试方式: 1. Halo 需要使用 https://github.com/halo-dev/halo/pull/2624 PR 的分支。 2. Console 需要 `pnpm install` 3. 修改已安装的插件,构建之后更新插件,检查是否更新成功。 #### Does this PR introduce a user-facing change? ```release-note 支持插件升级 ```pull/3445/head
parent
4ca853e159
commit
a23c4318cc
|
@ -33,7 +33,7 @@
|
||||||
"@formkit/inputs": "^1.0.0-beta.11",
|
"@formkit/inputs": "^1.0.0-beta.11",
|
||||||
"@formkit/themes": "^1.0.0-beta.11",
|
"@formkit/themes": "^1.0.0-beta.11",
|
||||||
"@formkit/vue": "^1.0.0-beta.11",
|
"@formkit/vue": "^1.0.0-beta.11",
|
||||||
"@halo-dev/api-client": "^0.0.38",
|
"@halo-dev/api-client": "^0.0.39",
|
||||||
"@halo-dev/components": "workspace:*",
|
"@halo-dev/components": "workspace:*",
|
||||||
"@halo-dev/console-shared": "workspace:*",
|
"@halo-dev/console-shared": "workspace:*",
|
||||||
"@halo-dev/richtext-editor": "^0.0.0-alpha.8",
|
"@halo-dev/richtext-editor": "^0.0.0-alpha.8",
|
||||||
|
|
|
@ -13,7 +13,7 @@ importers:
|
||||||
'@formkit/inputs': ^1.0.0-beta.11
|
'@formkit/inputs': ^1.0.0-beta.11
|
||||||
'@formkit/themes': ^1.0.0-beta.11
|
'@formkit/themes': ^1.0.0-beta.11
|
||||||
'@formkit/vue': ^1.0.0-beta.11
|
'@formkit/vue': ^1.0.0-beta.11
|
||||||
'@halo-dev/api-client': ^0.0.38
|
'@halo-dev/api-client': ^0.0.39
|
||||||
'@halo-dev/components': workspace:*
|
'@halo-dev/components': workspace:*
|
||||||
'@halo-dev/console-shared': workspace:*
|
'@halo-dev/console-shared': workspace:*
|
||||||
'@halo-dev/richtext-editor': ^0.0.0-alpha.8
|
'@halo-dev/richtext-editor': ^0.0.0-alpha.8
|
||||||
|
@ -101,7 +101,7 @@ importers:
|
||||||
'@formkit/inputs': 1.0.0-beta.11
|
'@formkit/inputs': 1.0.0-beta.11
|
||||||
'@formkit/themes': 1.0.0-beta.11_tailwindcss@3.1.8
|
'@formkit/themes': 1.0.0-beta.11_tailwindcss@3.1.8
|
||||||
'@formkit/vue': 1.0.0-beta.11_k5hp3txgeyj6le63abiyc7wx3u
|
'@formkit/vue': 1.0.0-beta.11_k5hp3txgeyj6le63abiyc7wx3u
|
||||||
'@halo-dev/api-client': 0.0.38
|
'@halo-dev/api-client': 0.0.39
|
||||||
'@halo-dev/components': link:packages/components
|
'@halo-dev/components': link:packages/components
|
||||||
'@halo-dev/console-shared': link:packages/shared
|
'@halo-dev/console-shared': link:packages/shared
|
||||||
'@halo-dev/richtext-editor': 0.0.0-alpha.8_vue@3.2.40
|
'@halo-dev/richtext-editor': 0.0.0-alpha.8_vue@3.2.40
|
||||||
|
@ -1892,8 +1892,8 @@ packages:
|
||||||
- windicss
|
- windicss
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@halo-dev/api-client/0.0.38:
|
/@halo-dev/api-client/0.0.39:
|
||||||
resolution: {integrity: sha512-7Vlc/tXkpERi2xWxtoWOVtYbZi+sksrueBAj64gr0cAUOqRy7A82oJXpeabLKeJAjDNdQKZ7eL7CClnf9NJTEA==}
|
resolution: {integrity: sha512-GuTTJDOj0PPMXo3KTiNYGACRUXqJKnjnApK303eNPWqVodgR3mJVLFTXwa+euAJOkcSG3KkB5OtUFAkZeHRbPA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@halo-dev/richtext-editor/0.0.0-alpha.8_vue@3.2.40:
|
/@halo-dev/richtext-editor/0.0.0-alpha.8_vue@3.2.40:
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
VSpace,
|
VSpace,
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import PluginListItem from "./components/PluginListItem.vue";
|
import PluginListItem from "./components/PluginListItem.vue";
|
||||||
import PluginInstallModal from "./components/PluginInstallModal.vue";
|
import PluginUploadModal from "./components/PluginUploadModal.vue";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { apiClient } from "@/utils/api-client";
|
import { apiClient } from "@/utils/api-client";
|
||||||
import type { PluginList } from "@halo-dev/api-client";
|
import type { PluginList } from "@halo-dev/api-client";
|
||||||
|
@ -140,7 +140,7 @@ function handleSortItemChange(sortItem?: SortItem) {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<PluginInstallModal
|
<PluginUploadModal
|
||||||
v-if="currentUserHasPermission(['system:plugins:manage'])"
|
v-if="currentUserHasPermission(['system:plugins:manage'])"
|
||||||
v-model:visible="pluginInstall"
|
v-model:visible="pluginInstall"
|
||||||
@close="handleFetchPlugins"
|
@close="handleFetchPlugins"
|
||||||
|
@ -306,7 +306,7 @@ function handleSortItemChange(sortItem?: SortItem) {
|
||||||
role="list"
|
role="list"
|
||||||
>
|
>
|
||||||
<li v-for="(plugin, index) in plugins.items" :key="index">
|
<li v-for="(plugin, index) in plugins.items" :key="index">
|
||||||
<PluginListItem :plugin="plugin" />
|
<PluginListItem :plugin="plugin" @reload="handleFetchPlugins" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ import {
|
||||||
VEntityField,
|
VEntityField,
|
||||||
VAvatar,
|
VAvatar,
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import { toRefs } from "vue";
|
import PluginUploadModal from "./PluginUploadModal.vue";
|
||||||
|
import { ref, toRefs } from "vue";
|
||||||
import { usePluginLifeCycle } from "../composables/use-plugin";
|
import { usePluginLifeCycle } from "../composables/use-plugin";
|
||||||
import type { Plugin } from "@halo-dev/api-client";
|
import type { Plugin } from "@halo-dev/api-client";
|
||||||
import { formatDatetime } from "@/utils/date";
|
import { formatDatetime } from "@/utils/date";
|
||||||
|
@ -26,11 +27,26 @@ const props = withDefaults(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(event: "reload"): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
const { plugin } = toRefs(props);
|
const { plugin } = toRefs(props);
|
||||||
|
|
||||||
|
const upgradeModal = ref(false);
|
||||||
|
|
||||||
const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
|
const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
|
||||||
|
|
||||||
|
const onUpgradeModalClose = () => {
|
||||||
|
emit("reload");
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
<PluginUploadModal
|
||||||
|
v-model:visible="upgradeModal"
|
||||||
|
:upgrade-plugin="plugin"
|
||||||
|
@close="onUpgradeModalClose"
|
||||||
|
/>
|
||||||
<VEntity>
|
<VEntity>
|
||||||
<template #start>
|
<template #start>
|
||||||
<VEntityField>
|
<VEntityField>
|
||||||
|
@ -108,6 +124,14 @@ const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
|
||||||
v-if="currentUserHasPermission(['system:plugins:manage'])"
|
v-if="currentUserHasPermission(['system:plugins:manage'])"
|
||||||
#dropdownItems
|
#dropdownItems
|
||||||
>
|
>
|
||||||
|
<VButton
|
||||||
|
v-close-popper
|
||||||
|
block
|
||||||
|
type="secondary"
|
||||||
|
@click="upgradeModal = true"
|
||||||
|
>
|
||||||
|
升级
|
||||||
|
</VButton>
|
||||||
<VButton v-close-popper block type="danger" @click="uninstall">
|
<VButton v-close-popper block type="danger" @click="uninstall">
|
||||||
卸载
|
卸载
|
||||||
</VButton>
|
</VButton>
|
||||||
|
|
|
@ -6,12 +6,14 @@ import type { Plugin } from "@halo-dev/api-client";
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosResponse } from "axios";
|
||||||
|
|
||||||
withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
|
upgradePlugin?: Plugin;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
visible: false,
|
visible: false,
|
||||||
|
upgradePlugin: undefined,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -22,6 +24,12 @@ const emit = defineEmits<{
|
||||||
|
|
||||||
const FilePondUploadRef = ref();
|
const FilePondUploadRef = ref();
|
||||||
|
|
||||||
|
const modalTitle = computed(() => {
|
||||||
|
return props.upgradePlugin
|
||||||
|
? `升级插件(${props.upgradePlugin.spec.displayName})`
|
||||||
|
: "安装插件";
|
||||||
|
});
|
||||||
|
|
||||||
const handleVisibleChange = (visible: boolean) => {
|
const handleVisibleChange = (visible: boolean) => {
|
||||||
emit("update:visible", visible);
|
emit("update:visible", visible);
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
|
@ -31,6 +39,16 @@ const handleVisibleChange = (visible: boolean) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadHandler = computed(() => {
|
const uploadHandler = computed(() => {
|
||||||
|
if (props.upgradePlugin) {
|
||||||
|
return (file, config) =>
|
||||||
|
apiClient.plugin.upgradePlugin(
|
||||||
|
{
|
||||||
|
name: props.upgradePlugin.metadata.name as string,
|
||||||
|
file: file,
|
||||||
|
},
|
||||||
|
config
|
||||||
|
);
|
||||||
|
}
|
||||||
return (file, config) =>
|
return (file, config) =>
|
||||||
apiClient.plugin.installPlugin(
|
apiClient.plugin.installPlugin(
|
||||||
{
|
{
|
||||||
|
@ -41,6 +59,11 @@ const uploadHandler = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const onUploaded = async (response: AxiosResponse) => {
|
const onUploaded = async (response: AxiosResponse) => {
|
||||||
|
if (props.upgradePlugin) {
|
||||||
|
handleVisibleChange(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const plugin = response.data as Plugin;
|
const plugin = response.data as Plugin;
|
||||||
handleVisibleChange(false);
|
handleVisibleChange(false);
|
||||||
Dialog.success({
|
Dialog.success({
|
||||||
|
@ -71,10 +94,11 @@ const onUploaded = async (response: AxiosResponse) => {
|
||||||
<VModal
|
<VModal
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
:width="500"
|
:width="500"
|
||||||
title="安装插件"
|
:title="modalTitle"
|
||||||
@update:visible="handleVisibleChange"
|
@update:visible="handleVisibleChange"
|
||||||
>
|
>
|
||||||
<FilePondUpload
|
<FilePondUpload
|
||||||
|
v-if="visible && uploadHandler"
|
||||||
ref="FilePondUploadRef"
|
ref="FilePondUploadRef"
|
||||||
:allow-multiple="false"
|
:allow-multiple="false"
|
||||||
:handler="uploadHandler"
|
:handler="uploadHandler"
|
Loading…
Reference in New Issue