mirror of https://github.com/halo-dev/halo-admin
feat: add plugin uninstall support
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/591/head
parent
f99deaec83
commit
7405b57c6d
|
@ -11,6 +11,7 @@ import {
|
||||||
import type { PropType } from "vue";
|
import type { PropType } from "vue";
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import type { Type } from "@/components/dialog/interface";
|
import type { Type } from "@/components/dialog/interface";
|
||||||
|
import type { Type as ButtonType } from "@/components/button/interface";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: {
|
type: {
|
||||||
|
@ -29,6 +30,10 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: "确定",
|
default: "确定",
|
||||||
},
|
},
|
||||||
|
confirmType: {
|
||||||
|
type: String as PropType<ButtonType>,
|
||||||
|
default: "primary",
|
||||||
|
},
|
||||||
cancelText: {
|
cancelText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "取消",
|
default: "取消",
|
||||||
|
@ -112,7 +117,7 @@ const handleClose = () => {
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="flex flex-col sm:flex-row gap-[10px]">
|
<div class="flex flex-col sm:flex-row gap-[10px]">
|
||||||
<VButton :loading="loading" type="secondary" @click="handleConfirm">
|
<VButton :loading="loading" :type="confirmType" @click="handleConfirm">
|
||||||
{{ confirmText }}
|
{{ confirmText }}
|
||||||
</VButton>
|
</VButton>
|
||||||
<VButton @click="handleCancel">{{ cancelText }}</VButton>
|
<VButton @click="handleCancel">{{ cancelText }}</VButton>
|
||||||
|
|
|
@ -17,6 +17,7 @@ provide(DialogProviderProvideKey, options);
|
||||||
v-model:visible="options.visible"
|
v-model:visible="options.visible"
|
||||||
:cancel-text="options.cancelText"
|
:cancel-text="options.cancelText"
|
||||||
:confirm-text="options.confirmText"
|
:confirm-text="options.confirmText"
|
||||||
|
:confirm-type="options.confirmType"
|
||||||
:description="options.description"
|
:description="options.description"
|
||||||
:onCancel="options.onCancel"
|
:onCancel="options.onCancel"
|
||||||
:onConfirm="options.onConfirm"
|
:onConfirm="options.onConfirm"
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
export type Type = "success" | "info" | "warning" | "error";
|
export type Type = "success" | "info" | "warning" | "error";
|
||||||
export const DialogProviderProvideKey = "DIALOG_PROVIDER_PROVIDE_KEY";
|
export const DialogProviderProvideKey = "DIALOG_PROVIDER_PROVIDE_KEY";
|
||||||
|
import type { Type as ButtonType } from "@/components/button/interface";
|
||||||
|
|
||||||
export interface useDialogOptions {
|
export interface useDialogOptions {
|
||||||
type?: Type;
|
type?: Type;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
confirmType?: ButtonType;
|
||||||
confirmText?: string;
|
confirmText?: string;
|
||||||
cancelText?: string;
|
cancelText?: string;
|
||||||
onConfirm?: () => void;
|
onConfirm?: () => void;
|
||||||
|
|
|
@ -22,6 +22,9 @@ export function useDialog(): useDialogReturn {
|
||||||
}
|
}
|
||||||
|
|
||||||
const createDialog = (type: Type) => (options: useDialogUserOptions) => {
|
const createDialog = (type: Type) => (options: useDialogUserOptions) => {
|
||||||
|
// clear previous dialog
|
||||||
|
dialogOptions.value = { title: "", visible: false };
|
||||||
|
|
||||||
dialogOptions.value = { ...dialogOptions.value, ...options };
|
dialogOptions.value = { ...dialogOptions.value, ...options };
|
||||||
dialogOptions.value.type = type;
|
dialogOptions.value.type = type;
|
||||||
dialogOptions.value.visible = true;
|
dialogOptions.value.visible = true;
|
||||||
|
|
|
@ -270,11 +270,11 @@ async function initApp() {
|
||||||
await loadCurrentUser();
|
await loadCurrentUser();
|
||||||
app.provide<MenuGroupType[]>("menus", menus);
|
app.provide<MenuGroupType[]>("menus", menus);
|
||||||
app.provide<MenuItemType[]>("minimenus", minimenus);
|
app.provide<MenuItemType[]>("minimenus", minimenus);
|
||||||
messageContainerApp.unmount();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
} finally {
|
} finally {
|
||||||
app.use(router);
|
app.use(router);
|
||||||
|
messageContainerApp.unmount();
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,38 @@ const handleChangeStatus = (plugin: Plugin) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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>
|
||||||
<template>
|
<template>
|
||||||
|
@ -236,6 +268,7 @@ onMounted(handleFetchPlugins);
|
||||||
<div v-if="plugin.spec.logo" class="mr-4">
|
<div v-if="plugin.spec.logo" class="mr-4">
|
||||||
<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"
|
||||||
|
@ -310,7 +343,7 @@ onMounted(handleFetchPlugins);
|
||||||
class="flex items-center"
|
class="flex items-center"
|
||||||
>
|
>
|
||||||
<VSwitch
|
<VSwitch
|
||||||
:model-value="isStarted(plugin)"
|
:model-value="plugin.spec.enabled"
|
||||||
@click="handleChangeStatus(plugin)"
|
@click="handleChangeStatus(plugin)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -318,7 +351,22 @@ onMounted(handleFetchPlugins);
|
||||||
v-permission="['system:plugins:manage']"
|
v-permission="['system:plugins:manage']"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
>
|
>
|
||||||
<IconSettings @click.stop="handleRouteToDetail(plugin)" />
|
<FloatingDropdown>
|
||||||
|
<IconSettings />
|
||||||
|
<template #popper>
|
||||||
|
<div class="links-w-48 links-p-2">
|
||||||
|
<VSpace class="links-w-full" direction="column">
|
||||||
|
<VButton
|
||||||
|
block
|
||||||
|
type="danger"
|
||||||
|
@click="handleUninstall(plugin)"
|
||||||
|
>
|
||||||
|
卸载
|
||||||
|
</VButton>
|
||||||
|
</VSpace>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</FloatingDropdown>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue