perf: refine ui permissions adapter

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/3445/head
Ryan Wang 2022-10-10 15:29:05 +08:00
parent d2fbb8b98f
commit f761c64035
12 changed files with 216 additions and 160 deletions

View File

@ -15,10 +15,13 @@ import {
import { computed, markRaw, onMounted, ref, watch, type Component } from "vue"; import { computed, markRaw, onMounted, ref, watch, type Component } from "vue";
import Fuse from "fuse.js"; import Fuse from "fuse.js";
import { apiClient } from "@/utils/api-client"; import { apiClient } from "@/utils/api-client";
import { usePermission } from "@/utils/permission";
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const { currentUserHasPermission } = usePermission();
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
visible: boolean; visible: boolean;
@ -74,200 +77,217 @@ const handleBuildSearchIndex = () => {
}); });
}); });
apiClient.extension.user.listv1alpha1User().then((response) => { if (currentUserHasPermission(["system:users:view"])) {
response.data.items.forEach((user) => { apiClient.extension.user.listv1alpha1User().then((response) => {
fuse.add({ response.data.items.forEach((user) => {
title: user.spec.displayName,
icon: {
component: markRaw(IconUserSettings),
},
group: "用户",
route: {
name: "UserDetail",
params: {
name: user.metadata.name,
},
},
});
});
});
apiClient.extension.plugin
.listpluginHaloRunV1alpha1Plugin()
.then((response) => {
response.data.items.forEach((plugin) => {
fuse.add({ fuse.add({
title: plugin.spec.displayName as string, title: user.spec.displayName,
icon: { icon: {
src: plugin.spec.logo as string, component: markRaw(IconUserSettings),
}, },
group: "插件", group: "用户",
route: { route: {
name: "PluginDetail", name: "UserDetail",
params: { params: {
name: plugin.metadata.name, name: user.metadata.name,
}, },
}, },
}); });
}); });
}); });
}
apiClient.extension.post.listcontentHaloRunV1alpha1Post().then((response) => { if (currentUserHasPermission(["system:plugins:view"])) {
response.data.items.forEach((post) => { apiClient.extension.plugin
fuse.add({ .listpluginHaloRunV1alpha1Plugin()
title: post.spec.title, .then((response) => {
icon: { response.data.items.forEach((plugin) => {
component: markRaw(IconBookRead), fuse.add({
}, title: plugin.spec.displayName as string,
group: "文章", icon: {
route: { src: plugin.spec.logo as string,
name: "PostEditor", },
query: { group: "插件",
name: post.metadata.name, route: {
}, name: "PluginDetail",
}, params: {
name: plugin.metadata.name,
},
},
});
});
}); });
}); }
});
apiClient.extension.category if (currentUserHasPermission(["system:posts:view"])) {
.listcontentHaloRunV1alpha1Category() apiClient.extension.post
.then((response) => { .listcontentHaloRunV1alpha1Post()
response.data.items.forEach((category) => { .then((response) => {
response.data.items.forEach((post) => {
fuse.add({
title: post.spec.title,
icon: {
component: markRaw(IconBookRead),
},
group: "文章",
route: {
name: "PostEditor",
query: {
name: post.metadata.name,
},
},
});
});
});
apiClient.extension.category
.listcontentHaloRunV1alpha1Category()
.then((response) => {
response.data.items.forEach((category) => {
fuse.add({
title: category.spec.displayName,
icon: {
component: markRaw(IconBookRead),
},
group: "分类",
route: {
name: "Categories",
query: {
name: category.metadata.name,
},
},
});
});
});
apiClient.extension.tag.listcontentHaloRunV1alpha1Tag().then((response) => {
response.data.items.forEach((tag) => {
fuse.add({ fuse.add({
title: category.spec.displayName, title: tag.spec.displayName,
icon: { icon: {
component: markRaw(IconBookRead), component: markRaw(IconBookRead),
}, },
group: "分类", group: "标签",
route: { route: {
name: "Categories", name: "Tags",
query: { query: {
name: category.metadata.name, name: tag.metadata.name,
}, },
}, },
}); });
}); });
}); });
}
apiClient.extension.tag.listcontentHaloRunV1alpha1Tag().then((response) => { if (currentUserHasPermission(["system:singlepages:view"])) {
response.data.items.forEach((tag) => { apiClient.extension.singlePage
fuse.add({ .listcontentHaloRunV1alpha1SinglePage()
title: tag.spec.displayName, .then((response) => {
icon: { response.data.items.forEach((singlePage) => {
component: markRaw(IconBookRead), fuse.add({
}, title: singlePage.spec.title,
group: "标签", icon: {
route: { component: markRaw(IconPages),
name: "Tags",
query: {
name: tag.metadata.name,
},
},
});
});
});
apiClient.extension.singlePage
.listcontentHaloRunV1alpha1SinglePage()
.then((response) => {
response.data.items.forEach((singlePage) => {
fuse.add({
title: singlePage.spec.title,
icon: {
component: markRaw(IconPages),
},
group: "自定义页面",
route: {
name: "SinglePageEditor",
query: {
name: singlePage.metadata.name,
}, },
}, group: "自定义页面",
route: {
name: "SinglePageEditor",
query: {
name: singlePage.metadata.name,
},
},
});
}); });
}); });
}); }
apiClient.extension.storage.attachment if (currentUserHasPermission(["system:attachments:view"])) {
.liststorageHaloRunV1alpha1Attachment() apiClient.extension.storage.attachment
.then((response) => { .liststorageHaloRunV1alpha1Attachment()
response.data.items.forEach((attachment) => { .then((response) => {
fuse.add({ response.data.items.forEach((attachment) => {
title: attachment.spec.displayName as string, fuse.add({
icon: { title: attachment.spec.displayName as string,
component: markRaw(IconFolder), icon: {
}, component: markRaw(IconFolder),
group: "附件",
route: {
name: "Attachments",
query: {
name: attachment.metadata.name,
}, },
}, group: "附件",
route: {
name: "Attachments",
query: {
name: attachment.metadata.name,
},
},
});
}); });
}); });
}); }
apiClient.extension.setting if (
.getv1alpha1Setting({ name: "system" }) currentUserHasPermission(["system:settings:view"]) &&
.then((response) => { currentUserHasPermission(["system:configmaps:view"])
response.data.spec.forms.forEach((form) => { ) {
fuse.add({ apiClient.extension.setting
title: form.label as string, .getv1alpha1Setting({ name: "system" })
icon: { .then((response) => {
component: markRaw(IconSettings), response.data.spec.forms.forEach((form) => {
}, fuse.add({
group: "设置", title: form.label as string,
route: { icon: {
name: "SystemSetting", component: markRaw(IconSettings),
params: {
group: form.group,
}, },
}, group: "设置",
route: {
name: "SystemSetting",
params: {
group: form.group,
},
},
});
}); });
}); });
});
// get theme settings // get theme settings
apiClient.extension.configMap apiClient.extension.configMap
.getv1alpha1ConfigMap({ .getv1alpha1ConfigMap({
name: "system", name: "system",
}) })
.then(({ data: systemConfigMap }) => { .then(({ data: systemConfigMap }) => {
if (systemConfigMap.data?.theme) { if (systemConfigMap.data?.theme) {
const themeConfig = JSON.parse(systemConfigMap.data.theme); const themeConfig = JSON.parse(systemConfigMap.data.theme);
apiClient.extension.theme apiClient.extension.theme
.getthemeHaloRunV1alpha1Theme({ .getthemeHaloRunV1alpha1Theme({
name: themeConfig.active, name: themeConfig.active,
}) })
.then(({ data: theme }) => { .then(({ data: theme }) => {
if (theme && theme.spec.settingName) { if (theme && theme.spec.settingName) {
apiClient.extension.setting apiClient.extension.setting
.getv1alpha1Setting({ .getv1alpha1Setting({
name: theme.spec.settingName, name: theme.spec.settingName,
}) })
.then(({ data: themeSettings }) => { .then(({ data: themeSettings }) => {
themeSettings.spec.forms.forEach((form) => { themeSettings.spec.forms.forEach((form) => {
fuse.add({ fuse.add({
title: `${theme.spec.displayName} / ${form.label}`, title: `${theme.spec.displayName} / ${form.label}`,
icon: { icon: {
component: markRaw(IconPalette), component: markRaw(IconPalette),
},
group: "主题设置",
route: {
name: "ThemeSetting",
params: {
group: form.group,
}, },
}, group: "主题设置",
route: {
name: "ThemeSetting",
params: {
group: form.group,
},
},
});
}); });
}); });
}); }
} });
}); }
} });
}); }
}; };
const handleKeydown = (e: KeyboardEvent) => { const handleKeydown = (e: KeyboardEvent) => {

View File

@ -10,6 +10,9 @@ import Draggable from "vuedraggable";
import type { CategoryTree } from "../utils"; import type { CategoryTree } from "../utils";
import { ref } from "vue"; import { ref } from "vue";
import { formatDatetime } from "@/utils/date"; import { formatDatetime } from "@/utils/date";
import { usePermission } from "@/utils/permission";
const { currentUserHasPermission } = usePermission();
withDefaults( withDefaults(
defineProps<{ defineProps<{
@ -87,7 +90,10 @@ function onDelete(category: CategoryTree) {
</template> </template>
</VEntityField> </VEntityField>
</template> </template>
<template #dropdownItems> <template
v-if="currentUserHasPermission(['system:posts:manage'])"
#dropdownItems
>
<VButton <VButton
v-permission="['system:posts:manage']" v-permission="['system:posts:manage']"
v-close-popper v-close-popper

View File

@ -28,6 +28,9 @@ import { formatDatetime } from "@/utils/date";
import { useRouteQuery } from "@vueuse/router"; import { useRouteQuery } from "@vueuse/router";
import { apiClient } from "@/utils/api-client"; import { apiClient } from "@/utils/api-client";
import { usePermission } from "@/utils/permission";
const { currentUserHasPermission } = usePermission();
const viewTypes = [ const viewTypes = [
{ {
@ -206,7 +209,10 @@ onMounted(async () => {
</template> </template>
</VEntityField> </VEntityField>
</template> </template>
<template #dropdownItems> <template
v-if="currentUserHasPermission(['system:posts:manage'])"
#dropdownItems
>
<VButton <VButton
v-permission="['system:posts:manage']" v-permission="['system:posts:manage']"
v-close-popper v-close-popper

View File

@ -68,7 +68,7 @@ watch(
<FormKitSchema :schema="formSchema" /> <FormKitSchema :schema="formSchema" />
</FormKit> </FormKit>
</div> </div>
<div class="pt-5"> <div v-permission="['system:configmaps:manage']" class="pt-5">
<div class="flex justify-start"> <div class="flex justify-start">
<VButton <VButton
:loading="saving" :loading="saving"

View File

@ -27,6 +27,9 @@ import {
} from "@halo-dev/components"; } from "@halo-dev/components";
import ThemeListModal from "../components/ThemeListModal.vue"; import ThemeListModal from "../components/ThemeListModal.vue";
import type { SettingForm, Theme } from "@halo-dev/api-client"; import type { SettingForm, Theme } from "@halo-dev/api-client";
import { usePermission } from "@/utils/permission";
const { currentUserHasPermission } = usePermission();
interface ThemeTab { interface ThemeTab {
id: string; id: string;
@ -83,6 +86,12 @@ watch(
if (selectedTheme.value) { if (selectedTheme.value) {
// reset tabs // reset tabs
tabs.value = cloneDeep(initialTabs); tabs.value = cloneDeep(initialTabs);
if (!currentUserHasPermission(["system:settings:view"])) {
handleTriggerTabChange();
return;
}
await handleFetchSettings(); await handleFetchSettings();
if (setting.value) { if (setting.value) {

View File

@ -29,7 +29,7 @@ export default definePlugin({
component: ThemeSetting, component: ThemeSetting,
meta: { meta: {
title: "主题设置", title: "主题设置",
permissions: ["system:themes:view"], permissions: ["system:settings:view"],
}, },
}, },
], ],

View File

@ -16,6 +16,9 @@ import PluginInstallModal from "./components/PluginInstallModal.vue";
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import { apiClient } from "@/utils/api-client"; import { apiClient } from "@/utils/api-client";
import type { PluginList } from "@halo-dev/api-client"; import type { PluginList } from "@halo-dev/api-client";
import { usePermission } from "@/utils/permission";
const { currentUserHasPermission } = usePermission();
const plugins = ref<PluginList>({ const plugins = ref<PluginList>({
page: 1, page: 1,
@ -119,8 +122,8 @@ function handleSortItemChange(sortItem?: SortItem) {
</script> </script>
<template> <template>
<PluginInstallModal <PluginInstallModal
v-if="currentUserHasPermission(['system:plugins:manage'])"
v-model:visible="pluginInstall" v-model:visible="pluginInstall"
v-permission="['system:plugins:manage']"
@close="handleFetchPlugins" @close="handleFetchPlugins"
/> />

View File

@ -77,7 +77,7 @@ await handleFetchPlugin();
<FormKitSchema :schema="formSchema" /> <FormKitSchema :schema="formSchema" />
</FormKit> </FormKit>
</div> </div>
<div class="pt-5"> <div v-permission="['system:configmaps:manage']" class="pt-5">
<div class="flex justify-start"> <div class="flex justify-start">
<VButton <VButton
:loading="saving" :loading="saving"

View File

@ -17,6 +17,9 @@ import { BasicLayout } from "@halo-dev/console-shared";
// types // types
import type { Ref } from "vue"; import type { Ref } from "vue";
import type { Plugin, SettingForm } from "@halo-dev/api-client"; import type { Plugin, SettingForm } from "@halo-dev/api-client";
import { usePermission } from "@/utils/permission";
const { currentUserHasPermission } = usePermission();
interface PluginTab { interface PluginTab {
id: string; id: string;
@ -96,6 +99,12 @@ const handleTriggerTabChange = () => {
onMounted(async () => { onMounted(async () => {
await handleFetchPlugin(); await handleFetchPlugin();
if (!currentUserHasPermission(["system:settings:view"])) {
handleTriggerTabChange();
return;
}
await handleFetchSettings(); await handleFetchSettings();
tabs.value = cloneDeep(initialTabs); tabs.value = cloneDeep(initialTabs);

View File

@ -43,6 +43,7 @@ export default definePlugin({
component: PluginDetail, component: PluginDetail,
meta: { meta: {
title: "插件详情", title: "插件详情",
permissions: ["system:plugins:view"],
}, },
}, },
{ {
@ -51,6 +52,7 @@ export default definePlugin({
component: PluginSetting, component: PluginSetting,
meta: { meta: {
title: "插件设置", title: "插件设置",
permissions: ["system:settings:view"],
}, },
}, },
], ],

View File

@ -48,7 +48,7 @@ await handleFetchConfigMap();
<FormKitSchema :schema="formSchema" /> <FormKitSchema :schema="formSchema" />
</FormKit> </FormKit>
</div> </div>
<div class="pt-5"> <div v-permission="['system:configmaps:manage']" class="pt-5">
<div class="flex justify-start"> <div class="flex justify-start">
<VButton <VButton
:loading="saving" :loading="saving"

View File

@ -18,6 +18,7 @@ export default definePlugin({
component: SystemSetting, component: SystemSetting,
meta: { meta: {
title: "系统设置", title: "系统设置",
permissions: ["system:settings:view"],
}, },
}, },
], ],