mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-01 03:28:59 +08:00
feat(脑图): 脑图拖拽拦截&空白节点保存&部分 bug 修复
This commit is contained in:
parent
7ee89429c7
commit
99328a50e5
@ -94,9 +94,11 @@
|
|||||||
const stepTag = t('ms.minders.stepDesc');
|
const stepTag = t('ms.minders.stepDesc');
|
||||||
const textTag = t('ms.minders.textDesc');
|
const textTag = t('ms.minders.textDesc');
|
||||||
const prerequisiteTag = t('ms.minders.precondition');
|
const prerequisiteTag = t('ms.minders.precondition');
|
||||||
const remarkTag = t('common.remark');
|
const stepExpectTag = t('ms.minders.stepExpect');
|
||||||
|
const remarkTag = t('ms.minders.remark');
|
||||||
const descTags = [stepTag, textTag];
|
const descTags = [stepTag, textTag];
|
||||||
const caseChildTags = [prerequisiteTag, stepTag, textTag, remarkTag];
|
const caseChildTags = [prerequisiteTag, stepTag, textTag, remarkTag];
|
||||||
|
const caseOffspringTags = [...caseChildTags, stepTag, stepExpectTag, textTag, remarkTag];
|
||||||
const importJson = ref<MinderJson>({
|
const importJson = ref<MinderJson>({
|
||||||
root: {} as MinderJsonNode,
|
root: {} as MinderJsonNode,
|
||||||
template: 'default',
|
template: 'default',
|
||||||
@ -110,6 +112,7 @@
|
|||||||
updateCaseList: [],
|
updateCaseList: [],
|
||||||
updateModuleList: [],
|
updateModuleList: [],
|
||||||
deleteResourceList: [],
|
deleteResourceList: [],
|
||||||
|
additionalNodeList: [],
|
||||||
});
|
});
|
||||||
const templateId = ref('');
|
const templateId = ref('');
|
||||||
|
|
||||||
@ -153,6 +156,7 @@
|
|||||||
id: 'NONE',
|
id: 'NONE',
|
||||||
text: t('ms.minders.allModule'),
|
text: t('ms.minders.allModule'),
|
||||||
resource: [moduleTag],
|
resource: [moduleTag],
|
||||||
|
disabled: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
window.minder.importJson(importJson.value);
|
window.minder.importJson(importJson.value);
|
||||||
@ -217,31 +221,31 @@
|
|||||||
let remarkNode: MinderJsonNode | undefined; // 备注
|
let remarkNode: MinderJsonNode | undefined; // 备注
|
||||||
const stepNodes: MinderJsonNode[] = []; // 步骤描述
|
const stepNodes: MinderJsonNode[] = []; // 步骤描述
|
||||||
node.children?.forEach((item) => {
|
node.children?.forEach((item) => {
|
||||||
if (item.data.resource?.includes(textTag)) {
|
if (item.data?.resource?.includes(textTag)) {
|
||||||
textStep = item;
|
textStep = item;
|
||||||
} else if (item.data.resource?.includes(stepTag)) {
|
} else if (item.data?.resource?.includes(stepTag)) {
|
||||||
stepNodes.push(item);
|
stepNodes.push(item);
|
||||||
} else if (item.data.resource?.includes(prerequisiteTag)) {
|
} else if (item.data?.resource?.includes(prerequisiteTag)) {
|
||||||
prerequisiteNode = item;
|
prerequisiteNode = item;
|
||||||
} else if (item.data.resource?.includes(remarkTag)) {
|
} else if (item.data?.resource?.includes(remarkTag)) {
|
||||||
remarkNode = item;
|
remarkNode = item;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const steps: FeatureCaseMinderStepItem[] = stepNodes.map((child, i) => {
|
const steps: FeatureCaseMinderStepItem[] = stepNodes.map((child, i) => {
|
||||||
return {
|
return {
|
||||||
id: child.data.id,
|
id: child.data?.id || getGenerateId(),
|
||||||
num: i,
|
num: i,
|
||||||
desc: child.data.text,
|
desc: child.data?.text || '',
|
||||||
result: child.children?.[0].data.text || '',
|
result: child.children?.[0].data?.text || '',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
prerequisite: prerequisiteNode?.data.text || '',
|
prerequisite: prerequisiteNode?.data?.text || '',
|
||||||
caseEditType: steps.length > 0 ? 'STEP' : ('TEXT' as FeatureCaseMinderEditType),
|
caseEditType: steps.length > 0 ? 'STEP' : ('TEXT' as FeatureCaseMinderEditType),
|
||||||
steps: JSON.stringify(steps),
|
steps: JSON.stringify(steps),
|
||||||
textDescription: textStep?.data.text || '',
|
textDescription: textStep?.data?.text || '',
|
||||||
expectedResult: textStep?.children?.[0]?.data.text || '',
|
expectedResult: textStep?.children?.[0]?.data?.text || '',
|
||||||
description: remarkNode?.data.text || '',
|
description: remarkNode?.data?.text || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,15 +254,14 @@
|
|||||||
* @param node 节点
|
* @param node 节点
|
||||||
* @param parent 父节点
|
* @param parent 父节点
|
||||||
*/
|
*/
|
||||||
function getNodeMoveInfo(node: MinderJsonNode, parent?: MinderJsonNode): { moveMode: MoveMode; targetId?: string } {
|
function getNodeMoveInfo(nodeIndex: number, parent?: MinderJsonNode): { moveMode: MoveMode; targetId?: string } {
|
||||||
const nodeIndex = parent?.children?.findIndex((e) => e.data.id === node.data.id);
|
const moveMode = nodeIndex === 0 ? 'BEFORE' : 'AFTER'; // 除了第一个以外,其他都是在目标节点后面插入
|
||||||
const moveMode = nodeIndex === 0 ? 'BEFORE' : 'AFTER';
|
|
||||||
return {
|
return {
|
||||||
moveMode,
|
moveMode,
|
||||||
targetId:
|
targetId:
|
||||||
moveMode === 'BEFORE'
|
moveMode === 'BEFORE'
|
||||||
? parent?.children?.[1]?.data.id
|
? parent?.children?.[1]?.data?.id
|
||||||
: parent?.children?.[(nodeIndex || parent.children.length - 1) - 1]?.data.id,
|
: parent?.children?.[(nodeIndex || parent.children.length - 1) - 1]?.data?.id,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,17 +270,19 @@
|
|||||||
*/
|
*/
|
||||||
function makeMinderParams(): FeatureCaseMinderUpdateParams {
|
function makeMinderParams(): FeatureCaseMinderUpdateParams {
|
||||||
const fullJson: MinderJson = window.minder.exportJson();
|
const fullJson: MinderJson = window.minder.exportJson();
|
||||||
filterTree(fullJson.root.children, (node, parent) => {
|
filterTree(fullJson.root.children, (node, nodeIndex, parent) => {
|
||||||
if (node.data.isNew !== false || node.data.changed === true) {
|
if (node.data.isNew !== false || node.data.changed === true) {
|
||||||
if (node.data.resource?.includes(moduleTag)) {
|
if (node.data.resource?.includes(moduleTag)) {
|
||||||
|
// 处理模块节点
|
||||||
tempMinderParams.value.updateModuleList.push({
|
tempMinderParams.value.updateModuleList.push({
|
||||||
id: node.data.id,
|
id: node.data.id,
|
||||||
name: node.data.text,
|
name: node.data.text,
|
||||||
parentId: parent?.data.id || 'NONE',
|
parentId: parent?.data.id || 'NONE',
|
||||||
type: node.data.isNew !== false ? 'ADD' : 'UPDATE',
|
type: node.data.isNew !== false ? 'ADD' : 'UPDATE',
|
||||||
...getNodeMoveInfo(node as MinderJsonNode, parent as MinderJsonNode),
|
...getNodeMoveInfo(nodeIndex, parent as MinderJsonNode),
|
||||||
});
|
});
|
||||||
} else if (node.data.resource?.includes(caseTag)) {
|
} else if (node.data.resource?.includes(caseTag)) {
|
||||||
|
// 处理用例节点
|
||||||
const caseNodeInfo = getCaseNodeInfo(node as MinderJsonNode);
|
const caseNodeInfo = getCaseNodeInfo(node as MinderJsonNode);
|
||||||
const caseBaseInfo = baseInfoRef.value?.makeParams();
|
const caseBaseInfo = baseInfoRef.value?.makeParams();
|
||||||
tempMinderParams.value.updateCaseList.push({
|
tempMinderParams.value.updateCaseList.push({
|
||||||
@ -288,10 +293,19 @@
|
|||||||
tags: caseBaseInfo?.tags || [],
|
tags: caseBaseInfo?.tags || [],
|
||||||
customFields: caseBaseInfo?.customFields || [],
|
customFields: caseBaseInfo?.customFields || [],
|
||||||
name: caseBaseInfo?.name || node.data.text,
|
name: caseBaseInfo?.name || node.data.text,
|
||||||
...getNodeMoveInfo(node as MinderJsonNode, parent as MinderJsonNode),
|
...getNodeMoveInfo(nodeIndex, parent as MinderJsonNode),
|
||||||
...caseNodeInfo,
|
...caseNodeInfo,
|
||||||
});
|
});
|
||||||
return false; // 用例的子孙节点已经处理过,跳过
|
return false; // 用例的子孙节点已经处理过,跳过
|
||||||
|
} else if (!node.data.resource) {
|
||||||
|
// 处理文本节点
|
||||||
|
tempMinderParams.value.additionalNodeList.push({
|
||||||
|
id: node.data.id,
|
||||||
|
parentId: parent?.data.id || 'NONE',
|
||||||
|
type: node.data.isNew !== false ? 'ADD' : 'UPDATE',
|
||||||
|
name: node.data.text,
|
||||||
|
...getNodeMoveInfo(nodeIndex, parent as MinderJsonNode),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -316,7 +330,7 @@
|
|||||||
* 已选中节点的可替换标签判断
|
* 已选中节点的可替换标签判断
|
||||||
* @param node 选中节点
|
* @param node 选中节点
|
||||||
*/
|
*/
|
||||||
function replaceableTags(node: MinderJsonNode, nodes: MinderJsonNode[]) {
|
function replaceableTags(nodes: MinderJsonNode[]) {
|
||||||
if (nodes.length > 1) {
|
if (nodes.length > 1) {
|
||||||
// 选中的节点大于 1 时
|
// 选中的节点大于 1 时
|
||||||
if (nodes.some((e) => (e.data?.resource || []).length > 0)) {
|
if (nodes.some((e) => (e.data?.resource || []).length > 0)) {
|
||||||
@ -328,10 +342,11 @@
|
|||||||
return [moduleTag];
|
return [moduleTag];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const node = nodes[0];
|
||||||
if (
|
if (
|
||||||
Object.keys(node.data || {}).length === 0 ||
|
Object.keys(node.data || {}).length === 0 ||
|
||||||
node.data?.id === 'root' ||
|
node.data?.id === 'root' ||
|
||||||
(node.parent?.data.resource || []).length === 0
|
(node.parent?.data?.resource || []).length === 0
|
||||||
) {
|
) {
|
||||||
// 没有数据的节点、默认模块节点、父节点为文本节点的节点不可替换标签
|
// 没有数据的节点、默认模块节点、父节点为文本节点的节点不可替换标签
|
||||||
return [];
|
return [];
|
||||||
@ -357,18 +372,21 @@
|
|||||||
// 选中节点无标签,且父节点为用例节点,可替换用例下级标签
|
// 选中节点无标签,且父节点为用例节点,可替换用例下级标签
|
||||||
return caseChildTags;
|
return caseChildTags;
|
||||||
}
|
}
|
||||||
if (
|
if ((!node.data?.resource || node.data.resource.length === 0) && node.parent?.data?.resource?.includes(moduleTag)) {
|
||||||
(!node.data?.resource || node.data.resource.length === 0) &&
|
// 选中节点是文本节点、选中节点的父节点是模块节点
|
||||||
(!node.parent?.data?.resource ||
|
if (
|
||||||
node.parent?.data?.resource.length === 0 ||
|
(node.children &&
|
||||||
node.parent?.data?.resource?.some((e) => topTags.includes(e)))
|
(node.children.some((e) => e.data?.resource?.includes(caseTag)) ||
|
||||||
) {
|
node.children.some((e) => e.data?.resource?.includes(moduleTag)))) ||
|
||||||
// 如果选中节点子级含有用例节点或模块节点,则不可将选中节点标记为用例
|
node.parent?.data?.id === 'NONE'
|
||||||
return node.children &&
|
) {
|
||||||
(node.children.some((e) => e.data?.resource?.includes(caseTag)) ||
|
// 如果选中节点子级含有用例节点或模块节点,或者选中节点的父节点是根节点 NONE,只能将节点标记为模块节点
|
||||||
node.children.some((e) => e.data?.resource?.includes(moduleTag)))
|
return [moduleTag];
|
||||||
? topTags.filter((e) => e !== caseTag)
|
}
|
||||||
: topTags;
|
if (!node.children || node.children.length === 0) {
|
||||||
|
// 如果选中节点无子级,可标记为用例节点或模块节点
|
||||||
|
return topTags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@ -383,7 +401,22 @@
|
|||||||
window.minder.execCommand(command, node);
|
window.minder.execCommand(command, node);
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const newNode: MinderJsonNode = window.minder.getSelectedNode();
|
const newNode: MinderJsonNode = window.minder.getSelectedNode();
|
||||||
|
if (!newNode.data) {
|
||||||
|
newNode.data = {
|
||||||
|
id: getGenerateId(),
|
||||||
|
text: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
newNode.data.isNew = true; // 新建的节点标记为新建
|
newNode.data.isNew = true; // 新建的节点标记为新建
|
||||||
|
if (newNode.data?.resource?.some((e) => caseOffspringTags.includes(e))) {
|
||||||
|
// 用例子孙节点更新,标记用例节点变化
|
||||||
|
if (newNode.parent?.data?.resource?.includes(caseTag)) {
|
||||||
|
newNode.parent.data.changed = true;
|
||||||
|
} else if (newNode.parent?.parent?.data?.resource?.includes(caseTag)) {
|
||||||
|
// 期望结果是第三层节点
|
||||||
|
newNode.parent.parent.data.changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,8 +470,8 @@
|
|||||||
parent: node,
|
parent: node,
|
||||||
data: {
|
data: {
|
||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
text: t('ms.minders.stepDesc'),
|
text: stepTag,
|
||||||
resource: [t('ms.minders.stepDesc')],
|
resource: [stepTag],
|
||||||
isNew: true,
|
isNew: true,
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
@ -447,8 +480,8 @@
|
|||||||
parent: child,
|
parent: child,
|
||||||
data: {
|
data: {
|
||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
text: t('ms.minders.stepExpect'),
|
text: stepExpectTag,
|
||||||
resource: [t('ms.minders.stepExpect')],
|
resource: [stepExpectTag],
|
||||||
isNew: true,
|
isNew: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -468,8 +501,8 @@
|
|||||||
parent: node,
|
parent: node,
|
||||||
data: {
|
data: {
|
||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
text: t('ms.minders.stepExpect'),
|
text: stepExpectTag,
|
||||||
resource: [t('ms.minders.stepExpect')],
|
resource: [stepExpectTag],
|
||||||
isNew: true,
|
isNew: true,
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
@ -587,14 +620,22 @@
|
|||||||
if (tag === moduleTag && node.data) {
|
if (tag === moduleTag && node.data) {
|
||||||
// 排除是从用例节点切换到模块节点的数据
|
// 排除是从用例节点切换到模块节点的数据
|
||||||
tempMinderParams.value.updateCaseList = tempMinderParams.value.updateCaseList.filter(
|
tempMinderParams.value.updateCaseList = tempMinderParams.value.updateCaseList.filter(
|
||||||
(e) => e.id !== node.data.id
|
(e) => e.id !== node.data?.id
|
||||||
);
|
);
|
||||||
window.minder.execCommand('priority');
|
window.minder.execCommand('priority');
|
||||||
} else if (node.data.resource?.includes(caseTag)) {
|
} else if (node.data?.resource?.includes(caseTag)) {
|
||||||
// 排除是从模块节点切换到用例节点的数据
|
// 排除是从模块节点切换到用例节点的数据
|
||||||
tempMinderParams.value.updateModuleList = tempMinderParams.value.updateModuleList.filter(
|
tempMinderParams.value.updateModuleList = tempMinderParams.value.updateModuleList.filter(
|
||||||
(e) => e.id !== node.data.id
|
(e) => e.id !== node.data?.id
|
||||||
);
|
);
|
||||||
|
} else if (node.data?.resource?.some((e) => caseOffspringTags.includes(e))) {
|
||||||
|
// 用例子孙节点更新,标记用例节点变化
|
||||||
|
if (node.parent?.data?.resource?.includes(caseTag)) {
|
||||||
|
node.parent.data.changed = true;
|
||||||
|
} else if (node.parent?.parent?.data?.resource?.includes(caseTag)) {
|
||||||
|
// 期望结果是第三层节点
|
||||||
|
node.parent.parent.data.changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const baseInfoLoading = ref(false);
|
const baseInfoLoading = ref(false);
|
||||||
@ -792,9 +833,12 @@
|
|||||||
node.expand();
|
node.expand();
|
||||||
node.renderTree();
|
node.renderTree();
|
||||||
window.minder.layout();
|
window.minder.layout();
|
||||||
|
window.minder.execCommand('camera', node, 600);
|
||||||
if (node.data) {
|
if (node.data) {
|
||||||
node.data.isLoaded = true;
|
node.data.isLoaded = true;
|
||||||
}
|
}
|
||||||
|
// 加载完用例数据后,更新当前importJson数据
|
||||||
|
importJson.value = window.minder.exportJson();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@ -812,25 +856,33 @@
|
|||||||
* @param event 脑图事件对象
|
* @param event 脑图事件对象
|
||||||
*/
|
*/
|
||||||
function handleAction(event: MinderCustomEvent) {
|
function handleAction(event: MinderCustomEvent) {
|
||||||
const { node, name } = event;
|
const { nodes, name } = event;
|
||||||
if (node) {
|
if (nodes && nodes.length > 0) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case MinderEventName.DELETE_NODE:
|
case MinderEventName.DELETE_NODE:
|
||||||
tempMinderParams.value.deleteResourceList.push({
|
// TODO:循环优化
|
||||||
id: node.data.id,
|
nodes.forEach((node) => {
|
||||||
type: node.data?.resource?.[0] || moduleTag,
|
tempMinderParams.value.deleteResourceList.push({
|
||||||
|
id: node.data?.id || getGenerateId(),
|
||||||
|
type: node.data?.resource?.[0] || moduleTag,
|
||||||
|
});
|
||||||
|
if (node.data?.resource?.includes(caseTag)) {
|
||||||
|
// 删除用例节点
|
||||||
|
tempMinderParams.value.updateCaseList = tempMinderParams.value.updateCaseList.filter(
|
||||||
|
(e) => e.id !== node.data?.id
|
||||||
|
);
|
||||||
|
} else if (node.data?.resource?.includes(moduleTag)) {
|
||||||
|
// 删除模块节点
|
||||||
|
tempMinderParams.value.updateModuleList = tempMinderParams.value.updateModuleList.filter(
|
||||||
|
(e) => e.id !== node.data?.id
|
||||||
|
);
|
||||||
|
} else if (!node.data?.resource) {
|
||||||
|
// 删除文本节点
|
||||||
|
tempMinderParams.value.additionalNodeList = tempMinderParams.value.additionalNodeList.filter(
|
||||||
|
(e) => e.id !== node.data?.id
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (node.data?.resource?.includes(caseTag)) {
|
|
||||||
// 删除用例节点
|
|
||||||
tempMinderParams.value.updateCaseList = tempMinderParams.value.updateCaseList.filter(
|
|
||||||
(e) => e.id !== node.data.id
|
|
||||||
);
|
|
||||||
} else if (node.data?.resource?.includes(moduleTag)) {
|
|
||||||
// 删除模块节点
|
|
||||||
tempMinderParams.value.updateModuleList = tempMinderParams.value.updateModuleList.filter(
|
|
||||||
(e) => e.id !== node.data.id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -838,10 +890,111 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否停止拖拽动作
|
||||||
|
* @param dragNode 拖动节点
|
||||||
|
* @param dropNode 目标节点
|
||||||
|
* @param mode 拖拽模式
|
||||||
|
*/
|
||||||
|
function stopDrag(
|
||||||
|
dragNodes: MinderJsonNode | MinderJsonNode[],
|
||||||
|
dropNode: MinderJsonNode,
|
||||||
|
mode: 'movetoparent' | 'arrange'
|
||||||
|
) {
|
||||||
|
if (!Array.isArray(dragNodes)) {
|
||||||
|
dragNodes = [dragNodes];
|
||||||
|
}
|
||||||
|
for (let i = 0; i < dragNodes.length; i++) {
|
||||||
|
const dragNode = (dragNodes as MinderJsonNode[])[i];
|
||||||
|
if (mode === 'movetoparent') {
|
||||||
|
// 拖拽到目标节点内
|
||||||
|
if (dragNode.data?.resource?.includes(caseTag) && dropNode.data?.id === 'NONE') {
|
||||||
|
// 用例不能拖拽到根模块节点内
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(dragNode.data?.resource?.includes(moduleTag) || dragNode.data?.resource?.includes(caseTag)) &&
|
||||||
|
dropNode.data?.resource?.includes(moduleTag)
|
||||||
|
) {
|
||||||
|
// 模块、用例只能拖拽到模块节点内
|
||||||
|
if (dragNode.data) {
|
||||||
|
dragNode.data.changed = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dragNode.data?.resource && (dropNode.data?.resource?.includes(moduleTag) || !dropNode.data?.resource)) {
|
||||||
|
// 文本节点只能拖拽到模块、文本节点内
|
||||||
|
if (dragNode.data) {
|
||||||
|
dragNode.data.changed = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
dragNode.data?.resource?.some((e) => caseChildTags.includes(e)) &&
|
||||||
|
dropNode.data?.resource?.includes(caseTag) &&
|
||||||
|
dragNode.parent?.data?.id === dropNode.data?.id
|
||||||
|
) {
|
||||||
|
// 一个用例下的子节点只能拖拽到它自身内
|
||||||
|
if (dragNode.parent?.data) {
|
||||||
|
dragNode.parent.data.changed = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (mode === 'arrange') {
|
||||||
|
// 拖拽到目标节点前后
|
||||||
|
if (
|
||||||
|
(dragNode.data?.resource?.includes(moduleTag) ||
|
||||||
|
dragNode.data?.resource?.includes(caseTag) ||
|
||||||
|
!dragNode.data?.resource) &&
|
||||||
|
(dropNode.data?.resource?.includes(moduleTag) ||
|
||||||
|
dropNode.data?.resource?.includes(caseTag) ||
|
||||||
|
!dropNode.data?.resource)
|
||||||
|
) {
|
||||||
|
if (dragNode.data) {
|
||||||
|
dragNode.data.changed = true;
|
||||||
|
}
|
||||||
|
// 模块、用例、文本节点只能拖拽到模块、用例、文本节点前后
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dragNode.data?.resource?.includes(stepTag) && dropNode.data?.resource?.includes(stepTag)) {
|
||||||
|
if (dragNode.parent?.data) {
|
||||||
|
dragNode.parent.data.changed = true;
|
||||||
|
}
|
||||||
|
// 用例节点下的步骤节点之间拖拽排序
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 脑图命令执行前拦截
|
||||||
|
* @param event 命令执行事件
|
||||||
|
*/
|
||||||
function handleBeforeExecCommand(event: MinderEvent) {
|
function handleBeforeExecCommand(event: MinderEvent) {
|
||||||
if (event.commandName === 'movetoparent') {
|
if (event.commandName === 'movetoparent') {
|
||||||
// TODO:拖拽拦截
|
// 拖拽到节点内拦截
|
||||||
event.stopPropagation();
|
if (stopDrag(event.commandArgs[0] as MinderJsonNode, event.commandArgs[1] as MinderJsonNode, 'movetoparent')) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
} else if (event.commandName === 'arrange') {
|
||||||
|
// 拖拽排序拦截
|
||||||
|
const dragNodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
||||||
|
let dropNode: MinderJsonNode;
|
||||||
|
if (dragNodes[0].parent?.children?.[event.commandArgs[0] as number]) {
|
||||||
|
// 释放到目标节点后
|
||||||
|
dropNode = dragNodes[0].parent?.children?.[event.commandArgs[0] as number];
|
||||||
|
} else if (dragNodes[0].parent?.children?.[(event.commandArgs[0] as number) - 1]) {
|
||||||
|
// 释放到目标节点前
|
||||||
|
dropNode = dragNodes[0].parent?.children?.[(event.commandArgs[0] as number) - 1];
|
||||||
|
} else {
|
||||||
|
// 释放到最后一个节点
|
||||||
|
dropNode = dragNodes[dragNodes.length - 1];
|
||||||
|
}
|
||||||
|
if (stopDrag(dragNodes, dropNode, 'arrange')) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -4,6 +4,7 @@ export default {
|
|||||||
'ms.minders.stepDesc': 'Step Description',
|
'ms.minders.stepDesc': 'Step Description',
|
||||||
'ms.minders.stepExpect': 'Expected Result',
|
'ms.minders.stepExpect': 'Expected Result',
|
||||||
'ms.minders.textDesc': 'Text Description',
|
'ms.minders.textDesc': 'Text Description',
|
||||||
|
'ms.minders.remark': 'Remark Information',
|
||||||
'ms.minders.caseName': 'Test Case Name',
|
'ms.minders.caseName': 'Test Case Name',
|
||||||
'ms.minders.caseNameNotNull': 'Test Case Name cannot be empty',
|
'ms.minders.caseNameNotNull': 'Test Case Name cannot be empty',
|
||||||
'ms.minders.commentTotal': '{num} Comments in Total',
|
'ms.minders.commentTotal': '{num} Comments in Total',
|
||||||
|
@ -4,6 +4,7 @@ export default {
|
|||||||
'ms.minders.stepDesc': '步骤描述',
|
'ms.minders.stepDesc': '步骤描述',
|
||||||
'ms.minders.stepExpect': '预期结果',
|
'ms.minders.stepExpect': '预期结果',
|
||||||
'ms.minders.textDesc': '文本描述',
|
'ms.minders.textDesc': '文本描述',
|
||||||
|
'ms.minders.remark': '备注信息',
|
||||||
'ms.minders.caseName': '用例名称',
|
'ms.minders.caseName': '用例名称',
|
||||||
'ms.minders.caseNameNotNull': '用例名称不能为空',
|
'ms.minders.caseNameNotNull': '用例名称不能为空',
|
||||||
'ms.minders.commentTotal': '共 {num} 评论',
|
'ms.minders.commentTotal': '共 {num} 评论',
|
||||||
|
@ -44,7 +44,8 @@ export default function useEventListener(listener: UseEventListenerProps) {
|
|||||||
// console.log('dragFinish', minder.history);
|
// console.log('dragFinish', minder.history);
|
||||||
// });
|
// });
|
||||||
|
|
||||||
minder.on('beforeExecCommand', (e: any) => {
|
// 监听脑图执行命令前(可通过e.stopPropagation拦截命令执行)
|
||||||
|
minder.on('beforeExecCommand', (e: MinderEvent) => {
|
||||||
if (listener.handleBeforeExecCommand) {
|
if (listener.handleBeforeExecCommand) {
|
||||||
listener.handleBeforeExecCommand(e);
|
listener.handleBeforeExecCommand(e);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useMinderStore from '@/store/modules/components/minder-editor';
|
import useMinderStore from '@/store/modules/components/minder-editor';
|
||||||
import { findNodePathByKey } from '@/utils';
|
import { findNodePathByKey, getGenerateId } from '@/utils';
|
||||||
|
|
||||||
import { MinderEventName } from '@/enums/minderEnum';
|
import { MinderEventName } from '@/enums/minderEnum';
|
||||||
|
|
||||||
@ -94,6 +94,7 @@
|
|||||||
mainEditorProps,
|
mainEditorProps,
|
||||||
MinderJson,
|
MinderJson,
|
||||||
MinderJsonNode,
|
MinderJsonNode,
|
||||||
|
MinderJsonNodeData,
|
||||||
priorityProps,
|
priorityProps,
|
||||||
tagProps,
|
tagProps,
|
||||||
} from '../props';
|
} from '../props';
|
||||||
@ -214,14 +215,6 @@
|
|||||||
init();
|
init();
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.importJson,
|
|
||||||
(val) => {
|
|
||||||
innerImportJson.value = val;
|
|
||||||
window.minder.importJson(val);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const menuVisible = ref(false);
|
const menuVisible = ref(false);
|
||||||
const menuPopupOffset = ref([0, 0]);
|
const menuPopupOffset = ref([0, 0]);
|
||||||
|
|
||||||
@ -229,12 +222,17 @@
|
|||||||
* 切换脑图展示的节点层级
|
* 切换脑图展示的节点层级
|
||||||
* @param node 切换的节点
|
* @param node 切换的节点
|
||||||
*/
|
*/
|
||||||
function switchNode(node: MinderJsonNode) {
|
function switchNode(node: MinderJsonNode | MinderJsonNodeData) {
|
||||||
innerImportJson.value = cloneDeep(findNodePathByKey([props.importJson.root], node.data?.id, 'data', 'id'));
|
if (node.data) {
|
||||||
|
innerImportJson.value = cloneDeep(findNodePathByKey([props.importJson.root], node.data.id, 'data', 'id'));
|
||||||
|
} else {
|
||||||
|
innerImportJson.value = cloneDeep(findNodePathByKey([props.importJson.root], node.id, 'data', 'id'));
|
||||||
|
}
|
||||||
innerImportJson.value.data.expandState = 'expand';
|
innerImportJson.value.data.expandState = 'expand';
|
||||||
window.minder.importJson(innerImportJson.value);
|
window.minder.importJson(innerImportJson.value);
|
||||||
window.minder.execCommand('template', Object.keys(window.kityminder.Minder.getTemplateList())[minderStore.mold]);
|
setTimeout(() => {
|
||||||
minderStore.dispatchEvent(MinderEventName.ENTER_NODE, undefined, undefined, node);
|
window.minder.execCommand('camera', window.minder.getRoot(), 600);
|
||||||
|
}, 100); // TODO:暂未知渲染时机,临时延迟解决
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -248,8 +246,8 @@
|
|||||||
];
|
];
|
||||||
menuVisible.value = true;
|
menuVisible.value = true;
|
||||||
}
|
}
|
||||||
if (minderStore.event.name === MinderEventName.ENTER_NODE && minderStore.event.node) {
|
if (minderStore.event.name === MinderEventName.ENTER_NODE && minderStore.event.nodes) {
|
||||||
switchNode(minderStore.event.node);
|
switchNode(minderStore.event.nodes[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -268,6 +266,12 @@
|
|||||||
window.minder.execCommand(command);
|
window.minder.execCommand(command);
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const newNode: MinderJsonNode = window.minder.getSelectedNode();
|
const newNode: MinderJsonNode = window.minder.getSelectedNode();
|
||||||
|
if (!newNode.data) {
|
||||||
|
newNode.data = {
|
||||||
|
id: getGenerateId(),
|
||||||
|
text: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
newNode.data.isNew = true; // 新建的节点标记为新建
|
newNode.data.isNew = true; // 新建的节点标记为新建
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -278,49 +282,52 @@
|
|||||||
* @param val 选择的菜单项
|
* @param val 选择的菜单项
|
||||||
*/
|
*/
|
||||||
function handleMinderMenuSelect(val: string | number | Record<string, any> | undefined) {
|
function handleMinderMenuSelect(val: string | number | Record<string, any> | undefined) {
|
||||||
const selectedNode = window.minder.getSelectedNode();
|
const selectedNodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
||||||
switch (val) {
|
if (selectedNodes.length > 0) {
|
||||||
case 'expand':
|
switch (val) {
|
||||||
if (selectedNode.data.expandState === 'collapse') {
|
case 'expand':
|
||||||
window.minder.execCommand('Expand');
|
if (selectedNodes.some((node) => node.data?.expandState === 'collapse')) {
|
||||||
} else {
|
window.minder.execCommand('Expand');
|
||||||
window.minder.execCommand('Collapse');
|
} else {
|
||||||
}
|
window.minder.execCommand('Collapse');
|
||||||
minderStore.dispatchEvent(MinderEventName.EXPAND, undefined, undefined, selectedNode);
|
}
|
||||||
break;
|
minderStore.dispatchEvent(MinderEventName.EXPAND, undefined, undefined, selectedNodes);
|
||||||
case 'insetParent':
|
break;
|
||||||
execInsertCommand('AppendParentNode');
|
case 'insetParent':
|
||||||
minderStore.dispatchEvent(MinderEventName.INSERT_PARENT, undefined, undefined, selectedNode);
|
execInsertCommand('AppendParentNode');
|
||||||
break;
|
minderStore.dispatchEvent(MinderEventName.INSERT_PARENT, undefined, undefined, selectedNodes);
|
||||||
case 'insetSon':
|
break;
|
||||||
execInsertCommand('AppendChildNode');
|
case 'insetSon':
|
||||||
minderStore.dispatchEvent(MinderEventName.INSERT_CHILD, undefined, undefined, selectedNode);
|
execInsertCommand('AppendChildNode');
|
||||||
break;
|
minderStore.dispatchEvent(MinderEventName.INSERT_CHILD, undefined, undefined, selectedNodes);
|
||||||
case 'insetBrother':
|
break;
|
||||||
execInsertCommand('AppendSiblingNode');
|
case 'insetBrother':
|
||||||
minderStore.dispatchEvent(MinderEventName.INSERT_SIBLING, undefined, undefined, selectedNode);
|
execInsertCommand('AppendSiblingNode');
|
||||||
break;
|
minderStore.dispatchEvent(MinderEventName.INSERT_SIBLING, undefined, undefined, selectedNodes);
|
||||||
case 'copy':
|
break;
|
||||||
window.minder.execCommand('Copy');
|
case 'copy':
|
||||||
minderStore.dispatchEvent(MinderEventName.COPY_NODE, undefined, undefined, selectedNode);
|
window.minder.execCommand('Copy');
|
||||||
break;
|
minderStore.dispatchEvent(MinderEventName.COPY_NODE, undefined, undefined, selectedNodes);
|
||||||
case 'cut':
|
break;
|
||||||
window.minder.execCommand('Cut');
|
case 'cut':
|
||||||
minderStore.dispatchEvent(MinderEventName.CUT_NODE, undefined, undefined, selectedNode);
|
window.minder.execCommand('Cut');
|
||||||
break;
|
minderStore.dispatchEvent(MinderEventName.CUT_NODE, undefined, undefined, selectedNodes);
|
||||||
case 'paste':
|
break;
|
||||||
window.minder.execCommand('Paste');
|
case 'paste':
|
||||||
minderStore.dispatchEvent(MinderEventName.PASTE_NODE, undefined, undefined, selectedNode);
|
window.minder.execCommand('Paste');
|
||||||
break;
|
minderStore.dispatchEvent(MinderEventName.PASTE_NODE, undefined, undefined, selectedNodes);
|
||||||
case 'delete':
|
break;
|
||||||
window.minder.execCommand('RemoveNode');
|
case 'delete':
|
||||||
minderStore.dispatchEvent(MinderEventName.DELETE_NODE, undefined, undefined, selectedNode);
|
window.minder.execCommand('RemoveNode');
|
||||||
break;
|
minderStore.dispatchEvent(MinderEventName.DELETE_NODE, undefined, undefined, selectedNodes);
|
||||||
case 'enterNode':
|
break;
|
||||||
switchNode(selectedNode.data);
|
case 'enterNode':
|
||||||
break;
|
switchNode(selectedNodes[0]);
|
||||||
default:
|
minderStore.dispatchEvent(MinderEventName.ENTER_NODE, undefined, undefined, [selectedNodes[0]]);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
import { MinderEventName } from '@/enums/minderEnum';
|
import { MinderEventName } from '@/enums/minderEnum';
|
||||||
|
|
||||||
import { delProps } from '../../props';
|
import { delProps, MinderJsonNode } from '../../props';
|
||||||
import { isDeleteDisableNode } from '../../script/tool/utils';
|
import { isDeleteDisableNode } from '../../script/tool/utils';
|
||||||
|
|
||||||
const minderStore = useMinderStore();
|
const minderStore = useMinderStore();
|
||||||
@ -59,19 +59,19 @@
|
|||||||
if (removeNodeDisabled.value || !minder.queryCommandState || !minder.execCommand) {
|
if (removeNodeDisabled.value || !minder.queryCommandState || !minder.execCommand) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const node = minder.getSelectedNode();
|
const nodes: MinderJsonNode[] = minder.getSelectedNodes();
|
||||||
let position: MinderNodePosition | undefined;
|
let position: MinderNodePosition | undefined;
|
||||||
if (node) {
|
if (nodes.length > 0) {
|
||||||
if (props.delConfirm) {
|
if (props.delConfirm) {
|
||||||
props.delConfirm(node);
|
props.delConfirm(nodes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const box = node.getRenderBox();
|
const box = nodes[0].getRenderBox();
|
||||||
position = {
|
position = {
|
||||||
x: box.cx,
|
x: box.cx,
|
||||||
y: box.cy,
|
y: box.cy,
|
||||||
};
|
};
|
||||||
minderStore.dispatchEvent(MinderEventName.DELETE_NODE, position, node.rc.node, node.data);
|
minderStore.dispatchEvent(MinderEventName.DELETE_NODE, position, nodes[0].rc.node, nodes);
|
||||||
}
|
}
|
||||||
minder.forceRemoveNode();
|
minder.forceRemoveNode();
|
||||||
}
|
}
|
||||||
|
@ -47,11 +47,10 @@
|
|||||||
minder.on('selectionchange', () => {
|
minder.on('selectionchange', () => {
|
||||||
commandDisabled.value = isDisable();
|
commandDisabled.value = isDisable();
|
||||||
const nodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
const nodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
||||||
const node: MinderJsonNode = minder.getSelectedNode();
|
|
||||||
if (commandDisabled.value) {
|
if (commandDisabled.value) {
|
||||||
tagList.value = [];
|
tagList.value = [];
|
||||||
} else if (props.replaceableTags) {
|
} else if (props.replaceableTags) {
|
||||||
tagList.value = props.replaceableTags(node, nodes);
|
tagList.value = props.replaceableTags(nodes);
|
||||||
} else {
|
} else {
|
||||||
tagList.value = [];
|
tagList.value = [];
|
||||||
}
|
}
|
||||||
@ -70,8 +69,8 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (props.tagEditCheck) {
|
if (props.tagEditCheck) {
|
||||||
const node: MinderJsonNode = minder.getSelectedNode();
|
const nodes: MinderJsonNode[] = minder.getSelectedNodes();
|
||||||
if (!props.tagEditCheck(node, resourceName)) {
|
if (!props.tagEditCheck(nodes, resourceName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,13 +99,12 @@
|
|||||||
}
|
}
|
||||||
window.minder.execCommand('resource', origin);
|
window.minder.execCommand('resource', origin);
|
||||||
const nodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
const nodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
||||||
const node: MinderJsonNode = minder.getSelectedNode();
|
minderStore.dispatchEvent(MinderEventName.SET_TAG, undefined, undefined, nodes);
|
||||||
minderStore.dispatchEvent(MinderEventName.SET_TAG, undefined, undefined, node);
|
|
||||||
if (props.replaceableTags) {
|
if (props.replaceableTags) {
|
||||||
tagList.value = props.replaceableTags(node, nodes);
|
tagList.value = props.replaceableTags(nodes);
|
||||||
}
|
}
|
||||||
if (props.afterTagEdit) {
|
if (props.afterTagEdit) {
|
||||||
props.afterTagEdit(node, resourceName);
|
props.afterTagEdit(nodes, resourceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -6,19 +6,6 @@ import type { MoveMode } from '@/models/common';
|
|||||||
|
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
|
|
||||||
export interface MinderClass {
|
|
||||||
stopPropagation: () => void; // 阻止事件冒泡
|
|
||||||
stopPropagationImmediately: () => void; // 立即阻止事件冒泡
|
|
||||||
[key: string]: any; // TODO: 其他事件属性
|
|
||||||
}
|
|
||||||
// TODO:脑图事件类型补充
|
|
||||||
export interface MinderEvent extends MinderClass {
|
|
||||||
command: any;
|
|
||||||
commandArgs: Record<string, any>[];
|
|
||||||
commandName: string;
|
|
||||||
minder: any;
|
|
||||||
type: string;
|
|
||||||
}
|
|
||||||
export interface MinderIconButtonItem {
|
export interface MinderIconButtonItem {
|
||||||
icon: string;
|
icon: string;
|
||||||
tooltip: string;
|
tooltip: string;
|
||||||
@ -35,10 +22,11 @@ export interface MinderJsonNodeData {
|
|||||||
changed?: boolean; // 脑图节点是否发生过变化
|
changed?: boolean; // 脑图节点是否发生过变化
|
||||||
moveMode?: MoveMode; // 移动方式(节点移动或新增时需要)
|
moveMode?: MoveMode; // 移动方式(节点移动或新增时需要)
|
||||||
targetId?: string; // 目标节点 id(节点移动或新增时需要)
|
targetId?: string; // 目标节点 id(节点移动或新增时需要)
|
||||||
|
disabled?: boolean; // 是否禁用
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
export interface MinderJsonNode {
|
export interface MinderJsonNode {
|
||||||
data: MinderJsonNodeData;
|
data?: MinderJsonNodeData;
|
||||||
parent?: MinderJsonNode;
|
parent?: MinderJsonNode;
|
||||||
children?: MinderJsonNode[];
|
children?: MinderJsonNode[];
|
||||||
[key: string]: any; // minder 内置字段
|
[key: string]: any; // minder 内置字段
|
||||||
@ -49,6 +37,20 @@ export interface MinderJson {
|
|||||||
template: string;
|
template: string;
|
||||||
treePath: Record<string, MinderJsonNode>[];
|
treePath: Record<string, MinderJsonNode>[];
|
||||||
}
|
}
|
||||||
|
// 脑图类
|
||||||
|
export interface MinderClass {
|
||||||
|
stopPropagation: () => void; // 阻止事件冒泡
|
||||||
|
stopPropagationImmediately: () => void; // 立即阻止事件冒泡
|
||||||
|
[key: string]: any; // TODO: 其他事件属性
|
||||||
|
}
|
||||||
|
// TODO:脑图事件类型补充
|
||||||
|
export interface MinderEvent extends MinderClass {
|
||||||
|
command: any;
|
||||||
|
commandArgs: ((Record<string, any> & MinderJsonNode) | (Record<string, any> & MinderJsonNode)[] | number)[];
|
||||||
|
commandName: string;
|
||||||
|
minder: any;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const mainEditorProps = {
|
export const mainEditorProps = {
|
||||||
importJson: {
|
importJson: {
|
||||||
@ -122,10 +124,10 @@ export const tagProps = {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
replaceableTags: Function as PropType<(node: MinderJsonNode, nodes: MinderJsonNode[]) => string[]>,
|
replaceableTags: Function as PropType<(nodes: MinderJsonNode[]) => string[]>,
|
||||||
tagDisableCheck: Function,
|
tagDisableCheck: Function,
|
||||||
tagEditCheck: Function as PropType<(node: MinderJsonNode, tag: string) => boolean>,
|
tagEditCheck: Function as PropType<(nodes: MinderJsonNode[], tag: string) => boolean>,
|
||||||
afterTagEdit: Function as PropType<(node: MinderJsonNode, tag: string) => void>,
|
afterTagEdit: Function as PropType<(nodes: MinderJsonNode[], tag: string) => void>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const insertProps = {
|
export const insertProps = {
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
import type { MinderJsonNode } from '../../props';
|
import type { MinderJsonNode } from '../../props';
|
||||||
|
|
||||||
export function isDisableNode(minder: any) {
|
export function isDisableNode(minder: any) {
|
||||||
let node;
|
let node: MinderJsonNode;
|
||||||
if (minder && minder.getSelectedNode) {
|
if (minder && minder.getSelectedNode) {
|
||||||
node = minder.getSelectedNode();
|
node = minder.getSelectedNode();
|
||||||
}
|
if (node && node.data?.disabled === true) {
|
||||||
if (node && node.data.disable === true) {
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isDeleteDisableNode(minder: any) {
|
export function isDeleteDisableNode(minder: any) {
|
||||||
let node;
|
let node: MinderJsonNode;
|
||||||
if (minder && minder.getSelectedNode) {
|
if (minder && minder.getSelectedNode) {
|
||||||
node = minder.getSelectedNode();
|
node = minder.getSelectedNode();
|
||||||
}
|
if (node && node.data?.disabled === true && !node.data.allowDelete) {
|
||||||
if (node && node.data.disable === true && !node.data.allowDelete) {
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTagEnableNode(node: MinderJsonNode) {
|
export function isTagEnableNode(node: MinderJsonNode) {
|
||||||
if (node && (node.data.tagEnable === true || node.data.allowDisabledTag === true)) {
|
if (node.data && (node.data.tagEnable === true || node.data.allowDisabledTag === true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTagEnable(minder: any) {
|
export function isTagEnable(minder: any) {
|
||||||
let node;
|
let node: MinderJsonNode;
|
||||||
if (minder && minder.getSelectedNode) {
|
if (minder && minder.getSelectedNode) {
|
||||||
node = minder.getSelectedNode();
|
node = minder.getSelectedNode();
|
||||||
}
|
if (isTagEnableNode(node)) {
|
||||||
if (isTagEnableNode(node)) {
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -46,10 +46,10 @@ export function markChangeNode(node: MinderJsonNode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function markDelNode(node: MinderJsonNode, deleteChild: any) {
|
function markDelNode(node: MinderJsonNode, deleteChild: MinderJsonNode) {
|
||||||
deleteChild.push(node.data);
|
deleteChild.push(node.data);
|
||||||
if (node.children) {
|
if (node.children) {
|
||||||
node.children.forEach((child: any) => {
|
node.children.forEach((child: MinderJsonNode) => {
|
||||||
markDelNode(child, deleteChild);
|
markDelNode(child, deleteChild);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -58,9 +58,9 @@ function markDelNode(node: MinderJsonNode, deleteChild: any) {
|
|||||||
// 在父节点记录删除的节点
|
// 在父节点记录删除的节点
|
||||||
export function markDeleteNode(minder: any) {
|
export function markDeleteNode(minder: any) {
|
||||||
if (minder) {
|
if (minder) {
|
||||||
const nodes = minder.getSelectedNodes();
|
const nodes: MinderJsonNode[] = minder.getSelectedNodes();
|
||||||
nodes.forEach((node: MinderJsonNode) => {
|
nodes.forEach((node: MinderJsonNode) => {
|
||||||
if (node && node.parent) {
|
if (node.parent?.data) {
|
||||||
const pData = node.parent.data;
|
const pData = node.parent.data;
|
||||||
if (!pData.deleteChild) {
|
if (!pData.deleteChild) {
|
||||||
pData.deleteChild = [];
|
pData.deleteChild = [];
|
||||||
@ -101,7 +101,7 @@ export function setPriorityView(priorityStartWithZero: boolean, priorityPrefix:
|
|||||||
* 将节点及其子节点id置为null,changed 标记为true
|
* 将节点及其子节点id置为null,changed 标记为true
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
export function resetNodes(nodes: any) {
|
export function resetNodes(nodes: MinderJsonNode[]) {
|
||||||
if (nodes) {
|
if (nodes) {
|
||||||
nodes.forEach((item: any) => {
|
nodes.forEach((item: any) => {
|
||||||
if (item.data) {
|
if (item.data) {
|
||||||
@ -115,7 +115,7 @@ export function resetNodes(nodes: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isDisableForNode(node: MinderJsonNode) {
|
export function isDisableForNode(node: MinderJsonNode) {
|
||||||
if (node && node.data.disable === true) {
|
if (node && node.data?.disabled === true) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -382,7 +382,15 @@ export interface FeatureCaseMinderUpdateModuleItem {
|
|||||||
moveMode?: MoveMode;
|
moveMode?: MoveMode;
|
||||||
targetId?: string;
|
targetId?: string;
|
||||||
}
|
}
|
||||||
|
// 脑图新增/修改的文本节点集合
|
||||||
|
export interface FeatureCaseMinderUpdateTextNodeItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
parentId: string;
|
||||||
|
type: FeatureCaseMinderActionType;
|
||||||
|
moveMode?: MoveMode;
|
||||||
|
targetId?: string;
|
||||||
|
}
|
||||||
export interface CustomField {
|
export interface CustomField {
|
||||||
fieldId: string;
|
fieldId: string;
|
||||||
value: string;
|
value: string;
|
||||||
@ -419,4 +427,5 @@ export interface FeatureCaseMinderUpdateParams {
|
|||||||
updateCaseList: FeatureCaseMinderUpdateCaseItem[];
|
updateCaseList: FeatureCaseMinderUpdateCaseItem[];
|
||||||
updateModuleList: FeatureCaseMinderUpdateModuleItem[];
|
updateModuleList: FeatureCaseMinderUpdateModuleItem[];
|
||||||
deleteResourceList: FeatureCaseMinderDeleteResourceItem[];
|
deleteResourceList: FeatureCaseMinderDeleteResourceItem[];
|
||||||
|
additionalNodeList: FeatureCaseMinderUpdateTextNodeItem[];
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ const useMinderStore = defineStore('minder', {
|
|||||||
y: 0,
|
y: 0,
|
||||||
},
|
},
|
||||||
nodeDom: undefined,
|
nodeDom: undefined,
|
||||||
node: undefined,
|
nodes: undefined,
|
||||||
},
|
},
|
||||||
mold: 0,
|
mold: 0,
|
||||||
}),
|
}),
|
||||||
@ -27,15 +27,20 @@ const useMinderStore = defineStore('minder', {
|
|||||||
* @param name 事件名称
|
* @param name 事件名称
|
||||||
* @param position 触发事件的节点/鼠标位置
|
* @param position 触发事件的节点/鼠标位置
|
||||||
* @param nodeDom 节点 DOM
|
* @param nodeDom 节点 DOM
|
||||||
* @param node 节点
|
* @param nodes 节点集合
|
||||||
*/
|
*/
|
||||||
dispatchEvent(name: MinderEventName, position?: MinderNodePosition, nodeDom?: HTMLElement, node?: MinderJsonNode) {
|
dispatchEvent(
|
||||||
|
name: MinderEventName,
|
||||||
|
position?: MinderNodePosition,
|
||||||
|
nodeDom?: HTMLElement,
|
||||||
|
nodes?: MinderJsonNode[]
|
||||||
|
) {
|
||||||
this.event = {
|
this.event = {
|
||||||
name,
|
name,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
nodePosition: position,
|
nodePosition: position,
|
||||||
nodeDom,
|
nodeDom,
|
||||||
node,
|
nodes,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
setMold(val: number) {
|
setMold(val: number) {
|
||||||
|
@ -12,7 +12,7 @@ export interface MinderCustomEvent {
|
|||||||
timestamp: number;
|
timestamp: number;
|
||||||
nodePosition?: MinderNodePosition;
|
nodePosition?: MinderNodePosition;
|
||||||
nodeDom?: HTMLElement;
|
nodeDom?: HTMLElement;
|
||||||
node?: MinderJsonNode;
|
nodes?: MinderJsonNode[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MinderState {
|
export interface MinderState {
|
||||||
|
@ -281,7 +281,7 @@ export function mapTree<T>(
|
|||||||
*/
|
*/
|
||||||
export function filterTree<T>(
|
export function filterTree<T>(
|
||||||
tree: TreeNode<T> | TreeNode<T>[] | T | T[],
|
tree: TreeNode<T> | TreeNode<T>[] | T | T[],
|
||||||
filterFn: (node: TreeNode<T>, parent?: TreeNode<T> | null) => boolean,
|
filterFn: (node: TreeNode<T>, nodeIndex: number, parent?: TreeNode<T> | null) => boolean,
|
||||||
customChildrenKey = 'children',
|
customChildrenKey = 'children',
|
||||||
parentNode: TreeNode<T> | null = null
|
parentNode: TreeNode<T> | null = null
|
||||||
): TreeNode<T>[] {
|
): TreeNode<T>[] {
|
||||||
@ -292,7 +292,7 @@ export function filterTree<T>(
|
|||||||
for (let i = 0; i < tree.length; i++) {
|
for (let i = 0; i < tree.length; i++) {
|
||||||
const node = (tree as TreeNode<T>[])[i];
|
const node = (tree as TreeNode<T>[])[i];
|
||||||
// 如果节点满足过滤条件,则保留该节点,并递归过滤子节点
|
// 如果节点满足过滤条件,则保留该节点,并递归过滤子节点
|
||||||
if (filterFn(node, parentNode)) {
|
if (filterFn(node, i, parentNode)) {
|
||||||
const newNode = cloneDeep(node);
|
const newNode = cloneDeep(node);
|
||||||
if (node[customChildrenKey] && node[customChildrenKey].length > 0) {
|
if (node[customChildrenKey] && node[customChildrenKey].length > 0) {
|
||||||
// 递归过滤子节点,并将过滤后的子节点添加到当前节点中
|
// 递归过滤子节点,并将过滤后的子节点添加到当前节点中
|
||||||
|
@ -855,6 +855,7 @@
|
|||||||
|
|
||||||
/** 环境管理-环境组 end */
|
/** 环境管理-环境组 end */
|
||||||
|
|
||||||
|
const defaultLineData = ref(cloneDeep(props.defaultParamItem));
|
||||||
/**
|
/**
|
||||||
* 当表格输入框变化时,给参数表格添加一行数据行
|
* 当表格输入框变化时,给参数表格添加一行数据行
|
||||||
* @param val 输入值
|
* @param val 输入值
|
||||||
@ -875,7 +876,7 @@
|
|||||||
const nextLine = {
|
const nextLine = {
|
||||||
id,
|
id,
|
||||||
enable: true, // 是否勾选
|
enable: true, // 是否勾选
|
||||||
...cloneDeep(props.defaultParamItem), // 深拷贝,避免有嵌套引用类型,数据隔离
|
...cloneDeep(defaultLineData.value), // 深拷贝,避免有嵌套引用类型,数据隔离
|
||||||
} as any;
|
} as any;
|
||||||
selectColumnKeys.forEach((key) => {
|
selectColumnKeys.forEach((key) => {
|
||||||
// 如果是更改了下拉框导致添加新的一列,需要将更改后的下拉框的值应用到下一行(产品为了方便统一输入参数类型)
|
// 如果是更改了下拉框导致添加新的一列,需要将更改后的下拉框的值应用到下一行(产品为了方便统一输入参数类型)
|
||||||
@ -894,6 +895,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
paramsData.value.push(nextLine);
|
paramsData.value.push(nextLine);
|
||||||
|
defaultLineData.value = cloneDeep(nextLine);
|
||||||
}
|
}
|
||||||
emitChange('addTableLine', isInit);
|
emitChange('addTableLine', isInit);
|
||||||
handleMustContainColChange(true);
|
handleMustContainColChange(true);
|
||||||
@ -910,7 +912,7 @@
|
|||||||
// 批量添加过来的数据最后一行会是 undefined
|
// 批量添加过来的数据最后一行会是 undefined
|
||||||
hasNoIdItem = true;
|
hasNoIdItem = true;
|
||||||
return {
|
return {
|
||||||
...cloneDeep(props.defaultParamItem),
|
...cloneDeep(defaultLineData.value),
|
||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -927,7 +929,7 @@
|
|||||||
if (
|
if (
|
||||||
(!props.disabledExceptParam || !props.disabledParamValue) &&
|
(!props.disabledExceptParam || !props.disabledParamValue) &&
|
||||||
hasNoIdItem &&
|
hasNoIdItem &&
|
||||||
!filterKeyValParams(arr, props.defaultParamItem, !props.selectable).lastDataIsDefault &&
|
!filterKeyValParams(arr, defaultLineData.value, !props.selectable).lastDataIsDefault &&
|
||||||
!props.isTreeTable
|
!props.isTreeTable
|
||||||
) {
|
) {
|
||||||
addTableLine(arr.length - 1, false, true);
|
addTableLine(arr.length - 1, false, true);
|
||||||
@ -939,7 +941,7 @@
|
|||||||
{
|
{
|
||||||
id, // 默认给时间戳 id,若 props.defaultParamItem 有 id,则覆盖
|
id, // 默认给时间戳 id,若 props.defaultParamItem 有 id,则覆盖
|
||||||
enable: true, // 是否勾选
|
enable: true, // 是否勾选
|
||||||
...cloneDeep(props.defaultParamItem),
|
...cloneDeep(defaultLineData.value),
|
||||||
},
|
},
|
||||||
] as any[];
|
] as any[];
|
||||||
emitChange('watch props.params', true);
|
emitChange('watch props.params', true);
|
||||||
|
Loading…
Reference in New Issue
Block a user