@tmagic/editor 1.3.0-beta.1 → 1.3.0-beta.3
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.
- package/dist/style.css +67 -75
- package/dist/tmagic-editor.js +1667 -1062
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +1692 -1084
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +10 -10
- package/src/Editor.vue +70 -65
- package/src/components/ContentMenu.vue +5 -1
- package/src/components/SearchInput.vue +5 -1
- package/src/components/ToolButton.vue +1 -1
- package/src/editorProps.ts +51 -129
- package/src/fields/Code.vue +9 -3
- package/src/fields/DataSourceFieldSelect.vue +28 -16
- package/src/fields/DataSourceFields.vue +95 -7
- package/src/fields/DataSourceMethodSelect.vue +23 -14
- package/src/fields/DataSourceMocks.vue +237 -0
- package/src/fields/EventSelect.vue +30 -11
- package/src/index.ts +4 -1
- package/src/initService.ts +50 -20
- package/src/layouts/CodeEditor.vue +20 -4
- package/src/layouts/Framework.vue +3 -1
- package/src/layouts/PropsPanel.vue +3 -1
- package/src/layouts/sidebar/ComponentListPanel.vue +18 -8
- package/src/layouts/sidebar/Sidebar.vue +7 -10
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +3 -1
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +3 -1
- package/src/layouts/sidebar/layer/LayerNode.vue +206 -0
- package/src/layouts/sidebar/layer/LayerNodeTool.vue +32 -0
- package/src/layouts/sidebar/layer/LayerPanel.vue +85 -0
- package/src/layouts/sidebar/layer/use-drag.ts +157 -0
- package/src/layouts/sidebar/layer/use-filter.ts +70 -0
- package/src/layouts/sidebar/layer/use-keybinding.ts +47 -0
- package/src/layouts/sidebar/layer/use-node-status.ts +103 -0
- package/src/layouts/workspace/Workspace.vue +3 -1
- package/src/layouts/workspace/viewer/NodeListMenu.vue +16 -9
- package/src/layouts/workspace/viewer/Stage.vue +19 -17
- package/src/layouts/workspace/viewer/ViewerMenu.vue +1 -1
- package/src/services/dataSource.ts +21 -0
- package/src/services/editor.ts +45 -5
- package/src/theme/common/var.scss +2 -2
- package/src/theme/content-menu.scss +22 -20
- package/src/theme/framework.scss +2 -0
- package/src/theme/layer-panel.scss +63 -63
- package/src/theme/props-panel.scss +8 -0
- package/src/theme/sidebar.scss +1 -5
- package/src/type.ts +61 -0
- package/src/utils/data-source/index.ts +23 -0
- package/src/utils/dep.ts +26 -11
- package/src/utils/editor.ts +14 -3
- package/src/utils/props.ts +4 -0
- package/types/editorProps.d.ts +61 -107
- package/types/fields/Code.vue.d.ts +10 -6
- package/types/fields/DataSourceMocks.vue.d.ts +32 -0
- package/types/index.d.ts +2 -1
- package/types/initService.d.ts +5 -4
- package/types/layouts/CodeEditor.vue.d.ts +5 -0
- package/types/layouts/Framework.vue.d.ts +2 -12
- package/types/layouts/PropsPanel.vue.d.ts +2 -3
- package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +2 -7
- package/types/layouts/sidebar/Sidebar.vue.d.ts +2 -17
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +2 -7
- package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +2 -9
- package/types/layouts/sidebar/{LayerMenu.vue.d.ts → layer/LayerMenu.vue.d.ts} +1 -1
- package/types/layouts/sidebar/layer/LayerNode.vue.d.ts +50 -0
- package/types/layouts/sidebar/{LayerNode.vue.d.ts → layer/LayerNodeTool.vue.d.ts} +1 -1
- package/types/layouts/sidebar/{LayerPanel.vue.d.ts → layer/LayerPanel.vue.d.ts} +2 -8
- package/types/layouts/sidebar/layer/use-drag.d.ts +14 -0
- package/types/layouts/sidebar/layer/use-filter.d.ts +8 -0
- package/types/layouts/sidebar/layer/use-keybinding.d.ts +4 -0
- package/types/layouts/sidebar/layer/use-node-status.d.ts +7 -0
- package/types/layouts/workspace/Workspace.vue.d.ts +2 -11
- package/types/layouts/workspace/viewer/Stage.vue.d.ts +1 -1
- package/types/services/dataSource.d.ts +7 -0
- package/types/services/editor.d.ts +1 -0
- package/types/type.d.ts +61 -0
- package/types/utils/dep.d.ts +1 -1
- package/types/utils/editor.d.ts +3 -2
- package/src/layouts/sidebar/LayerNode.vue +0 -40
- package/src/layouts/sidebar/LayerPanel.vue +0 -369
- package/types/Editor.vue.d.ts +0 -233
- /package/src/layouts/sidebar/{LayerMenu.vue → layer/LayerMenu.vue} +0 -0
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
<MagicTable :data="model[name]" :columns="fieldColumns"></MagicTable>
|
|
4
4
|
|
|
5
5
|
<div class="m-editor-data-source-fields-footer">
|
|
6
|
+
<TMagicButton size="small" :disabled="disabled" plain @click="newFromJsonHandler()">快速添加</TMagicButton>
|
|
6
7
|
<TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
|
|
7
8
|
</div>
|
|
8
9
|
|
|
9
10
|
<MFormDrawer
|
|
10
11
|
ref="addDialog"
|
|
11
12
|
label-width="80px"
|
|
12
|
-
:title="
|
|
13
|
+
:title="fieldTitle"
|
|
13
14
|
:config="dataSourceFieldsConfig"
|
|
14
15
|
:values="fieldValues"
|
|
15
16
|
:parentValues="model[name]"
|
|
@@ -17,14 +18,25 @@
|
|
|
17
18
|
:width="width"
|
|
18
19
|
@submit="fieldChange"
|
|
19
20
|
></MFormDrawer>
|
|
21
|
+
|
|
22
|
+
<MFormDrawer
|
|
23
|
+
ref="addFromJsonDialog"
|
|
24
|
+
title="快速添加数据定义"
|
|
25
|
+
:config="jsonFromConfig"
|
|
26
|
+
:values="jsonFromValues"
|
|
27
|
+
:disabled="disabled"
|
|
28
|
+
:width="width"
|
|
29
|
+
@submit="addFromJsonFromChange"
|
|
30
|
+
></MFormDrawer>
|
|
20
31
|
</div>
|
|
21
32
|
</template>
|
|
22
33
|
|
|
23
34
|
<script setup lang="ts">
|
|
24
35
|
import { computed, inject, ref } from 'vue';
|
|
25
36
|
|
|
26
|
-
import { TMagicButton, tMagicMessageBox } from '@tmagic/design';
|
|
37
|
+
import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
|
|
27
38
|
import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
|
|
39
|
+
import type { DataSchema } from '@tmagic/schema';
|
|
28
40
|
import { MagicTable } from '@tmagic/table';
|
|
29
41
|
|
|
30
42
|
import type { Services } from '@editor/type';
|
|
@@ -49,14 +61,15 @@ const emit = defineEmits(['change']);
|
|
|
49
61
|
const services = inject<Services>('services');
|
|
50
62
|
|
|
51
63
|
const addDialog = ref<InstanceType<typeof MFormDrawer>>();
|
|
64
|
+
|
|
52
65
|
const fieldValues = ref<Record<string, any>>({});
|
|
53
|
-
const
|
|
66
|
+
const fieldTitle = ref('');
|
|
54
67
|
|
|
55
68
|
const width = computed(() => globalThis.document.body.clientWidth - (services?.uiService.get('columnWidth').left || 0));
|
|
56
69
|
|
|
57
70
|
const newHandler = () => {
|
|
58
71
|
fieldValues.value = {};
|
|
59
|
-
|
|
72
|
+
fieldTitle.value = '新增属性';
|
|
60
73
|
addDialog.value?.show();
|
|
61
74
|
};
|
|
62
75
|
|
|
@@ -100,7 +113,7 @@ const fieldColumns = [
|
|
|
100
113
|
...row,
|
|
101
114
|
index,
|
|
102
115
|
};
|
|
103
|
-
|
|
116
|
+
fieldTitle.value = `编辑${row.title}`;
|
|
104
117
|
addDialog.value?.show();
|
|
105
118
|
},
|
|
106
119
|
},
|
|
@@ -171,11 +184,14 @@ const dataSourceFieldsConfig: FormConfig = [
|
|
|
171
184
|
{
|
|
172
185
|
name: 'defaultValue',
|
|
173
186
|
text: '默认值',
|
|
187
|
+
height: '200px',
|
|
188
|
+
parse: true,
|
|
174
189
|
type: (mForm: FormState | undefined, { model }: any) => {
|
|
175
190
|
if (model.type === 'number') return 'number';
|
|
176
191
|
if (model.type === 'boolean') return 'select';
|
|
192
|
+
if (model.type === 'string') return 'text';
|
|
177
193
|
|
|
178
|
-
return '
|
|
194
|
+
return 'vs-code';
|
|
179
195
|
},
|
|
180
196
|
options: [
|
|
181
197
|
{ text: 'true', value: true },
|
|
@@ -192,7 +208,79 @@ const dataSourceFieldsConfig: FormConfig = [
|
|
|
192
208
|
name: 'fields',
|
|
193
209
|
type: 'data-source-fields',
|
|
194
210
|
defaultValue: [],
|
|
195
|
-
display: (formState: FormState | undefined, { model }: any) => model.type === 'object',
|
|
211
|
+
display: (formState: FormState | undefined, { model }: any) => model.type === 'object' || model.type === 'array',
|
|
196
212
|
},
|
|
197
213
|
];
|
|
214
|
+
|
|
215
|
+
const addFromJsonDialog = ref<InstanceType<typeof MFormDrawer>>();
|
|
216
|
+
const jsonFromConfig: FormConfig = [
|
|
217
|
+
{
|
|
218
|
+
name: 'data',
|
|
219
|
+
type: 'vs-code',
|
|
220
|
+
labelWidth: '0',
|
|
221
|
+
language: 'json',
|
|
222
|
+
height: '600px',
|
|
223
|
+
options: inject('codeOptions', {}),
|
|
224
|
+
},
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
const jsonFromValues = ref({
|
|
228
|
+
data: {},
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const newFromJsonHandler = () => {
|
|
232
|
+
addFromJsonDialog.value?.show();
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const getValueType = (value: any) => {
|
|
236
|
+
if (Array.isArray(value)) return 'array';
|
|
237
|
+
if (value === null) return 'null';
|
|
238
|
+
if (typeof value === 'object') return 'object';
|
|
239
|
+
if (typeof value === 'number') return 'number';
|
|
240
|
+
if (typeof value === 'boolean') return 'boolean';
|
|
241
|
+
if (typeof value === 'string') return 'string';
|
|
242
|
+
|
|
243
|
+
return 'any';
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const getFieldsConfig = (value: any) => {
|
|
247
|
+
if (!value || typeof value !== 'object') throw new Error('数据格式错误');
|
|
248
|
+
|
|
249
|
+
const fields: DataSchema[] = [];
|
|
250
|
+
Object.entries(value).forEach(([key, value]) => {
|
|
251
|
+
const type = getValueType(value);
|
|
252
|
+
|
|
253
|
+
let childFields: DataSchema[] = [];
|
|
254
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
255
|
+
childFields = getFieldsConfig(value[0]);
|
|
256
|
+
} else if (type === 'object') {
|
|
257
|
+
childFields = getFieldsConfig(value);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
fields.push({
|
|
261
|
+
name: key,
|
|
262
|
+
title: key,
|
|
263
|
+
type,
|
|
264
|
+
defaultValue: value,
|
|
265
|
+
fields: childFields,
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
return fields;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const addFromJsonFromChange = ({ data }: { data: string }) => {
|
|
273
|
+
console.log(data);
|
|
274
|
+
try {
|
|
275
|
+
const value = JSON.parse(data);
|
|
276
|
+
|
|
277
|
+
props.model[props.name] = getFieldsConfig(value);
|
|
278
|
+
|
|
279
|
+
addFromJsonDialog.value?.hide();
|
|
280
|
+
|
|
281
|
+
emit('change', props.model[props.name]);
|
|
282
|
+
} catch (e: any) {
|
|
283
|
+
tMagicMessage.error(e.message);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
198
286
|
</script>
|
|
@@ -50,11 +50,13 @@ defineOptions({
|
|
|
50
50
|
const services = inject<Services>('services');
|
|
51
51
|
const emit = defineEmits(['change']);
|
|
52
52
|
|
|
53
|
+
const dataSourceService = services?.dataSourceService;
|
|
54
|
+
|
|
53
55
|
const props = withDefaults(defineProps<FieldProps<DataSourceMethodSelectConfig>>(), {
|
|
54
56
|
disabled: false,
|
|
55
57
|
});
|
|
56
58
|
|
|
57
|
-
const dataSources = computed(() =>
|
|
59
|
+
const dataSources = computed(() => dataSourceService?.get('dataSources'));
|
|
58
60
|
|
|
59
61
|
const getParamItemsConfig = ([dataSourceId, medthodName]: [Id, string] = ['', '']): CodeParamStatement[] => {
|
|
60
62
|
if (!dataSourceId) return [];
|
|
@@ -85,28 +87,35 @@ const setParamsConfig = (dataSourceMethod: [Id, string], formState: any = {}) =>
|
|
|
85
87
|
}
|
|
86
88
|
};
|
|
87
89
|
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
text: '数据源方法',
|
|
91
|
-
name: props.name,
|
|
92
|
-
labelWidth: '80px',
|
|
93
|
-
options: () =>
|
|
90
|
+
const methodsOptions = computed(
|
|
91
|
+
() =>
|
|
94
92
|
dataSources.value
|
|
95
|
-
?.filter((ds) => ds.methods?.length)
|
|
93
|
+
?.filter((ds) => ds.methods?.length || dataSourceService?.getFormMethod(ds.type).length)
|
|
96
94
|
?.map((ds) => ({
|
|
97
95
|
label: ds.title || ds.id,
|
|
98
96
|
value: ds.id,
|
|
99
|
-
children:
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
children: [
|
|
98
|
+
...(dataSourceService?.getFormMethod(ds.type) || []),
|
|
99
|
+
...(ds.methods || []).map((method) => ({
|
|
100
|
+
label: method.name,
|
|
101
|
+
value: method.name,
|
|
102
|
+
})),
|
|
103
|
+
],
|
|
103
104
|
})) || [],
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const cascaderConfig = computed(() => ({
|
|
108
|
+
type: 'cascader',
|
|
109
|
+
text: '数据源方法',
|
|
110
|
+
name: props.name,
|
|
111
|
+
labelWidth: '80px',
|
|
112
|
+
options: methodsOptions.value,
|
|
104
113
|
onChange: (formState: any, dataSourceMethod: [Id, string]) => {
|
|
105
114
|
setParamsConfig(dataSourceMethod, formState);
|
|
106
115
|
|
|
107
116
|
return dataSourceMethod;
|
|
108
117
|
},
|
|
109
|
-
};
|
|
118
|
+
}));
|
|
110
119
|
|
|
111
120
|
/**
|
|
112
121
|
* 参数值修改更新
|
|
@@ -121,7 +130,7 @@ const { codeBlockEditor, codeConfig, editCode, submitCode } = useDataSourceMetho
|
|
|
121
130
|
const editCodeHandler = () => {
|
|
122
131
|
const [id, name] = props.model[props.name];
|
|
123
132
|
|
|
124
|
-
const dataSource =
|
|
133
|
+
const dataSource = dataSourceService?.getDataSourceById(id);
|
|
125
134
|
|
|
126
135
|
if (!dataSource) return;
|
|
127
136
|
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-editor-data-source-fields">
|
|
3
|
+
<MagicTable :data="model[name]" :columns="columns"></MagicTable>
|
|
4
|
+
|
|
5
|
+
<div class="m-editor-data-source-fields-footer">
|
|
6
|
+
<TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<MFormDrawer
|
|
10
|
+
ref="addDialog"
|
|
11
|
+
label-width="120px"
|
|
12
|
+
:title="drawerTitle"
|
|
13
|
+
:config="formConfig"
|
|
14
|
+
:values="formValues"
|
|
15
|
+
:parentValues="model[name]"
|
|
16
|
+
:disabled="disabled"
|
|
17
|
+
:width="width"
|
|
18
|
+
@submit="formChangeHandler"
|
|
19
|
+
></MFormDrawer>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script setup lang="ts">
|
|
24
|
+
import { computed, inject, ref } from 'vue';
|
|
25
|
+
|
|
26
|
+
import { TMagicButton, tMagicMessageBox, TMagicSwitch } from '@tmagic/design';
|
|
27
|
+
import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
|
|
28
|
+
import type { MockSchema } from '@tmagic/schema';
|
|
29
|
+
import { MagicTable } from '@tmagic/table';
|
|
30
|
+
import { getDefaultValueFromFields } from '@tmagic/utils';
|
|
31
|
+
|
|
32
|
+
import CodeEditor from '@editor/layouts/CodeEditor.vue';
|
|
33
|
+
import { Services } from '@editor/type';
|
|
34
|
+
|
|
35
|
+
defineOptions({
|
|
36
|
+
name: 'MEditorDataSourceMocks',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const props = withDefaults(
|
|
40
|
+
defineProps<
|
|
41
|
+
FieldProps<{
|
|
42
|
+
type: 'data-source-mocks';
|
|
43
|
+
}>
|
|
44
|
+
>(),
|
|
45
|
+
{
|
|
46
|
+
disabled: false,
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const emit = defineEmits(['change']);
|
|
51
|
+
|
|
52
|
+
const services = inject<Services>('services');
|
|
53
|
+
const width = computed(() => globalThis.document.body.clientWidth - (services?.uiService.get('columnWidth').left || 0));
|
|
54
|
+
|
|
55
|
+
const addDialog = ref<InstanceType<typeof MFormDrawer>>();
|
|
56
|
+
const drawerTitle = ref('');
|
|
57
|
+
const formValues = ref<Record<string, any>>({});
|
|
58
|
+
|
|
59
|
+
const formConfig: FormConfig = [
|
|
60
|
+
{ name: 'index', type: 'hidden', filter: 'number', defaultValue: -1 },
|
|
61
|
+
{
|
|
62
|
+
name: 'title',
|
|
63
|
+
text: '名称',
|
|
64
|
+
rules: [
|
|
65
|
+
{
|
|
66
|
+
required: true,
|
|
67
|
+
message: '请输入字段名称',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
required: true,
|
|
71
|
+
message: '请输入名称',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'description',
|
|
77
|
+
text: '描述',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'enable',
|
|
81
|
+
text: '启用',
|
|
82
|
+
type: 'switch',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'useInEditor',
|
|
86
|
+
text: '编辑器中使用',
|
|
87
|
+
type: 'switch',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'data',
|
|
91
|
+
text: 'mock数据',
|
|
92
|
+
type: 'vs-code',
|
|
93
|
+
language: 'json',
|
|
94
|
+
options: inject('codeOptions', {}),
|
|
95
|
+
defaultValue: '{}',
|
|
96
|
+
height: '400px',
|
|
97
|
+
onChange: (formState: FormState | undefined, v: string | any) => {
|
|
98
|
+
if (typeof v !== 'string') return v;
|
|
99
|
+
return JSON.parse(v);
|
|
100
|
+
},
|
|
101
|
+
rules: [
|
|
102
|
+
{
|
|
103
|
+
validator: ({ value, callback }) => {
|
|
104
|
+
if (typeof value !== 'string') return callback();
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
// 检测json是否存在语法错误
|
|
108
|
+
JSON.parse(value);
|
|
109
|
+
|
|
110
|
+
callback();
|
|
111
|
+
} catch (error: any) {
|
|
112
|
+
callback(error);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
const columns = [
|
|
121
|
+
{
|
|
122
|
+
type: 'expand',
|
|
123
|
+
component: CodeEditor,
|
|
124
|
+
props: (row: MockSchema) => ({
|
|
125
|
+
initValues: row.data,
|
|
126
|
+
language: 'json',
|
|
127
|
+
height: '150px',
|
|
128
|
+
options: {
|
|
129
|
+
readOnly: true,
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
label: '名称',
|
|
135
|
+
prop: 'title',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
label: '描述',
|
|
139
|
+
prop: 'description',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
label: '是否启用',
|
|
143
|
+
prop: 'enable',
|
|
144
|
+
type: 'component',
|
|
145
|
+
component: TMagicSwitch,
|
|
146
|
+
props: (row: MockSchema) => ({
|
|
147
|
+
modelValue: row.enable,
|
|
148
|
+
activeValue: true,
|
|
149
|
+
inactiveValue: false,
|
|
150
|
+
}),
|
|
151
|
+
listeners: (row: MockSchema, index: number) => ({
|
|
152
|
+
'update:modelValue': (v: boolean) => {
|
|
153
|
+
toggleValue(row, 'enable', v, index);
|
|
154
|
+
},
|
|
155
|
+
}),
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
label: '编辑器中使用',
|
|
159
|
+
prop: 'useInEditor',
|
|
160
|
+
type: 'component',
|
|
161
|
+
component: TMagicSwitch,
|
|
162
|
+
props: (row: MockSchema) => ({
|
|
163
|
+
modelValue: row.useInEditor,
|
|
164
|
+
activeValue: true,
|
|
165
|
+
inactiveValue: false,
|
|
166
|
+
}),
|
|
167
|
+
listeners: (row: MockSchema, index: number) => ({
|
|
168
|
+
'update:modelValue': (v: boolean) => {
|
|
169
|
+
toggleValue(row, 'useInEditor', v, index);
|
|
170
|
+
},
|
|
171
|
+
}),
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
label: '操作',
|
|
175
|
+
fixed: 'right',
|
|
176
|
+
actions: [
|
|
177
|
+
{
|
|
178
|
+
text: '编辑',
|
|
179
|
+
handler: (row: MockSchema, index: number) => {
|
|
180
|
+
formValues.value = {
|
|
181
|
+
...row,
|
|
182
|
+
index,
|
|
183
|
+
};
|
|
184
|
+
drawerTitle.value = `编辑${row.title}`;
|
|
185
|
+
addDialog.value?.show();
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
text: '删除',
|
|
190
|
+
buttonType: 'danger',
|
|
191
|
+
handler: async (row: MockSchema, index: number) => {
|
|
192
|
+
await tMagicMessageBox.confirm(`确定删除${row.title}?`, '提示');
|
|
193
|
+
props.model[props.name].splice(index, 1);
|
|
194
|
+
emit('change', props.model[props.name]);
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
const newHandler = () => {
|
|
202
|
+
const isFirstRow = props.model[props.name].length === 0;
|
|
203
|
+
formValues.value = {
|
|
204
|
+
data: getDefaultValueFromFields(props.model.fields || []),
|
|
205
|
+
useInEditor: isFirstRow,
|
|
206
|
+
enable: isFirstRow,
|
|
207
|
+
};
|
|
208
|
+
drawerTitle.value = '新增Mock';
|
|
209
|
+
addDialog.value?.show();
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const formChangeHandler = ({ index, ...value }: Record<string, any>) => {
|
|
213
|
+
if (index > -1) {
|
|
214
|
+
props.model[props.name][index] = value;
|
|
215
|
+
} else {
|
|
216
|
+
props.model[props.name].push(value);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
addDialog.value?.hide();
|
|
220
|
+
|
|
221
|
+
emit('change', props.model[props.name]);
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const toggleValue = (row: MockSchema, key: 'enable' | 'useInEditor', value: boolean, index: number) => {
|
|
225
|
+
if (value) {
|
|
226
|
+
props.model[props.name].forEach((item: MockSchema) => {
|
|
227
|
+
item[key] = false;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
formChangeHandler({
|
|
232
|
+
...row,
|
|
233
|
+
[key]: value,
|
|
234
|
+
index,
|
|
235
|
+
});
|
|
236
|
+
};
|
|
237
|
+
</script>
|
|
@@ -52,6 +52,7 @@ import { computed, inject } from 'vue';
|
|
|
52
52
|
import { Delete } from '@element-plus/icons-vue';
|
|
53
53
|
import { has } from 'lodash-es';
|
|
54
54
|
|
|
55
|
+
import type { EventOption } from '@tmagic/core';
|
|
55
56
|
import { TMagicButton } from '@tmagic/design';
|
|
56
57
|
import type { FieldProps, FormState } from '@tmagic/form';
|
|
57
58
|
import { ActionType } from '@tmagic/schema';
|
|
@@ -68,6 +69,11 @@ const emit = defineEmits(['change']);
|
|
|
68
69
|
|
|
69
70
|
const services = inject<Services>('services');
|
|
70
71
|
|
|
72
|
+
const editorService = services?.editorService;
|
|
73
|
+
const dataSourceService = services?.dataSourceService;
|
|
74
|
+
const eventsService = services?.eventsService;
|
|
75
|
+
const codeBlockService = services?.codeBlockService;
|
|
76
|
+
|
|
71
77
|
// 事件名称下拉框表单配置
|
|
72
78
|
const eventNameConfig = computed(() => {
|
|
73
79
|
const defaultEventNameConfig = {
|
|
@@ -75,11 +81,22 @@ const eventNameConfig = computed(() => {
|
|
|
75
81
|
text: '事件',
|
|
76
82
|
type: 'select',
|
|
77
83
|
labelWidth: '40px',
|
|
78
|
-
options: (mForm: FormState, { formValue }: any) =>
|
|
79
|
-
|
|
84
|
+
options: (mForm: FormState, { formValue }: any) => {
|
|
85
|
+
let events: EventOption[] = [];
|
|
86
|
+
|
|
87
|
+
if (!eventsService || !dataSourceService) return events;
|
|
88
|
+
|
|
89
|
+
if (props.config.src === 'component') {
|
|
90
|
+
events = eventsService.getEvent(formValue.type);
|
|
91
|
+
} else if (props.config.src === 'datasource') {
|
|
92
|
+
events = dataSourceService.getFormEvent(formValue.type);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return events.map((option) => ({
|
|
80
96
|
text: option.label,
|
|
81
97
|
value: option.value,
|
|
82
|
-
}))
|
|
98
|
+
}));
|
|
99
|
+
},
|
|
83
100
|
};
|
|
84
101
|
return { ...defaultEventNameConfig, ...props.config.eventNameConfig };
|
|
85
102
|
});
|
|
@@ -101,13 +118,15 @@ const actionTypeConfig = computed(() => {
|
|
|
101
118
|
{
|
|
102
119
|
text: '代码',
|
|
103
120
|
label: '代码',
|
|
104
|
-
disabled: !Object.keys(
|
|
121
|
+
disabled: !Object.keys(codeBlockService?.getCodeDsl() || {}).length,
|
|
105
122
|
value: ActionType.CODE,
|
|
106
123
|
},
|
|
107
124
|
{
|
|
108
125
|
text: '数据源',
|
|
109
126
|
label: '数据源',
|
|
110
|
-
disabled: !
|
|
127
|
+
disabled: !dataSourceService
|
|
128
|
+
?.get('dataSources')
|
|
129
|
+
?.filter((ds) => ds.methods?.length || dataSourceService?.getFormMethod(ds.type).length).length,
|
|
111
130
|
value: ActionType.DATA_SOURCE,
|
|
112
131
|
},
|
|
113
132
|
],
|
|
@@ -136,10 +155,10 @@ const compActionConfig = computed(() => {
|
|
|
136
155
|
type: 'select',
|
|
137
156
|
display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP,
|
|
138
157
|
options: (mForm: FormState, { model }: any) => {
|
|
139
|
-
const node =
|
|
158
|
+
const node = editorService?.getNodeById(model.to);
|
|
140
159
|
if (!node?.type) return [];
|
|
141
160
|
|
|
142
|
-
return
|
|
161
|
+
return eventsService?.getMethod(node.type).map((option: any) => ({
|
|
143
162
|
text: option.label,
|
|
144
163
|
value: option.value,
|
|
145
164
|
}));
|
|
@@ -154,7 +173,7 @@ const codeActionConfig = computed(() => {
|
|
|
154
173
|
type: 'code-select-col',
|
|
155
174
|
labelWidth: 0,
|
|
156
175
|
name: 'codeId',
|
|
157
|
-
disabled: () => !
|
|
176
|
+
disabled: () => !codeBlockService?.getEditStatus(),
|
|
158
177
|
display: (mForm, { model }) => model.actionType === ActionType.CODE,
|
|
159
178
|
};
|
|
160
179
|
return { ...defaultCodeActionConfig, ...props.config.codeActionConfig };
|
|
@@ -181,7 +200,7 @@ const tableConfig = computed(() => ({
|
|
|
181
200
|
label: '事件名',
|
|
182
201
|
type: eventNameConfig.value.type,
|
|
183
202
|
options: (mForm: FormState, { formValue }: any) =>
|
|
184
|
-
|
|
203
|
+
eventsService?.getEvent(formValue.type).map((option: any) => ({
|
|
185
204
|
text: option.label,
|
|
186
205
|
value: option.value,
|
|
187
206
|
})),
|
|
@@ -196,10 +215,10 @@ const tableConfig = computed(() => ({
|
|
|
196
215
|
label: '动作',
|
|
197
216
|
type: compActionConfig.value.type,
|
|
198
217
|
options: (mForm: FormState, { model }: any) => {
|
|
199
|
-
const node =
|
|
218
|
+
const node = editorService?.getNodeById(model.to);
|
|
200
219
|
if (!node?.type) return [];
|
|
201
220
|
|
|
202
|
-
return
|
|
221
|
+
return eventsService?.getMethod(node.type).map((option: any) => ({
|
|
203
222
|
text: option.label,
|
|
204
223
|
value: option.value,
|
|
205
224
|
}));
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ import DataSourceFieldSelect from './fields/DataSourceFieldSelect.vue';
|
|
|
26
26
|
import DataSourceInput from './fields/DataSourceInput.vue';
|
|
27
27
|
import DataSourceMethods from './fields/DataSourceMethods.vue';
|
|
28
28
|
import DataSourceMethodSelect from './fields/DataSourceMethodSelect.vue';
|
|
29
|
+
import DataSourceMocks from './fields/DataSourceMocks.vue';
|
|
29
30
|
import DataSourceSelect from './fields/DataSourceSelect.vue';
|
|
30
31
|
import EventSelect from './fields/EventSelect.vue';
|
|
31
32
|
import KeyValue from './fields/KeyValue.vue';
|
|
@@ -55,10 +56,11 @@ export { default as uiService } from './services/ui';
|
|
|
55
56
|
export { default as codeBlockService } from './services/codeBlock';
|
|
56
57
|
export { default as depService } from './services/dep';
|
|
57
58
|
export { default as ComponentListPanel } from './layouts/sidebar/ComponentListPanel.vue';
|
|
58
|
-
export { default as LayerPanel } from './layouts/sidebar/LayerPanel.vue';
|
|
59
|
+
export { default as LayerPanel } from './layouts/sidebar/layer/LayerPanel.vue';
|
|
59
60
|
export { default as CodeSelect } from './fields/CodeSelect.vue';
|
|
60
61
|
export { default as CodeSelectCol } from './fields/CodeSelectCol.vue';
|
|
61
62
|
export { default as DataSourceFields } from './fields/DataSourceFields.vue';
|
|
63
|
+
export { default as DataSourceMocks } from './fields/DataSourceMocks.vue';
|
|
62
64
|
export { default as DataSourceMethods } from './fields/DataSourceMethods.vue';
|
|
63
65
|
export { default as DataSourceInput } from './fields/DataSourceInput.vue';
|
|
64
66
|
export { default as DataSourceSelect } from './fields/DataSourceSelect.vue';
|
|
@@ -98,6 +100,7 @@ export default {
|
|
|
98
100
|
app.component('m-fields-code-select-col', CodeSelectCol);
|
|
99
101
|
app.component('m-fields-event-select', EventSelect);
|
|
100
102
|
app.component('m-fields-data-source-fields', DataSourceFields);
|
|
103
|
+
app.component('m-fields-data-source-mocks', DataSourceMocks);
|
|
101
104
|
app.component('m-fields-key-value', KeyValue);
|
|
102
105
|
app.component('m-fields-data-source-input', DataSourceInput);
|
|
103
106
|
app.component('m-fields-data-source-select', DataSourceSelect);
|