@tmagic/editor 1.3.0-alpha.12 → 1.3.0-alpha.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/style.css +41 -113
  2. package/dist/tmagic-editor.js +1346 -1195
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +1357 -1202
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +11 -11
  7. package/src/Editor.vue +0 -4
  8. package/src/components/CodeBlockEditor.vue +155 -0
  9. package/src/components/CodeParams.vue +59 -0
  10. package/src/fields/Code.vue +27 -19
  11. package/src/fields/CodeSelect.vue +7 -1
  12. package/src/fields/CodeSelectCol.vue +65 -74
  13. package/src/fields/DataSourceFields.vue +7 -9
  14. package/src/fields/DataSourceMethodSelect.vue +147 -0
  15. package/src/fields/DataSourceMethods.vue +103 -0
  16. package/src/fields/EventSelect.vue +33 -7
  17. package/src/fields/UISelect.vue +37 -6
  18. package/src/icons/CodeIcon.vue +0 -2
  19. package/src/index.ts +8 -0
  20. package/src/layouts/CodeEditor.vue +32 -1
  21. package/src/layouts/Framework.vue +7 -3
  22. package/src/layouts/sidebar/Sidebar.vue +2 -10
  23. package/src/layouts/sidebar/code-block/CodeBlockList.vue +79 -117
  24. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +64 -0
  25. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +23 -33
  26. package/src/layouts/sidebar/data-source/DataSourceList.vue +111 -0
  27. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +13 -81
  28. package/src/services/codeBlock.ts +18 -71
  29. package/src/services/dataSource.ts +2 -0
  30. package/src/theme/code-block.scss +0 -122
  31. package/src/theme/code-editor.scss +27 -2
  32. package/src/theme/data-source-methods.scss +13 -0
  33. package/src/theme/event.scss +15 -12
  34. package/src/theme/theme.scss +1 -0
  35. package/src/type.ts +21 -6
  36. package/src/utils/data-source/index.ts +11 -0
  37. package/src/utils/use-code-block-edit.ts +84 -0
  38. package/src/utils/use-data-source-method.ts +101 -0
  39. package/types/components/CodeBlockEditor.vue.d.ts +21 -0
  40. package/types/components/CodeParams.vue.d.ts +26 -0
  41. package/types/components/ContentMenu.vue.d.ts +2 -2
  42. package/types/fields/Code.vue.d.ts +26 -6
  43. package/types/fields/CodeSelectCol.vue.d.ts +16 -5
  44. package/types/fields/DataSourceFields.vue.d.ts +2 -0
  45. package/types/fields/DataSourceMethodSelect.vue.d.ts +44 -0
  46. package/types/fields/DataSourceMethods.vue.d.ts +45 -0
  47. package/types/index.d.ts +4 -0
  48. package/types/layouts/CodeEditor.vue.d.ts +2 -0
  49. package/types/layouts/PropsPanel.vue.d.ts +8 -8
  50. package/types/layouts/sidebar/Sidebar.vue.d.ts +0 -3
  51. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +4 -9
  52. package/types/layouts/sidebar/code-block/{CodeBlockEditor.vue.d.ts → CodeBlockListPanel.vue.d.ts} +5 -6
  53. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
  54. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +14 -0
  55. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -11
  56. package/types/services/codeBlock.d.ts +6 -37
  57. package/types/services/dataSource.d.ts +1 -0
  58. package/types/type.d.ts +19 -6
  59. package/types/{components/FunctionEditor.vue.d.ts → utils/use-code-block-edit.d.ts} +26 -123
  60. package/types/utils/use-data-source-method.d.ts +116 -0
  61. package/src/components/CodeDraftEditor.vue +0 -148
  62. package/src/components/FunctionEditor.vue +0 -197
  63. package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +0 -100
  64. package/types/components/CodeDraftEditor.vue.d.ts +0 -61
@@ -1,90 +1,69 @@
1
1
  <template>
2
- <TMagicScrollbar class="m-editor-code-block-list m-editor-dep-list-panel">
3
- <slot name="code-block-panel-header">
4
- <div class="search-wrapper">
5
- <SearchInput @search="filterTextChangeHandler"></SearchInput>
6
- <TMagicButton class="create-code-button" type="primary" size="small" @click="createCodeBlock" v-if="editable"
7
- >新增</TMagicButton
8
- >
9
- </div>
10
- </slot>
11
-
12
- <!-- 代码块列表 -->
13
- <TMagicTree
14
- ref="tree"
15
- class="magic-editor-layer-tree"
16
- node-key="id"
17
- empty-text="暂无代码块"
18
- :default-expanded-keys="expandedKeys"
19
- :expand-on-click-node="false"
20
- :data="codeList"
21
- :props="treeProps"
22
- :highlight-current="true"
23
- :filter-node-method="filterNode"
24
- @node-click="clickHandler"
25
- >
26
- <template #default="{ data }">
27
- <div :id="data.id" class="list-container">
28
- <div class="list-item">
29
- <CodeIcon v-if="data.type === 'code'" class="codeIcon"></CodeIcon>
30
- <AppManageIcon v-if="data.type === 'node'" class="compIcon"></AppManageIcon>
31
- <span class="name" :class="{ code: data.type === 'code', hook: data.type === 'key' }"
32
- >{{ data.name }} ({{ data.id }})</span
33
- >
34
- <!-- 右侧工具栏 -->
35
- <div class="right-tool" v-if="data.type === 'code'">
36
- <TMagicTooltip effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
37
- <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editCode(`${data.id}`)"></Icon>
38
- </TMagicTooltip>
39
- <TMagicTooltip effect="dark" content="删除" placement="bottom" v-if="editable">
40
- <Icon :icon="Close" class="edit-icon" @click.stop="deleteCode(`${data.id}`)"></Icon>
41
- </TMagicTooltip>
42
- <slot name="code-block-panel-tool" :id="data.id" :data="data.codeBlockContent"></slot>
43
- </div>
2
+ <TMagicTree
3
+ ref="tree"
4
+ class="magic-editor-layer-tree"
5
+ node-key="id"
6
+ empty-text="暂无代码块"
7
+ :default-expanded-keys="expandedKeys"
8
+ :expand-on-click-node="false"
9
+ :data="codeList"
10
+ :props="{
11
+ children: 'children',
12
+ label: 'name',
13
+ value: 'id',
14
+ }"
15
+ :highlight-current="true"
16
+ :filter-node-method="filterNode"
17
+ @node-click="clickHandler"
18
+ >
19
+ <template #default="{ data }">
20
+ <div :id="data.id" class="list-container">
21
+ <div class="list-item">
22
+ <CodeIcon v-if="data.type === 'code'" class="codeIcon"></CodeIcon>
23
+ <AppManageIcon v-if="data.type === 'node'" class="compIcon"></AppManageIcon>
24
+ <span class="name" :class="{ code: data.type === 'code', hook: data.type === 'key' }"
25
+ >{{ data.name }} ({{ data.id }})</span
26
+ >
27
+ <!-- 右侧工具栏 -->
28
+ <div class="right-tool" v-if="data.type === 'code'">
29
+ <TMagicTooltip effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
30
+ <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editCode(data.id)"></Icon>
31
+ </TMagicTooltip>
32
+ <TMagicTooltip v-if="editable" effect="dark" content="删除" placement="bottom">
33
+ <Icon :icon="Close" class="edit-icon" @click.stop="deleteCode(`${data.id}`)"></Icon>
34
+ </TMagicTooltip>
35
+ <slot name="code-block-panel-tool" :id="data.id" :data="data.codeBlockContent"></slot>
44
36
  </div>
45
37
  </div>
46
- </template>
47
- </TMagicTree>
48
-
49
- <!-- 代码块编辑区 -->
50
- <CodeBlockEditor v-if="isShowCodeBlockEditor" :paramsColConfig="paramsColConfig">
51
- <template #code-block-edit-panel-header="{ id }">
52
- <slot name="code-block-edit-panel-header" :id="id"></slot>
53
- </template>
54
- </CodeBlockEditor>
55
- </TMagicScrollbar>
38
+ </div>
39
+ </template>
40
+ </TMagicTree>
56
41
  </template>
57
42
 
58
- <script setup lang="ts">
43
+ <script lang="ts" setup>
59
44
  import { computed, inject, ref } from 'vue';
60
45
  import { Close, Edit, View } from '@element-plus/icons-vue';
61
46
 
62
- import { TMagicButton, tMagicMessage, TMagicScrollbar, TMagicTooltip, TMagicTree } from '@tmagic/design';
63
- import { ColumnConfig } from '@tmagic/form';
64
- import { CodeBlockContent, Id } from '@tmagic/schema';
47
+ import { tMagicMessage, tMagicMessageBox, TMagicTooltip, TMagicTree } from '@tmagic/design';
48
+ import type { Id } from '@tmagic/schema';
65
49
 
66
50
  import Icon from '@editor/components/Icon.vue';
67
- import SearchInput from '@editor/components/SearchInput.vue';
68
51
  import AppManageIcon from '@editor/icons/AppManageIcon.vue';
69
52
  import CodeIcon from '@editor/icons/CodeIcon.vue';
70
53
  import { CodeDeleteErrorType, CodeDslItem, Services } from '@editor/type';
71
54
 
72
- import CodeBlockEditor from './CodeBlockEditor.vue';
73
-
74
55
  defineOptions({
75
56
  name: 'MEditorCodeBlockList',
76
57
  });
77
58
 
78
59
  const props = defineProps<{
79
60
  customError?: (id: Id, errorType: CodeDeleteErrorType) => any;
80
- paramsColConfig?: ColumnConfig;
81
61
  }>();
82
62
 
83
- const treeProps = {
84
- children: 'children',
85
- label: 'name',
86
- value: 'id',
87
- };
63
+ const emit = defineEmits<{
64
+ edit: [id: string];
65
+ remove: [id: string];
66
+ }>();
88
67
 
89
68
  const { codeBlockService, depService, editorService } = inject<Services>('services') || {};
90
69
 
@@ -107,58 +86,10 @@ const codeList = computed(() =>
107
86
  };
108
87
  }),
109
88
  );
110
-
111
89
  // 默认展开组件层级的节点
112
90
  const expandedKeys = computed(() => codeList.value.map((item) => item.id));
113
-
114
91
  const editable = computed(() => codeBlockService?.getEditStatus());
115
92
 
116
- // 是否展示代码编辑区
117
- const isShowCodeBlockEditor = computed(() => codeBlockService?.getCodeEditorShowStatus() || false);
118
-
119
- // 新增代码块
120
- const createCodeBlock = async () => {
121
- if (!codeBlockService) {
122
- tMagicMessage.error('新增代码块失败');
123
- return;
124
- }
125
-
126
- const codeConfig: CodeBlockContent = {
127
- name: '代码块',
128
- content: `({app, params}) => {\n // place your code here\n}`,
129
- params: [],
130
- };
131
-
132
- const id = await codeBlockService.getUniqueId();
133
-
134
- await codeBlockService.setCodeDslById(id, codeConfig);
135
- codeBlockService.setCodeEditorContent(true, id);
136
- };
137
-
138
- // 编辑代码块
139
- const editCode = async (key: Id) => {
140
- codeBlockService?.setCodeEditorContent(true, key);
141
- };
142
-
143
- // 删除代码块
144
- const deleteCode = (key: Id) => {
145
- const currentCode = codeList.value.find((codeItem) => codeItem.id === key);
146
- const existBinds = Boolean(currentCode?.children.length);
147
- const undeleteableList = codeBlockService?.getUndeletableList() || [];
148
- if (!existBinds && !undeleteableList.includes(key)) {
149
- // 无绑定关系,且不在不可删除列表中
150
- codeBlockService?.deleteCodeDslByIds([key]);
151
- } else {
152
- if (typeof props.customError === 'function') {
153
- props.customError(key, existBinds ? CodeDeleteErrorType.BIND : CodeDeleteErrorType.UNDELETEABLE);
154
- } else {
155
- tMagicMessage.error('代码块删除失败');
156
- }
157
- }
158
- };
159
-
160
- const tree = ref<InstanceType<typeof TMagicTree>>();
161
-
162
93
  const filterNode = (value: string, data: CodeDslItem): boolean => {
163
94
  if (!value) {
164
95
  return true;
@@ -166,10 +97,6 @@ const filterNode = (value: string, data: CodeDslItem): boolean => {
166
97
  return `${data.name}${data.id}`.toLocaleLowerCase().indexOf(value.toLocaleLowerCase()) !== -1;
167
98
  };
168
99
 
169
- const filterTextChangeHandler = (val: string) => {
170
- tree.value?.filter(val);
171
- };
172
-
173
100
  // 选中组件
174
101
  const selectComp = (compId: Id) => {
175
102
  const stage = editorService?.get('stage');
@@ -184,4 +111,39 @@ const clickHandler = (data: any, node: any) => {
184
111
  selectComp(node.parent.data.id);
185
112
  }
186
113
  };
114
+
115
+ // 编辑代码块
116
+ const editCode = (id: string) => {
117
+ emit('edit', id);
118
+ };
119
+
120
+ const deleteCode = async (id: string) => {
121
+ const currentCode = codeList.value.find((codeItem) => codeItem.id === id);
122
+ const existBinds = Boolean(currentCode?.children.length);
123
+ const undeleteableList = codeBlockService?.getUndeletableList() || [];
124
+ if (!existBinds && !undeleteableList.includes(id)) {
125
+ await tMagicMessageBox.confirm('确定删除该代码块吗?', '提示', {
126
+ confirmButtonText: '确定',
127
+ cancelButtonText: '取消',
128
+ type: 'warning',
129
+ });
130
+
131
+ // 无绑定关系,且不在不可删除列表中
132
+ emit('remove', id);
133
+ } else {
134
+ if (typeof props.customError === 'function') {
135
+ props.customError(id, existBinds ? CodeDeleteErrorType.BIND : CodeDeleteErrorType.UNDELETEABLE);
136
+ } else {
137
+ tMagicMessage.error('代码块删除失败');
138
+ }
139
+ }
140
+ };
141
+
142
+ const tree = ref<InstanceType<typeof TMagicTree>>();
143
+
144
+ defineExpose({
145
+ filter(val: string) {
146
+ tree.value?.filter(val);
147
+ },
148
+ });
187
149
  </script>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <TMagicScrollbar class="m-editor-code-block-list m-editor-dep-list-panel">
3
+ <slot name="code-block-panel-header">
4
+ <div class="search-wrapper">
5
+ <SearchInput @search="filterTextChangeHandler"></SearchInput>
6
+ <TMagicButton v-if="editable" class="create-code-button" type="primary" size="small" @click="createCodeBlock"
7
+ >新增</TMagicButton
8
+ >
9
+ </div>
10
+ </slot>
11
+
12
+ <!-- 代码块列表 -->
13
+ <CodeBlockList
14
+ ref="codeBlockList"
15
+ :custom-error="customError"
16
+ @edit="editCode"
17
+ @remove="deleteCode"
18
+ ></CodeBlockList>
19
+
20
+ <!-- 代码块编辑区 -->
21
+ <CodeBlockEditor
22
+ v-if="codeConfig"
23
+ ref="codeBlockEditor"
24
+ :disabled="!editable"
25
+ :content="codeConfig"
26
+ @submit="submitCodeBlockHandler"
27
+ ></CodeBlockEditor>
28
+ </TMagicScrollbar>
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ import { computed, inject, ref } from 'vue';
33
+
34
+ import { TMagicButton, TMagicScrollbar } from '@tmagic/design';
35
+ import type { Id } from '@tmagic/schema';
36
+
37
+ import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
38
+ import SearchInput from '@editor/components/SearchInput.vue';
39
+ import type { CodeDeleteErrorType, Services } from '@editor/type';
40
+ import { useCodeBlockEdit } from '@editor/utils/use-code-block-edit';
41
+
42
+ import CodeBlockList from './CodeBlockList.vue';
43
+
44
+ defineOptions({
45
+ name: 'MEditorCodeBlockListPanel',
46
+ });
47
+
48
+ defineProps<{
49
+ customError?: (id: Id, errorType: CodeDeleteErrorType) => any;
50
+ }>();
51
+
52
+ const { codeBlockService } = inject<Services>('services') || {};
53
+
54
+ const editable = computed(() => codeBlockService?.getEditStatus());
55
+
56
+ const { codeBlockEditor, codeConfig, editCode, deleteCode, createCodeBlock, submitCodeBlockHandler } =
57
+ useCodeBlockEdit(codeBlockService);
58
+
59
+ const codeBlockList = ref<InstanceType<typeof CodeBlockList>>();
60
+
61
+ const filterTextChangeHandler = (val: string) => {
62
+ codeBlockList.value?.filter(val);
63
+ };
64
+ </script>
@@ -1,29 +1,23 @@
1
1
  <template>
2
- <TMagicDrawer
3
- v-model="visible"
2
+ <MFormDrawer
3
+ ref="fomDrawer"
4
+ label-width="80px"
4
5
  :title="title"
5
- :close-on-press-escape="true"
6
- :append-to-body="true"
7
- :show-close="true"
8
- :close-on-click-modal="true"
9
- :size="size"
10
- >
11
- <MForm ref="form" :config="dataSourceConfig" :init-values="initValues" @change="changeHandler"></MForm>
12
-
13
- <template #footer>
14
- <div>
15
- <TMagicButton type="primary" @click="submitHandler">确定</TMagicButton>
16
- <TMagicButton @click="hide">关闭</TMagicButton>
17
- </div>
18
- </template>
19
- </TMagicDrawer>
6
+ :width="size"
7
+ :config="dataSourceConfig"
8
+ :values="initValues"
9
+ :disabled="disabled"
10
+ @change="changeHandler"
11
+ @submit="submitHandler"
12
+ @error="errorHandler"
13
+ ></MFormDrawer>
20
14
  </template>
21
15
 
22
16
  <script setup lang="ts">
23
17
  import { computed, inject, ref, watchEffect } from 'vue';
24
18
 
25
- import { TMagicButton, TMagicDrawer, tMagicMessage } from '@tmagic/design';
26
- import { MForm } from '@tmagic/form';
19
+ import { tMagicMessage } from '@tmagic/design';
20
+ import { MFormDrawer } from '@tmagic/form';
27
21
 
28
22
  import type { Services } from '@editor/type';
29
23
 
@@ -34,6 +28,7 @@ defineOptions({
34
28
  const props = defineProps<{
35
29
  title?: string;
36
30
  values: any;
31
+ disabled: boolean;
37
32
  }>();
38
33
 
39
34
  const type = ref('base');
@@ -46,7 +41,7 @@ const size = computed(() => globalThis.document.body.clientWidth - (services?.ui
46
41
 
47
42
  const dataSourceConfig = computed(() => services?.dataSourceService.getFormConfig(type.value) || []);
48
43
 
49
- const form = ref<InstanceType<typeof MForm>>();
44
+ const fomDrawer = ref<InstanceType<typeof MFormDrawer>>();
50
45
 
51
46
  const initValues = ref({});
52
47
 
@@ -63,26 +58,21 @@ const changeHandler = (value: Record<string, any>) => {
63
58
  initValues.value = value;
64
59
  };
65
60
 
66
- const submitHandler = async () => {
67
- try {
68
- const values = await form.value?.submitForm();
69
- emit('submit', values);
70
- } catch (error: any) {
71
- tMagicMessage.error(error.message);
72
- }
61
+ const submitHandler = (values: any) => {
62
+ emit('submit', values);
73
63
  };
74
64
 
75
- const visible = ref(false);
76
-
77
- const hide = () => {
78
- visible.value = false;
65
+ const errorHandler = (error: any) => {
66
+ tMagicMessage.error(error.message);
79
67
  };
80
68
 
81
69
  defineExpose({
82
70
  show() {
83
- visible.value = true;
71
+ fomDrawer.value?.show();
84
72
  },
85
73
 
86
- hide,
74
+ hide() {
75
+ fomDrawer.value?.hide();
76
+ },
87
77
  });
88
78
  </script>
@@ -0,0 +1,111 @@
1
+ <template>
2
+ <TMagicTree
3
+ ref="tree"
4
+ class="magic-editor-layer-tree"
5
+ node-key="id"
6
+ empty-text="暂无代码块"
7
+ default-expand-all
8
+ :expand-on-click-node="false"
9
+ :data="list"
10
+ :highlight-current="true"
11
+ @node-click="clickHandler"
12
+ >
13
+ <template #default="{ data }">
14
+ <div :id="data.id" class="list-container">
15
+ <div class="list-item">
16
+ <Icon v-if="data.type === 'code'" class="codeIcon" :icon="Coin"></Icon>
17
+ <Icon v-if="data.type === 'node'" class="compIcon" :icon="Aim"></Icon>
18
+ <span class="name" :class="{ code: data.type === 'code', hook: data.type === 'key' }"
19
+ >{{ data.name }}({{ data.id }})</span
20
+ >
21
+ <!-- 右侧工具栏 -->
22
+ <div class="right-tool" v-if="data.type === 'code'">
23
+ <TMagicTooltip effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
24
+ <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editHandler(`${data.id}`)"></Icon>
25
+ </TMagicTooltip>
26
+ <TMagicTooltip v-if="editable" effect="dark" content="删除" placement="bottom">
27
+ <Icon :icon="Close" class="edit-icon" @click.stop="removeHandler(`${data.id}`)"></Icon>
28
+ </TMagicTooltip>
29
+ <slot name="data-source-panel-tool" :id="data.id" :data="data.codeBlockContent"></slot>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ </template>
34
+ </TMagicTree>
35
+ </template>
36
+
37
+ <script lang="ts" setup>
38
+ import { computed, inject, ref } from 'vue';
39
+ import { Aim, Close, Coin, Edit, View } from '@element-plus/icons-vue';
40
+
41
+ import { tMagicMessageBox, TMagicTooltip, TMagicTree } from '@tmagic/design';
42
+ import { Id } from '@tmagic/schema';
43
+
44
+ import Icon from '@editor/components/Icon.vue';
45
+ import type { Services } from '@editor/type';
46
+
47
+ defineOptions({
48
+ name: 'MEditorDataSourceList',
49
+ });
50
+
51
+ const emit = defineEmits<{
52
+ edit: [id: string];
53
+ remove: [id: string];
54
+ }>();
55
+
56
+ const { depService, editorService, dataSourceService } = inject<Services>('services') || {};
57
+
58
+ const editable = computed(() => dataSourceService?.get('editable') ?? true);
59
+
60
+ const list = computed(() =>
61
+ Object.values(depService?.targets['data-source'] || {}).map((target) => ({
62
+ id: target.id,
63
+ name: target.name,
64
+ type: 'code',
65
+ children: Object.entries(target.deps).map(([id, dep]) => ({
66
+ name: dep.name,
67
+ type: 'node',
68
+ id,
69
+ children: dep.keys.map((key) => ({ name: key, id: key, type: 'key' })),
70
+ })),
71
+ })),
72
+ );
73
+
74
+ const editHandler = (id: string) => {
75
+ emit('edit', id);
76
+ };
77
+
78
+ const removeHandler = async (id: string) => {
79
+ await tMagicMessageBox.confirm('确定删除?', '提示', {
80
+ confirmButtonText: '确定',
81
+ cancelButtonText: '取消',
82
+ type: 'warning',
83
+ });
84
+
85
+ emit('remove', id);
86
+ };
87
+
88
+ // 选中组件
89
+ const selectComp = (compId: Id) => {
90
+ const stage = editorService?.get('stage');
91
+ editorService?.select(compId);
92
+ stage?.select(compId);
93
+ };
94
+
95
+ const clickHandler = (data: any, node: any) => {
96
+ if (data.type === 'node') {
97
+ selectComp(data.id);
98
+ } else if (data.type === 'key') {
99
+ selectComp(node.parent.data.id);
100
+ }
101
+ };
102
+
103
+ const tree = ref<InstanceType<typeof TMagicTree>>();
104
+
105
+ defineExpose({
106
+ filter(val: string) {
107
+ debugger;
108
+ tree.value?.filter(val);
109
+ },
110
+ });
111
+ </script>
@@ -2,46 +2,15 @@
2
2
  <TMagicScrollbar class="data-source-list-panel m-editor-dep-list-panel">
3
3
  <div class="search-wrapper">
4
4
  <SearchInput @search="filterTextChangeHandler"></SearchInput>
5
- <TMagicButton type="primary" size="small" @click="addHandler">新增</TMagicButton>
5
+ <TMagicButton v-if="editable" type="primary" size="small" @click="addHandler">新增</TMagicButton>
6
6
  </div>
7
7
 
8
8
  <!-- 数据源列表 -->
9
- <TMagicTree
10
- ref="tree"
11
- class="magic-editor-layer-tree"
12
- node-key="id"
13
- empty-text="暂无代码块"
14
- default-expand-all
15
- :expand-on-click-node="false"
16
- :data="list"
17
- :highlight-current="true"
18
- @node-click="clickHandler"
19
- >
20
- <template #default="{ data }">
21
- <div :id="data.id" class="list-container">
22
- <div class="list-item">
23
- <Icon v-if="data.type === 'code'" class="codeIcon" :icon="Coin"></Icon>
24
- <Icon v-if="data.type === 'node'" class="compIcon" :icon="Aim"></Icon>
25
- <span class="name" :class="{ code: data.type === 'code', hook: data.type === 'key' }"
26
- >{{ data.name }}({{ data.id }})</span
27
- >
28
- <!-- 右侧工具栏 -->
29
- <div class="right-tool" v-if="data.type === 'code'">
30
- <TMagicTooltip effect="dark" content="编辑" placement="bottom">
31
- <Icon class="edit-icon" :icon="Edit" @click.stop="editHandler(`${data.id}`)"></Icon>
32
- </TMagicTooltip>
33
- <TMagicTooltip effect="dark" content="删除" placement="bottom">
34
- <Icon :icon="Close" class="edit-icon" @click.stop="removeHandler(`${data.id}`)"></Icon>
35
- </TMagicTooltip>
36
- <slot name="data-source-panel-tool" :id="data.id" :data="data.codeBlockContent"></slot>
37
- </div>
38
- </div>
39
- </div>
40
- </template>
41
- </TMagicTree>
9
+ <DataSourceList @edit="editHandler" @remove="removeHandler"></DataSourceList>
42
10
 
43
11
  <DataSourceConfigPanel
44
12
  ref="editDialog"
13
+ :disabled="!editable"
45
14
  :values="dataSourceValues"
46
15
  :title="typeof dataSourceValues.id !== 'undefined' ? `编辑${dataSourceValues.title}` : '新增'"
47
16
  @submit="submitDataSourceHandler"
@@ -51,42 +20,28 @@
51
20
 
52
21
  <script setup lang="ts" name="MEditorDataSourceListPanel">
53
22
  import { computed, inject, ref } from 'vue';
54
- import { Aim, Close, Coin, Edit } from '@element-plus/icons-vue';
55
23
 
56
- import { TMagicButton, tMagicMessageBox, TMagicScrollbar, TMagicTooltip, TMagicTree } from '@tmagic/design';
57
- import { DataSourceSchema, Id } from '@tmagic/schema';
24
+ import { TMagicButton, TMagicScrollbar } from '@tmagic/design';
25
+ import type { DataSourceSchema } from '@tmagic/schema';
58
26
 
59
- import Icon from '@editor/components/Icon.vue';
60
27
  import SearchInput from '@editor/components/SearchInput.vue';
61
28
  import type { Services } from '@editor/type';
62
29
 
63
30
  import DataSourceConfigPanel from './DataSourceConfigPanel.vue';
31
+ import DataSourceList from './DataSourceList.vue';
64
32
 
65
33
  defineOptions({
66
34
  name: 'MEditorDataSourceListPanel',
67
35
  });
68
36
 
69
- const services = inject<Partial<Services>>('services', {});
70
- const { dataSourceService, depService, editorService } = inject<Services>('services') || {};
71
-
72
- const list = computed(() =>
73
- Object.values(depService?.targets['data-source'] || {}).map((target) => ({
74
- id: target.id,
75
- name: target.name,
76
- type: 'code',
77
- children: Object.entries(target.deps).map(([id, dep]) => ({
78
- name: dep.name,
79
- type: 'node',
80
- id,
81
- children: dep.keys.map((key) => ({ name: key, id: key, type: 'key' })),
82
- })),
83
- })),
84
- );
37
+ const { dataSourceService } = inject<Services>('services') || {};
85
38
 
86
39
  const editDialog = ref<InstanceType<typeof DataSourceConfigPanel>>();
87
40
 
88
41
  const dataSourceValues = ref<Record<string, any>>({});
89
42
 
43
+ const editable = computed(() => dataSourceService?.get('editable') ?? true);
44
+
90
45
  const addHandler = () => {
91
46
  if (!editDialog.value) return;
92
47
 
@@ -96,7 +51,7 @@ const addHandler = () => {
96
51
  };
97
52
 
98
53
  const editHandler = (id: string) => {
99
- if (!editDialog.value || !services) return;
54
+ if (!editDialog.value) return;
100
55
 
101
56
  dataSourceValues.value = {
102
57
  ...dataSourceService?.getDataSourceById(id),
@@ -105,19 +60,11 @@ const editHandler = (id: string) => {
105
60
  editDialog.value.show();
106
61
  };
107
62
 
108
- const removeHandler = async (id: string) => {
109
- await tMagicMessageBox.confirm('确定删除?', '提示', {
110
- confirmButtonText: '确定',
111
- cancelButtonText: '取消',
112
- type: 'warning',
113
- });
114
-
63
+ const removeHandler = (id: string) => {
115
64
  dataSourceService?.remove(id);
116
65
  };
117
66
 
118
67
  const submitDataSourceHandler = (value: DataSourceSchema) => {
119
- if (!services) return;
120
-
121
68
  if (value.id) {
122
69
  dataSourceService?.update(value);
123
70
  } else {
@@ -127,24 +74,9 @@ const submitDataSourceHandler = (value: DataSourceSchema) => {
127
74
  editDialog.value?.hide();
128
75
  };
129
76
 
130
- const tree = ref<InstanceType<typeof TMagicTree>>();
77
+ const dataSourceList = ref<InstanceType<typeof DataSourceList>>();
131
78
 
132
79
  const filterTextChangeHandler = (val: string) => {
133
- tree.value?.filter(val);
134
- };
135
-
136
- // 选中组件
137
- const selectComp = (compId: Id) => {
138
- const stage = editorService?.get('stage');
139
- editorService?.select(compId);
140
- stage?.select(compId);
141
- };
142
-
143
- const clickHandler = (data: any, node: any) => {
144
- if (data.type === 'node') {
145
- selectComp(data.id);
146
- } else if (data.type === 'key') {
147
- selectComp(node.parent.data.id);
148
- }
80
+ dataSourceList.value?.filter(val);
149
81
  };
150
82
  </script>