mirror of https://github.com/halo-dev/halo
fix: missing ui permission condition about users (#4619)
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/4657/head
parent
d3e296d782
commit
f953201307
|
@ -0,0 +1,16 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { usePermission } from "@/utils/permission";
|
||||||
|
|
||||||
|
withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
permissions: string[];
|
||||||
|
}>(),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
const { currentUserHasPermission } = usePermission();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<slot v-if="currentUserHasPermission(permissions)" />
|
||||||
|
</template>
|
|
@ -0,0 +1,39 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { usePermission } from "@/utils/permission";
|
||||||
|
import type { Contributor } from "@halo-dev/api-client";
|
||||||
|
import { VAvatar } from "@halo-dev/components";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
|
withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
contributors: Contributor[];
|
||||||
|
}>(),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { currentUserHasPermission } = usePermission();
|
||||||
|
|
||||||
|
function handleRouteToUserDetail(contributor: Contributor) {
|
||||||
|
if (!currentUserHasPermission(["system:users:view"])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
router.push({
|
||||||
|
name: "UserDetail",
|
||||||
|
params: { name: contributor.name },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VAvatar
|
||||||
|
v-for="(contributor, contributorIndex) in contributors"
|
||||||
|
:key="contributorIndex"
|
||||||
|
v-tooltip="contributor.displayName"
|
||||||
|
size="xs"
|
||||||
|
:src="contributor.avatar"
|
||||||
|
:alt="contributor.displayName"
|
||||||
|
circle
|
||||||
|
@click="handleRouteToUserDetail(contributor)"
|
||||||
|
></VAvatar>
|
||||||
|
</template>
|
|
@ -356,10 +356,12 @@ onMounted(() => {
|
||||||
}) || []),
|
}) || []),
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
<UserFilterDropdown
|
<HasPermission :permissions="['system:users:view']">
|
||||||
v-model="selectedUser"
|
<UserFilterDropdown
|
||||||
:label="$t('core.attachment.filters.owner.label')"
|
v-model="selectedUser"
|
||||||
/>
|
:label="$t('core.attachment.filters.owner.label')"
|
||||||
|
/>
|
||||||
|
</HasPermission>
|
||||||
<FilterDropdown
|
<FilterDropdown
|
||||||
v-model="selectedSort"
|
v-model="selectedSort"
|
||||||
:label="$t('core.common.filters.labels.sort')"
|
:label="$t('core.common.filters.labels.sort')"
|
||||||
|
@ -610,6 +612,11 @@ onMounted(() => {
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
class="text-xs text-gray-500"
|
class="text-xs text-gray-500"
|
||||||
|
:class="{
|
||||||
|
'pointer-events-none': !currentUserHasPermission([
|
||||||
|
'system:users:view',
|
||||||
|
]),
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
{{ attachment.spec.ownerName }}
|
{{ attachment.spec.ownerName }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
|
@ -283,10 +283,12 @@ const handleApproveInBatch = async () => {
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
<UserFilterDropdown
|
<HasPermission :permissions="['system:users:view']">
|
||||||
v-model="selectedUser"
|
<UserFilterDropdown
|
||||||
:label="$t('core.comment.filters.owner.label')"
|
v-model="selectedUser"
|
||||||
/>
|
:label="$t('core.comment.filters.owner.label')"
|
||||||
|
/>
|
||||||
|
</HasPermission>
|
||||||
<FilterDropdown
|
<FilterDropdown
|
||||||
v-model="selectedSort"
|
v-model="selectedSort"
|
||||||
:label="$t('core.common.filters.labels.sort')"
|
:label="$t('core.common.filters.labels.sort')"
|
||||||
|
|
|
@ -9,7 +9,6 @@ import {
|
||||||
VSpace,
|
VSpace,
|
||||||
Dialog,
|
Dialog,
|
||||||
VEmpty,
|
VEmpty,
|
||||||
VAvatar,
|
|
||||||
VEntity,
|
VEntity,
|
||||||
VEntityField,
|
VEntityField,
|
||||||
VPageHeader,
|
VPageHeader,
|
||||||
|
@ -22,11 +21,11 @@ import { ref, watch } from "vue";
|
||||||
import type { ListedSinglePage, SinglePage } from "@halo-dev/api-client";
|
import type { ListedSinglePage, SinglePage } from "@halo-dev/api-client";
|
||||||
import { apiClient } from "@/utils/api-client";
|
import { apiClient } from "@/utils/api-client";
|
||||||
import { formatDatetime } from "@/utils/date";
|
import { formatDatetime } from "@/utils/date";
|
||||||
import { RouterLink } from "vue-router";
|
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import { usePermission } from "@/utils/permission";
|
import { usePermission } from "@/utils/permission";
|
||||||
import { useQuery } from "@tanstack/vue-query";
|
import { useQuery } from "@tanstack/vue-query";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import ContributorList from "../_components/ContributorList.vue";
|
||||||
|
|
||||||
const { currentUserHasPermission } = usePermission();
|
const { currentUserHasPermission } = usePermission();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -338,25 +337,7 @@ watch(
|
||||||
<template #end>
|
<template #end>
|
||||||
<VEntityField>
|
<VEntityField>
|
||||||
<template #description>
|
<template #description>
|
||||||
<RouterLink
|
<ContributorList :contributors="singlePage.contributors" />
|
||||||
v-for="(
|
|
||||||
contributor, contributorIndex
|
|
||||||
) in singlePage.contributors"
|
|
||||||
:key="contributorIndex"
|
|
||||||
:to="{
|
|
||||||
name: 'UserDetail',
|
|
||||||
params: { name: contributor.name },
|
|
||||||
}"
|
|
||||||
class="flex items-center"
|
|
||||||
>
|
|
||||||
<VAvatar
|
|
||||||
v-tooltip="contributor.displayName"
|
|
||||||
size="xs"
|
|
||||||
:src="contributor.avatar"
|
|
||||||
:alt="contributor.displayName"
|
|
||||||
circle
|
|
||||||
></VAvatar>
|
|
||||||
</RouterLink>
|
|
||||||
</template>
|
</template>
|
||||||
</VEntityField>
|
</VEntityField>
|
||||||
<VEntityField v-if="!singlePage?.page?.spec.deleted">
|
<VEntityField v-if="!singlePage?.page?.spec.deleted">
|
||||||
|
|
|
@ -379,10 +379,12 @@ watch(selectedPageNames, (newValue) => {
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
<UserFilterDropdown
|
<HasPermission :permissions="['system:users:view']">
|
||||||
v-model="selectedContributor"
|
<UserFilterDropdown
|
||||||
:label="$t('core.page.filters.author.label')"
|
v-model="selectedContributor"
|
||||||
/>
|
:label="$t('core.page.filters.author.label')"
|
||||||
|
/>
|
||||||
|
</HasPermission>
|
||||||
<FilterDropdown
|
<FilterDropdown
|
||||||
v-model="selectedSort"
|
v-model="selectedSort"
|
||||||
:label="$t('core.common.filters.labels.sort')"
|
:label="$t('core.common.filters.labels.sort')"
|
||||||
|
|
|
@ -5,7 +5,6 @@ import {
|
||||||
IconExternalLinkLine,
|
IconExternalLinkLine,
|
||||||
VSpace,
|
VSpace,
|
||||||
Dialog,
|
Dialog,
|
||||||
VAvatar,
|
|
||||||
VStatusDot,
|
VStatusDot,
|
||||||
VEntity,
|
VEntity,
|
||||||
VEntityField,
|
VEntityField,
|
||||||
|
@ -25,6 +24,7 @@ import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { inject } from "vue";
|
import { inject } from "vue";
|
||||||
import type { Ref } from "vue";
|
import type { Ref } from "vue";
|
||||||
|
import ContributorList from "../../_components/ContributorList.vue";
|
||||||
|
|
||||||
const { currentUserHasPermission } = usePermission();
|
const { currentUserHasPermission } = usePermission();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -189,23 +189,7 @@ const handleDelete = async () => {
|
||||||
<template #end>
|
<template #end>
|
||||||
<VEntityField>
|
<VEntityField>
|
||||||
<template #description>
|
<template #description>
|
||||||
<RouterLink
|
<ContributorList :contributors="singlePage.contributors" />
|
||||||
v-for="(contributor, contributorIndex) in singlePage.contributors"
|
|
||||||
:key="contributorIndex"
|
|
||||||
:to="{
|
|
||||||
name: 'UserDetail',
|
|
||||||
params: { name: contributor.name },
|
|
||||||
}"
|
|
||||||
class="flex items-center"
|
|
||||||
>
|
|
||||||
<VAvatar
|
|
||||||
v-tooltip="contributor.displayName"
|
|
||||||
size="xs"
|
|
||||||
:src="contributor.avatar"
|
|
||||||
:alt="contributor.displayName"
|
|
||||||
circle
|
|
||||||
></VAvatar>
|
|
||||||
</RouterLink>
|
|
||||||
</template>
|
</template>
|
||||||
</VEntityField>
|
</VEntityField>
|
||||||
<VEntityField :description="publishStatus">
|
<VEntityField :description="publishStatus">
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
VPageHeader,
|
VPageHeader,
|
||||||
VPagination,
|
VPagination,
|
||||||
VSpace,
|
VSpace,
|
||||||
VAvatar,
|
|
||||||
VStatusDot,
|
VStatusDot,
|
||||||
VEntity,
|
VEntity,
|
||||||
VEntityField,
|
VEntityField,
|
||||||
|
@ -27,6 +26,7 @@ import { usePermission } from "@/utils/permission";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import { useQuery } from "@tanstack/vue-query";
|
import { useQuery } from "@tanstack/vue-query";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import ContributorList from "../_components/ContributorList.vue";
|
||||||
|
|
||||||
const { currentUserHasPermission } = usePermission();
|
const { currentUserHasPermission } = usePermission();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -353,25 +353,7 @@ watch(
|
||||||
<template #end>
|
<template #end>
|
||||||
<VEntityField>
|
<VEntityField>
|
||||||
<template #description>
|
<template #description>
|
||||||
<RouterLink
|
<ContributorList :contributors="post.contributors" />
|
||||||
v-for="(
|
|
||||||
contributor, contributorIndex
|
|
||||||
) in post.contributors"
|
|
||||||
:key="contributorIndex"
|
|
||||||
:to="{
|
|
||||||
name: 'UserDetail',
|
|
||||||
params: { name: contributor.name },
|
|
||||||
}"
|
|
||||||
class="flex items-center"
|
|
||||||
>
|
|
||||||
<VAvatar
|
|
||||||
v-tooltip="contributor.displayName"
|
|
||||||
size="xs"
|
|
||||||
:src="contributor.avatar"
|
|
||||||
:alt="contributor.displayName"
|
|
||||||
circle
|
|
||||||
></VAvatar>
|
|
||||||
</RouterLink>
|
|
||||||
</template>
|
</template>
|
||||||
</VEntityField>
|
</VEntityField>
|
||||||
<VEntityField v-if="!post?.post?.spec.deleted">
|
<VEntityField v-if="!post?.post?.spec.deleted">
|
||||||
|
|
|
@ -393,10 +393,12 @@ watch(selectedPostNames, (newValue) => {
|
||||||
v-model="selectedTag"
|
v-model="selectedTag"
|
||||||
:label="$t('core.post.filters.tag.label')"
|
:label="$t('core.post.filters.tag.label')"
|
||||||
/>
|
/>
|
||||||
<UserFilterDropdown
|
<HasPermission :permissions="['system:users:view']">
|
||||||
v-model="selectedContributor"
|
<UserFilterDropdown
|
||||||
:label="$t('core.post.filters.author.label')"
|
v-model="selectedContributor"
|
||||||
/>
|
:label="$t('core.post.filters.author.label')"
|
||||||
|
/>
|
||||||
|
</HasPermission>
|
||||||
<FilterDropdown
|
<FilterDropdown
|
||||||
v-model="selectedSort"
|
v-model="selectedSort"
|
||||||
:label="$t('core.common.filters.labels.sort')"
|
:label="$t('core.common.filters.labels.sort')"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { VAvatar, VEntityField } from "@halo-dev/components";
|
import { VEntityField } from "@halo-dev/components";
|
||||||
import type { ListedPost } from "@halo-dev/api-client";
|
import type { ListedPost } from "@halo-dev/api-client";
|
||||||
|
import ContributorList from "@/modules/contents/_components/ContributorList.vue";
|
||||||
|
|
||||||
withDefaults(
|
withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
@ -13,23 +14,7 @@ withDefaults(
|
||||||
<template>
|
<template>
|
||||||
<VEntityField>
|
<VEntityField>
|
||||||
<template #description>
|
<template #description>
|
||||||
<RouterLink
|
<ContributorList :contributors="post.contributors" />
|
||||||
v-for="(contributor, contributorIndex) in post.contributors"
|
|
||||||
:key="contributorIndex"
|
|
||||||
:to="{
|
|
||||||
name: 'UserDetail',
|
|
||||||
params: { name: contributor.name },
|
|
||||||
}"
|
|
||||||
class="flex items-center"
|
|
||||||
>
|
|
||||||
<VAvatar
|
|
||||||
v-tooltip="contributor.displayName"
|
|
||||||
size="xs"
|
|
||||||
:src="contributor.avatar"
|
|
||||||
:alt="contributor.displayName"
|
|
||||||
circle
|
|
||||||
></VAvatar>
|
|
||||||
</RouterLink>
|
|
||||||
</template>
|
</template>
|
||||||
</VEntityField>
|
</VEntityField>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -11,6 +11,7 @@ import FilterCleanButton from "@/components/filter/FilterCleanButton.vue";
|
||||||
import SearchInput from "@/components/input/SearchInput.vue";
|
import SearchInput from "@/components/input/SearchInput.vue";
|
||||||
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
||||||
import AttachmentFileTypeIcon from "@/components/icon/AttachmentFileTypeIcon.vue";
|
import AttachmentFileTypeIcon from "@/components/icon/AttachmentFileTypeIcon.vue";
|
||||||
|
import HasPermission from "@/components/permission/HasPermission.vue";
|
||||||
|
|
||||||
export function setupComponents(app: App) {
|
export function setupComponents(app: App) {
|
||||||
app.use(VueGridLayout);
|
app.use(VueGridLayout);
|
||||||
|
@ -37,4 +38,5 @@ export function setupComponents(app: App) {
|
||||||
app.component("SearchInput", SearchInput);
|
app.component("SearchInput", SearchInput);
|
||||||
app.component("AnnotationsForm", AnnotationsForm);
|
app.component("AnnotationsForm", AnnotationsForm);
|
||||||
app.component("AttachmentFileTypeIcon", AttachmentFileTypeIcon);
|
app.component("AttachmentFileTypeIcon", AttachmentFileTypeIcon);
|
||||||
|
app.component("HasPermission", HasPermission);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue