mirror of https://github.com/halo-dev/halo-admin
refactor: structure of the setting extension (#616)
#### What type of PR is this? /kind improvement /milestone 2.0 /kind api-change #### What this PR does / why we need it: 重构 Setting 模型的结构,适配 https://github.com/halo-dev/halo/pull/2440 todo list: - [x] 更新 `@halo-dev/api-client` #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/2414 #### Special notes for your reviewer: 测试方式: 1. 本地 admin 仓库切换到当前 PR 的分支,halo 仓库切换到 https://github.com/halo-dev/halo/pull/2440 PR 的分支。 2. 测试后台各个表单功能是否正常。 3. 主题设置表单可使用 https://github.com/halo-sigs/theme-anatole/pull/2 PR 的分支进行测试。 #### Does this PR introduce a user-facing change? ```release-note None ```pull/617/head
parent
36bb28cd0e
commit
f2f657b55c
|
@ -34,7 +34,7 @@
|
|||
"@formkit/themes": "1.0.0-beta.10",
|
||||
"@formkit/vue": "1.0.0-beta.10",
|
||||
"@halo-dev/admin-shared": "workspace:*",
|
||||
"@halo-dev/api-client": "^0.0.23",
|
||||
"@halo-dev/api-client": "^0.0.25",
|
||||
"@halo-dev/components": "workspace:*",
|
||||
"@halo-dev/richtext-editor": "^0.0.0-alpha.7",
|
||||
"@tiptap/extension-character-count": "2.0.0-beta.31",
|
||||
|
|
|
@ -7,9 +7,8 @@ import { apiClient } from "../utils/api-client";
|
|||
// libs
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import merge from "lodash.merge";
|
||||
import type { FormKitSetting, FormKitSettingSpec } from "../types/formkit";
|
||||
import type { ConfigMap } from "@halo-dev/api-client";
|
||||
import type { FormKitSchemaNode } from "@formkit/core";
|
||||
import type { ConfigMap, Setting, SettingForm } from "@halo-dev/api-client";
|
||||
import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core";
|
||||
|
||||
const initialConfigMap: ConfigMap = {
|
||||
apiVersion: "v1alpha1",
|
||||
|
@ -21,7 +20,7 @@ const initialConfigMap: ConfigMap = {
|
|||
};
|
||||
|
||||
interface useSettingFormReturn {
|
||||
settings: Ref<FormKitSetting | undefined>;
|
||||
setting: Ref<Setting | undefined>;
|
||||
configMap: Ref<ConfigMap>;
|
||||
configMapFormData: Ref<Record<string, Record<string, string>> | undefined>;
|
||||
saving: Ref<boolean>;
|
||||
|
@ -35,7 +34,7 @@ export function useSettingForm(
|
|||
settingName: Ref<string | undefined>,
|
||||
configMapName: Ref<string | undefined>
|
||||
): useSettingFormReturn {
|
||||
const settings = ref<FormKitSetting | undefined>();
|
||||
const setting = ref<Setting>();
|
||||
const configMap = ref<ConfigMap>(cloneDeep(initialConfigMap));
|
||||
const configMapFormData = ref<
|
||||
Record<string, Record<string, string>> | undefined
|
||||
|
@ -45,29 +44,32 @@ export function useSettingForm(
|
|||
|
||||
const handleFetchSettings = async () => {
|
||||
if (!settingName.value) {
|
||||
settings.value = undefined;
|
||||
setting.value = undefined;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const response = await apiClient.extension.setting.getv1alpha1Setting({
|
||||
const { data } = await apiClient.extension.setting.getv1alpha1Setting({
|
||||
name: settingName.value,
|
||||
});
|
||||
settings.value = response.data as FormKitSetting;
|
||||
setting.value = data;
|
||||
|
||||
// init configMapFormData
|
||||
if (!configMapFormData.value) {
|
||||
const { spec: schemaGroups } = settings.value;
|
||||
const { forms } = setting.value.spec;
|
||||
const initialConfigMapFormData: Record<
|
||||
string,
|
||||
Record<string, string>
|
||||
> = {};
|
||||
schemaGroups.forEach((schemaGroup) => {
|
||||
initialConfigMapFormData[schemaGroup.group] = {};
|
||||
const formSchema = schemaGroup.formSchema as FormKitSchemaNode[];
|
||||
forms.forEach((form) => {
|
||||
initialConfigMapFormData[form.group] = {};
|
||||
const formSchema = form.formSchema as (
|
||||
| FormKitSchemaCondition
|
||||
| FormKitSchemaNode
|
||||
)[];
|
||||
formSchema.forEach((schema) => {
|
||||
// @ts-ignore
|
||||
if ("name" in schema && "$formkit" in schema) {
|
||||
initialConfigMapFormData[schemaGroup.group][schema.name] =
|
||||
initialConfigMapFormData[form.group][schema.name] =
|
||||
schema.value || undefined;
|
||||
}
|
||||
});
|
||||
|
@ -75,7 +77,7 @@ export function useSettingForm(
|
|||
configMapFormData.value = cloneDeep(initialConfigMapFormData);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error("Failed to fetch setting", e);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -98,20 +100,20 @@ export function useSettingForm(
|
|||
|
||||
if (data) {
|
||||
// merge objects value
|
||||
const { spec: schemaGroups } = settings.value || {};
|
||||
const { forms } = setting.value?.spec || {};
|
||||
|
||||
schemaGroups?.forEach((schemaGroup) => {
|
||||
forms?.forEach((form) => {
|
||||
if (!configMapFormData.value) {
|
||||
return;
|
||||
}
|
||||
configMapFormData.value[schemaGroup.group] = merge(
|
||||
configMapFormData.value[schemaGroup.group] || {},
|
||||
JSON.parse(data[schemaGroup.group] || "{}")
|
||||
configMapFormData.value[form.group] = merge(
|
||||
configMapFormData.value[form.group] || {},
|
||||
JSON.parse(data[form.group] || "{}")
|
||||
);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error("Failed to fetch configMap", e);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -123,7 +125,7 @@ export function useSettingForm(
|
|||
configMap.value.metadata.name = configMapName.value;
|
||||
}
|
||||
|
||||
settings?.value?.spec.forEach((item: FormKitSettingSpec) => {
|
||||
setting.value?.spec.forms.forEach((item: SettingForm) => {
|
||||
// @ts-ignore
|
||||
configMap.value.data[item.group] = JSON.stringify(
|
||||
configMapFormData?.value?.[item.group]
|
||||
|
@ -141,7 +143,7 @@ export function useSettingForm(
|
|||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error("Failed to save configMap", e);
|
||||
} finally {
|
||||
await handleFetchSettings();
|
||||
await handleFetchConfigMap();
|
||||
|
@ -150,13 +152,13 @@ export function useSettingForm(
|
|||
};
|
||||
|
||||
const handleReset = () => {
|
||||
settings.value = undefined;
|
||||
setting.value = undefined;
|
||||
configMap.value = cloneDeep(initialConfigMap);
|
||||
configMapFormData.value = undefined;
|
||||
};
|
||||
|
||||
return {
|
||||
settings,
|
||||
setting,
|
||||
configMap,
|
||||
configMapFormData,
|
||||
saving,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
export * from "./types/plugin";
|
||||
export * from "./types/menus";
|
||||
export * from "./types/formkit";
|
||||
export * from "./core/plugins";
|
||||
export * from "./states/pages";
|
||||
export * from "./states/attachment-selector";
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import type { Setting, SettingSpec } from "@halo-dev/api-client";
|
||||
import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core";
|
||||
|
||||
export interface FormKitSettingSpec extends Omit<SettingSpec, "formSchema"> {
|
||||
formSchema: FormKitSchemaCondition | FormKitSchemaNode[];
|
||||
}
|
||||
|
||||
export interface FormKitSetting extends Omit<Setting, "spec"> {
|
||||
spec: Array<FormKitSettingSpec>;
|
||||
}
|
|
@ -14,7 +14,7 @@ importers:
|
|||
'@formkit/themes': 1.0.0-beta.10
|
||||
'@formkit/vue': 1.0.0-beta.10
|
||||
'@halo-dev/admin-shared': workspace:*
|
||||
'@halo-dev/api-client': ^0.0.23
|
||||
'@halo-dev/api-client': ^0.0.25
|
||||
'@halo-dev/components': workspace:*
|
||||
'@halo-dev/richtext-editor': ^0.0.0-alpha.7
|
||||
'@iconify-json/mdi': ^1.1.33
|
||||
|
@ -96,7 +96,7 @@ importers:
|
|||
'@formkit/themes': 1.0.0-beta.10_tailwindcss@3.1.8
|
||||
'@formkit/vue': 1.0.0-beta.10_jhzixbi2r7n2xnmwczrcaimaey
|
||||
'@halo-dev/admin-shared': link:packages/shared
|
||||
'@halo-dev/api-client': 0.0.23
|
||||
'@halo-dev/api-client': 0.0.25
|
||||
'@halo-dev/components': link:packages/components
|
||||
'@halo-dev/richtext-editor': 0.0.0-alpha.7_vue@3.2.39
|
||||
'@tiptap/extension-character-count': 2.0.0-beta.31
|
||||
|
@ -1890,8 +1890,8 @@ packages:
|
|||
- windicss
|
||||
dev: false
|
||||
|
||||
/@halo-dev/api-client/0.0.23:
|
||||
resolution: {integrity: sha512-YI+uGnHvGgKvt6HRtwf/AI73gQCDT1/vS4c3vsaTzDm9h66joL4ST0t1xSLuc1IXVmtf9ktggInqEktUgVko0Q==}
|
||||
/@halo-dev/api-client/0.0.25:
|
||||
resolution: {integrity: sha512-USCCsKam7wH6vExP3SrTBz+vvOndRWPek2CZSfv0FeE8T+TNDR/X/wNRy3BPl//O0wf7TkJUgFyhgbRf+z02YA==}
|
||||
dev: false
|
||||
|
||||
/@halo-dev/richtext-editor/0.0.0-alpha.7_vue@3.2.39:
|
||||
|
|
|
@ -5,7 +5,12 @@ import cloneDeep from "lodash.clonedeep";
|
|||
import { computed, ref, watch, watchEffect } from "vue";
|
||||
import { apiClient, useSettingForm } from "@halo-dev/admin-shared";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { reset, submitForm } from "@formkit/core";
|
||||
import {
|
||||
reset,
|
||||
submitForm,
|
||||
type FormKitSchemaCondition,
|
||||
type FormKitSchemaNode,
|
||||
} from "@formkit/core";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
|
||||
|
@ -51,7 +56,7 @@ const settingName = computed(
|
|||
const configMapName = computed(() => formState.value.spec.configMapRef?.name);
|
||||
|
||||
const {
|
||||
settings,
|
||||
setting,
|
||||
configMapFormData,
|
||||
saving,
|
||||
handleFetchConfigMap,
|
||||
|
@ -61,11 +66,14 @@ const {
|
|||
} = useSettingForm(settingName, configMapName);
|
||||
|
||||
const formSchema = computed(() => {
|
||||
if (!settings?.value?.spec) {
|
||||
if (!setting.value) {
|
||||
return undefined;
|
||||
}
|
||||
return settings.value.spec.find((item) => item.group === "default")
|
||||
?.formSchema;
|
||||
const { forms } = setting.value.spec;
|
||||
return forms.find((item) => item.group === "default")?.formSchema as (
|
||||
| FormKitSchemaCondition
|
||||
| FormKitSchemaNode
|
||||
)[];
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
|
@ -75,7 +83,7 @@ watchEffect(() => {
|
|||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (configMapName.value && settings.value) {
|
||||
if (configMapName.value && setting.value) {
|
||||
handleFetchConfigMap();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ import type { Theme } from "@halo-dev/api-client";
|
|||
// hooks
|
||||
import { useSettingForm } from "@halo-dev/admin-shared";
|
||||
import { useRouteParams } from "@vueuse/router";
|
||||
import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core";
|
||||
|
||||
const group = useRouteParams<string>("group");
|
||||
|
||||
|
@ -21,7 +22,7 @@ const settingName = computed(() => selectedTheme?.value?.spec.settingName);
|
|||
const configMapName = computed(() => selectedTheme?.value?.spec.configMapName);
|
||||
|
||||
const {
|
||||
settings,
|
||||
setting,
|
||||
configMapFormData,
|
||||
saving,
|
||||
handleFetchConfigMap,
|
||||
|
@ -30,11 +31,14 @@ const {
|
|||
} = useSettingForm(settingName, configMapName);
|
||||
|
||||
const formSchema = computed(() => {
|
||||
if (!settings?.value?.spec) {
|
||||
if (!setting.value) {
|
||||
return;
|
||||
}
|
||||
return settings.value.spec.find((item) => item.group === group?.value)
|
||||
?.formSchema;
|
||||
const { forms } = setting.value.spec;
|
||||
return forms.find((item) => item.group === group?.value)?.formSchema as (
|
||||
| FormKitSchemaCondition
|
||||
| FormKitSchemaNode
|
||||
)[];
|
||||
});
|
||||
|
||||
await handleFetchSettings();
|
||||
|
|
|
@ -10,7 +10,6 @@ import cloneDeep from "lodash.clonedeep";
|
|||
// hooks
|
||||
import { useThemeLifeCycle } from "../composables/use-theme";
|
||||
// types
|
||||
import type { FormKitSettingSpec } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout, useSettingForm } from "@halo-dev/admin-shared";
|
||||
|
||||
// components
|
||||
|
@ -26,7 +25,7 @@ import {
|
|||
VTabbar,
|
||||
} from "@halo-dev/components";
|
||||
import ThemeListModal from "../components/ThemeListModal.vue";
|
||||
import type { Theme } from "@halo-dev/api-client";
|
||||
import type { SettingForm, Theme } from "@halo-dev/api-client";
|
||||
|
||||
interface ThemeTab {
|
||||
id: string;
|
||||
|
@ -58,7 +57,7 @@ const { loading, isActivated, activatedTheme, handleActiveTheme } =
|
|||
const settingName = computed(() => selectedTheme.value?.spec.settingName);
|
||||
const configMapName = computed(() => selectedTheme.value?.spec.configMapName);
|
||||
|
||||
const { settings, handleFetchSettings } = useSettingForm(
|
||||
const { setting, handleFetchSettings } = useSettingForm(
|
||||
settingName,
|
||||
configMapName
|
||||
);
|
||||
|
@ -85,10 +84,11 @@ watch(
|
|||
tabs.value = cloneDeep(initialTabs);
|
||||
await handleFetchSettings();
|
||||
|
||||
if (settings.value && settings.value.spec) {
|
||||
if (setting.value) {
|
||||
const { forms } = setting.value.spec;
|
||||
tabs.value = [
|
||||
...tabs.value,
|
||||
...settings.value.spec.map((item: FormKitSettingSpec) => {
|
||||
...forms.map((item: SettingForm) => {
|
||||
return {
|
||||
id: item.group,
|
||||
label: item.label || "",
|
||||
|
|
|
@ -11,6 +11,7 @@ import { VButton } from "@halo-dev/components";
|
|||
// types
|
||||
import type { Plugin } 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");
|
||||
|
@ -21,7 +22,7 @@ const settingName = computed(() => plugin?.value?.spec.settingName);
|
|||
const configMapName = computed(() => plugin?.value?.spec.configMapName);
|
||||
|
||||
const {
|
||||
settings,
|
||||
setting,
|
||||
configMapFormData,
|
||||
saving,
|
||||
handleFetchSettings,
|
||||
|
@ -30,11 +31,14 @@ const {
|
|||
} = useSettingForm(settingName, configMapName);
|
||||
|
||||
const formSchema = computed(() => {
|
||||
if (!settings?.value?.spec) {
|
||||
if (!setting.value) {
|
||||
return;
|
||||
}
|
||||
return settings.value.spec.find((item) => item.group === group.value)
|
||||
?.formSchema;
|
||||
const { forms } = setting.value.spec;
|
||||
return forms.find((item) => item.group === group.value)?.formSchema as (
|
||||
| FormKitSchemaCondition
|
||||
| FormKitSchemaNode
|
||||
)[];
|
||||
});
|
||||
|
||||
const handleFetchPlugin = async () => {
|
||||
|
|
|
@ -16,8 +16,7 @@ import { BasicLayout } from "@halo-dev/admin-shared";
|
|||
|
||||
// types
|
||||
import type { Ref } from "vue";
|
||||
import type { Plugin } from "@halo-dev/api-client";
|
||||
import type { FormKitSettingSpec } from "@halo-dev/admin-shared";
|
||||
import type { Plugin, SettingForm } from "@halo-dev/api-client";
|
||||
|
||||
interface PluginTab {
|
||||
id: string;
|
||||
|
@ -51,7 +50,7 @@ provide<Ref<string | undefined>>("activeTab", activeTab);
|
|||
const settingName = computed(() => plugin.value?.spec.settingName);
|
||||
const configMapName = computed(() => plugin.value?.spec.configMapName);
|
||||
|
||||
const { settings, handleFetchSettings } = useSettingForm(
|
||||
const { setting, handleFetchSettings } = useSettingForm(
|
||||
settingName,
|
||||
configMapName
|
||||
);
|
||||
|
@ -101,10 +100,11 @@ onMounted(async () => {
|
|||
|
||||
tabs.value = cloneDeep(initialTabs);
|
||||
|
||||
if (settings.value && settings.value.spec) {
|
||||
if (setting.value) {
|
||||
const { forms } = setting.value.spec;
|
||||
tabs.value = [
|
||||
...tabs.value,
|
||||
...settings.value.spec.map((item: FormKitSettingSpec) => {
|
||||
...forms.map((item: SettingForm) => {
|
||||
return {
|
||||
id: item.group,
|
||||
label: item.label || "",
|
||||
|
|
|
@ -8,11 +8,12 @@ import { VButton } from "@halo-dev/components";
|
|||
// hooks
|
||||
import { useSettingForm } from "@halo-dev/admin-shared";
|
||||
import { useRouteParams } from "@vueuse/router";
|
||||
import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core";
|
||||
|
||||
const group = useRouteParams<string>("group");
|
||||
|
||||
const {
|
||||
settings,
|
||||
setting,
|
||||
configMapFormData,
|
||||
saving,
|
||||
handleFetchConfigMap,
|
||||
|
@ -21,11 +22,11 @@ const {
|
|||
} = useSettingForm(ref("system"), ref("system"));
|
||||
|
||||
const formSchema = computed(() => {
|
||||
if (!settings?.value?.spec) {
|
||||
if (!setting.value) {
|
||||
return;
|
||||
}
|
||||
return settings.value.spec.find((item) => item.group === group?.value)
|
||||
?.formSchema;
|
||||
return setting.value.spec.forms.find((item) => item.group === group?.value)
|
||||
?.formSchema as (FormKitSchemaCondition | FormKitSchemaNode)[];
|
||||
});
|
||||
|
||||
await handleFetchSettings();
|
||||
|
|
|
@ -5,7 +5,6 @@ import { ref, watch } from "vue";
|
|||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
// types
|
||||
import type { FormKitSettingSpec } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout, useSettingForm } from "@halo-dev/admin-shared";
|
||||
|
||||
// components
|
||||
|
@ -15,6 +14,7 @@ import {
|
|||
VTabbar,
|
||||
IconSettings,
|
||||
} from "@halo-dev/components";
|
||||
import type { SettingForm } from "@halo-dev/api-client";
|
||||
|
||||
interface SettingTab {
|
||||
id: string;
|
||||
|
@ -28,7 +28,7 @@ interface SettingTab {
|
|||
const tabs = ref<SettingTab[]>([] as SettingTab[]);
|
||||
const activeTab = ref("");
|
||||
|
||||
const { settings, handleFetchSettings } = useSettingForm(
|
||||
const { setting, handleFetchSettings } = useSettingForm(
|
||||
ref("system"),
|
||||
ref("system")
|
||||
);
|
||||
|
@ -47,8 +47,9 @@ const handleTabChange = (id: string) => {
|
|||
onMounted(async () => {
|
||||
await handleFetchSettings();
|
||||
|
||||
if (settings.value && settings.value.spec) {
|
||||
tabs.value = settings.value.spec.map((item: FormKitSettingSpec) => {
|
||||
if (setting.value) {
|
||||
const { forms } = setting.value.spec;
|
||||
tabs.value = forms.map((item: SettingForm) => {
|
||||
return {
|
||||
id: item.group,
|
||||
label: item.label || "",
|
||||
|
|
Loading…
Reference in New Issue