mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-04-06 03:57:56 +08:00
feat(editor): 代码编辑交互优化
1、代码列表中代码块和组件区分不够清晰,查看按钮太靠边,开发模式下未对齐 2、代码编辑/查看弹窗希望可以点击蒙层或者esc键退出 3、代码块绑定到组件的地方和事件绑定UI统一 4、在代码绑定的地方需要支持查看或者编辑 Bug: 1、旧格式的事件联动删除到只剩最后一个时无法成功删除
This commit is contained in:
parent
abc6835786
commit
51dadabc2c
@ -25,7 +25,6 @@
|
||||
</template>
|
||||
<script lang="ts" setup name="MEditorCodeDraftEditor">
|
||||
import { computed, inject, ref, watchEffect } from 'vue';
|
||||
import type { Action } from 'element-plus';
|
||||
import type * as monaco from 'monaco-editor';
|
||||
|
||||
import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
|
||||
@ -93,7 +92,7 @@ const saveCodeDraft = async (codeValue: string) => {
|
||||
return;
|
||||
}
|
||||
services?.codeBlockService.setCodeDraft(props.id, codeValue);
|
||||
tMagicMessage.success(`代码草稿保存成功 ${datetimeFormatter(new Date())}`);
|
||||
tMagicMessage.success(`代码草稿成功保存到本地 ${datetimeFormatter(new Date())}`);
|
||||
};
|
||||
|
||||
// 保存并关闭
|
||||
@ -108,24 +107,23 @@ const saveAndClose = (): void => {
|
||||
const close = async (): Promise<void> => {
|
||||
const codeDraft = services?.codeBlockService.getCodeDraft(props.id);
|
||||
if (codeDraft) {
|
||||
tMagicMessageBox
|
||||
.confirm('您有代码修改未保存,是否保存后再关闭?', '提示', {
|
||||
try {
|
||||
await tMagicMessageBox.confirm('您有代码修改未保存,是否保存后再关闭?', '提示', {
|
||||
confirmButtonText: '保存并关闭',
|
||||
cancelButtonText: '直接关闭',
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true,
|
||||
})
|
||||
.then(async () => {
|
||||
// 保存之后再关闭
|
||||
saveAndClose();
|
||||
})
|
||||
.catch((action: Action) => {
|
||||
if (action === 'cancel') {
|
||||
// 删除草稿 直接关闭
|
||||
services?.codeBlockService.removeCodeDraft(props.id);
|
||||
emit('close');
|
||||
}
|
||||
});
|
||||
|
||||
// 保存之后再关闭
|
||||
saveAndClose();
|
||||
} catch (action: any) {
|
||||
if (action === 'cancel') {
|
||||
// 删除草稿 直接关闭
|
||||
services?.codeBlockService.removeCodeDraft(props.id);
|
||||
emit('close');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
emit('close');
|
||||
}
|
||||
@ -138,4 +136,9 @@ const toggleFullScreen = (): void => {
|
||||
codeEditor.value.focus();
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
saveAndClose,
|
||||
close,
|
||||
});
|
||||
</script>
|
||||
|
@ -1,21 +0,0 @@
|
||||
<template>
|
||||
<svg width="2em" height="2em" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M8.94034 2.55798L6.09333 13.1832L7.05925 13.442L9.90626 2.8168L8.94034 2.55798Z"
|
||||
fill="currentColor"
|
||||
fill-opacity="0.9"
|
||||
></path>
|
||||
<path
|
||||
d="M2.14982 8.00001L5.57495 11.4251L4.86784 12.1323L1.15987 8.42428C0.925551 8.18996 0.925553 7.81006 1.15987 7.57575L4.86784 3.86777L5.57495 4.57488L2.14982 8.00001Z"
|
||||
fill="currentColor"
|
||||
fill-opacity="0.9"
|
||||
></path>
|
||||
<path
|
||||
d="M13.846 8.00001L10.4054 11.4016L11.1085 12.1127L14.8368 8.42668C15.0744 8.19183 15.0744 7.80819 14.8368 7.57333L11.1085 3.88732L10.4054 4.59845L13.846 8.00001Z"
|
||||
fill="currentColor"
|
||||
fill-opacity="0.9"
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="MEditorCodeIcon"></script>
|
@ -20,6 +20,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<CodeDraftEditor
|
||||
ref="codeDraftEditor"
|
||||
:id="id"
|
||||
:content="codeContent"
|
||||
:editable="editable"
|
||||
@ -32,7 +33,7 @@
|
||||
</TMagicCard>
|
||||
</template>
|
||||
<script lang="ts" setup name="MEditorFunctionEditor">
|
||||
import { inject, provide, ref, watchEffect } from 'vue';
|
||||
import { inject, ref, watchEffect } from 'vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import { TMagicCard, TMagicInput, tMagicMessage } from '@tmagic/design';
|
||||
@ -116,19 +117,12 @@ const tableConfig: TableConfig = {
|
||||
],
|
||||
};
|
||||
|
||||
const emit = defineEmits(['change', 'field-input']);
|
||||
|
||||
const services = inject<Services>('services');
|
||||
|
||||
const codeName = ref<string>('');
|
||||
const codeContent = ref<string>('');
|
||||
const evalRes = ref(true);
|
||||
|
||||
provide('mForm', {
|
||||
$emit: emit,
|
||||
setField: () => {},
|
||||
});
|
||||
|
||||
const tableModel = ref<{ params: CodeParam[] }>();
|
||||
watchEffect(() => {
|
||||
codeName.value = props.name;
|
||||
@ -169,7 +163,7 @@ const saveCode = async (codeValue: string): Promise<void> => {
|
||||
content: codeValue,
|
||||
params: tableModel.value?.params || [],
|
||||
});
|
||||
tMagicMessage.success('代码保存成功');
|
||||
tMagicMessage.success('代码成功保存到本地');
|
||||
// 删除草稿
|
||||
services?.codeBlockService.removeCodeDraft(props.id);
|
||||
}
|
||||
@ -187,4 +181,10 @@ const saveAndClose = async (codeValue: string): Promise<void> => {
|
||||
const close = (): void => {
|
||||
services?.codeBlockService.setCodeEditorShowStatus(false);
|
||||
};
|
||||
|
||||
const codeDraftEditor = ref<InstanceType<typeof CodeDraftEditor>>();
|
||||
|
||||
defineExpose({
|
||||
codeDraftEditor,
|
||||
});
|
||||
</script>
|
||||
|
@ -1,111 +1,43 @@
|
||||
<template>
|
||||
<div class="m-fields-code-select" :class="config.className">
|
||||
<m-form-table
|
||||
:config="tableConfig"
|
||||
:model="model[name]"
|
||||
name="hookData"
|
||||
:enableToggleMode="false"
|
||||
:prop="prop"
|
||||
:size="size"
|
||||
@change="changeHandler"
|
||||
>
|
||||
<template #operateCol="{ scope }">
|
||||
<Icon
|
||||
v-if="scope.row.codeId && config.editable"
|
||||
:icon="editable ? Edit : View"
|
||||
class="edit-icon"
|
||||
@click="editCode(scope.row.codeId)"
|
||||
></Icon>
|
||||
</template>
|
||||
</m-form-table>
|
||||
<TMagicCard>
|
||||
<m-form-container :config="codeConfig" :model="model[name]" @change="changeHandler"> </m-form-container>
|
||||
</TMagicCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="MEditorCodeSelect">
|
||||
import { computed, defineEmits, defineProps, inject, watch } from 'vue';
|
||||
import { Edit, View } from '@element-plus/icons-vue';
|
||||
import { isEmpty, map } from 'lodash-es';
|
||||
import { computed, defineEmits, defineProps, watch } from 'vue';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
|
||||
import { createValues, FormItem, FormState, TableConfig } from '@tmagic/form';
|
||||
import { HookType, Id } from '@tmagic/schema';
|
||||
import { TMagicCard } from '@tmagic/design';
|
||||
import { HookType } from '@tmagic/schema';
|
||||
|
||||
import Icon from '@editor/components/Icon.vue';
|
||||
import type { CodeParamStatement, HookData, Services } from '@editor/type';
|
||||
|
||||
const services = inject<Services>('services');
|
||||
const mForm = inject<FormState>('mForm');
|
||||
const emit = defineEmits(['change']);
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
config: {
|
||||
tableConfig?: TableConfig;
|
||||
className?: string;
|
||||
editable?: boolean;
|
||||
};
|
||||
model: any;
|
||||
prop: string;
|
||||
name: string;
|
||||
size: 'small' | 'default' | 'large';
|
||||
}>(),
|
||||
{
|
||||
config: () => ({
|
||||
editable: true,
|
||||
}),
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
const codeDsl = computed(() => services?.codeBlockService.getCodeDsl());
|
||||
|
||||
const tableConfig = computed<FormItem>(() => {
|
||||
const defaultConfig = {
|
||||
dropSort: false,
|
||||
enableFullscreen: false,
|
||||
border: true,
|
||||
operateColWidth: 60,
|
||||
items: [
|
||||
{
|
||||
type: 'select',
|
||||
label: '代码块',
|
||||
name: 'codeId',
|
||||
width: '200px',
|
||||
options: () => {
|
||||
if (codeDsl.value) {
|
||||
return map(codeDsl.value, (value, key) => ({
|
||||
text: `${value.name}(${key})`,
|
||||
label: `${value.name}(${key})`,
|
||||
value: key,
|
||||
}));
|
||||
}
|
||||
return [];
|
||||
},
|
||||
onChange: (formState: any, codeId: Id, { model }: any) => {
|
||||
// 参数的items是根据函数生成的,当codeId变化后修正model的值,避免写入其他codeId的params
|
||||
model.params = {};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'params',
|
||||
label: '参数',
|
||||
defaultValue: {},
|
||||
itemsFunction: (row: HookData) => {
|
||||
const paramsConfig = getParamsConfig(row.codeId);
|
||||
// 如果参数没有填值,则使用createValues补全空值
|
||||
if (!row.params || isEmpty(row.params)) {
|
||||
createValues(mForm, paramsConfig, {}, row.params);
|
||||
}
|
||||
return paramsConfig;
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
return {
|
||||
...defaultConfig,
|
||||
...props.config.tableConfig,
|
||||
};
|
||||
});
|
||||
|
||||
const editable = computed(() => services?.codeBlockService.getEditStatus());
|
||||
const codeConfig = computed(() => ({
|
||||
type: 'group-list',
|
||||
name: 'hookData',
|
||||
enableToggleMode: false,
|
||||
items: [
|
||||
{
|
||||
type: 'code-select-col',
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
watch(
|
||||
() => props.model[props.name],
|
||||
@ -127,20 +59,4 @@ watch(
|
||||
const changeHandler = async () => {
|
||||
emit('change', props.model[props.name]);
|
||||
};
|
||||
|
||||
const getParamsConfig = (codeId: Id): CodeParamStatement[] => {
|
||||
if (!codeDsl.value) return [];
|
||||
const paramStatements = codeDsl.value[codeId]?.params;
|
||||
if (isEmpty(paramStatements)) return [];
|
||||
return paramStatements.map((paramState: CodeParamStatement) => ({
|
||||
labelWidth: '100px',
|
||||
text: paramState.name,
|
||||
inline: true,
|
||||
...paramState,
|
||||
}));
|
||||
};
|
||||
|
||||
const editCode = (codeId: Id) => {
|
||||
services?.codeBlockService.setCodeEditorContent(true, codeId);
|
||||
};
|
||||
</script>
|
||||
|
@ -1,7 +1,16 @@
|
||||
<template>
|
||||
<div class="m-fields-code-select-col">
|
||||
<!-- 代码块下拉框 -->
|
||||
<m-form-container :config="selectConfig" :model="model" @change="onParamsChangeHandler"></m-form-container>
|
||||
<div class="code-select-container">
|
||||
<!-- 代码块下拉框 -->
|
||||
<m-form-container
|
||||
class="select"
|
||||
:config="selectConfig"
|
||||
:model="model"
|
||||
@change="onParamsChangeHandler"
|
||||
></m-form-container>
|
||||
<!-- 查看/编辑按钮 -->
|
||||
<Icon class="icon" :icon="editable ? Edit : View" @click="editCode"></Icon>
|
||||
</div>
|
||||
<!-- 参数填写框 -->
|
||||
<m-form-container :config="codeParamsConfig" :model="model" @change="onParamsChangeHandler"></m-form-container>
|
||||
</div>
|
||||
@ -9,11 +18,13 @@
|
||||
|
||||
<script lang="ts" setup name="MEditorCodeSelectCol">
|
||||
import { computed, defineEmits, defineProps, inject, ref, watch } from 'vue';
|
||||
import { Edit, View } from '@element-plus/icons-vue';
|
||||
import { isEmpty, map } from 'lodash-es';
|
||||
|
||||
import { createValues, FieldsetConfig, FormState } from '@tmagic/form';
|
||||
import { Id } from '@tmagic/schema';
|
||||
|
||||
import Icon from '@editor/components/Icon.vue';
|
||||
import type { CodeParamStatement, Services } from '@editor/type';
|
||||
|
||||
const services = inject<Services>('services');
|
||||
@ -31,6 +42,7 @@ const props = withDefaults(
|
||||
{},
|
||||
);
|
||||
const codeDsl = computed(() => services?.codeBlockService.getCodeDsl());
|
||||
const editable = computed(() => services?.codeBlockService.getEditStatus());
|
||||
const codeParamsConfig = ref<FieldsetConfig>({
|
||||
type: 'fieldset',
|
||||
items: [],
|
||||
@ -115,4 +127,9 @@ watch(
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
// 打开代码编辑框
|
||||
const editCode = () => {
|
||||
services?.codeBlockService.setCodeEditorContent(true, props.model.codeId);
|
||||
};
|
||||
</script>
|
||||
|
@ -1,13 +1,14 @@
|
||||
<template>
|
||||
<div class="m-fields-event-select">
|
||||
<m-form-container
|
||||
<m-form-table
|
||||
v-if="isOldVersion"
|
||||
ref="eventForm"
|
||||
:size="props.size"
|
||||
:model="model"
|
||||
name="events"
|
||||
:config="tableConfig"
|
||||
@change="onChangeHandler"
|
||||
></m-form-container>
|
||||
></m-form-table>
|
||||
|
||||
<div v-else class="fullWidth">
|
||||
<TMagicButton class="create-button" type="primary" size="small" @click="addEvent()">添加事件</TMagicButton>
|
||||
|
11
packages/editor/src/icons/AppManageIcon.vue
Normal file
11
packages/editor/src/icons/AppManageIcon.vue
Normal file
@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<!-- app-manage cdn链接:https://cloudcache.tencent-cloud.com/qcloud/ui/static/console_aside_v4/6638c8a5-2e7f-477a-83b1-a413a0e4ba39.svg -->
|
||||
<svg width="16px" height="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#7C878E" fill-rule="evenodd">
|
||||
<path d="M15.3,5.5 L8,0 L0.7,5.5 L8,11 L15.3,5.5 Z M8,2.5 L12,5.5 L8,8.5 L4,5.5 L8,2.5 Z" fill-rule="nonzero" />
|
||||
<path d="M8 13.5L2.3 9.2 0.7 10.5 8 16 15.3 10.5 13.7 9.2z" />
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="MEditorAppManageIcon"></script>
|
35
packages/editor/src/icons/CodeIcon.vue
Normal file
35
packages/editor/src/icons/CodeIcon.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<!-- 代码icon,cdn链接:https://cloudcache.tencent-cloud.com/qcloud/ui/static/government/0d463ed5-6407-4498-8865-3d05b5e70115.svg -->
|
||||
<svg
|
||||
width="32px"
|
||||
height="32px"
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<!-- Generator: Sketch 60.1 (88133) - https://sketch.com -->
|
||||
<title>gsd-icon-line-Universal-code</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs><rect id="path-1" x="0" y="0" width="32" height="32"></rect></defs>
|
||||
<g id="组件规范" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="03图标" transform="translate(-561.000000, -2356.000000)">
|
||||
<g id="icon/line/Universal/code" transform="translate(561.000000, 2356.000000)">
|
||||
<g id="路径">
|
||||
<mask id="mask-2" fill="white"><use xlink:href="#path-1"></use></mask>
|
||||
<use id="蒙版" fill="#D8D8D8" opacity="0" xlink:href="#path-1"></use>
|
||||
<path
|
||||
d="M21.9284587,7.9482233 L29.8079004,15.827665 C29.9055315,15.9252961 29.9055315,16.0835874 29.8079004,16.1812184 L21.9284587,24.0606602 C21.8308276,24.1582912 21.6725364,24.1582912 21.5749053,24.0606602 L20.3374684,22.8232233 C20.2419143,22.7276698 20.2398813,22.5740096 20.331369,22.4759832 L20.3374687,22.4696702 L26.8027181,16.0044417 L20.3374687,9.53921328 C20.2398372,9.44158265 20.2398369,9.2832914 20.3374679,9.18566017 L21.5749053,7.9482233 C21.6725364,7.85059223 21.8308276,7.85059223 21.9284587,7.9482233 Z M10.3999684,7.9482233 L11.6374053,9.18566017 C11.7329594,9.28121371 11.7349925,9.43487387 11.6435048,9.53290029 L11.637405,9.53921328 L5.17215562,16.0044417 L11.637405,22.4696702 C11.7329593,22.5652236 11.7349926,22.7188837 11.643505,22.8169103 L11.6374053,22.8232233 L10.3999684,24.0606602 C10.3023374,24.1582912 10.1440461,24.1582912 10.046415,24.0606602 L2.1669733,16.1812184 C2.06934223,16.0835874 2.06934223,15.9252961 2.1669733,15.827665 L10.046415,7.9482233 C10.1440461,7.85059223 10.3023374,7.85059223 10.3999684,7.9482233 Z M17.2612532,9.29310422 L18.9262468,9.83189578 C19.0576112,9.87440526 19.1296423,10.0153579 19.0871328,10.1467222 L15.0848232,22.514807 C15.0423138,22.6461714 14.9013612,22.7182025 14.7699968,22.675693 L13.1050032,22.1369014 C12.9736388,22.0943919 12.9016077,21.9534393 12.9441172,21.822075 L16.9464268,9.45399022 C16.9889362,9.32262585 17.1298888,9.25059474 17.2612532,9.29310422 Z"
|
||||
id="形状"
|
||||
fill="#1D1F24"
|
||||
mask="url(#mask-2)"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="icon切图" transform="translate(226.000000, 1782.000000)"></g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="MEditorCodeIcon"></script>
|
@ -3,11 +3,12 @@
|
||||
class="code-editor-dialog"
|
||||
:model-value="true"
|
||||
:title="currentTitle"
|
||||
:close-on-press-escape="false"
|
||||
:close-on-press-escape="true"
|
||||
:append-to-body="true"
|
||||
:show-close="false"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-click-modal="true"
|
||||
:size="size"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<Layout v-model:left="left" :min-left="45" class="code-editor-layout">
|
||||
<!-- 右侧区域 -->
|
||||
@ -15,6 +16,7 @@
|
||||
<div v-if="!isEmpty(codeConfig)" class="m-editor-code-block-editor-panel">
|
||||
<slot name="code-block-edit-panel-header" :id="id"></slot>
|
||||
<FunctionEditor
|
||||
ref="functionEditor"
|
||||
v-if="codeConfig"
|
||||
:id="id"
|
||||
:name="codeConfig.name"
|
||||
@ -84,4 +86,11 @@ watchEffect(async () => {
|
||||
});
|
||||
currentTitle.value = state.codeList[0]?.name || '';
|
||||
});
|
||||
|
||||
const functionEditor = ref<InstanceType<typeof FunctionEditor>>();
|
||||
|
||||
const handleClose = async () => {
|
||||
// 触发codeDraftEditor组件关闭事件
|
||||
await functionEditor.value?.codeDraftEditor?.close();
|
||||
};
|
||||
</script>
|
||||
|
@ -25,8 +25,11 @@
|
||||
<template #default="{ data }">
|
||||
<div :id="data.id" class="list-container">
|
||||
<div class="list-item">
|
||||
<CodeIcon style="width: 15px; margin-right: 5px" v-if="data.type === 'code'"></CodeIcon>
|
||||
<span class="code-name">{{ data.name }}({{ data.id }})</span>
|
||||
<CodeIcon v-if="data.type === 'code'" class="codeIcon"></CodeIcon>
|
||||
<AppManageIcon v-if="data.type === 'node'" class="compIcon"></AppManageIcon>
|
||||
<span class="code-name" :class="{ code: data.type === 'code', hook: data.type === 'key' }"
|
||||
>{{ data.name }}({{ data.id }})</span
|
||||
>
|
||||
<!-- 右侧工具栏 -->
|
||||
<div class="right-tool" v-if="data.type === 'code'">
|
||||
<TMagicTooltip effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
|
||||
@ -59,9 +62,10 @@ import { TMagicButton, tMagicMessage, TMagicScrollbar, TMagicTooltip, TMagicTree
|
||||
import { ColumnConfig } from '@tmagic/form';
|
||||
import { CodeBlockContent, Id } from '@tmagic/schema';
|
||||
|
||||
import CodeIcon from '@editor/components/CodeIcon.vue';
|
||||
import Icon from '@editor/components/Icon.vue';
|
||||
import SearchInput from '@editor/components/SearchInput.vue';
|
||||
import AppManageIcon from '@editor/icons/AppManageIcon.vue';
|
||||
import CodeIcon from '@editor/icons/CodeIcon.vue';
|
||||
import { CodeDeleteErrorType, CodeDslItem, Services } from '@editor/type';
|
||||
|
||||
import CodeBlockEditor from './CodeBlockEditor.vue';
|
||||
@ -75,21 +79,25 @@ const { codeBlockService, depService, editorService } = inject<Services>('servic
|
||||
|
||||
// 代码块列表
|
||||
const codeList = computed(() =>
|
||||
Object.values(depService?.targets['code-block'] || {}).map((target) => ({
|
||||
id: target.id,
|
||||
name: target.name,
|
||||
type: 'code',
|
||||
codeBlockContent: codeBlockService?.getCodeContentById(target.id),
|
||||
children: Object.entries(target.deps).map(([id, dep]) => ({
|
||||
Object.values(depService?.targets['code-block'] || {}).map((target) => {
|
||||
// 组件节点
|
||||
const compNodes = Object.entries(target.deps).map(([id, dep]) => ({
|
||||
name: dep.name,
|
||||
type: 'node',
|
||||
id,
|
||||
children: dep.keys.map((key) => ({ name: key, id: key, type: 'key' })),
|
||||
})),
|
||||
})),
|
||||
}));
|
||||
return {
|
||||
id: target.id,
|
||||
name: target.name,
|
||||
type: 'code',
|
||||
codeBlockContent: codeBlockService?.getCodeContentById(target.id),
|
||||
children: compNodes,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
// 默认展开节点
|
||||
// 默认展开组件层级的节点
|
||||
const expandedKeys = computed(() => codeList.value.map((item) => item.id));
|
||||
|
||||
const editable = computed(() => codeBlockService?.getEditStatus());
|
||||
|
@ -36,21 +36,45 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
|
||||
.right-tool {
|
||||
display: flex;
|
||||
width: fit-content !important;
|
||||
align-items: center;
|
||||
margin-right: 10px;
|
||||
.edit-icon {
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.codeIcon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.compIcon {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.code-name {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 0 !important;
|
||||
flex: 1;
|
||||
line-height: 18px;
|
||||
line-height: 22px;
|
||||
|
||||
&.code {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&.hook {
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,9 +82,8 @@
|
||||
|
||||
.m-fields-code-select {
|
||||
width: 100%;
|
||||
.edit-icon {
|
||||
cursor: pointer;
|
||||
margin-right: 5px;
|
||||
.el-card__header {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,4 +21,16 @@
|
||||
}
|
||||
.m-fields-code-select-col {
|
||||
width: 100%;
|
||||
.code-select-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.select {
|
||||
flex: 10 0 100px;
|
||||
}
|
||||
.icon {
|
||||
flex: 1 0 20px;
|
||||
cursor: pointer;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,10 +29,12 @@ export default {
|
||||
{
|
||||
name: 'age',
|
||||
type: 'number',
|
||||
tip: '年纪',
|
||||
},
|
||||
{
|
||||
name: 'studentName',
|
||||
type: 'text',
|
||||
tip: '学生姓名',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user