mirror of https://github.com/halo-dev/halo
perf: refine ui permissions adapter
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/3445/head
parent
d2fbb8b98f
commit
f761c64035
|
@ -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) => {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ export default definePlugin({
|
||||||
component: ThemeSetting,
|
component: ThemeSetting,
|
||||||
meta: {
|
meta: {
|
||||||
title: "主题设置",
|
title: "主题设置",
|
||||||
permissions: ["system:themes:view"],
|
permissions: ["system:settings:view"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -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"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -18,6 +18,7 @@ export default definePlugin({
|
||||||
component: SystemSetting,
|
component: SystemSetting,
|
||||||
meta: {
|
meta: {
|
||||||
title: "系统设置",
|
title: "系统设置",
|
||||||
|
permissions: ["system:settings:view"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue