From ab888119efe1eab41b22c4cf2cb26ddd32bd82a8 Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Mon, 30 Jan 2023 14:36:10 +0800 Subject: [PATCH] refactor: use new apis to refactor themes management (#820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement #### What this PR does / why we need it: 使用新的 API 来管理主题,用于区分主题管理和配置相关的权限。适配:https://github.com/halo-dev/halo/pull/3135 #### 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/3135 分支。 2. Console 需要 `pnpm install`。 1. 主题设置项,需要测试保存,安装新主题之后表单是否正常。 3. 创建一个角色,测试仅有管理/查看主题的角色,登录之后检查是否符合预期。 #### Does this PR introduce a user-facing change? ```release-note 重构 Console 端主题的设置表单逻辑。 ``` --- .../global-search/GlobalSearchModal.vue | 64 +++++-------- src/composables/use-setting-form.ts | 67 ++++++++++++- src/main.ts | 6 +- .../dashboard/widgets/QuickLinkWidget.vue | 1 + src/modules/interface/themes/ThemeSetting.vue | 74 +++++++++----- .../components/preview/ThemePreviewModal.vue | 96 +++++++++++++------ .../interface/themes/composables/use-theme.ts | 20 +--- .../interface/themes/layouts/ThemeLayout.vue | 28 +++--- src/modules/interface/themes/module.ts | 2 +- src/stores/theme.ts | 34 +++---- 10 files changed, 245 insertions(+), 147 deletions(-) diff --git a/src/components/global-search/GlobalSearchModal.vue b/src/components/global-search/GlobalSearchModal.vue index 9a7b3ae1..ffed0670 100644 --- a/src/components/global-search/GlobalSearchModal.vue +++ b/src/components/global-search/GlobalSearchModal.vue @@ -16,11 +16,14 @@ import { computed, markRaw, ref, watch, type Component } from "vue"; import Fuse from "fuse.js"; import { apiClient } from "@/utils/api-client"; import { usePermission } from "@/utils/permission"; +import { useThemeStore } from "@/stores/theme"; +import { storeToRefs } from "pinia"; const router = useRouter(); const route = useRoute(); const { currentUserHasPermission } = usePermission(); +const { activatedTheme } = storeToRefs(useThemeStore()); const props = withDefaults( defineProps<{ @@ -248,46 +251,29 @@ const handleBuildSearchIndex = () => { }); }); }); + } - // get theme settings - apiClient.extension.configMap - .getv1alpha1ConfigMap({ - name: "system", - }) - .then(({ data: systemConfigMap }) => { - if (systemConfigMap.data?.theme) { - const themeConfig = JSON.parse(systemConfigMap.data.theme); - - apiClient.extension.theme - .getthemeHaloRunV1alpha1Theme({ - name: themeConfig.active, - }) - .then(({ data: theme }) => { - if (theme && theme.spec.settingName) { - apiClient.extension.setting - .getv1alpha1Setting({ - name: theme.spec.settingName, - }) - .then(({ data: themeSettings }) => { - themeSettings.spec.forms.forEach((form) => { - fuse.add({ - title: `${theme.spec.displayName} / ${form.label}`, - icon: { - component: markRaw(IconPalette), - }, - group: "主题设置", - route: { - name: "ThemeSetting", - params: { - group: form.group, - }, - }, - }); - }); - }); - } - }); - } + if (currentUserHasPermission(["system:themes:view"])) { + apiClient.theme + .fetchThemeSetting({ name: "-" }) + .then(({ data: themeSettings }) => { + themeSettings.spec.forms.forEach((form) => { + fuse.add({ + title: [activatedTheme.value?.spec.displayName, form.label].join( + " / " + ), + icon: { + component: markRaw(IconPalette), + }, + group: "主题设置", + route: { + name: "ThemeSetting", + params: { + group: form.group, + }, + }, + }); + }); }); } }; diff --git a/src/composables/use-setting-form.ts b/src/composables/use-setting-form.ts index d4449edf..e959ec31 100644 --- a/src/composables/use-setting-form.ts +++ b/src/composables/use-setting-form.ts @@ -1,6 +1,6 @@ // core libs // types -import type { Ref } from "vue"; +import { computed, watch, type ComputedRef, type Ref } from "vue"; import { ref } from "vue"; import { apiClient } from "../utils/api-client"; @@ -179,3 +179,68 @@ export function useSettingForm( handleReset, }; } + +interface useSettingFormConvertReturn { + formSchema: ComputedRef< + (FormKitSchemaCondition | FormKitSchemaNode)[] | undefined + >; + configMapFormData: Ref>>; + convertToSave: () => ConfigMap | undefined; +} + +export function useSettingFormConvert( + setting: Ref, + configMap: Ref, + group: Ref +): useSettingFormConvertReturn { + const configMapFormData = ref>>({}); + + const formSchema = computed(() => { + if (!setting.value) { + return; + } + const { forms } = setting.value.spec; + return forms.find((item) => item.group === group?.value)?.formSchema as ( + | FormKitSchemaCondition + | FormKitSchemaNode + )[]; + }); + + watch( + () => configMap.value, + () => { + const { forms } = setting.value?.spec || {}; + + forms?.forEach((form) => { + configMapFormData.value[form.group] = JSON.parse( + configMap.value?.data?.[form.group] || "{}" + ); + }); + } + ); + + function convertToSave() { + const configMapToUpdate = cloneDeep(configMap.value); + + if (!configMapToUpdate) { + return; + } + + const data: { + [key: string]: string; + } = {}; + + setting.value?.spec.forms.forEach((item: SettingForm) => { + data[item.group] = JSON.stringify(configMapFormData?.value?.[item.group]); + }); + + configMapToUpdate.data = data; + return configMapToUpdate; + } + + return { + formSchema, + configMapFormData, + convertToSave, + }; +} diff --git a/src/main.ts b/src/main.ts index 640d43e0..d76759bf 100644 --- a/src/main.ts +++ b/src/main.ts @@ -203,7 +203,11 @@ async function loadUserPermissions() { return; } - enable ? (el.style.backgroundColor = "red") : el.remove(); + if (enable) { + //TODO + return; + } + el?.remove?.(); } ); } diff --git a/src/modules/dashboard/widgets/QuickLinkWidget.vue b/src/modules/dashboard/widgets/QuickLinkWidget.vue index e529053c..bad4eed5 100644 --- a/src/modules/dashboard/widgets/QuickLinkWidget.vue +++ b/src/modules/dashboard/widgets/QuickLinkWidget.vue @@ -44,6 +44,7 @@ const actions: Action[] = [ action: () => { themePreviewVisible.value = true; }, + permissions: ["system:themes:view"], }, { icon: markRaw(IconBookRead), diff --git a/src/modules/interface/themes/ThemeSetting.vue b/src/modules/interface/themes/ThemeSetting.vue index f1fd12b5..8660a26f 100644 --- a/src/modules/interface/themes/ThemeSetting.vue +++ b/src/modules/interface/themes/ThemeSetting.vue @@ -1,45 +1,73 @@