mirror of https://github.com/halo-dev/halo-admin
refactor: use new apis to refactor plugins management (#824)
#### What type of PR is this? /kind improvement /milestone 2.2.x #### What this PR does / why we need it: 使用新的 API 来管理插件,用于区分插件管理和配置相关的权限。适配:https://github.com/halo-dev/halo/pull/3142 #### Which issue(s) this PR fixes: Ref https://github.com/halo-dev/halo/issues/3069 #### Screenshots: #### Special notes for your reviewer: 测试方式: 1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/3142 分支。 2. Console 需要 `pnpm install`。 1. 插件设置项,需要测试保存,安装新插件之后表单是否正常。 3. 创建一个角色,测试仅有管理/查看插件的角色,登录之后检查是否符合预期。 #### Does this PR introduce a user-facing change? ```release-note 重构 Console 端插件的设置表单逻辑。 ```pull/828/head^2
parent
ab888119ef
commit
62f8e2e703
|
@ -1,65 +1,67 @@
|
|||
<script lang="ts" setup>
|
||||
// core libs
|
||||
import { computed, ref } from "vue";
|
||||
import { inject, ref, type Ref } from "vue";
|
||||
|
||||
// hooks
|
||||
import { useSettingForm } from "@/composables/use-setting-form";
|
||||
import { useSettingFormConvert } from "@/composables/use-setting-form";
|
||||
import { apiClient } from "@/utils/api-client";
|
||||
|
||||
// components
|
||||
import { VButton } from "@halo-dev/components";
|
||||
|
||||
// types
|
||||
import type { Plugin } from "@halo-dev/api-client";
|
||||
import type { ConfigMap, Plugin, Setting } from "@halo-dev/api-client";
|
||||
import { useRouteParams } from "@vueuse/router";
|
||||
import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core";
|
||||
|
||||
const name = useRouteParams<string>("name");
|
||||
const group = useRouteParams<string>("group");
|
||||
|
||||
const plugin = ref<Plugin | undefined>();
|
||||
const plugin = inject<Ref<Plugin | undefined>>("plugin");
|
||||
const saving = ref(false);
|
||||
const setting = ref<Setting>();
|
||||
const configMap = ref<ConfigMap>();
|
||||
|
||||
const settingName = computed(() => plugin?.value?.spec.settingName);
|
||||
const configMapName = computed(() => plugin?.value?.spec.configMapName);
|
||||
|
||||
const {
|
||||
const { configMapFormData, formSchema, convertToSave } = useSettingFormConvert(
|
||||
setting,
|
||||
configMapFormData,
|
||||
saving,
|
||||
handleFetchSettings,
|
||||
handleFetchConfigMap,
|
||||
handleSaveConfigMap,
|
||||
} = useSettingForm(settingName, configMapName);
|
||||
configMap,
|
||||
group
|
||||
);
|
||||
|
||||
const formSchema = computed(() => {
|
||||
if (!setting.value) {
|
||||
return;
|
||||
}
|
||||
const { forms } = setting.value.spec;
|
||||
return forms.find((item) => item.group === group.value)?.formSchema as (
|
||||
| FormKitSchemaCondition
|
||||
| FormKitSchemaNode
|
||||
)[];
|
||||
});
|
||||
|
||||
const handleFetchPlugin = async () => {
|
||||
try {
|
||||
const { data } =
|
||||
await apiClient.extension.plugin.getpluginHaloRunV1alpha1Plugin({
|
||||
name: name.value,
|
||||
const handleFetchSettings = async () => {
|
||||
if (!plugin?.value) return;
|
||||
const { data } = await apiClient.plugin.fetchPluginSetting({
|
||||
name: plugin.value.metadata.name,
|
||||
});
|
||||
plugin.value = data;
|
||||
|
||||
if (settingName.value && configMapName.value) {
|
||||
await handleFetchSettings();
|
||||
await handleFetchConfigMap();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to fetch plugin and settings", e);
|
||||
}
|
||||
setting.value = data;
|
||||
};
|
||||
|
||||
await handleFetchPlugin();
|
||||
const handleFetchConfigMap = async () => {
|
||||
if (!plugin?.value) return;
|
||||
const { data } = await apiClient.plugin.fetchPluginConfig({
|
||||
name: plugin.value.metadata.name,
|
||||
});
|
||||
configMap.value = data;
|
||||
};
|
||||
|
||||
const handleSaveConfigMap = async () => {
|
||||
saving.value = true;
|
||||
const configMapToUpdate = convertToSave();
|
||||
if (!configMapToUpdate || !plugin?.value) {
|
||||
saving.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: newConfigMap } = await apiClient.plugin.updatePluginConfig({
|
||||
name: plugin.value.metadata.name,
|
||||
configMap: configMapToUpdate,
|
||||
});
|
||||
|
||||
await handleFetchSettings();
|
||||
configMap.value = newConfigMap;
|
||||
saving.value = false;
|
||||
};
|
||||
|
||||
await handleFetchSettings();
|
||||
await handleFetchConfigMap();
|
||||
</script>
|
||||
<template>
|
||||
<Transition mode="out-in" name="fade">
|
||||
|
@ -81,7 +83,7 @@ await handleFetchPlugin();
|
|||
/>
|
||||
</FormKit>
|
||||
</div>
|
||||
<div v-permission="['system:configmaps:manage']" class="pt-5">
|
||||
<div v-permission="['system:plugins:manage']" class="pt-5">
|
||||
<div class="flex justify-start">
|
||||
<VButton
|
||||
:loading="saving"
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
<script lang="ts" setup>
|
||||
// core libs
|
||||
import { computed, nextTick, onMounted, provide, ref, watch } from "vue";
|
||||
import { nextTick, onMounted, provide, ref, watch } from "vue";
|
||||
import { RouterView, useRoute, useRouter } from "vue-router";
|
||||
import { apiClient } from "@/utils/api-client";
|
||||
|
||||
// libs
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
|
||||
// hooks
|
||||
import { useSettingForm } from "@/composables/use-setting-form";
|
||||
|
||||
// components
|
||||
import {
|
||||
VButton,
|
||||
VCard,
|
||||
VPageHeader,
|
||||
VTabbar,
|
||||
|
@ -23,7 +19,7 @@ import BasicLayout from "@/layouts/BasicLayout.vue";
|
|||
|
||||
// types
|
||||
import type { Ref } from "vue";
|
||||
import type { Plugin, SettingForm } from "@halo-dev/api-client";
|
||||
import type { Plugin, Setting, SettingForm } from "@halo-dev/api-client";
|
||||
import { usePermission } from "@/utils/permission";
|
||||
import { usePluginLifeCycle } from "../composables/use-plugin";
|
||||
|
||||
|
@ -52,22 +48,15 @@ const route = useRoute();
|
|||
const router = useRouter();
|
||||
|
||||
const plugin = ref<Plugin>();
|
||||
const setting = ref<Setting>();
|
||||
const tabs = ref<PluginTab[]>(cloneDeep(initialTabs));
|
||||
const activeTab = ref<string>();
|
||||
|
||||
provide<Ref<Plugin | undefined>>("plugin", plugin);
|
||||
provide<Ref<string | undefined>>("activeTab", activeTab);
|
||||
|
||||
const settingName = computed(() => plugin.value?.spec.settingName);
|
||||
const configMapName = computed(() => plugin.value?.spec.configMapName);
|
||||
|
||||
const { isStarted } = usePluginLifeCycle(plugin);
|
||||
|
||||
const { setting, handleFetchSettings } = useSettingForm(
|
||||
settingName,
|
||||
configMapName
|
||||
);
|
||||
|
||||
const handleFetchPlugin = async () => {
|
||||
try {
|
||||
const response =
|
||||
|
@ -80,6 +69,14 @@ const handleFetchPlugin = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleFetchSettings = async () => {
|
||||
if (!plugin.value) return;
|
||||
const { data } = await apiClient.plugin.fetchPluginSetting({
|
||||
name: plugin.value?.metadata.name,
|
||||
});
|
||||
setting.value = data;
|
||||
};
|
||||
|
||||
const handleTabChange = (id: string) => {
|
||||
const tab = tabs.value.find((item) => item.id === id);
|
||||
if (tab) {
|
||||
|
@ -110,7 +107,7 @@ const handleTriggerTabChange = () => {
|
|||
onMounted(async () => {
|
||||
await handleFetchPlugin();
|
||||
|
||||
if (!currentUserHasPermission(["system:settings:view"])) {
|
||||
if (!currentUserHasPermission(["system:plugins:manage"])) {
|
||||
handleTriggerTabChange();
|
||||
return;
|
||||
}
|
||||
|
@ -161,9 +158,6 @@ watch([() => route.name, () => route.params], () => {
|
|||
size="sm"
|
||||
/>
|
||||
</template>
|
||||
<template #actions>
|
||||
<VButton class="opacity-0" type="secondary">安装</VButton>
|
||||
</template>
|
||||
</VPageHeader>
|
||||
|
||||
<div class="m-0 md:m-4">
|
||||
|
|
|
@ -56,7 +56,7 @@ export default definePlugin({
|
|||
component: PluginSetting,
|
||||
meta: {
|
||||
title: "插件设置",
|
||||
permissions: ["system:settings:view"],
|
||||
permissions: ["system:plugins:manage"],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue