diff --git a/console/docs/extension-points/entity-listitem-field.md b/console/docs/extension-points/entity-listitem-field.md index 4b26da2bd..559c88858 100644 --- a/console/docs/extension-points/entity-listitem-field.md +++ b/console/docs/extension-points/entity-listitem-field.md @@ -9,6 +9,7 @@ 目前支持扩展的数据列表: - 插件:`"plugin:list-item:field:create"?: (plugin: Ref) => | EntityFieldItem[] | Promise` +- 文章:`"post:list-item:field:create"?: (post: Ref) => | EntityFieldItem[] | Promise` 示例: diff --git a/console/packages/shared/src/types/plugin.ts b/console/packages/shared/src/types/plugin.ts index 09417d7d9..845f741bf 100644 --- a/console/packages/shared/src/types/plugin.ts +++ b/console/packages/shared/src/types/plugin.ts @@ -57,6 +57,10 @@ export interface ExtensionPoint { plugin: Ref ) => EntityFieldItem[] | Promise; + "post:list-item:field:create"?: ( + post: Ref + ) => EntityFieldItem[] | Promise; + "theme:list:tabs:create"?: () => ThemeListTab[] | Promise; "theme:list-item:operation:create"?: ( diff --git a/console/src/modules/contents/comments/components/CommentListItem.vue b/console/src/modules/contents/comments/components/CommentListItem.vue index ff82b6b1a..7dfddd3a5 100644 --- a/console/src/modules/contents/comments/components/CommentListItem.vue +++ b/console/src/modules/contents/comments/components/CommentListItem.vue @@ -32,11 +32,11 @@ import { usePermission } from "@/utils/permission"; import { useQuery, useQueryClient } from "@tanstack/vue-query"; import { useI18n } from "vue-i18n"; import { usePluginModuleStore } from "@/stores/plugin"; -import type { PluginModule } from "@halo-dev/console-shared"; import type { + PluginModule, CommentSubjectRefProvider, CommentSubjectRefResult, -} from "packages/shared/dist"; +} from "@halo-dev/console-shared"; const { currentUserHasPermission } = usePermission(); const { t } = useI18n(); diff --git a/console/src/modules/contents/posts/PostList.vue b/console/src/modules/contents/posts/PostList.vue index d55989278..1cd96f444 100644 --- a/console/src/modules/contents/posts/PostList.vue +++ b/console/src/modules/contents/posts/PostList.vue @@ -472,7 +472,7 @@ watch(selectedPostNames, (newValue) => { class="box-border h-full w-full divide-y divide-gray-100" role="list" > -
  • +
  • import { Dialog, - IconExternalLinkLine, - IconEye, - IconEyeOff, Toast, - VAvatar, VDropdownDivider, VDropdownItem, VEntity, VEntityField, - VSpace, - VStatusDot, } from "@halo-dev/components"; -import PostTag from "../tags/components/PostTag.vue"; import { formatDatetime } from "@/utils/date"; import type { ListedPost, Post } from "@halo-dev/api-client"; import { useI18n } from "vue-i18n"; import { usePermission } from "@/utils/permission"; -import { postLabels } from "@/constants/labels"; import { apiClient } from "@/utils/api-client"; -import { useMutation, useQueryClient } from "@tanstack/vue-query"; -import { inject } from "vue"; +import { useQueryClient } from "@tanstack/vue-query"; import type { Ref } from "vue"; -import { ref } from "vue"; -import { computed } from "vue"; -import { markRaw } from "vue"; +import { computed, toRefs, markRaw, ref, inject } from "vue"; import { useRouter } from "vue-router"; +import { useEntityFieldItemExtensionPoint } from "@/composables/use-entity-extension-points"; import { useOperationItemExtensionPoint } from "@/composables/use-operation-extension-points"; import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue"; -import { toRefs } from "vue"; -import type { OperationItem } from "packages/shared/dist"; +import type { EntityFieldItem, OperationItem } from "@halo-dev/console-shared"; +import TitleField from "./entity-fields/TitleField.vue"; +import EntityFieldItems from "@/components/entity-fields/EntityFieldItems.vue"; +import ContributorsField from "./entity-fields/ContributorsField.vue"; +import PublishStatusField from "./entity-fields/PublishStatusField.vue"; +import VisibleField from "./entity-fields/VisibleField.vue"; +import StatusDotField from "@/components/entity-fields/StatusDotField.vue"; const { currentUserHasPermission } = usePermission(); const { t } = useI18n(); @@ -55,56 +50,6 @@ const emit = defineEmits<{ const selectedPostNames = inject>("selectedPostNames", ref([])); -const externalUrl = computed(() => { - const { status, metadata } = props.post.post; - if (metadata.labels?.[postLabels.PUBLISHED] === "true") { - return status?.permalink; - } - return `/preview/posts/${metadata.name}`; -}); - -const publishStatus = computed(() => { - const { labels } = props.post.post.metadata; - return labels?.[postLabels.PUBLISHED] === "true" - ? t("core.post.filters.status.items.published") - : t("core.post.filters.status.items.draft"); -}); - -const isPublishing = computed(() => { - const { spec, status, metadata } = props.post.post; - return ( - (spec.publish && metadata.labels?.[postLabels.PUBLISHED] !== "true") || - (spec.releaseSnapshot === spec.headSnapshot && status?.inProgress) - ); -}); - -const { mutate: changeVisibleMutation } = useMutation({ - mutationFn: async (post: Post) => { - const { data } = - await apiClient.extension.post.getcontentHaloRunV1alpha1Post({ - name: post.metadata.name, - }); - data.spec.visible = data.spec.visible === "PRIVATE" ? "PUBLIC" : "PRIVATE"; - await apiClient.extension.post.updatecontentHaloRunV1alpha1Post( - { - name: post.metadata.name, - post: data, - }, - { - mute: true, - } - ); - await queryClient.invalidateQueries({ queryKey: ["posts"] }); - }, - retry: 3, - onSuccess: () => { - Toast.success(t("core.common.toast.operation_success")); - }, - onError: () => { - Toast.error(t("core.common.toast.operation_failed")); - }, -}); - const handleDelete = async () => { Dialog.warning({ title: t("core.post.operations.delete.title"), @@ -164,6 +109,64 @@ const { operationItems } = useOperationItemExtensionPoint( }, ]) ); + +const { startFields, endFields } = useEntityFieldItemExtensionPoint( + "post:list-item:field:create", + post, + computed((): EntityFieldItem[] => [ + { + priority: 10, + position: "start", + component: markRaw(TitleField), + props: { + post: props.post, + }, + }, + { + priority: 10, + position: "end", + component: markRaw(ContributorsField), + props: { + post: props.post, + }, + }, + { + priority: 20, + position: "end", + component: markRaw(PublishStatusField), + props: { + post: props.post, + }, + }, + { + priority: 30, + position: "end", + component: markRaw(VisibleField), + props: { + post: props.post, + }, + }, + { + priority: 40, + position: "end", + component: markRaw(StatusDotField), + props: { + tooltip: t("core.common.status.deleting"), + state: "warning", + animate: true, + }, + hidden: !props.post.post.spec.deleted, + }, + { + priority: 50, + position: "end", + component: markRaw(VEntityField), + props: { + description: formatDatetime(props.post.post.spec.publishTime), + }, + }, + ]) +);