();
@@ -59,6 +60,7 @@ defineProps<{
const emit = defineEmits<{
edit: [id: string];
remove: [id: string];
+ 'node-contextmenu': [event: MouseEvent, data: TreeNodeData];
}>();
const { depService, editorService, dataSourceService } = inject('services') || {};
@@ -159,12 +161,6 @@ const editHandler = (id: string) => {
};
const removeHandler = async (id: string) => {
- await tMagicMessageBox.confirm('确定删除?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- });
-
emit('remove', id);
};
@@ -181,6 +177,10 @@ const clickHandler = (event: MouseEvent, data: any) => {
}
};
+const nodeContentMenuHandler = (event: MouseEvent, data: TreeNodeData) => {
+ emit('node-contextmenu', event, data);
+};
+
defineExpose({
filter: filterTextChangeHandler,
});
diff --git a/packages/editor/src/layouts/sidebar/data-source/DataSourceListPanel.vue b/packages/editor/src/layouts/sidebar/data-source/DataSourceListPanel.vue
index 508c74f2..ba51578b 100644
--- a/packages/editor/src/layouts/sidebar/data-source/DataSourceListPanel.vue
+++ b/packages/editor/src/layouts/sidebar/data-source/DataSourceListPanel.vue
@@ -35,6 +35,7 @@
:next-level-indent-increment="nextLevelIndentIncrement"
@edit="editHandler"
@remove="removeHandler"
+ @node-contextmenu="nodeContentMenuHandler"
>
@@ -45,21 +46,40 @@
:title="dialogTitle"
@submit="submitDataSourceHandler"
>
+
+
+
+
diff --git a/packages/editor/src/layouts/sidebar/data-source/useContentMenu.ts b/packages/editor/src/layouts/sidebar/data-source/useContentMenu.ts
new file mode 100644
index 00000000..3d2c1f7a
--- /dev/null
+++ b/packages/editor/src/layouts/sidebar/data-source/useContentMenu.ts
@@ -0,0 +1,81 @@
+import { inject, markRaw, useTemplateRef } from 'vue';
+import { CopyDocument, Delete, Edit } from '@element-plus/icons-vue';
+import { cloneDeep } from 'lodash-es';
+
+import ContentMenu from '@editor/components/ContentMenu.vue';
+import type { EventBus, MenuButton, MenuComponent, Services, TreeNodeData } from '@editor/type';
+
+export const useContentMenu = () => {
+ const eventBus = inject('eventBus');
+ const menuRef = useTemplateRef>('menu');
+
+ let selectId = '';
+
+ const menuData: (MenuButton | MenuComponent)[] = [
+ {
+ type: 'button',
+ text: '编辑',
+ icon: Edit,
+ display: (services) => services?.dataSourceService?.get('editable') ?? true,
+ handler: () => {
+ if (!selectId) {
+ return;
+ }
+
+ eventBus?.emit('edit-data-source', selectId);
+ },
+ },
+ {
+ type: 'button',
+ text: '复制并粘贴至当前',
+ icon: markRaw(CopyDocument),
+ handler: ({ dataSourceService }: Services) => {
+ if (!selectId) {
+ return;
+ }
+
+ const ds = dataSourceService.getDataSourceById(selectId);
+ if (!ds) {
+ return;
+ }
+
+ dataSourceService.add(cloneDeep(ds));
+ },
+ },
+ {
+ type: 'button',
+ text: '删除',
+ icon: Delete,
+ handler: () => {
+ if (!selectId) {
+ return;
+ }
+
+ eventBus?.emit('remove-data-source', selectId);
+ },
+ },
+ ];
+
+ const nodeContentMenuHandler = (event: MouseEvent, data: TreeNodeData) => {
+ event.preventDefault();
+
+ if (data.type === 'ds') {
+ menuRef.value?.show(event);
+ if (data.id) {
+ selectId = `${data.id}`;
+ } else {
+ selectId = '';
+ }
+ }
+ };
+
+ const contentMenuHideHandler = () => {
+ selectId = '';
+ };
+
+ return {
+ menuData,
+ nodeContentMenuHandler,
+ contentMenuHideHandler,
+ };
+};
diff --git a/packages/editor/src/layouts/sidebar/layer/LayerMenu.vue b/packages/editor/src/layouts/sidebar/layer/LayerMenu.vue
index 71f37746..afb9b9b8 100644
--- a/packages/editor/src/layouts/sidebar/layer/LayerMenu.vue
+++ b/packages/editor/src/layouts/sidebar/layer/LayerMenu.vue
@@ -10,23 +10,17 @@ import { isPage, isPageFragment } from '@tmagic/utils';
import ContentMenu from '@editor/components/ContentMenu.vue';
import FolderMinusIcon from '@editor/icons/FolderMinusIcon.vue';
-import type { ComponentGroup, MenuButton, MenuComponent, Services } from '@editor/type';
+import type { ComponentGroup, CustomContentMenuFunction, MenuButton, MenuComponent, Services } from '@editor/type';
import { useCopyMenu, useDeleteMenu, useMoveToMenu, usePasteMenu } from '@editor/utils/content-menu';
defineOptions({
name: 'MEditorLayerMenu',
});
-const props = withDefaults(
- defineProps<{
- layerContentMenu: (MenuButton | MenuComponent)[];
- customContentMenu?: (menus: (MenuButton | MenuComponent)[], type: string) => (MenuButton | MenuComponent)[];
- }>(),
- {
- layerContentMenu: () => [],
- customContentMenu: (menus: (MenuButton | MenuComponent)[]) => menus,
- },
-);
+const props = defineProps<{
+ layerContentMenu: (MenuButton | MenuComponent)[];
+ customContentMenu: CustomContentMenuFunction;
+}>();
const emit = defineEmits<{
'collapse-all': [];
diff --git a/packages/editor/src/layouts/sidebar/layer/LayerPanel.vue b/packages/editor/src/layouts/sidebar/layer/LayerPanel.vue
index c9533210..74ece688 100644
--- a/packages/editor/src/layouts/sidebar/layer/LayerPanel.vue
+++ b/packages/editor/src/layouts/sidebar/layer/LayerPanel.vue
@@ -55,7 +55,14 @@ import { TMagicScrollbar } from '@tmagic/design';
import SearchInput from '@editor/components/SearchInput.vue';
import Tree from '@editor/components/Tree.vue';
import { useFilter } from '@editor/hooks/use-filter';
-import type { LayerPanelSlots, MenuButton, MenuComponent, Services, TreeNodeData } from '@editor/type';
+import type {
+ CustomContentMenuFunction,
+ LayerPanelSlots,
+ MenuButton,
+ MenuComponent,
+ Services,
+ TreeNodeData,
+} from '@editor/type';
import LayerMenu from './LayerMenu.vue';
import LayerNodeTool from './LayerNodeTool.vue';
@@ -74,7 +81,7 @@ defineProps<{
layerContentMenu: (MenuButton | MenuComponent)[];
indent?: number;
nextLevelIndentIncrement?: number;
- customContentMenu?: (menus: (MenuButton | MenuComponent)[], type: string) => (MenuButton | MenuComponent)[];
+ customContentMenu: CustomContentMenuFunction;
}>();
const services = inject('services');
diff --git a/packages/editor/src/layouts/workspace/Workspace.vue b/packages/editor/src/layouts/workspace/Workspace.vue
index 3d75d5a5..06d815e8 100644
--- a/packages/editor/src/layouts/workspace/Workspace.vue
+++ b/packages/editor/src/layouts/workspace/Workspace.vue
@@ -19,7 +19,14 @@