mirror of https://github.com/halo-dev/halo
feat: system configmap setting page (halo-dev/console#603)
Signed-off-by: Ryan Wang <i@ryanc.cc> Signed-off-by: Ryan Wang <i@ryanc.cc>pull/3445/head
parent
b9a8f5055c
commit
35b244dba8
|
@ -40,9 +40,11 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@halo-dev/api-client": "^0.0.14",
|
"@halo-dev/api-client": "^0.0.14",
|
||||||
"@halo-dev/components": "workspace:*",
|
"@halo-dev/components": "workspace:*",
|
||||||
"axios": "^0.27.2"
|
"axios": "^0.27.2",
|
||||||
|
"lodash.merge": "^4.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/lodash.merge": "^4.6.7",
|
||||||
"vite-plugin-dts": "^1.4.1"
|
"vite-plugin-dts": "^1.4.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|
|
@ -6,8 +6,10 @@ import { apiClient } from "../utils/api-client";
|
||||||
|
|
||||||
// libs
|
// libs
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
|
import merge from "lodash.merge";
|
||||||
import type { FormKitSetting, FormKitSettingSpec } from "../types/formkit";
|
import type { FormKitSetting, FormKitSettingSpec } from "../types/formkit";
|
||||||
import type { ConfigMap } from "@halo-dev/api-client";
|
import type { ConfigMap } from "@halo-dev/api-client";
|
||||||
|
import type { FormKitSchemaNode } from "@formkit/core";
|
||||||
|
|
||||||
const initialConfigMap: ConfigMap = {
|
const initialConfigMap: ConfigMap = {
|
||||||
apiVersion: "v1alpha1",
|
apiVersion: "v1alpha1",
|
||||||
|
@ -38,6 +40,7 @@ export function useSettingForm(
|
||||||
const configMapFormData = ref<
|
const configMapFormData = ref<
|
||||||
Record<string, Record<string, string>> | undefined
|
Record<string, Record<string, string>> | undefined
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const saving = ref(false);
|
const saving = ref(false);
|
||||||
|
|
||||||
const handleFetchSettings = async () => {
|
const handleFetchSettings = async () => {
|
||||||
|
@ -50,6 +53,27 @@ export function useSettingForm(
|
||||||
name: settingName.value,
|
name: settingName.value,
|
||||||
});
|
});
|
||||||
settings.value = response.data as FormKitSetting;
|
settings.value = response.data as FormKitSetting;
|
||||||
|
|
||||||
|
// init configMapFormData
|
||||||
|
if (!configMapFormData.value) {
|
||||||
|
const { spec: schemaGroups } = settings.value;
|
||||||
|
const initialConfigMapFormData: Record<
|
||||||
|
string,
|
||||||
|
Record<string, string>
|
||||||
|
> = {};
|
||||||
|
schemaGroups.forEach((schemaGroup) => {
|
||||||
|
initialConfigMapFormData[schemaGroup.group] = {};
|
||||||
|
const formSchema = schemaGroup.formSchema as FormKitSchemaNode[];
|
||||||
|
formSchema.forEach((schema) => {
|
||||||
|
// @ts-ignore
|
||||||
|
if ("name" in schema && "$formkit" in schema) {
|
||||||
|
initialConfigMapFormData[schemaGroup.group][schema.name] =
|
||||||
|
schema.value || undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
configMapFormData.value = cloneDeep(initialConfigMapFormData);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
@ -67,27 +91,27 @@ export function useSettingForm(
|
||||||
name: configMapName.value,
|
name: configMapName.value,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
configMap.value = response.data;
|
configMap.value = response.data;
|
||||||
|
|
||||||
const { data } = configMap.value;
|
const { data } = configMap.value;
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
configMapFormData.value = Object.keys(data).reduce((acc, key) => {
|
// merge objects value
|
||||||
// @ts-ignore
|
const { spec: schemaGroups } = settings.value || {};
|
||||||
acc[key] = JSON.parse(data[key]);
|
|
||||||
return acc;
|
schemaGroups?.forEach((schemaGroup) => {
|
||||||
}, {});
|
if (!configMapFormData.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
configMapFormData.value[schemaGroup.group] = merge(
|
||||||
|
configMapFormData.value[schemaGroup.group] || {},
|
||||||
|
JSON.parse(data[schemaGroup.group] || "{}")
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
} finally {
|
|
||||||
if (!configMapFormData.value) {
|
|
||||||
configMapFormData.value = settings.value?.spec.reduce((acc, item) => {
|
|
||||||
// @ts-ignore
|
|
||||||
acc[item.group] = {};
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -196,13 +196,17 @@ importers:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@halo-dev/api-client': ^0.0.14
|
'@halo-dev/api-client': ^0.0.14
|
||||||
'@halo-dev/components': workspace:*
|
'@halo-dev/components': workspace:*
|
||||||
|
'@types/lodash.merge': ^4.6.7
|
||||||
axios: ^0.27.2
|
axios: ^0.27.2
|
||||||
|
lodash.merge: ^4.6.2
|
||||||
vite-plugin-dts: ^1.4.1
|
vite-plugin-dts: ^1.4.1
|
||||||
dependencies:
|
dependencies:
|
||||||
'@halo-dev/api-client': 0.0.14
|
'@halo-dev/api-client': 0.0.14
|
||||||
'@halo-dev/components': link:../components
|
'@halo-dev/components': link:../components
|
||||||
axios: 0.27.2
|
axios: 0.27.2
|
||||||
|
lodash.merge: 4.6.2
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@types/lodash.merge': 4.6.7
|
||||||
vite-plugin-dts: 1.4.1
|
vite-plugin-dts: 1.4.1
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
@ -3196,6 +3200,12 @@ packages:
|
||||||
'@types/lodash': 4.14.182
|
'@types/lodash': 4.14.182
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/lodash.merge/4.6.7:
|
||||||
|
resolution: {integrity: sha512-OwxUJ9E50gw3LnAefSHJPHaBLGEKmQBQ7CZe/xflHkyy/wH2zVyEIAKReHvVrrn7zKdF58p16We9kMfh7v0RRQ==}
|
||||||
|
dependencies:
|
||||||
|
'@types/lodash': 4.14.182
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/lodash/4.14.182:
|
/@types/lodash/4.14.182:
|
||||||
resolution: {integrity: sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==}
|
resolution: {integrity: sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -6724,7 +6734,6 @@ packages:
|
||||||
|
|
||||||
/lodash.merge/4.6.2:
|
/lodash.merge/4.6.2:
|
||||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/lodash.mergewith/4.6.2:
|
/lodash.mergewith/4.6.2:
|
||||||
resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==}
|
resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==}
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VButton } from "@halo-dev/components";
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="w-1/3">
|
|
||||||
<FormKit type="form">
|
|
||||||
<FormKit
|
|
||||||
help="插入代码到所有页面的 head 标签部分"
|
|
||||||
label="全局 head"
|
|
||||||
type="textarea"
|
|
||||||
></FormKit>
|
|
||||||
<FormKit
|
|
||||||
help="插入代码到文章页面和自定义页面的 head 标签部分"
|
|
||||||
label="内容页 head"
|
|
||||||
type="textarea"
|
|
||||||
></FormKit>
|
|
||||||
<FormKit
|
|
||||||
help="插入代码到所有页面的页脚部分"
|
|
||||||
label="页脚"
|
|
||||||
type="textarea"
|
|
||||||
></FormKit>
|
|
||||||
</FormKit>
|
|
||||||
</div>
|
|
||||||
<div class="pt-5">
|
|
||||||
<div class="flex justify-start">
|
|
||||||
<VButton type="secondary"> 保存</VButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,41 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VButton } from "@halo-dev/components";
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="w-1/3">
|
|
||||||
<FormKit :actions="false" type="form">
|
|
||||||
<FormKit
|
|
||||||
:options="[
|
|
||||||
{ label: '启用', value: true },
|
|
||||||
{ label: '禁用', value: false },
|
|
||||||
]"
|
|
||||||
:value="true"
|
|
||||||
label="启用评论"
|
|
||||||
type="radio"
|
|
||||||
></FormKit>
|
|
||||||
<FormKit
|
|
||||||
:options="[
|
|
||||||
{ label: '是', value: true },
|
|
||||||
{ label: '否', value: false },
|
|
||||||
]"
|
|
||||||
:value="true"
|
|
||||||
label="新评论审核"
|
|
||||||
type="radio"
|
|
||||||
></FormKit>
|
|
||||||
<FormKit
|
|
||||||
:options="[
|
|
||||||
{ label: '是', value: true },
|
|
||||||
{ label: '否', value: false },
|
|
||||||
]"
|
|
||||||
:value="true"
|
|
||||||
label="仅限注册用户评论"
|
|
||||||
type="radio"
|
|
||||||
></FormKit>
|
|
||||||
</FormKit>
|
|
||||||
</div>
|
|
||||||
<div class="pt-5">
|
|
||||||
<div class="flex justify-start">
|
|
||||||
<VButton type="secondary"> 保存</VButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VButton } from "@halo-dev/components";
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="w-1/3">
|
|
||||||
<FormKit :actions="false" type="form">
|
|
||||||
<FormKit label="站点标题" type="text"></FormKit>
|
|
||||||
<FormKit label="站点副标题" type="text"></FormKit>
|
|
||||||
<FormKit label="Logo" type="url"></FormKit>
|
|
||||||
<FormKit label="Favicon" type="url"></FormKit>
|
|
||||||
</FormKit>
|
|
||||||
</div>
|
|
||||||
<div class="pt-5">
|
|
||||||
<div class="flex justify-start">
|
|
||||||
<VButton type="secondary"> 保存</VButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,11 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VButton } from "@halo-dev/components";
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="w-1/3">// TODO</div>
|
|
||||||
<div class="pt-5">
|
|
||||||
<div class="flex justify-start">
|
|
||||||
<VButton type="secondary"> 保存</VButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,34 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VButton } from "@halo-dev/components";
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="w-1/3">
|
|
||||||
<FormKit type="form">
|
|
||||||
<FormKit
|
|
||||||
:options="[
|
|
||||||
{ label: '发布时间', value: '' },
|
|
||||||
{ label: '更新时间', value: '' },
|
|
||||||
{ label: '浏览量', value: '' },
|
|
||||||
]"
|
|
||||||
label="默认排序方式"
|
|
||||||
type="select"
|
|
||||||
></FormKit>
|
|
||||||
<FormKit label="默认显示条数" type="number"></FormKit>
|
|
||||||
<FormKit
|
|
||||||
:options="[
|
|
||||||
{ label: '是', value: true },
|
|
||||||
{ label: '否', value: false },
|
|
||||||
]"
|
|
||||||
:value="false"
|
|
||||||
label="新文章审核"
|
|
||||||
help="用户发布文章是否需要管理员审核"
|
|
||||||
type="radio"
|
|
||||||
></FormKit>
|
|
||||||
</FormKit>
|
|
||||||
</div>
|
|
||||||
<div class="pt-5">
|
|
||||||
<div class="flex justify-start">
|
|
||||||
<VButton type="secondary"> 保存</VButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,25 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VButton } from "@halo-dev/components";
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="w-1/3">
|
|
||||||
<FormKit type="form">
|
|
||||||
<FormKit
|
|
||||||
:options="[
|
|
||||||
{ label: '是', value: true },
|
|
||||||
{ label: '否', value: false },
|
|
||||||
]"
|
|
||||||
:value="false"
|
|
||||||
label="屏蔽搜索引擎"
|
|
||||||
type="radio"
|
|
||||||
></FormKit>
|
|
||||||
<FormKit label="站点关键词" type="textarea"></FormKit>
|
|
||||||
<FormKit label="站点描述" type="textarea"></FormKit>
|
|
||||||
</FormKit>
|
|
||||||
</div>
|
|
||||||
<div class="pt-5">
|
|
||||||
<div class="flex justify-start">
|
|
||||||
<VButton type="secondary"> 保存</VButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
// core libs
|
||||||
|
import { computed, inject, onMounted, ref } from "vue";
|
||||||
|
|
||||||
|
// components
|
||||||
|
import { VButton } from "@halo-dev/components";
|
||||||
|
|
||||||
|
// types
|
||||||
|
import type { Ref } from "vue";
|
||||||
|
|
||||||
|
// hooks
|
||||||
|
import { useSettingForm } from "@halo-dev/admin-shared";
|
||||||
|
|
||||||
|
const group = inject<Ref<string | undefined>>("activeTab");
|
||||||
|
|
||||||
|
const settingName = ref("system");
|
||||||
|
const configMapName = ref("system");
|
||||||
|
const {
|
||||||
|
settings,
|
||||||
|
configMapFormData,
|
||||||
|
saving,
|
||||||
|
handleFetchConfigMap,
|
||||||
|
handleFetchSettings,
|
||||||
|
handleSaveConfigMap,
|
||||||
|
} = useSettingForm(settingName, configMapName);
|
||||||
|
|
||||||
|
const formSchema = computed(() => {
|
||||||
|
if (!settings?.value?.spec) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return settings.value.spec.find((item) => item.group === group?.value)
|
||||||
|
?.formSchema;
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await handleFetchSettings();
|
||||||
|
await handleFetchConfigMap();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="bg-white p-4 sm:px-6">
|
||||||
|
<div class="w-1/3">
|
||||||
|
<FormKit
|
||||||
|
v-if="group && formSchema && configMapFormData"
|
||||||
|
:id="group"
|
||||||
|
v-model="configMapFormData[group]"
|
||||||
|
:actions="false"
|
||||||
|
:preserve="true"
|
||||||
|
type="form"
|
||||||
|
@submit="handleSaveConfigMap"
|
||||||
|
>
|
||||||
|
<FormKitSchema :schema="formSchema" />
|
||||||
|
</FormKit>
|
||||||
|
</div>
|
||||||
|
<div class="pt-5">
|
||||||
|
<div class="flex justify-start">
|
||||||
|
<VButton
|
||||||
|
:loading="saving"
|
||||||
|
type="secondary"
|
||||||
|
@click="$formkit.submit(group || '')"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</VButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,24 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VButton } from "@halo-dev/components";
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="w-1/3">
|
|
||||||
<FormKit type="form">
|
|
||||||
<FormKit
|
|
||||||
:options="[
|
|
||||||
{ label: '是', value: true },
|
|
||||||
{ label: '否', value: false },
|
|
||||||
]"
|
|
||||||
:value="false"
|
|
||||||
label="是否公开注册"
|
|
||||||
type="radio"
|
|
||||||
></FormKit>
|
|
||||||
<FormKit label="默认角色" type="select"></FormKit>
|
|
||||||
</FormKit>
|
|
||||||
</div>
|
|
||||||
<div class="pt-5">
|
|
||||||
<div class="flex justify-start">
|
|
||||||
<VButton type="secondary"> 保存</VButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,70 +1,94 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { BasicLayout } from "@halo-dev/admin-shared";
|
// core libs
|
||||||
|
import { onMounted, type Ref } from "vue";
|
||||||
|
import { provide, 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
|
||||||
import {
|
import {
|
||||||
IconSettings,
|
|
||||||
VButton,
|
|
||||||
VCard,
|
VCard,
|
||||||
VPageHeader,
|
VPageHeader,
|
||||||
VTabbar,
|
VTabbar,
|
||||||
|
IconSettings,
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import { onMounted, ref } from "vue";
|
|
||||||
import { RouterView, useRoute, useRouter } from "vue-router";
|
|
||||||
|
|
||||||
const SettingTabs = [
|
interface SettingTab {
|
||||||
{
|
id: string;
|
||||||
id: "general",
|
label: string;
|
||||||
label: "基本设置",
|
route: {
|
||||||
routeName: "GeneralSettings",
|
name: string;
|
||||||
},
|
params?: Record<string, string>;
|
||||||
{
|
};
|
||||||
id: "user",
|
}
|
||||||
label: "用户设置",
|
|
||||||
routeName: "UserSettings",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "post",
|
|
||||||
label: "文章设置",
|
|
||||||
routeName: "PostSettings",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "seo",
|
|
||||||
label: "SEO 设置",
|
|
||||||
routeName: "SeoSettings",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "comment",
|
|
||||||
label: "评论设置",
|
|
||||||
routeName: "CommentSettings",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "code-inject",
|
|
||||||
label: "代码注入",
|
|
||||||
routeName: "CodeInjectSettings",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "notification",
|
|
||||||
label: "通知设置",
|
|
||||||
routeName: "NotificationSettings",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const activeTab = ref();
|
const tabs = ref<SettingTab[]>([] as SettingTab[]);
|
||||||
|
const activeTab = ref("");
|
||||||
|
|
||||||
const { name: currentRouteName } = useRoute();
|
const settingName = ref("system");
|
||||||
|
const configMapName = ref("system");
|
||||||
|
|
||||||
|
const { settings, handleFetchSettings } = useSettingForm(
|
||||||
|
settingName,
|
||||||
|
configMapName
|
||||||
|
);
|
||||||
|
|
||||||
|
provide<Ref<string | undefined>>("activeTab", activeTab);
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
// set default active tab
|
|
||||||
onMounted(() => {
|
|
||||||
const tab = SettingTabs.find((tab) => tab.routeName === currentRouteName);
|
|
||||||
activeTab.value = tab ? tab.id : SettingTabs[0].id;
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleTabChange = (id: string) => {
|
const handleTabChange = (id: string) => {
|
||||||
const tab = SettingTabs.find((tab) => tab.id === id);
|
const tab = tabs.value.find((item) => item.id === id);
|
||||||
if (tab) {
|
if (tab) {
|
||||||
router.push({ name: tab.routeName });
|
router.push(tab.route);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await handleFetchSettings();
|
||||||
|
if (settings.value && settings.value.spec) {
|
||||||
|
tabs.value = settings.value.spec.map((item: FormKitSettingSpec) => {
|
||||||
|
return {
|
||||||
|
id: item.group,
|
||||||
|
label: item.label || "",
|
||||||
|
route: {
|
||||||
|
name: "SystemSetting",
|
||||||
|
params: {
|
||||||
|
group: item.group,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
onTabChange(route.name as string);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const onTabChange = (routeName: string) => {
|
||||||
|
const tab = tabs.value.find((tab) => {
|
||||||
|
return (
|
||||||
|
tab.route.name === routeName &&
|
||||||
|
tab.route.params?.group === route.params.group
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (tab) {
|
||||||
|
activeTab.value = tab.id;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
activeTab.value = tabs.value[0].id;
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.name,
|
||||||
|
async (newRouteName) => {
|
||||||
|
onTabChange(newRouteName as string);
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<BasicLayout>
|
<BasicLayout>
|
||||||
|
@ -72,24 +96,23 @@ const handleTabChange = (id: string) => {
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<IconSettings class="mr-2 self-center" />
|
<IconSettings class="mr-2 self-center" />
|
||||||
</template>
|
</template>
|
||||||
<template #actions>
|
|
||||||
<VButton class="opacity-0" type="secondary">安装</VButton>
|
|
||||||
</template>
|
|
||||||
</VPageHeader>
|
</VPageHeader>
|
||||||
|
|
||||||
<div class="m-0 md:m-4">
|
<div class="m-0 md:m-4">
|
||||||
<VCard>
|
<VCard :body-class="['!p-0']">
|
||||||
<template #header>
|
<template #header>
|
||||||
<VTabbar
|
<VTabbar
|
||||||
v-model:active-id="activeTab"
|
v-model:active-id="activeTab"
|
||||||
:items="SettingTabs"
|
:items="tabs"
|
||||||
class="w-full !rounded-none"
|
class="w-full !rounded-none"
|
||||||
type="outline"
|
type="outline"
|
||||||
@change="handleTabChange"
|
@change="handleTabChange"
|
||||||
></VTabbar>
|
></VTabbar>
|
||||||
</template>
|
</template>
|
||||||
<RouterView></RouterView>
|
|
||||||
</VCard>
|
</VCard>
|
||||||
|
<div>
|
||||||
|
<RouterView :key="activeTab" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</BasicLayout>
|
</BasicLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
import { definePlugin } from "@halo-dev/admin-shared";
|
import { definePlugin } from "@halo-dev/admin-shared";
|
||||||
import SystemSettingsLayout from "./layouts/SystemSettingsLayout.vue";
|
import SystemSettingsLayout from "./layouts/SystemSettingsLayout.vue";
|
||||||
import GeneralSettings from "./GeneralSettings.vue";
|
import SystemSetting from "./SystemSetting.vue";
|
||||||
import UserSettings from "./UserSettings.vue";
|
|
||||||
import PostSettings from "./PostSettings.vue";
|
|
||||||
import SeoSettings from "./SeoSettings.vue";
|
|
||||||
import CommentSettings from "./CommentSettings.vue";
|
|
||||||
import CodeInjectSettings from "./CodeInjectSettings.vue";
|
|
||||||
import NotificationSettings from "./NotificationSettings.vue";
|
|
||||||
import { IconSettings } from "@halo-dev/components";
|
import { IconSettings } from "@halo-dev/components";
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
|
@ -16,42 +10,11 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
path: "/settings",
|
path: "/settings",
|
||||||
component: SystemSettingsLayout,
|
component: SystemSettingsLayout,
|
||||||
redirect: "/settings/general",
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "general",
|
path: ":group",
|
||||||
name: "GeneralSettings",
|
name: "SystemSetting",
|
||||||
component: GeneralSettings,
|
component: SystemSetting,
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "user",
|
|
||||||
name: "UserSettings",
|
|
||||||
component: UserSettings,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "post",
|
|
||||||
name: "PostSettings",
|
|
||||||
component: PostSettings,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "seo",
|
|
||||||
name: "SeoSettings",
|
|
||||||
component: SeoSettings,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "comment",
|
|
||||||
name: "CommentSettings",
|
|
||||||
component: CommentSettings,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "code-inject",
|
|
||||||
name: "CodeInjectSettings",
|
|
||||||
component: CodeInjectSettings,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "notification",
|
|
||||||
name: "NotificationSettings",
|
|
||||||
component: NotificationSettings,
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -62,7 +25,7 @@ export default definePlugin({
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
name: "设置",
|
name: "设置",
|
||||||
path: "/settings",
|
path: "/settings/basic",
|
||||||
icon: IconSettings,
|
icon: IconSettings,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue