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
Ryan Wang 2 years ago committed by GitHub
parent ab888119ef
commit 62f8e2e703
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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 handleFetchSettings = async () => {
if (!plugin?.value) return;
const { data } = await apiClient.plugin.fetchPluginSetting({
name: plugin.value.metadata.name,
});
setting.value = data;
};
const handleFetchConfigMap = async () => {
if (!plugin?.value) return;
const { data } = await apiClient.plugin.fetchPluginConfig({
name: plugin.value.metadata.name,
});
configMap.value = data;
};
const formSchema = computed(() => {
if (!setting.value) {
const handleSaveConfigMap = async () => {
saving.value = true;
const configMapToUpdate = convertToSave();
if (!configMapToUpdate || !plugin?.value) {
saving.value = false;
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 { data: newConfigMap } = await apiClient.plugin.updatePluginConfig({
name: plugin.value.metadata.name,
configMap: configMapToUpdate,
});
plugin.value = data;
if (settingName.value && configMapName.value) {
await handleFetchSettings();
await handleFetchConfigMap();
}
} catch (e) {
console.error("Failed to fetch plugin and settings", e);
}
configMap.value = newConfigMap;
saving.value = false;
};
await handleFetchPlugin();
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…
Cancel
Save