Skip to content

Commit

Permalink
feat(editor,schema): 支持配置数据源mock
Browse files Browse the repository at this point in the history
  • Loading branch information
roymondchen committed Oct 1, 2023
1 parent 2b2a9c6 commit d4a8b89
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 15 deletions.
12 changes: 9 additions & 3 deletions packages/editor/src/fields/Code.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
...config.options,
readOnly: disabled,
}"
:parse="config.parse"
@save="save"
></MagicCodeEditor>
</template>
Expand All @@ -20,22 +21,27 @@ defineOptions({
name: 'MEditorCode',
});
const emit = defineEmits(['change']);
const emit = defineEmits<{
change: [value: string | any];
}>();
const props = withDefaults(
defineProps<
FieldProps<{
language?: string;
options?: Object;
options?: {
[key: string]: any;
};
height?: string;
parse?: boolean;
}>
>(),
{
disabled: false,
},
);
const save = (v: string) => {
const save = (v: string | any) => {
props.model[props.name] = v;
emit('change', v);
};
Expand Down
8 changes: 4 additions & 4 deletions packages/editor/src/fields/DataSourceFields.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<MFormDrawer
ref="addDialog"
label-width="80px"
:title="filedTitle"
:title="fieldTitle"
:config="dataSourceFieldsConfig"
:values="fieldValues"
:parentValues="model[name]"
Expand Down Expand Up @@ -50,13 +50,13 @@ const services = inject<Services>('services');
const addDialog = ref<InstanceType<typeof MFormDrawer>>();
const fieldValues = ref<Record<string, any>>({});
const filedTitle = ref('');
const fieldTitle = ref('');
const width = computed(() => globalThis.document.body.clientWidth - (services?.uiService.get('columnWidth').left || 0));
const newHandler = () => {
fieldValues.value = {};
filedTitle.value = '新增属性';
fieldTitle.value = '新增属性';
addDialog.value?.show();
};
Expand Down Expand Up @@ -100,7 +100,7 @@ const fieldColumns = [
...row,
index,
};
filedTitle.value = `编辑${row.title}`;
fieldTitle.value = `编辑${row.title}`;
addDialog.value?.show();
},
},
Expand Down
187 changes: 187 additions & 0 deletions packages/editor/src/fields/DataSourceMocks.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<template>
<div class="m-editor-data-source-fields">
<MagicTable :data="model[name]" :columns="columns"></MagicTable>

<div class="m-editor-data-source-fields-footer">
<TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
</div>

<MFormDrawer
ref="addDialog"
label-width="80px"
:title="drawerTitle"
:config="formConfig"
:values="formValues"
:parentValues="model[name]"
:disabled="disabled"
:width="width"
@submit="formChangeHandler"
></MFormDrawer>
</div>
</template>

<script setup lang="ts">
import { computed, inject, ref } from 'vue';
import { TMagicButton, tMagicMessageBox, TMagicSwitch } from '@tmagic/design';
import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
import type { MockSchema } from '@tmagic/schema';
import { MagicTable } from '@tmagic/table';
import { Services } from '@editor/type';
defineOptions({
name: 'MEditorDataSourceMocks',
});
const props = withDefaults(
defineProps<
FieldProps<{
type: 'data-source-mocks';
}>
>(),
{
disabled: false,
},
);
const emit = defineEmits(['change']);
const services = inject<Services>('services');
const width = computed(() => globalThis.document.body.clientWidth - (services?.uiService.get('columnWidth').left || 0));
const addDialog = ref<InstanceType<typeof MFormDrawer>>();
const drawerTitle = ref('');
const formValues = ref<Record<string, any>>({});
const formConfig: FormConfig = [
{ name: 'index', type: 'hidden', filter: 'number', defaultValue: -1 },
{
name: 'title',
text: '名称',
rules: [
{
required: true,
message: '请输入字段名称',
},
{
required: true,
message: '请输入名称',
},
],
},
{
name: 'description',
text: '描述',
},
{
name: 'enable',
text: '启用',
type: 'switch',
},
{
name: 'data',
text: 'mock数据',
type: 'vs-code',
language: 'json',
options: inject('codeOptions', {}),
defaultValue: '{}',
height: '400px',
onChange: (formState: FormState | undefined, v: string | any) => {
if (typeof v !== 'string') return v;
return JSON.parse(v);
},
rules: [
{
validator: ({ value, callback }) => {
if (typeof value !== 'string') return callback();
try {
// 检测json是否存在语法错误
JSON.parse(value);
callback();
} catch (error: any) {
callback(error);
}
},
},
],
},
];
const columns = [
{
label: '名称',
prop: 'title',
},
{
label: '描述',
prop: 'description',
},
{
label: '是否启用',
prop: 'enable',
type: 'component',
component: TMagicSwitch,
props: (row: MockSchema) => ({
modelValue: row.enable,
activeValue: true,
inactiveValue: false,
}),
listeners: (row: MockSchema, index: number) => ({
'update:modelValue': (v: boolean) => {
formChangeHandler({
...row,
enable: v,
index,
});
},
}),
},
{
label: '操作',
fixed: 'right',
actions: [
{
text: '编辑',
handler: (row: MockSchema, index: number) => {
formValues.value = {
...row,
index,
};
drawerTitle.value = `编辑${row.title}`;
addDialog.value?.show();
},
},
{
text: '删除',
buttonType: 'danger',
handler: async (row: MockSchema, index: number) => {
await tMagicMessageBox.confirm(`确定删除${row.title}?`, '提示');
props.model[props.name].splice(index, 1);
emit('change', props.model[props.name]);
},
},
],
},
];
const newHandler = () => {
formValues.value = {};
drawerTitle.value = '新增Mock';
addDialog.value?.show();
};
const formChangeHandler = ({ index, ...value }: Record<string, any>) => {
if (index > -1) {
props.model[props.name][index] = value;
} else {
props.model[props.name].push(value);
}
addDialog.value?.hide();
emit('change', props.model[props.name]);
};
</script>
3 changes: 3 additions & 0 deletions packages/editor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import DataSourceFieldSelect from './fields/DataSourceFieldSelect.vue';
import DataSourceInput from './fields/DataSourceInput.vue';
import DataSourceMethods from './fields/DataSourceMethods.vue';
import DataSourceMethodSelect from './fields/DataSourceMethodSelect.vue';
import DataSourceMocks from './fields/DataSourceMocks.vue';
import DataSourceSelect from './fields/DataSourceSelect.vue';
import EventSelect from './fields/EventSelect.vue';
import KeyValue from './fields/KeyValue.vue';
Expand Down Expand Up @@ -59,6 +60,7 @@ export { default as LayerPanel } from './layouts/sidebar/LayerPanel.vue';
export { default as CodeSelect } from './fields/CodeSelect.vue';
export { default as CodeSelectCol } from './fields/CodeSelectCol.vue';
export { default as DataSourceFields } from './fields/DataSourceFields.vue';
export { default as DataSourceMocks } from './fields/DataSourceMocks.vue';
export { default as DataSourceMethods } from './fields/DataSourceMethods.vue';
export { default as DataSourceInput } from './fields/DataSourceInput.vue';
export { default as DataSourceSelect } from './fields/DataSourceSelect.vue';
Expand Down Expand Up @@ -98,6 +100,7 @@ export default {
app.component('m-fields-code-select-col', CodeSelectCol);
app.component('m-fields-event-select', EventSelect);
app.component('m-fields-data-source-fields', DataSourceFields);
app.component('m-fields-data-source-mocks', DataSourceMocks);
app.component('m-fields-key-value', KeyValue);
app.component('m-fields-data-source-input', DataSourceInput);
app.component('m-fields-data-source-select', DataSourceSelect);
Expand Down
24 changes: 20 additions & 4 deletions packages/editor/src/layouts/CodeEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import serialize from 'serialize-javascript';
import { TMagicButton } from '@tmagic/design';
import { getConfig } from '@editor/utils/config';
defineOptions({
name: 'MEditorCodeEditor',
});
Expand All @@ -42,13 +44,15 @@ const props = withDefaults(
};
height?: string;
autoSave?: boolean;
parse?: boolean;
}>(),
{
autoSave: true,
language: 'javascript',
options: () => ({
tabSize: 2,
}),
parse: false,
},
);
Expand All @@ -57,7 +61,7 @@ const emit = defineEmits(['initd', 'save']);
const toString = (v: string | any, language: string): string => {
let value = '';
if (typeof v !== 'string') {
if (props.language.toLocaleLowerCase() === 'json') {
if (language === 'json') {
value = JSON.stringify(v, null, 2);
} else {
value = serialize(v, {
Expand All @@ -74,6 +78,18 @@ const toString = (v: string | any, language: string): string => {
return value;
};
const parse = (v: string | any, language: string): any => {
if (typeof v !== 'string') {
return v;
}
if (language === 'json') {
return JSON.parse(v);
}
return getConfig('parseDSL')(v);
};
let vsEditor: monaco.editor.IStandaloneCodeEditor | null = null;
let vsDiffEditor: monaco.editor.IStandaloneDiffEditor | null = null;
Expand All @@ -89,7 +105,7 @@ const resizeObserver = new globalThis.ResizeObserver(
);
const setEditorValue = (v: string | any, m: string | any) => {
values.value = toString(v, props.language);
values.value = toString(v, props.language.toLocaleLowerCase());
if (props.type === 'diff') {
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
Expand Down Expand Up @@ -135,7 +151,7 @@ const init = async () => {
e.stopPropagation();
const newValue = getEditorValue();
values.value = newValue;
emit('save', newValue);
emit('save', props.parse ? parse(newValue, props.language) : newValue);
}
});
Expand All @@ -144,7 +160,7 @@ const init = async () => {
const newValue = getEditorValue();
if (values.value !== newValue) {
values.value = newValue;
emit('save', newValue);
emit('save', props.parse ? parse(newValue, props.language) : newValue);
}
});
}
Expand Down
11 changes: 11 additions & 0 deletions packages/editor/src/utils/data-source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ const fillConfig = (config: FormConfig): FormConfig => [
},
],
},
{
type: 'panel',
title: 'mock数据',
items: [
{
name: 'mocks',
type: 'data-source-mocks',
defaultValue: () => [],
},
],
},
];

export const getFormConfig = (type: string, configs: Record<string, FormConfig>): FormConfig => {
Expand Down
Loading

0 comments on commit d4a8b89

Please sign in to comment.