mirror of https://github.com/halo-dev/halo-admin
refactor: logic for plugin lifecircle management
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/591/head
parent
fad809fec2
commit
0997cb5b41
|
@ -1,42 +1,20 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useDialog, VSwitch, VTag } from "@halo-dev/components";
|
import { VSwitch, VTag } from "@halo-dev/components";
|
||||||
import type { Ref } from "vue";
|
import type { Ref } from "vue";
|
||||||
import { computed, inject, onMounted, ref } from "vue";
|
import { computed, inject, onMounted, ref } from "vue";
|
||||||
import { apiClient } from "@halo-dev/admin-shared";
|
import { apiClient } from "@halo-dev/admin-shared";
|
||||||
import type { Plugin, Role } from "@halo-dev/api-client";
|
import type { Plugin, Role } from "@halo-dev/api-client";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
|
||||||
import { pluginLabels } from "@/constants/labels";
|
import { pluginLabels } from "@/constants/labels";
|
||||||
import { rbacAnnotations } from "@/constants/annotations";
|
import { rbacAnnotations } from "@/constants/annotations";
|
||||||
|
import { usePluginLifeCycle } from "./composables/use-plugin";
|
||||||
|
|
||||||
const plugin = inject<Ref<Plugin>>("plugin", ref({} as Plugin));
|
const plugin = inject<Ref<Plugin>>("plugin", ref({} as Plugin));
|
||||||
|
const { changeStatus } = usePluginLifeCycle(plugin);
|
||||||
const dialog = useDialog();
|
|
||||||
|
|
||||||
const isStarted = computed(() => {
|
const isStarted = computed(() => {
|
||||||
return plugin.value.status?.phase === "STARTED" && plugin.value.spec.enabled;
|
return plugin.value.status?.phase === "STARTED" && plugin.value.spec.enabled;
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleChangePluginStatus = async () => {
|
|
||||||
const pluginToUpdate = cloneDeep(plugin.value);
|
|
||||||
|
|
||||||
dialog.info({
|
|
||||||
title: `确定要${plugin.value.spec.enabled ? "停止" : "启动"}该插件吗?`,
|
|
||||||
onConfirm: async () => {
|
|
||||||
try {
|
|
||||||
pluginToUpdate.spec.enabled = !pluginToUpdate.spec.enabled;
|
|
||||||
await apiClient.extension.plugin.updatepluginHaloRunV1alpha1Plugin(
|
|
||||||
plugin.value.metadata.name,
|
|
||||||
pluginToUpdate
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
} finally {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO 临时解决方案
|
// TODO 临时解决方案
|
||||||
interface RoleTemplateGroup {
|
interface RoleTemplateGroup {
|
||||||
module: string | null | undefined;
|
module: string | null | undefined;
|
||||||
|
@ -98,7 +76,7 @@ onMounted(() => {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-permission="['system:plugins:manage']">
|
<div v-permission="['system:plugins:manage']">
|
||||||
<VSwitch :model-value="isStarted" @change="handleChangePluginStatus" />
|
<VSwitch :model-value="isStarted" @change="changeStatus" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-t border-gray-200">
|
<div class="border-t border-gray-200">
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {
|
||||||
IconArrowDown,
|
IconArrowDown,
|
||||||
IconPlug,
|
IconPlug,
|
||||||
IconSettings,
|
IconSettings,
|
||||||
useDialog,
|
|
||||||
VButton,
|
VButton,
|
||||||
VCard,
|
VCard,
|
||||||
VPageHeader,
|
VPageHeader,
|
||||||
|
@ -15,23 +14,15 @@ import {
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import PluginInstallModal from "./components/PluginInstallModal.vue";
|
import PluginInstallModal from "./components/PluginInstallModal.vue";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
import { apiClient } from "@halo-dev/admin-shared";
|
import { apiClient } from "@halo-dev/admin-shared";
|
||||||
import type { Plugin } from "@halo-dev/api-client";
|
import type { Plugin } from "@halo-dev/api-client";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import { usePluginLifeCycle } from "./composables/use-plugin";
|
||||||
|
|
||||||
const plugins = ref<Plugin[]>([] as Plugin[]);
|
const plugins = ref<Plugin[]>([] as Plugin[]);
|
||||||
const pluginInstall = ref(false);
|
const pluginInstall = ref(false);
|
||||||
|
const selectedPlugin = ref<Plugin | null>(null);
|
||||||
|
|
||||||
const router = useRouter();
|
const { changeStatus, uninstall } = usePluginLifeCycle(selectedPlugin);
|
||||||
const dialog = useDialog();
|
|
||||||
|
|
||||||
const handleRouteToDetail = (plugin: Plugin) => {
|
|
||||||
router.push({
|
|
||||||
name: "PluginDetail",
|
|
||||||
params: { name: plugin.metadata.name },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const isStarted = (plugin: Plugin) => {
|
const isStarted = (plugin: Plugin) => {
|
||||||
return plugin.status?.phase === "STARTED" && plugin.spec.enabled;
|
return plugin.status?.phase === "STARTED" && plugin.spec.enabled;
|
||||||
|
@ -47,58 +38,15 @@ const handleFetchPlugins = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChangeStatus = (plugin: Plugin) => {
|
function handleChangeStatus(plugin: Plugin) {
|
||||||
const pluginToUpdate = cloneDeep(plugin);
|
selectedPlugin.value = plugin;
|
||||||
|
changeStatus();
|
||||||
|
}
|
||||||
|
|
||||||
dialog.info({
|
function handleUninstall(plugin: Plugin) {
|
||||||
title: `确定要${plugin.spec.enabled ? "停止" : "启动"}该插件吗?`,
|
selectedPlugin.value = plugin;
|
||||||
onConfirm: async () => {
|
uninstall();
|
||||||
try {
|
}
|
||||||
pluginToUpdate.spec.enabled = !pluginToUpdate.spec.enabled;
|
|
||||||
await apiClient.extension.plugin.updatepluginHaloRunV1alpha1Plugin(
|
|
||||||
pluginToUpdate.metadata.name,
|
|
||||||
pluginToUpdate
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
} finally {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleUninstall = (plugin: Plugin) => {
|
|
||||||
const { enabled } = plugin.spec;
|
|
||||||
dialog.warning({
|
|
||||||
title: `确定要卸载该插件吗?`,
|
|
||||||
description: `${
|
|
||||||
enabled ? "当前插件还在启用状态,将在停止运行后卸载。" : ""
|
|
||||||
}`,
|
|
||||||
confirmType: "danger",
|
|
||||||
confirmText: `${enabled ? "停止运行并卸载" : "卸载"}`,
|
|
||||||
onConfirm: async () => {
|
|
||||||
try {
|
|
||||||
if (enabled) {
|
|
||||||
const pluginToUpdate = cloneDeep(plugin);
|
|
||||||
pluginToUpdate.spec.enabled = false;
|
|
||||||
await apiClient.extension.plugin.updatepluginHaloRunV1alpha1Plugin(
|
|
||||||
plugin.metadata.name,
|
|
||||||
pluginToUpdate
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await apiClient.extension.plugin.deletepluginHaloRunV1alpha1Plugin(
|
|
||||||
plugin.metadata.name
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
} finally {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(handleFetchPlugins);
|
onMounted(handleFetchPlugins);
|
||||||
</script>
|
</script>
|
||||||
|
@ -266,9 +214,14 @@ onMounted(handleFetchPlugins);
|
||||||
>
|
>
|
||||||
<div class="relative flex flex-row items-center">
|
<div class="relative flex flex-row items-center">
|
||||||
<div v-if="plugin.spec.logo" class="mr-4">
|
<div v-if="plugin.spec.logo" class="mr-4">
|
||||||
|
<RouterLink
|
||||||
|
:to="{
|
||||||
|
name: 'PluginDetail',
|
||||||
|
params: { name: plugin.metadata.name },
|
||||||
|
}"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="h-12 w-12 rounded border bg-white p-1 hover:shadow-sm"
|
class="h-12 w-12 rounded border bg-white p-1 hover:shadow-sm"
|
||||||
@click.stop="handleRouteToDetail(plugin)"
|
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:alt="plugin.metadata.name"
|
:alt="plugin.metadata.name"
|
||||||
|
@ -276,15 +229,22 @@ onMounted(handleFetchPlugins);
|
||||||
class="h-full w-full"
|
class="h-full w-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<div class="flex flex-row items-center">
|
<div class="flex flex-row items-center">
|
||||||
|
<RouterLink
|
||||||
|
:to="{
|
||||||
|
name: 'PluginDetail',
|
||||||
|
params: { name: plugin.metadata.name },
|
||||||
|
}"
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
class="mr-2 truncate text-sm font-medium text-gray-900"
|
class="mr-2 truncate text-sm font-medium text-gray-900"
|
||||||
@click.stop="handleRouteToDetail(plugin)"
|
|
||||||
>
|
>
|
||||||
{{ plugin.spec.displayName }}
|
{{ plugin.spec.displayName }}
|
||||||
</span>
|
</span>
|
||||||
|
</RouterLink>
|
||||||
<VSpace>
|
<VSpace>
|
||||||
<VTag>
|
<VTag>
|
||||||
{{ isStarted(plugin) ? "已启用" : "未启用" }}
|
{{ isStarted(plugin) ? "已启用" : "未启用" }}
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
import type { Ref } from "vue";
|
||||||
|
import type { Plugin } from "@halo-dev/api-client";
|
||||||
|
import cloneDeep from "lodash.clonedeep";
|
||||||
|
import { apiClient } from "@halo-dev/admin-shared";
|
||||||
|
import { useDialog } from "@halo-dev/components";
|
||||||
|
|
||||||
|
export function usePluginLifeCycle(plugin: Ref<Plugin | null>) {
|
||||||
|
const dialog = useDialog();
|
||||||
|
|
||||||
|
const changeStatus = () => {
|
||||||
|
if (!plugin.value) return;
|
||||||
|
|
||||||
|
const pluginToUpdate = cloneDeep(plugin.value);
|
||||||
|
|
||||||
|
dialog.info({
|
||||||
|
title: `确定要${pluginToUpdate.spec.enabled ? "停止" : "启动"}该插件吗?`,
|
||||||
|
onConfirm: async () => {
|
||||||
|
try {
|
||||||
|
pluginToUpdate.spec.enabled = !pluginToUpdate.spec.enabled;
|
||||||
|
await apiClient.extension.plugin.updatepluginHaloRunV1alpha1Plugin(
|
||||||
|
pluginToUpdate.metadata.name,
|
||||||
|
pluginToUpdate
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const uninstall = () => {
|
||||||
|
if (!plugin.value) return;
|
||||||
|
|
||||||
|
const { enabled } = plugin.value.spec;
|
||||||
|
|
||||||
|
dialog.warning({
|
||||||
|
title: `确定要卸载该插件吗?`,
|
||||||
|
description: `${
|
||||||
|
enabled ? "当前插件还在启用状态,将在停止运行后卸载。" : ""
|
||||||
|
}`,
|
||||||
|
confirmType: "danger",
|
||||||
|
confirmText: `${enabled ? "停止运行并卸载" : "卸载"}`,
|
||||||
|
onConfirm: async () => {
|
||||||
|
if (!plugin.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (enabled) {
|
||||||
|
const pluginToUpdate = cloneDeep(plugin.value);
|
||||||
|
pluginToUpdate.spec.enabled = false;
|
||||||
|
await apiClient.extension.plugin.updatepluginHaloRunV1alpha1Plugin(
|
||||||
|
pluginToUpdate.metadata.name,
|
||||||
|
pluginToUpdate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await apiClient.extension.plugin.deletepluginHaloRunV1alpha1Plugin(
|
||||||
|
plugin.value.metadata.name
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
changeStatus,
|
||||||
|
uninstall,
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue