mirror of https://github.com/halo-dev/halo
feat: add entity param for list item operation extension point (#4515)
#### What type of PR is this? /area console /kind feature /milestone 2.9.x #### What this PR does / why we need it: Halo 在 https://github.com/halo-dev/halo/pull/4452 中为数据列表的操作选项添加了拓展点,用于通过插件扩展操作选项。但忽略了操作选项的组件需要自定义并且自行处理点击事件,这个时候组件应该比较难拿到数据列表项的数据。 此 PR 对此进行优化,在扩展点方法传入了需要的数据。 #### Does this PR introduce a user-facing change? ```release-note None ```pull/4523/head
parent
9c875e1731
commit
329b389d60
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
目前支持扩展的数据列表:
|
目前支持扩展的数据列表:
|
||||||
|
|
||||||
- 文章:`"post:list-item:operation:create"?: () => | EntityDropdownItem<ListedPost>[] | Promise<EntityDropdownItem<ListedPost>[]>`
|
- 文章:`"post:list-item:operation:create"?: (post: Ref<ListedPost>) => | EntityDropdownItem<ListedPost>[] | Promise<EntityDropdownItem<ListedPost>[]>`
|
||||||
- 插件:`"plugin:list-item:operation:create"?: () => | EntityDropdownItem<Plugin>[] | Promise<EntityDropdownItem<Plugin>[]>`
|
- 插件:`"plugin:list-item:operation:create"?: (plugin: Ref<Plugin>) => | EntityDropdownItem<Plugin>[] | Promise<EntityDropdownItem<Plugin>[]>`
|
||||||
- 备份:`"backup:list-item:operation:create"?: () => | EntityDropdownItem<Backup>[] | Promise<EntityDropdownItem<Backup>[]>`
|
- 备份:`"backup:list-item:operation:create"?: (backup: Ref<Backup>) => | EntityDropdownItem<Backup>[] | Promise<EntityDropdownItem<Backup>[]>`
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
|
|
||||||
|
|
|
@ -40,17 +40,19 @@ export interface ExtensionPoint {
|
||||||
| PluginInstallationTab[]
|
| PluginInstallationTab[]
|
||||||
| Promise<PluginInstallationTab[]>;
|
| Promise<PluginInstallationTab[]>;
|
||||||
|
|
||||||
"post:list-item:operation:create"?: () =>
|
"post:list-item:operation:create"?: (
|
||||||
|
post: Ref<ListedPost>
|
||||||
|
) =>
|
||||||
| EntityDropdownItem<ListedPost>[]
|
| EntityDropdownItem<ListedPost>[]
|
||||||
| Promise<EntityDropdownItem<ListedPost>[]>;
|
| Promise<EntityDropdownItem<ListedPost>[]>;
|
||||||
|
|
||||||
"plugin:list-item:operation:create"?: () =>
|
"plugin:list-item:operation:create"?: (
|
||||||
| EntityDropdownItem<Plugin>[]
|
plugin: Ref<Plugin>
|
||||||
| Promise<EntityDropdownItem<Plugin>[]>;
|
) => EntityDropdownItem<Plugin>[] | Promise<EntityDropdownItem<Plugin>[]>;
|
||||||
|
|
||||||
"backup:list-item:operation:create"?: () =>
|
"backup:list-item:operation:create"?: (
|
||||||
| EntityDropdownItem<Backup>[]
|
backup: Ref<Backup>
|
||||||
| Promise<EntityDropdownItem<Backup>[]>;
|
) => EntityDropdownItem<Backup>[] | Promise<EntityDropdownItem<Backup>[]>;
|
||||||
|
|
||||||
"plugin:list-item:field:create"?: (
|
"plugin:list-item:field:create"?: (
|
||||||
plugin: Ref<Plugin>
|
plugin: Ref<Plugin>
|
||||||
|
|
|
@ -5,15 +5,16 @@ import type {
|
||||||
EntityFieldItem,
|
EntityFieldItem,
|
||||||
PluginModule,
|
PluginModule,
|
||||||
} from "@halo-dev/console-shared";
|
} from "@halo-dev/console-shared";
|
||||||
import { onMounted, ref, type Ref, computed, type ComputedRef } from "vue";
|
import { onMounted, ref, type ComputedRef, type Ref, computed } from "vue";
|
||||||
|
|
||||||
export function useEntityDropdownItemExtensionPoint<T>(
|
export function useEntityDropdownItemExtensionPoint<T>(
|
||||||
extensionPointName: string,
|
extensionPointName: string,
|
||||||
presets: EntityDropdownItem<T>[]
|
entity: Ref<T>,
|
||||||
|
presets: ComputedRef<EntityDropdownItem<T>[]>
|
||||||
) {
|
) {
|
||||||
const { pluginModules } = usePluginModuleStore();
|
const { pluginModules } = usePluginModuleStore();
|
||||||
|
|
||||||
const dropdownItems = ref<EntityDropdownItem<T>[]>(presets);
|
const itemsFromPlugins = ref<EntityDropdownItem<T>[]>([]);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
pluginModules.forEach((pluginModule: PluginModule) => {
|
pluginModules.forEach((pluginModule: PluginModule) => {
|
||||||
|
@ -22,14 +23,16 @@ export function useEntityDropdownItemExtensionPoint<T>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const items = extensionPoints[
|
const items = extensionPoints[extensionPointName](
|
||||||
extensionPointName
|
entity
|
||||||
]() as EntityDropdownItem<T>[];
|
) as EntityDropdownItem<T>[];
|
||||||
|
|
||||||
dropdownItems.value.push(...items);
|
itemsFromPlugins.value.push(...items);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
dropdownItems.value.sort((a, b) => {
|
const dropdownItems = computed(() => {
|
||||||
|
return [...presets.value, ...itemsFromPlugins.value].sort((a, b) => {
|
||||||
return a.priority - b.priority;
|
return a.priority - b.priority;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,6 +29,7 @@ import { markRaw } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { useEntityDropdownItemExtensionPoint } from "@/composables/use-entity-extension-points";
|
import { useEntityDropdownItemExtensionPoint } from "@/composables/use-entity-extension-points";
|
||||||
import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue";
|
import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue";
|
||||||
|
import { toRefs } from "vue";
|
||||||
|
|
||||||
const { currentUserHasPermission } = usePermission();
|
const { currentUserHasPermission } = usePermission();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -45,6 +46,8 @@ const props = withDefaults(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { post } = toRefs(props);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "open-setting-modal", post: Post): void;
|
(event: "open-setting-modal", post: Post): void;
|
||||||
}>();
|
}>();
|
||||||
|
@ -121,7 +124,8 @@ const handleDelete = async () => {
|
||||||
|
|
||||||
const { dropdownItems } = useEntityDropdownItemExtensionPoint<ListedPost>(
|
const { dropdownItems } = useEntityDropdownItemExtensionPoint<ListedPost>(
|
||||||
"post:list-item:operation:create",
|
"post:list-item:operation:create",
|
||||||
[
|
post,
|
||||||
|
computed(() => [
|
||||||
{
|
{
|
||||||
priority: 10,
|
priority: 10,
|
||||||
component: markRaw(VDropdownItem),
|
component: markRaw(VDropdownItem),
|
||||||
|
@ -161,7 +165,7 @@ const { dropdownItems } = useEntityDropdownItemExtensionPoint<ListedPost>(
|
||||||
permissions: [],
|
permissions: [],
|
||||||
action: handleDelete,
|
action: handleDelete,
|
||||||
},
|
},
|
||||||
]
|
])
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import prettyBytes from "pretty-bytes";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useEntityDropdownItemExtensionPoint } from "@/composables/use-entity-extension-points";
|
import { useEntityDropdownItemExtensionPoint } from "@/composables/use-entity-extension-points";
|
||||||
import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue";
|
import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue";
|
||||||
|
import { toRefs } from "vue";
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -25,6 +26,8 @@ const props = defineProps<{
|
||||||
backup: Backup;
|
backup: Backup;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const { backup } = toRefs(props);
|
||||||
|
|
||||||
type Phase = {
|
type Phase = {
|
||||||
text: string;
|
text: string;
|
||||||
state: "default" | "warning" | "success" | "error";
|
state: "default" | "warning" | "success" | "error";
|
||||||
|
@ -99,7 +102,8 @@ function handleDelete() {
|
||||||
|
|
||||||
const { dropdownItems } = useEntityDropdownItemExtensionPoint<Backup>(
|
const { dropdownItems } = useEntityDropdownItemExtensionPoint<Backup>(
|
||||||
"backup:list-item:operation:create",
|
"backup:list-item:operation:create",
|
||||||
[
|
backup,
|
||||||
|
computed(() => [
|
||||||
{
|
{
|
||||||
priority: 10,
|
priority: 10,
|
||||||
component: markRaw(VDropdownItem),
|
component: markRaw(VDropdownItem),
|
||||||
|
@ -118,7 +122,7 @@ const { dropdownItems } = useEntityDropdownItemExtensionPoint<Backup>(
|
||||||
visible: true,
|
visible: true,
|
||||||
action: () => handleDelete(),
|
action: () => handleDelete(),
|
||||||
},
|
},
|
||||||
]
|
])
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,8 @@ const handleResetSettingConfig = async () => {
|
||||||
|
|
||||||
const { dropdownItems } = useEntityDropdownItemExtensionPoint<Plugin>(
|
const { dropdownItems } = useEntityDropdownItemExtensionPoint<Plugin>(
|
||||||
"plugin:list-item:operation:create",
|
"plugin:list-item:operation:create",
|
||||||
[
|
plugin,
|
||||||
|
computed(() => [
|
||||||
{
|
{
|
||||||
priority: 10,
|
priority: 10,
|
||||||
component: markRaw(VDropdownItem),
|
component: markRaw(VDropdownItem),
|
||||||
|
@ -150,7 +151,7 @@ const { dropdownItems } = useEntityDropdownItemExtensionPoint<Plugin>(
|
||||||
handleResetSettingConfig();
|
handleResetSettingConfig();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
const { startFields, endFields } = useEntityFieldItemExtensionPoint<Plugin>(
|
const { startFields, endFields } = useEntityFieldItemExtensionPoint<Plugin>(
|
||||||
|
|
Loading…
Reference in New Issue