mirror of https://github.com/halo-dev/halo
feat: make comment and reply list item operations extendable (#6438)
#### What type of PR is this? /area console /kind feature /milestone 2.18.x #### What this PR does / why we need it: 评论和回复管理列表项的操作按钮支持被插件扩展。 ![image](https://github.com/user-attachments/assets/20174eda-ec46-4ab2-b1d9-c27e4aaa6cba) ![image](https://github.com/user-attachments/assets/ac44c221-71f5-4077-8116-a92245c22697) #### Which issue(s) this PR fixes: Fixes #6392 #### Special notes for your reviewer: 需要评论和回复的关于列表的已有功能是否正常。 如果需要测试扩展点是否有效,可以使用此插件测试:[plugin-starter-1.0.0-SNAPSHOT.jar.zip](https://github.com/user-attachments/files/16482348/plugin-starter-1.0.0-SNAPSHOT.jar.zip) ``` export default definePlugin({ components: {}, routes: [], extensionPoints: { "comment:list-item:operation:create": (comment: Ref<ListedComment>) => { return [ { priority: 21, component: markRaw(VDropdownItem), label: "测试评论菜单", visible: true, permissions: [], action: () => { console.log(comment) }, }, ]; }, "reply:list-item:operation:create": (reply: Ref<ListedReply>) => { return [ { priority: 11, component: markRaw(VDropdownItem), label: "测试回复菜单", visible: true, permissions: [], action: () => { console.log(reply) }, }, ]; }, }, }); ``` #### Does this PR introduce a user-facing change? ```release-note Console 评论和回复管理列表项的操作按钮支持被插件扩展。 ```pull/6442/head
parent
684c3b045b
commit
4a4f8b655d
|
@ -29,12 +29,23 @@ import {
|
|||
import type {
|
||||
CommentSubjectRefProvider,
|
||||
CommentSubjectRefResult,
|
||||
OperationItem,
|
||||
} from "@halo-dev/console-shared";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
|
||||
import { computed, onMounted, provide, ref, type Ref } from "vue";
|
||||
import {
|
||||
computed,
|
||||
onMounted,
|
||||
provide,
|
||||
ref,
|
||||
type Ref,
|
||||
toRefs,
|
||||
markRaw,
|
||||
} from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import ReplyCreationModal from "./ReplyCreationModal.vue";
|
||||
import ReplyListItem from "./ReplyListItem.vue";
|
||||
import { useOperationItemExtensionPoint } from "@console/composables/use-operation-extension-points";
|
||||
import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue";
|
||||
|
||||
const { currentUserHasPermission } = usePermission();
|
||||
const { t } = useI18n();
|
||||
|
@ -50,6 +61,8 @@ const props = withDefaults(
|
|||
}
|
||||
);
|
||||
|
||||
const { comment } = toRefs(props);
|
||||
|
||||
const hoveredReply = ref<ListedReply>();
|
||||
const showReplies = ref(false);
|
||||
const replyModal = ref(false);
|
||||
|
@ -293,6 +306,35 @@ const subjectRefResult = computed(() => {
|
|||
}
|
||||
return subjectRef.resolve(subject);
|
||||
});
|
||||
|
||||
const { operationItems } = useOperationItemExtensionPoint<ListedComment>(
|
||||
"comment:list-item:operation:create",
|
||||
comment,
|
||||
computed((): OperationItem<ListedComment>[] => [
|
||||
{
|
||||
priority: 0,
|
||||
component: markRaw(VDropdownItem),
|
||||
label: t("core.comment.operations.approve_comment_in_batch.button"),
|
||||
action: handleApprove,
|
||||
hidden: props.comment?.comment.spec.approved,
|
||||
},
|
||||
{
|
||||
priority: 10,
|
||||
component: markRaw(VDropdownItem),
|
||||
label: t("core.comment.operations.approve_applies_in_batch.button"),
|
||||
action: handleApproveReplyInBatch,
|
||||
},
|
||||
{
|
||||
priority: 20,
|
||||
component: markRaw(VDropdownItem),
|
||||
props: {
|
||||
type: "danger",
|
||||
},
|
||||
label: t("core.common.buttons.delete"),
|
||||
action: handleDelete,
|
||||
},
|
||||
])
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -419,18 +461,7 @@ const subjectRefResult = computed(() => {
|
|||
v-if="currentUserHasPermission(['system:comments:manage'])"
|
||||
#dropdownItems
|
||||
>
|
||||
<VDropdownItem
|
||||
v-if="!comment?.comment.spec.approved"
|
||||
@click="handleApprove"
|
||||
>
|
||||
{{ $t("core.comment.operations.approve_comment_in_batch.button") }}
|
||||
</VDropdownItem>
|
||||
<VDropdownItem @click="handleApproveReplyInBatch">
|
||||
{{ $t("core.comment.operations.approve_applies_in_batch.button") }}
|
||||
</VDropdownItem>
|
||||
<VDropdownItem type="danger" @click="handleDelete">
|
||||
{{ $t("core.common.buttons.delete") }}
|
||||
</VDropdownItem>
|
||||
<EntityDropdownItems :dropdown-items="operationItems" :item="comment" />
|
||||
</template>
|
||||
|
||||
<template v-if="showReplies" #footer>
|
||||
|
|
|
@ -13,10 +13,13 @@ import {
|
|||
VStatusDot,
|
||||
VTag,
|
||||
} from "@halo-dev/components";
|
||||
import type { OperationItem } from "@halo-dev/console-shared";
|
||||
import { useQueryClient } from "@tanstack/vue-query";
|
||||
import { computed, inject, ref, type Ref } from "vue";
|
||||
import { computed, inject, ref, type Ref, toRefs, markRaw } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import ReplyCreationModal from "./ReplyCreationModal.vue";
|
||||
import { useOperationItemExtensionPoint } from "@console/composables/use-operation-extension-points";
|
||||
import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const queryClient = useQueryClient();
|
||||
|
@ -33,6 +36,8 @@ const props = withDefaults(
|
|||
}
|
||||
);
|
||||
|
||||
const { reply } = toRefs(props);
|
||||
|
||||
const quoteReply = computed(() => {
|
||||
const { quoteReply: replyName } = props.reply.reply.spec;
|
||||
|
||||
|
@ -119,6 +124,31 @@ function onReplyCreationModalClose() {
|
|||
});
|
||||
replyModal.value = false;
|
||||
}
|
||||
|
||||
const { operationItems } = useOperationItemExtensionPoint<ListedReply>(
|
||||
"reply:list-item:operation:create",
|
||||
reply,
|
||||
computed((): OperationItem<ListedReply>[] => [
|
||||
{
|
||||
priority: 0,
|
||||
component: markRaw(VDropdownItem),
|
||||
label: t("core.comment.operations.approve_reply.button"),
|
||||
permissions: ["system:comments:manage"],
|
||||
action: handleApprove,
|
||||
hidden: props.reply?.reply.spec.approved,
|
||||
},
|
||||
{
|
||||
priority: 10,
|
||||
component: markRaw(VDropdownItem),
|
||||
props: {
|
||||
type: "danger",
|
||||
},
|
||||
label: t("core.common.buttons.delete"),
|
||||
permissions: ["system:comments:manage"],
|
||||
action: handleDelete,
|
||||
},
|
||||
])
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -214,20 +244,7 @@ function onReplyCreationModalClose() {
|
|||
</VEntityField>
|
||||
</template>
|
||||
<template #dropdownItems>
|
||||
<VDropdownItem
|
||||
v-if="!reply?.reply.spec.approved"
|
||||
v-permission="['system:comments:manage']"
|
||||
@click="handleApprove"
|
||||
>
|
||||
{{ $t("core.comment.operations.approve_reply.button") }}
|
||||
</VDropdownItem>
|
||||
<VDropdownItem
|
||||
v-permission="['system:comments:manage']"
|
||||
type="danger"
|
||||
@click="handleDelete"
|
||||
>
|
||||
{{ $t("core.common.buttons.delete") }}
|
||||
</VDropdownItem>
|
||||
<EntityDropdownItems :dropdown-items="operationItems" :item="reply" />
|
||||
</template>
|
||||
</VEntity>
|
||||
</template>
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
目前支持扩展的数据列表:
|
||||
|
||||
- 文章:`"post:list-item:operation:create"?: (post: Ref<ListedPost>) => | OperationItem<ListedPost>[] | Promise<OperationItem<ListedPost>[]>`
|
||||
- 评论:`"comment:list-item:operation:create"?: (comment: Ref<ListedComment>) => | OperationItem<ListedComment>[] | Promise<OperationItem<ListedComment>[]>`
|
||||
- 回复:`"reply:list-item:operation:create"?: (reply: Ref<ListedReply>) => | OperationItem<ListedReply>[] | Promise<OperationItem<ListedReply>[]>`
|
||||
- 插件:`"plugin:list-item:operation:create"?: (plugin: Ref<Plugin>) => | OperationItem<Plugin>[] | Promise<OperationItem<Plugin>[]>`
|
||||
- 备份:`"backup:list-item:operation:create"?: (backup: Ref<Backup>) => | OperationItem<Backup>[] | Promise<OperationItem<Backup>[]>`
|
||||
- 主题:`"theme:list-item:operation:create"?: (theme: Ref<Theme>) => | OperationItem<Theme>[] | Promise<OperationItem<Theme>[]>`
|
||||
|
|
|
@ -11,6 +11,8 @@ import type {
|
|||
ListedPost,
|
||||
Plugin,
|
||||
Theme,
|
||||
ListedComment,
|
||||
ListedReply,
|
||||
} from "@halo-dev/api-client";
|
||||
import type { AnyExtension } from "@halo-dev/richtext-editor";
|
||||
import type { Component, Ref } from "vue";
|
||||
|
@ -52,6 +54,14 @@ export interface ExtensionPoint {
|
|||
post: Ref<ListedPost>
|
||||
) => OperationItem<ListedPost>[];
|
||||
|
||||
"comment:list-item:operation:create"?: (
|
||||
comment: Ref<ListedComment>
|
||||
) => OperationItem<ListedComment>[];
|
||||
|
||||
"reply:list-item:operation:create"?: (
|
||||
reply: Ref<ListedReply>
|
||||
) => OperationItem<ListedReply>[];
|
||||
|
||||
"plugin:list-item:operation:create"?: (
|
||||
plugin: Ref<Plugin>
|
||||
) => OperationItem<Plugin>[];
|
||||
|
|
Loading…
Reference in New Issue