feat(功能用例): 脑图保存
This commit is contained in:
parent
d258f4e669
commit
0e306a8ac2
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="h-full pl-[16px]">
|
<div class="h-full pl-[16px]">
|
||||||
<div class="baseInfo-form">
|
<div class="baseInfo-form" :class="props.activeCase.isNew ? 'baseInfo-form--no-bottom' : ''">
|
||||||
<a-skeleton v-if="baseInfoLoading || props.loading" :loading="baseInfoLoading || props.loading" :animation="true">
|
<a-skeleton v-if="baseInfoLoading || props.loading" :loading="baseInfoLoading || props.loading" :animation="true">
|
||||||
<a-space direction="vertical" class="w-full" size="large">
|
<a-space direction="vertical" class="w-full" size="large">
|
||||||
<a-skeleton-line :rows="10" :line-height="30" :line-spacing="30" />
|
<a-skeleton-line :rows="10" :line-height="30" :line-spacing="30" />
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-[12px] bg-white py-[16px]">
|
<div v-if="!props.activeCase.isNew" class="flex items-center gap-[12px] bg-white py-[16px]">
|
||||||
<a-button
|
<a-button
|
||||||
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
|
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
@ -200,4 +200,7 @@
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
height: calc(100% - 64px);
|
height: calc(100% - 64px);
|
||||||
}
|
}
|
||||||
|
.baseInfo-form--no-bottom {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
import { FormItem } from '@/components/pure/ms-form-create/types';
|
import { FormItem } from '@/components/pure/ms-form-create/types';
|
||||||
import MsMinderEditor from '@/components/pure/ms-minder-editor/minderEditor.vue';
|
import MsMinderEditor from '@/components/pure/ms-minder-editor/minderEditor.vue';
|
||||||
import type { MinderJson, MinderJsonNode, MinderJsonNodeData } from '@/components/pure/ms-minder-editor/props';
|
import type { MinderJson, MinderJsonNode, MinderJsonNodeData } from '@/components/pure/ms-minder-editor/props';
|
||||||
|
@ -113,7 +115,7 @@
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await getCaseModuleTree({
|
const res = await getCaseModuleTree({
|
||||||
projectId: appStore.currentProjectId,
|
projectId: appStore.currentProjectId,
|
||||||
moduleId: props.moduleId === 'all' ? '' : props.moduleId,
|
moduleId: props.moduleId === 'NONE' ? '' : props.moduleId,
|
||||||
});
|
});
|
||||||
caseTree.value = mapTree<MinderJsonNode>(res, (e) => ({
|
caseTree.value = mapTree<MinderJsonNode>(res, (e) => ({
|
||||||
...e,
|
...e,
|
||||||
|
@ -142,7 +144,7 @@
|
||||||
importJson.value.root = {
|
importJson.value.root = {
|
||||||
children: caseTree.value,
|
children: caseTree.value,
|
||||||
data: {
|
data: {
|
||||||
id: 'all',
|
id: 'NONE',
|
||||||
text: t('ms.minders.allModule'),
|
text: t('ms.minders.allModule'),
|
||||||
resource: [moduleTag],
|
resource: [moduleTag],
|
||||||
},
|
},
|
||||||
|
@ -204,10 +206,10 @@
|
||||||
* @param node 用例节点
|
* @param node 用例节点
|
||||||
*/
|
*/
|
||||||
function getCaseNodeInfo(node: MinderJsonNode) {
|
function getCaseNodeInfo(node: MinderJsonNode) {
|
||||||
let textStep: MinderJsonNode | undefined;
|
let textStep: MinderJsonNode | undefined; // 文本描述
|
||||||
let prerequisiteNode: MinderJsonNode | undefined;
|
let prerequisiteNode: MinderJsonNode | undefined; // 前置条件
|
||||||
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;
|
||||||
|
@ -230,7 +232,7 @@
|
||||||
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,
|
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 || '',
|
||||||
|
@ -242,25 +244,29 @@
|
||||||
*/
|
*/
|
||||||
function makeMinderParams(): FeatureCaseMinderUpdateParams {
|
function makeMinderParams(): FeatureCaseMinderUpdateParams {
|
||||||
const fullJson: MinderJson = window.minder.exportJson();
|
const fullJson: MinderJson = window.minder.exportJson();
|
||||||
filterTree(fullJson.root.children, (node) => {
|
filterTree(fullJson.root.children, (node, 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: node.parent?.data.id || '',
|
parentId: parent?.data.id || 'NONE',
|
||||||
type: node.data.isNew ? 'ADD' : 'UPDATE',
|
type: node.data.isNew !== false ? 'ADD' : 'UPDATE',
|
||||||
|
moveMode: node.data.moveMode,
|
||||||
|
targetId: node.data.targetId,
|
||||||
});
|
});
|
||||||
} 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);
|
||||||
tempMinderParams.value.updateCaseList.push({
|
tempMinderParams.value.updateCaseList.push({
|
||||||
id: node.data.id,
|
id: node.data.id,
|
||||||
name: node.data.text,
|
name: node.data.text,
|
||||||
moduleId: node.parent?.data.id || '',
|
moduleId: parent?.data.id || '',
|
||||||
type: node.data.isNew ? 'ADD' : 'UPDATE',
|
type: node.data.isNew !== false ? 'ADD' : 'UPDATE',
|
||||||
templateId: templateId.value,
|
templateId: templateId.value,
|
||||||
tags: node.data.resource || [],
|
tags: node.data.resource || [],
|
||||||
customFields: baseInfoRef.value?.makeParams().customFields || [],
|
customFields: baseInfoRef.value?.makeParams().customFields || [],
|
||||||
|
moveMode: node.data.moveMode,
|
||||||
|
targetId: node.data.targetId,
|
||||||
...caseNodeInfo,
|
...caseNodeInfo,
|
||||||
});
|
});
|
||||||
return false; // 用例的子孙节点已经处理过,跳过
|
return false; // 用例的子孙节点已经处理过,跳过
|
||||||
|
@ -273,10 +279,14 @@
|
||||||
|
|
||||||
async function handleMinderSave() {
|
async function handleMinderSave() {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true;
|
||||||
await saveCaseMinder(makeMinderParams());
|
await saveCaseMinder(makeMinderParams());
|
||||||
|
Message.success(t('common.saveSuccess'));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,9 +294,24 @@
|
||||||
* 已选中节点的可替换标签判断
|
* 已选中节点的可替换标签判断
|
||||||
* @param node 选中节点
|
* @param node 选中节点
|
||||||
*/
|
*/
|
||||||
function replaceableTags(node: MinderJsonNode) {
|
function replaceableTags(node: MinderJsonNode, nodes: MinderJsonNode[]) {
|
||||||
if (Object.keys(node.data || {}).length === 0 || node.data?.id === 'root') {
|
if (nodes.length > 1) {
|
||||||
// 没有数据的节点或默认模块节点不可替换
|
// 选中的节点大于 1 时
|
||||||
|
if (nodes.some((e) => (e.data?.resource || []).length > 0)) {
|
||||||
|
// 批量选中的节点已经打了标签,不可替换
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (nodes.every((e) => (e.data?.resource || []).length === 0)) {
|
||||||
|
// 批量选中的节点都没有打标签,可替换为模块标签
|
||||||
|
return [moduleTag];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Object.keys(node.data || {}).length === 0 ||
|
||||||
|
node.data?.id === 'root' ||
|
||||||
|
(node.parent?.data.resource || []).length === 0
|
||||||
|
) {
|
||||||
|
// 没有数据的节点、默认模块节点、父节点为文本节点的节点不可替换标签
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (node.data?.resource?.some((e) => topTags.includes(e))) {
|
if (node.data?.resource?.some((e) => topTags.includes(e))) {
|
||||||
|
@ -334,6 +359,22 @@
|
||||||
function execInert(command: string, node?: MinderJsonNodeData) {
|
function execInert(command: string, node?: MinderJsonNodeData) {
|
||||||
if (window.minder.queryCommandState(command) !== -1) {
|
if (window.minder.queryCommandState(command) !== -1) {
|
||||||
window.minder.execCommand(command, node);
|
window.minder.execCommand(command, node);
|
||||||
|
nextTick(() => {
|
||||||
|
const newNode: MinderJsonNode = window.minder.getSelectedNode();
|
||||||
|
newNode.data.isNew = true; // 新建的节点标记为新建
|
||||||
|
switch (command) {
|
||||||
|
case 'AppendChildNode':
|
||||||
|
newNode.data.moveMode = 'APPEND'; // 新建的节点标记为插入模式
|
||||||
|
newNode.data.targetId = newNode.parent?.data.id || '';
|
||||||
|
break;
|
||||||
|
case 'AppendSiblingNode':
|
||||||
|
newNode.data.moveMode = 'AFTER'; // 新建的节点标记为插入模式
|
||||||
|
newNode.data.targetId = newNode.data.id || '';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,6 +517,9 @@
|
||||||
} else if (node.data?.resource?.includes(prerequisiteTag) && (!node.children || node.children.length === 0)) {
|
} else if (node.data?.resource?.includes(prerequisiteTag) && (!node.children || node.children.length === 0)) {
|
||||||
// 当前节点是前置条件,则默认添加一个文本节点
|
// 当前节点是前置条件,则默认添加一个文本节点
|
||||||
execInert('AppendChildNode');
|
execInert('AppendChildNode');
|
||||||
|
} else {
|
||||||
|
// 文本节点下可添加文本节点
|
||||||
|
execInert('AppendChildNode');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'AppendSiblingNode':
|
case 'AppendSiblingNode':
|
||||||
|
@ -535,33 +579,12 @@
|
||||||
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
|
||||||
);
|
);
|
||||||
// tempMinderParams.value.updateModuleList.push({
|
|
||||||
// id: node.data.id,
|
|
||||||
// name: node.data.text,
|
|
||||||
// type: 'ADD',
|
|
||||||
// parentId: node.parent?.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
|
||||||
);
|
);
|
||||||
// tempMinderParams.value.updateCaseList.push({
|
|
||||||
// id: node.data.id,
|
|
||||||
// name: node.data.text,
|
|
||||||
// moduleId: node.parent?.data.id || '',
|
|
||||||
// type: 'ADD',
|
|
||||||
// templateId: templateId.value,
|
|
||||||
// prerequisite: '',
|
|
||||||
// caseEditType: 'STEP',
|
|
||||||
// steps: [],
|
|
||||||
// textDescription: '',
|
|
||||||
// expectedResult: '',
|
|
||||||
// description: '',
|
|
||||||
// tags: [],
|
|
||||||
// customFields: [],
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const baseInfoLoading = ref(false);
|
const baseInfoLoading = ref(false);
|
||||||
|
@ -589,7 +612,7 @@
|
||||||
label: t('caseManagement.featureCase.bug'),
|
label: t('caseManagement.featureCase.bug'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (activeCase.value.id) {
|
if (!activeCase.value.isNew) {
|
||||||
return fullTabList;
|
return fullTabList;
|
||||||
}
|
}
|
||||||
return fullTabList.filter((item) => item.value === 'baseInfo');
|
return fullTabList.filter((item) => item.value === 'baseInfo');
|
||||||
|
@ -629,7 +652,6 @@
|
||||||
if (fileIds.length) {
|
if (fileIds.length) {
|
||||||
checkUpdateFileIds.value = await checkFileIsUpdateRequest(fileIds);
|
checkUpdateFileIds.value = await checkFileIsUpdateRequest(fileIds);
|
||||||
}
|
}
|
||||||
formRules.value = initFormCreate(res.customFields, ['FUNCTIONAL_CASE:READ+UPDATE']);
|
|
||||||
if (res.attachments) {
|
if (res.attachments) {
|
||||||
// 处理文件列表
|
// 处理文件列表
|
||||||
fileList.value = res.attachments
|
fileList.value = res.attachments
|
||||||
|
@ -644,6 +666,7 @@
|
||||||
return convertToFile(fileInfo);
|
return convertToFile(fileInfo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
formRules.value = initFormCreate(res.customFields, ['FUNCTIONAL_CASE:READ+UPDATE']);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
@ -663,6 +686,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleContentChange(node: MinderJsonNode) {
|
function handleContentChange(node: MinderJsonNode) {
|
||||||
|
if (node?.data) {
|
||||||
const { resource } = node.data;
|
const { resource } = node.data;
|
||||||
// 用例下的子节点更改,触发用例更改
|
// 用例下的子节点更改,触发用例更改
|
||||||
if (
|
if (
|
||||||
|
@ -671,14 +695,15 @@
|
||||||
resource?.includes(textTag) ||
|
resource?.includes(textTag) ||
|
||||||
resource?.includes(remarkTag)
|
resource?.includes(remarkTag)
|
||||||
) {
|
) {
|
||||||
if (node.parent) {
|
if (node.parent?.data) {
|
||||||
node.parent.data.changed = true;
|
node.parent.data.changed = true;
|
||||||
}
|
}
|
||||||
} else if (node.parent?.parent?.data.resource?.includes(caseTag)) {
|
} else if (node.parent?.parent?.data?.resource?.includes(caseTag)) {
|
||||||
// 用例下子节点的子节点更改,触发用例更改
|
// 用例下子节点的子节点更改,触发用例更改
|
||||||
node.parent.parent.data.changed = true;
|
node.parent.parent.data.changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理脑图节点激活/点击
|
* 处理脑图节点激活/点击
|
||||||
|
@ -690,7 +715,16 @@
|
||||||
extraVisible.value = true;
|
extraVisible.value = true;
|
||||||
activeExtraKey.value = 'baseInfo';
|
activeExtraKey.value = 'baseInfo';
|
||||||
resetExtractInfo();
|
resetExtractInfo();
|
||||||
|
if (data.isNew === false) {
|
||||||
|
// 非新用例节点才能加载详情
|
||||||
initCaseDetail(data);
|
initCaseDetail(data);
|
||||||
|
} else {
|
||||||
|
activeCase.value = {
|
||||||
|
id: data.id,
|
||||||
|
name: data.text,
|
||||||
|
isNew: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
} else if (data?.resource?.includes(moduleTag) && data.count > 0 && data.isLoaded !== true) {
|
} else if (data?.resource?.includes(moduleTag) && data.count > 0 && data.isLoaded !== true) {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
|
@ -266,6 +266,10 @@
|
||||||
}
|
}
|
||||||
if (window.minder.queryCommandState(command) !== -1) {
|
if (window.minder.queryCommandState(command) !== -1) {
|
||||||
window.minder.execCommand(command);
|
window.minder.execCommand(command);
|
||||||
|
nextTick(() => {
|
||||||
|
const newNode: MinderJsonNode = window.minder.getSelectedNode();
|
||||||
|
newNode.data.isNew = true; // 新建的节点标记为新建
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,11 +46,12 @@
|
||||||
minder = window.minder;
|
minder = window.minder;
|
||||||
minder.on('selectionchange', () => {
|
minder.on('selectionchange', () => {
|
||||||
commandDisabled.value = isDisable();
|
commandDisabled.value = isDisable();
|
||||||
|
const nodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
||||||
const node: MinderJsonNode = minder.getSelectedNode();
|
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);
|
tagList.value = props.replaceableTags(node, nodes);
|
||||||
} else {
|
} else {
|
||||||
tagList.value = [];
|
tagList.value = [];
|
||||||
}
|
}
|
||||||
|
@ -98,10 +99,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.minder.execCommand('resource', origin);
|
window.minder.execCommand('resource', origin);
|
||||||
|
const nodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
||||||
const node: MinderJsonNode = minder.getSelectedNode();
|
const node: MinderJsonNode = minder.getSelectedNode();
|
||||||
minderStore.dispatchEvent(MinderEventName.SET_TAG, undefined, undefined, node);
|
minderStore.dispatchEvent(MinderEventName.SET_TAG, undefined, undefined, node);
|
||||||
if (props.replaceableTags) {
|
if (props.replaceableTags) {
|
||||||
tagList.value = props.replaceableTags(node);
|
tagList.value = props.replaceableTags(node, nodes);
|
||||||
}
|
}
|
||||||
if (props.afterTagEdit) {
|
if (props.afterTagEdit) {
|
||||||
props.afterTagEdit(node, resourceName);
|
props.afterTagEdit(node, resourceName);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-spin :loading="loading" :tip="t('minder.loading')" class="ms-minder-editor-container">
|
<a-spin :loading="loading" class="ms-minder-editor-container">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<minderHeader
|
<minderHeader
|
||||||
:sequence-enable="props.sequenceEnable"
|
:sequence-enable="props.sequenceEnable"
|
||||||
|
@ -67,7 +67,6 @@
|
||||||
import minderHeader from './main/header.vue';
|
import minderHeader from './main/header.vue';
|
||||||
import mainEditor from './main/mainEditor.vue';
|
import mainEditor from './main/mainEditor.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
|
||||||
import { MinderEvent } from '@/store/modules/components/minder-editor/types';
|
import { MinderEvent } from '@/store/modules/components/minder-editor/types';
|
||||||
|
|
||||||
import useEventListener from './hooks/useEventListener';
|
import useEventListener from './hooks/useEventListener';
|
||||||
|
@ -106,8 +105,6 @@
|
||||||
...viewMenuProps,
|
...viewMenuProps,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const loading = defineModel<boolean>('loading', {
|
const loading = defineModel<boolean>('loading', {
|
||||||
default: false,
|
default: false,
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* Api 列表
|
* Api 列表
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { MoveMode } from '@/models/common';
|
||||||
|
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
|
|
||||||
export interface MinderIconButtonItem {
|
export interface MinderIconButtonItem {
|
||||||
|
@ -18,6 +20,8 @@ export interface MinderJsonNodeData {
|
||||||
// 前端渲染字段
|
// 前端渲染字段
|
||||||
isNew?: boolean; // 是否脑图新增节点,需要在初始化脑图数据时标记已存在节点为 false 以区分是否新增节点
|
isNew?: boolean; // 是否脑图新增节点,需要在初始化脑图数据时标记已存在节点为 false 以区分是否新增节点
|
||||||
changed?: boolean; // 脑图节点是否发生过变化
|
changed?: boolean; // 脑图节点是否发生过变化
|
||||||
|
moveMode?: MoveMode; // 移动方式(节点移动或新增时需要)
|
||||||
|
targetId?: string; // 目标节点 id(节点移动或新增时需要)
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
export interface MinderJsonNode {
|
export interface MinderJsonNode {
|
||||||
|
@ -105,7 +109,7 @@ export const tagProps = {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
replaceableTags: Function as PropType<(node: MinderJsonNode) => string[]>,
|
replaceableTags: Function as PropType<(node: MinderJsonNode, nodes: MinderJsonNode[]) => string[]>,
|
||||||
tagDisableCheck: Function,
|
tagDisableCheck: Function,
|
||||||
tagEditCheck: Function as PropType<(node: MinderJsonNode, tag: string) => boolean>,
|
tagEditCheck: Function as PropType<(node: MinderJsonNode, tag: string) => boolean>,
|
||||||
afterTagEdit: Function as PropType<(node: MinderJsonNode, tag: string) => void>,
|
afterTagEdit: Function as PropType<(node: MinderJsonNode, tag: string) => void>,
|
||||||
|
|
|
@ -405,7 +405,7 @@ export interface FeatureCaseMinderUpdateCaseItem {
|
||||||
targetId?: string;
|
targetId?: string;
|
||||||
prerequisite: string; // 前置条件
|
prerequisite: string; // 前置条件
|
||||||
caseEditType: FeatureCaseMinderEditType;
|
caseEditType: FeatureCaseMinderEditType;
|
||||||
steps: FeatureCaseMinderStepItem[];
|
steps: string;
|
||||||
textDescription: string; // 文本描述
|
textDescription: string; // 文本描述
|
||||||
expectedResult: string; // 期望结果
|
expectedResult: string; // 期望结果
|
||||||
description: string;
|
description: string;
|
||||||
|
|
|
@ -281,8 +281,9 @@ 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>) => boolean,
|
filterFn: (node: TreeNode<T>, parent?: TreeNode<T> | null) => boolean,
|
||||||
customChildrenKey = 'children'
|
customChildrenKey = 'children',
|
||||||
|
parentNode: TreeNode<T> | null = null
|
||||||
): TreeNode<T>[] {
|
): TreeNode<T>[] {
|
||||||
if (!Array.isArray(tree)) {
|
if (!Array.isArray(tree)) {
|
||||||
tree = [tree];
|
tree = [tree];
|
||||||
|
@ -291,11 +292,11 @@ 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)) {
|
if (filterFn(node, parentNode)) {
|
||||||
const newNode = cloneDeep(node);
|
const newNode = cloneDeep(node);
|
||||||
if (node[customChildrenKey] && node[customChildrenKey].length > 0) {
|
if (node[customChildrenKey] && node[customChildrenKey].length > 0) {
|
||||||
// 递归过滤子节点,并将过滤后的子节点添加到当前节点中
|
// 递归过滤子节点,并将过滤后的子节点添加到当前节点中
|
||||||
newNode[customChildrenKey] = filterTree(node[customChildrenKey], filterFn, customChildrenKey);
|
newNode[customChildrenKey] = filterTree(node[customChildrenKey], filterFn, customChildrenKey, node);
|
||||||
} else {
|
} else {
|
||||||
newNode[customChildrenKey] = [];
|
newNode[customChildrenKey] = [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,9 +199,6 @@
|
||||||
<MsIcon :size="14" type="icon-icon_mindnote_outlined" />
|
<MsIcon :size="14" type="icon-icon_mindnote_outlined" />
|
||||||
</a-radio>
|
</a-radio>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
<MsTag no-margin size="large" class="cursor-pointer" theme="outline" @click="fetchData">
|
|
||||||
<MsIcon class="text-[16px] text-[var(color-text-4)]" :size="32" type="icon-icon_reset_outlined" />
|
|
||||||
</MsTag>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-[16px] h-[calc(100%-32px)] border-t border-[var(--color-text-n8)]">
|
<div class="mt-[16px] h-[calc(100%-32px)] border-t border-[var(--color-text-n8)]">
|
||||||
|
|
|
@ -271,15 +271,15 @@
|
||||||
type="line"
|
type="line"
|
||||||
@change="(v: boolean | string| number) => handleMenuStatusChange('BUG_SYNC_SYNC_ENABLE',v as boolean, MenuEnum.bugManagement)"
|
@change="(v: boolean | string| number) => handleMenuStatusChange('BUG_SYNC_SYNC_ENABLE',v as boolean, MenuEnum.bugManagement)"
|
||||||
/>
|
/>
|
||||||
<!-- 功能测试 同步缺陷 -->
|
<!-- 测试用例 关联需求 -->
|
||||||
<div v-permission="['PROJECT_APPLICATION_BUG:UPDATE']">
|
<div v-permission="['PROJECT_APPLICATION_CASE:UPDATE']">
|
||||||
<a-tooltip v-if="record.type === 'CASE_RELATED' && !allValueMap['CASE_RELATED_CASE_ENABLE']" position="tr">
|
<a-tooltip v-if="record.type === 'CASE_RELATED' && !allValueMap['CASE_RELATED_CASE_ENABLE']" position="tr">
|
||||||
<template #content>
|
<template #content>
|
||||||
<span>
|
<span>
|
||||||
{{ t('project.menu.notConfig') }}
|
{{ t('project.menu.notConfig') }}
|
||||||
<span class="cursor-pointer text-[rgb(var(--primary-4))]" @click="showDefectDrawer">{{
|
<span class="cursor-pointer text-[rgb(var(--primary-4))]" @click="showDefectDrawer">
|
||||||
t(`project.menu.${record.type}`)
|
{{ t(`project.menu.${record.type}`) }}
|
||||||
}}</span>
|
</span>
|
||||||
{{ t('project.menu.configure') }}
|
{{ t('project.menu.configure') }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -383,7 +383,7 @@
|
||||||
<RelatedCase
|
<RelatedCase
|
||||||
v-model:visible="relatedCaseDrawerVisible"
|
v-model:visible="relatedCaseDrawerVisible"
|
||||||
@cancel="relatedCaseDrawerVisible = false"
|
@cancel="relatedCaseDrawerVisible = false"
|
||||||
@ok="initMenuData()"
|
@ok="getMenuConfig(MenuEnum.caseManagement)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue