mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-04-06 03:57:56 +08:00
feat(editor): 代码块功能增加删除,完善一些边界情况的交互
This commit is contained in:
parent
0c25cf795f
commit
2f803c963a
@ -8,7 +8,14 @@
|
||||
:size="size"
|
||||
@change="changeHandler"
|
||||
></m-fields-select>
|
||||
<el-button type="primary" :icon="View" :size="size" @click="viewHandler">查看</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="View"
|
||||
:size="size"
|
||||
@click="viewHandler"
|
||||
:disabled="props.model[props.name].length === 0"
|
||||
>查看</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -35,6 +42,9 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
const changeHandler = (value: any) => {
|
||||
// 记录组件与代码块的绑定关系
|
||||
const { id = '' } = services?.editorService.get('node') || {};
|
||||
services?.codeBlockService.setCompRelation(id, value);
|
||||
emit('change', value);
|
||||
};
|
||||
|
||||
|
@ -7,13 +7,14 @@
|
||||
:append-to-body="true"
|
||||
>
|
||||
<template v-if="mode === EditorMode.LIST">
|
||||
<el-menu default-active="0" class="el-menu-vertical-demo code-editor-side-menu">
|
||||
<el-menu :default-active="selectedIds[0]" class="el-menu-vertical-demo code-editor-side-menu">
|
||||
<el-menu-item v-for="(value, key) in selectedValue" :index="key" :key="key" @click="menuSelectHandler">
|
||||
<template #title>{{ value.name }}({{ key }})</template>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</template>
|
||||
<div
|
||||
v-if="!isEmpty(codeConfig)"
|
||||
:class="[
|
||||
mode === EditorMode.LIST ? 'm-editor-code-block-editor-panel-list-mode' : '',
|
||||
'm-editor-code-block-editor-panel',
|
||||
@ -55,6 +56,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject, ref, watchEffect } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
|
||||
import type { CodeBlockContent, Services } from '../../../type';
|
||||
import { EditorMode } from '../../../type';
|
||||
@ -70,11 +72,10 @@ const isShowCodeBlockEditor = computed(() => codeConfig.value && services?.codeB
|
||||
const mode = computed(() => services?.codeBlockService.getMode());
|
||||
const id = computed(() => services?.codeBlockService.getId() || '');
|
||||
const editable = computed(() => services?.codeBlockService.getEditStatus());
|
||||
// 当前选中组件绑定的代码块id数组
|
||||
const selectedIds = computed(() => services?.codeBlockService.getCombineIds() || []);
|
||||
// select选择的内容(CodeBlockDSL)
|
||||
const selectedValue = computed(() => {
|
||||
const selectedIds = services?.codeBlockService.getCombineIds() || [];
|
||||
return services?.codeBlockService.getCodeDslByIds(selectedIds);
|
||||
});
|
||||
const selectedValue = computed(() => services?.codeBlockService.getCodeDslByIds(selectedIds.value));
|
||||
|
||||
watchEffect(() => {
|
||||
codeConfig.value = services?.codeBlockService.getCodeContentById(id.value) ?? null;
|
||||
|
@ -8,14 +8,17 @@
|
||||
</slot>
|
||||
|
||||
<!-- 代码块列表 -->
|
||||
<div class="list-container" v-if="codeList">
|
||||
<div class="list-container" v-if="!isEmpty(codeList)">
|
||||
<div v-for="(value, key) in codeList" :key="key">
|
||||
<div class="list-item">
|
||||
<div class="code-name">{{ value.name }}({{ key }})</div>
|
||||
<div class="right-tool">
|
||||
<el-tooltip effect="dark" content="编辑代码" placement="top">
|
||||
<el-tooltip effect="dark" content="编辑" placement="top">
|
||||
<el-icon class="edit-icon" @click="editCode(key)"><Edit /></el-icon>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" content="删除" placement="top">
|
||||
<el-icon class="edit-icon" @click="deleteCode(key)"><Close /></el-icon>
|
||||
</el-tooltip>
|
||||
<slot name="code-block-panel-tool" :id="key"></slot>
|
||||
</div>
|
||||
</div>
|
||||
@ -33,8 +36,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject } from 'vue';
|
||||
import { Edit } from '@element-plus/icons-vue';
|
||||
import { Close, Edit } from '@element-plus/icons-vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { flattenDeep, isEmpty, values } from 'lodash-es';
|
||||
|
||||
import type { CodeBlockContent, Services } from '../../../type';
|
||||
import { EditorMode } from '../../../type';
|
||||
@ -58,7 +62,7 @@ const createCodeBlock = () => {
|
||||
name: '代码块',
|
||||
content: `() => {\n // place your code here\n}`,
|
||||
};
|
||||
services?.codeBlockService.setMode(EditorMode.EDITOR);
|
||||
codeBlockService.setMode(EditorMode.EDITOR);
|
||||
const id = codeBlockService.getUniqueId();
|
||||
codeBlockService.setCodeDslById(id, codeConfig);
|
||||
codeBlockService.setCodeEditorContent(true, id);
|
||||
@ -69,4 +73,17 @@ const editCode = (key: string) => {
|
||||
services?.codeBlockService.setMode(EditorMode.EDITOR);
|
||||
services?.codeBlockService.setCodeEditorContent(true, key);
|
||||
};
|
||||
|
||||
// 删除代码块
|
||||
const deleteCode = (key: string) => {
|
||||
const compRelation = services?.codeBlockService.getCompRelation();
|
||||
const codeIds = flattenDeep(values(compRelation));
|
||||
const undeleteableList = services?.codeBlockService.getUndeletableList() || [];
|
||||
if (!codeIds.includes(key) && !undeleteableList.includes(key)) {
|
||||
// 无绑定关系,且不在不可删除列表中
|
||||
services?.codeBlockService.deleteCodeDslByIds([key]);
|
||||
} else {
|
||||
ElMessage.error('代码块删除失败');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -17,9 +17,9 @@
|
||||
*/
|
||||
|
||||
import { reactive } from 'vue';
|
||||
import { keys, pick } from 'lodash-es';
|
||||
import { keys, omit, pick } from 'lodash-es';
|
||||
|
||||
import type { CodeBlockContent, CodeBlockDSL, CodeState } from '../type';
|
||||
import type { CodeBlockContent, CodeBlockDSL, CodeState, CompRelation } from '../type';
|
||||
import { EditorMode } from '../type';
|
||||
import { info } from '../utils/logger';
|
||||
|
||||
@ -33,6 +33,8 @@ class CodeBlock extends BaseService {
|
||||
editable: true,
|
||||
mode: EditorMode.EDITOR,
|
||||
combineIds: [],
|
||||
compRelation: {},
|
||||
undeletableList: [],
|
||||
});
|
||||
|
||||
constructor() {
|
||||
@ -185,7 +187,7 @@ class CodeBlock extends BaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前已关联绑定的代码块id数组
|
||||
* 设置当前选中组件已关联绑定的代码块id数组
|
||||
* @param {string[]} ids 代码块id数组
|
||||
* @returns {void}
|
||||
*/
|
||||
@ -194,13 +196,63 @@ class CodeBlock extends BaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前已关联绑定的代码块id数组
|
||||
* 获取当前选中组件已关联绑定的代码块id数组
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public getCombineIds(): string[] {
|
||||
return this.state.combineIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置组件与代码块的绑定关系
|
||||
* @param {number | string} compId 组件id
|
||||
* @param {string[]} codeIds 代码块id数组
|
||||
* @returns {void}
|
||||
*/
|
||||
public setCompRelation(compId: number | string, codeIds: string[]) {
|
||||
if (!compId) return;
|
||||
this.state.compRelation = {
|
||||
[compId]: codeIds,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组件与代码块的绑定关系
|
||||
* @returns {CompRelation}
|
||||
*/
|
||||
public getCompRelation(): CompRelation {
|
||||
return this.state.compRelation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取不可删除列表
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public getUndeletableList(): string[] {
|
||||
return this.state.undeletableList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置不可删除列表:为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除)
|
||||
* @param {string[]} codeIds 代码块id数组
|
||||
* @returns {void}
|
||||
*/
|
||||
public setUndeleteableList(codeIds: string[]): void {
|
||||
this.state.undeletableList = codeIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在dsl数据源中删除指定id的代码块
|
||||
* @param {string[]} codeIds 需要删除的代码块id数组
|
||||
* @returns {CodeBlockDSL} 删除后的code dsl
|
||||
*/
|
||||
public deleteCodeDslByIds(codeIds: string[]): CodeBlockDSL {
|
||||
const currentDsl = this.getCodeDsl();
|
||||
const newDsl = omit(currentDsl, codeIds);
|
||||
this.setCodeDsl(newDsl);
|
||||
return newDsl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成代码块唯一id
|
||||
* @returns {string} 代码块唯一id
|
||||
|
@ -328,11 +328,23 @@ export type CodeState = {
|
||||
id: string;
|
||||
/** 代码块是否可编辑 */
|
||||
editable: boolean;
|
||||
/** 代码编辑面板的展示模式 */
|
||||
mode: EditorMode;
|
||||
/** list模式下左侧展示的代码列表 */
|
||||
combineIds: string[];
|
||||
/** 组件和代码块的绑定关系 */
|
||||
compRelation: CompRelation;
|
||||
/** 为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除) */
|
||||
undeletableList: string[];
|
||||
};
|
||||
|
||||
export enum EditorMode {
|
||||
/** 左侧菜单,右侧代码 */
|
||||
LIST = 'list',
|
||||
/** 全屏代码 */
|
||||
EDITOR = 'editor',
|
||||
}
|
||||
|
||||
export type CompRelation = {
|
||||
[compId: string | number]: string[];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user