feat: add plugin uninstall support

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/591/head
Ryan Wang 2022-07-26 11:45:00 +08:00
parent f99deaec83
commit 7405b57c6d
6 changed files with 63 additions and 4 deletions

View File

@ -11,6 +11,7 @@ import {
import type { PropType } from "vue";
import { computed, ref } from "vue";
import type { Type } from "@/components/dialog/interface";
import type { Type as ButtonType } from "@/components/button/interface";
const props = defineProps({
type: {
@ -29,6 +30,10 @@ const props = defineProps({
type: String,
default: "确定",
},
confirmType: {
type: String as PropType<ButtonType>,
default: "primary",
},
cancelText: {
type: String,
default: "取消",
@ -112,7 +117,7 @@ const handleClose = () => {
</div>
<template #footer>
<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 }}
</VButton>
<VButton @click="handleCancel">{{ cancelText }}</VButton>

View File

@ -17,6 +17,7 @@ provide(DialogProviderProvideKey, options);
v-model:visible="options.visible"
:cancel-text="options.cancelText"
:confirm-text="options.confirmText"
:confirm-type="options.confirmType"
:description="options.description"
:onCancel="options.onCancel"
:onConfirm="options.onConfirm"

View File

@ -1,11 +1,13 @@
export type Type = "success" | "info" | "warning" | "error";
export const DialogProviderProvideKey = "DIALOG_PROVIDER_PROVIDE_KEY";
import type { Type as ButtonType } from "@/components/button/interface";
export interface useDialogOptions {
type?: Type;
visible: boolean;
title: string;
description?: string;
confirmType?: ButtonType;
confirmText?: string;
cancelText?: string;
onConfirm?: () => void;

View File

@ -22,6 +22,9 @@ export function useDialog(): useDialogReturn {
}
const createDialog = (type: Type) => (options: useDialogUserOptions) => {
// clear previous dialog
dialogOptions.value = { title: "", visible: false };
dialogOptions.value = { ...dialogOptions.value, ...options };
dialogOptions.value.type = type;
dialogOptions.value.visible = true;

View File

@ -270,11 +270,11 @@ async function initApp() {
await loadCurrentUser();
app.provide<MenuGroupType[]>("menus", menus);
app.provide<MenuItemType[]>("minimenus", minimenus);
messageContainerApp.unmount();
} catch (e) {
console.error(e);
} finally {
app.use(router);
messageContainerApp.unmount();
app.mount("#app");
}
}

View File

@ -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);
</script>
<template>
@ -236,6 +268,7 @@ onMounted(handleFetchPlugins);
<div v-if="plugin.spec.logo" class="mr-4">
<div
class="h-12 w-12 rounded border bg-white p-1 hover:shadow-sm"
@click.stop="handleRouteToDetail(plugin)"
>
<img
:alt="plugin.metadata.name"
@ -310,7 +343,7 @@ onMounted(handleFetchPlugins);
class="flex items-center"
>
<VSwitch
:model-value="isStarted(plugin)"
:model-value="plugin.spec.enabled"
@click="handleChangeStatus(plugin)"
/>
</div>
@ -318,7 +351,22 @@ onMounted(handleFetchPlugins);
v-permission="['system:plugins:manage']"
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>
</div>
</div>