fix(全局): 部分 bug 修复
This commit is contained in:
parent
1b26df9c2d
commit
33929d6978
|
@ -85,7 +85,6 @@
|
|||
} from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import useMinderStore from '@/store/modules/components/minder-editor/index';
|
||||
import { MinderCustomEvent } from '@/store/modules/components/minder-editor/types';
|
||||
import { filterTree, getGenerateId, mapTree, replaceNodeInTree } from '@/utils';
|
||||
|
@ -160,60 +159,66 @@
|
|||
async function initCaseTree(notRemote = false) {
|
||||
try {
|
||||
loading.value = true;
|
||||
let res: MinderJsonNode[];
|
||||
if (notRemote) {
|
||||
res = caseTree.value;
|
||||
} else {
|
||||
res = await getCaseMinderTree({
|
||||
if (!notRemote) {
|
||||
const res = await getCaseMinderTree({
|
||||
projectId: appStore.currentProjectId,
|
||||
moduleId: '', // 始终加载全部,然后再进入对应的模块节点
|
||||
});
|
||||
}
|
||||
caseTree.value = mapTree<MinderJsonNode>(res, (e) => ({
|
||||
...e,
|
||||
data: {
|
||||
id: e.id,
|
||||
text: e.name,
|
||||
resource: props.modulesCount[e.id] !== undefined ? [moduleTag] : e.data?.resource,
|
||||
expandState: e.level === 1 ? 'expand' : 'collapse',
|
||||
count: props.modulesCount[e.id],
|
||||
isNew: false,
|
||||
changed: false,
|
||||
},
|
||||
children:
|
||||
props.modulesCount[e.id] > 0 && !e.children?.length
|
||||
? [
|
||||
{
|
||||
data: {
|
||||
id: 'fakeNode',
|
||||
text: 'fakeNode',
|
||||
resource: ['fakeNode'],
|
||||
isNew: false,
|
||||
changed: false,
|
||||
caseTree.value = mapTree<MinderJsonNode>(res, (e) => ({
|
||||
...e,
|
||||
data: {
|
||||
...e.data,
|
||||
id: e.id || e.data?.id || '',
|
||||
text: e.name || e.data?.text || '',
|
||||
resource: props.modulesCount[e.id] !== undefined ? [moduleTag] : e.data?.resource,
|
||||
expandState: e.level === 1 ? 'expand' : 'collapse',
|
||||
count: props.modulesCount[e.id],
|
||||
isNew: false,
|
||||
changed: false,
|
||||
},
|
||||
children:
|
||||
props.modulesCount[e.id] > 0 && !e.children?.length
|
||||
? [
|
||||
{
|
||||
data: {
|
||||
id: 'fakeNode',
|
||||
text: 'fakeNode',
|
||||
resource: ['fakeNode'],
|
||||
isNew: false,
|
||||
changed: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: e.children,
|
||||
}));
|
||||
importJson.value.root = {
|
||||
children: caseTree.value,
|
||||
data: {
|
||||
id: 'NONE',
|
||||
text: t('ms.minders.allModule'),
|
||||
resource: [moduleTag],
|
||||
disabled: true,
|
||||
},
|
||||
};
|
||||
importJson.value.treePath = [];
|
||||
window.minder.importJson(importJson.value);
|
||||
window.minder.execCommand('camera', window.minder.getRoot(), 100);
|
||||
if (props.moduleId !== 'all') {
|
||||
// 携带具体的模块 ID 加载时,进入该模块内
|
||||
nextTick(() => {
|
||||
minderStore.dispatchEvent(MinderEventName.ENTER_NODE, undefined, undefined, undefined, [
|
||||
window.minder.getNodeById(props.moduleId),
|
||||
]);
|
||||
});
|
||||
]
|
||||
: e.children,
|
||||
}));
|
||||
importJson.value.root = {
|
||||
children: caseTree.value,
|
||||
data: {
|
||||
id: 'NONE',
|
||||
text: t('ms.minders.allModule'),
|
||||
resource: [moduleTag],
|
||||
disabled: true,
|
||||
},
|
||||
};
|
||||
importJson.value.treePath = [];
|
||||
window.minder.importJson(importJson.value);
|
||||
}
|
||||
if (notRemote) {
|
||||
if (props.moduleId !== 'all') {
|
||||
// 携带具体的模块 ID 加载时,进入该模块内
|
||||
nextTick(() => {
|
||||
minderStore.dispatchEvent(MinderEventName.ENTER_NODE, undefined, undefined, undefined, [
|
||||
window.minder.getNodeById(props.moduleId),
|
||||
]);
|
||||
});
|
||||
} else {
|
||||
// 携带具体的模块 ID 加载时,进入该模块内
|
||||
nextTick(() => {
|
||||
minderStore.dispatchEvent(MinderEventName.ENTER_NODE, undefined, undefined, undefined, [
|
||||
importJson.value.root,
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
@ -391,12 +396,13 @@
|
|||
if ((!res || res.length === 0) && node.children?.length) {
|
||||
// 如果模块下没有用例且有别的模块节点,正常展开
|
||||
node.expand();
|
||||
node.renderTree();
|
||||
window.minder.renderNodeBatch(node.children);
|
||||
node.layout();
|
||||
data.isLoaded = true;
|
||||
return;
|
||||
}
|
||||
// TODO:递归渲染存在的子节点
|
||||
const waitingRenderNodes: MinderJsonNode[] = [];
|
||||
let waitingRenderNodes: MinderJsonNode[] = [];
|
||||
res.forEach((e) => {
|
||||
// 用例节点
|
||||
const child = window.minder.createNode(
|
||||
|
@ -439,14 +445,14 @@
|
|||
});
|
||||
node.expand();
|
||||
// node.renderTree();
|
||||
if (node.children && node.children.length > 0) {
|
||||
waitingRenderNodes = waitingRenderNodes.concat(node.children);
|
||||
}
|
||||
window.minder.renderNodeBatch(waitingRenderNodes);
|
||||
node.layout();
|
||||
window.minder.execCommand('camera', node, 100);
|
||||
if (node.data) {
|
||||
node.data.isLoaded = true;
|
||||
}
|
||||
data.isLoaded = true;
|
||||
// 加载完用例数据后,更新当前importJson数据
|
||||
replaceNodeInTree([importJson.value.root], node.data?.id || '', node, 'data', 'id');
|
||||
replaceNodeInTree([importJson.value.root], node.data?.id || '', window.minder.exportNode(node), 'data', 'id');
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
|
@ -458,11 +464,6 @@
|
|||
extraVisible.value = false;
|
||||
showDetailMenu.value = false;
|
||||
resetExtractInfo();
|
||||
if (node.children && node.children.length > 0 && node.data?.expandState === 'collapse') {
|
||||
node.expand();
|
||||
node.renderTree();
|
||||
node.layout();
|
||||
}
|
||||
}
|
||||
setPriorityView(true, 'P');
|
||||
}
|
||||
|
@ -524,7 +525,7 @@
|
|||
if (!caseOffspringTags.some((e) => node.data?.resource?.includes(e))) {
|
||||
// 非用例下的子孙节点的移除,才加入删除资源队列
|
||||
tempMinderParams.value.deleteResourceList.push({
|
||||
id: node.data?.id || getGenerateId(),
|
||||
id: node.data?.id || '',
|
||||
type: node.data?.resource?.[0] || moduleTag,
|
||||
});
|
||||
}
|
||||
|
@ -556,12 +557,12 @@
|
|||
* 解析用例节点信息
|
||||
* @param node 用例节点
|
||||
*/
|
||||
function getCaseNodeInfo(node: MinderJsonNode) {
|
||||
function getCaseNodeInfo(node?: MinderJsonNode) {
|
||||
let textStep: MinderJsonNode | undefined; // 文本描述
|
||||
let prerequisiteNode: MinderJsonNode | undefined; // 前置条件
|
||||
let remarkNode: MinderJsonNode | undefined; // 备注
|
||||
const stepNodes: MinderJsonNode[] = []; // 步骤描述
|
||||
node.children?.forEach((item) => {
|
||||
node?.children?.forEach((item) => {
|
||||
if (item.data?.resource?.includes(textDescTag)) {
|
||||
textStep = item;
|
||||
} else if (item.data?.resource?.includes(stepTag)) {
|
||||
|
@ -577,7 +578,7 @@
|
|||
id: child.data?.id || getGenerateId(),
|
||||
num: i,
|
||||
desc: child.data?.text || '',
|
||||
result: child.children?.[0].data?.text || '',
|
||||
result: child.children?.[0]?.data?.text || '',
|
||||
};
|
||||
});
|
||||
return {
|
||||
|
@ -587,7 +588,7 @@
|
|||
textDescription: textStep?.data?.text || '',
|
||||
expectedResult: textStep?.children?.[0]?.data?.text || '',
|
||||
description: remarkNode?.data?.text || '',
|
||||
priority: node.data?.priority,
|
||||
priority: node?.data?.priority,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -612,6 +613,17 @@
|
|||
};
|
||||
}
|
||||
|
||||
function resetMinderParams() {
|
||||
tempMinderParams.value = {
|
||||
projectId: appStore.currentProjectId,
|
||||
versionId: '',
|
||||
updateCaseList: [],
|
||||
updateModuleList: [],
|
||||
deleteResourceList: [],
|
||||
additionalNodeList: [],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成脑图保存的入参
|
||||
*/
|
||||
|
@ -675,28 +687,20 @@
|
|||
await saveCaseMinder(makeMinderParams(fullJson));
|
||||
extraVisible.value = false;
|
||||
Message.success(t('common.saveSuccess'));
|
||||
tempMinderParams.value = {
|
||||
projectId: appStore.currentProjectId,
|
||||
versionId: '',
|
||||
updateCaseList: [],
|
||||
updateModuleList: [],
|
||||
deleteResourceList: [],
|
||||
additionalNodeList: [],
|
||||
};
|
||||
resetMinderParams();
|
||||
emit('save');
|
||||
callback();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
resetMinderParams();
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
|
||||
watch(
|
||||
() => featureCaseStore.modulesCount,
|
||||
() => props.moduleId,
|
||||
() => {
|
||||
initCaseTree(true);
|
||||
},
|
||||
|
|
|
@ -259,9 +259,10 @@ export default function useMinderBaseApi({ hasEditPermission }: { hasEditPermiss
|
|||
if (
|
||||
Object.keys(node.data || {}).length === 0 ||
|
||||
node.data?.id === 'root' ||
|
||||
(node.parent?.data?.resource || []).length === 0
|
||||
(node.parent?.data?.resource || []).length === 0 ||
|
||||
node.parent?.data?.id === 'NONE'
|
||||
) {
|
||||
// 没有数据的节点、默认模块节点、父节点为文本节点的节点不可替换标签
|
||||
// 没有数据的节点、默认模块节点、父节点为文本节点、父节点为NONE虚拟根节点的节点不可替换标签
|
||||
return [];
|
||||
}
|
||||
if (node.data?.resource?.some((e) => topTags.includes(e))) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
:can-show-priority-menu="false"
|
||||
:can-show-float-menu="canShowFloatMenu"
|
||||
:can-show-delete-menu="canShowDeleteMenu"
|
||||
:disable="!hasEditPermission"
|
||||
:disabled="!hasEditPermission"
|
||||
custom-priority
|
||||
single-tag
|
||||
tag-enable
|
||||
|
@ -86,7 +86,7 @@
|
|||
</a-tooltip>
|
||||
</div>
|
||||
<a-form ref="configFormRef" :model="configForm" :disabled="!hasEditPermission" layout="vertical">
|
||||
<a-form-item v-if="hasEditPermission">
|
||||
<a-form-item v-if="hasEditPermission && configForm.level === 2">
|
||||
<template #label>
|
||||
<div class="flex items-center">
|
||||
<div>{{ t('testPlan.planForm.pickCases') }}</div>
|
||||
|
@ -127,27 +127,37 @@
|
|||
</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<template
|
||||
v-if="
|
||||
configForm.type !== PlanMinderCollectionType.FUNCTIONAL &&
|
||||
(configForm.level === 1 || !configForm.extended)
|
||||
"
|
||||
>
|
||||
<template v-if="configForm.type !== PlanMinderCollectionType.FUNCTIONAL">
|
||||
<a-form-item :label="t('system.project.resourcePool')">
|
||||
<a-select v-model:model-value="configForm.testResourcePoolId" :options="resourcePoolOptions"></a-select>
|
||||
<a-select
|
||||
v-model:model-value="configForm.testResourcePoolId"
|
||||
:options="resourcePoolOptions"
|
||||
:disabled="configForm.level === 2 && configForm.extended"
|
||||
></a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('project.environmental.env')">
|
||||
<a-select v-model:model-value="configForm.environmentId" :options="environmentOptions"></a-select>
|
||||
<a-select
|
||||
v-model:model-value="configForm.environmentId"
|
||||
:options="environmentOptions"
|
||||
:disabled="configForm.level === 2 && configForm.extended"
|
||||
></a-select>
|
||||
</a-form-item>
|
||||
<a-form-item class="hidden-item">
|
||||
<a-radio-group v-model:model-value="configForm.executeMethod">
|
||||
<a-radio-group
|
||||
v-model:model-value="configForm.executeMethod"
|
||||
:disabled="configForm.level === 2 && configForm.extended"
|
||||
>
|
||||
<a-radio :value="RunMode.SERIAL">{{ t('testPlan.testPlanIndex.serial') }}</a-radio>
|
||||
<a-radio :value="RunMode.PARALLEL">{{ t('testPlan.testPlanIndex.parallel') }}</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="configForm.executeMethod === RunMode.SERIAL" class="hidden-item">
|
||||
<div class="flex items-center gap-[8px]">
|
||||
<a-switch v-model:model-value="configForm.stopOnFail" size="small"></a-switch>
|
||||
<a-switch
|
||||
v-model:model-value="configForm.stopOnFail"
|
||||
size="small"
|
||||
:disabled="configForm.level === 2 && configForm.extended"
|
||||
></a-switch>
|
||||
<div>{{ t('ms.minders.failStop') }}</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
@ -206,7 +216,7 @@
|
|||
class="hidden-item"
|
||||
>
|
||||
<div class="flex items-center gap-[8px]">
|
||||
<a-switch v-model:model-value="configForm.extended" size="small"></a-switch>
|
||||
<a-switch v-model:model-value="configForm.extended" size="small" @change="handleExtendChange"></a-switch>
|
||||
<div>{{ t('ms.minders.extend') }}</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
@ -270,6 +280,7 @@
|
|||
|
||||
const props = defineProps<{
|
||||
planId: string;
|
||||
status: string;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'save'): void;
|
||||
|
@ -297,7 +308,9 @@
|
|||
const showConfigMenu = ref(false);
|
||||
const canShowDeleteMenu = ref(false);
|
||||
const extraVisible = ref<boolean>(false);
|
||||
const hasEditPermission = hasAnyPermission(['PROJECT_TEST_PLAN:READ+UPDATE']);
|
||||
const hasEditPermission = computed(
|
||||
() => props.status !== 'ARCHIVED' && hasAnyPermission(['PROJECT_TEST_PLAN:READ+UPDATE'])
|
||||
);
|
||||
|
||||
/**
|
||||
* 检测节点可展示的菜单项
|
||||
|
@ -306,13 +319,18 @@
|
|||
function checkNodeCanShowMenu(node: PlanMinderNode) {
|
||||
const { data } = node;
|
||||
|
||||
if (!hasEditPermission && (data?.level === 1 || data?.level === 2)) {
|
||||
if (!hasEditPermission.value && (data?.level === 1 || data?.level === 2)) {
|
||||
// 没有编辑权限,只能查看配置菜单(功能用例只有关联用例,所以配置菜单也不能看)
|
||||
if (data?.type === PlanMinderCollectionType.FUNCTIONAL) {
|
||||
canShowFloatMenu.value = false;
|
||||
} else {
|
||||
canShowFloatMenu.value = true;
|
||||
showConfigMenu.value = true;
|
||||
showAssociateCaseMenu.value = false;
|
||||
canShowExecuteMethodMenu.value = false;
|
||||
canShowDeleteMenu.value = false;
|
||||
insertSiblingMenus.value = [];
|
||||
insertSonMenus.value = [];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -694,6 +712,39 @@
|
|||
}
|
||||
}
|
||||
|
||||
function handleExtendChange(val: string | number | boolean) {
|
||||
if (val && configForm.value) {
|
||||
const node: PlanMinderNode = window.minder.getNodeById(configForm.value.id);
|
||||
if (node.parent?.data) {
|
||||
const {
|
||||
priority,
|
||||
executeMethod,
|
||||
grouped,
|
||||
environmentId,
|
||||
testResourcePoolId,
|
||||
retryOnFail,
|
||||
retryType,
|
||||
retryTimes,
|
||||
retryInterval,
|
||||
stopOnFail,
|
||||
} = node.parent.data;
|
||||
configForm.value = {
|
||||
...configForm.value,
|
||||
priority,
|
||||
executeMethod,
|
||||
grouped,
|
||||
environmentId,
|
||||
testResourcePoolId,
|
||||
retryOnFail,
|
||||
retryType,
|
||||
retryTimes,
|
||||
retryInterval,
|
||||
stopOnFail,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化测试规划脑图
|
||||
*/
|
||||
|
@ -762,6 +813,7 @@
|
|||
loading.value = true;
|
||||
await editPlanMinder(makeMinderParams(fullJson));
|
||||
Message.success(t('common.saveSuccess'));
|
||||
clearSelectedCases();
|
||||
handleConfigCancel();
|
||||
initMinder();
|
||||
callback();
|
||||
|
|
|
@ -90,7 +90,7 @@ export default function useEventListener(listener: UseEventListenerProps) {
|
|||
|
||||
// 监听脑图自定义事件
|
||||
watch(
|
||||
() => minderStore.event.timestamp,
|
||||
() => minderStore.event.eventId,
|
||||
() => {
|
||||
if (listener.handleMinderEvent) {
|
||||
listener.handleMinderEvent(minderStore.event);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="mec" class="ms-minder-container">
|
||||
<minderHeader :icon-buttons="props.iconButtons" @save="save" />
|
||||
<minderHeader :icon-buttons="props.iconButtons" :disabled="props.disabled" @save="save" />
|
||||
<Navigator />
|
||||
<div
|
||||
v-if="currentTreePath?.length > 0"
|
||||
|
@ -125,7 +125,6 @@
|
|||
]);
|
||||
if (selectNodes.length > 0 && !notChangeCommands.has(event.commandName.toLocaleLowerCase())) {
|
||||
minderStore.setMinderUnsaved(true);
|
||||
minderStore.dispatchEvent(MinderEventName.MINDER_CHANGED);
|
||||
selectNodes.forEach((node: MinderJsonNode) => {
|
||||
markChangeNode(node);
|
||||
});
|
||||
|
@ -155,7 +154,7 @@
|
|||
* 切换脑图展示的节点层级
|
||||
* @param node 切换的节点
|
||||
*/
|
||||
function switchNode(node: MinderJsonNode | MinderJsonNodeData) {
|
||||
function switchNode(node?: MinderJsonNode | MinderJsonNodeData) {
|
||||
if (minderStore.minderUnsaved) {
|
||||
// 切换前,如果脑图未保存,先把更改的节点信息同步一次
|
||||
replaceNodeInTree(
|
||||
|
@ -166,12 +165,12 @@
|
|||
'id'
|
||||
);
|
||||
}
|
||||
if (node.id === 'NONE') {
|
||||
if (node?.id === 'NONE') {
|
||||
innerImportJson.value = importJson.value;
|
||||
} else if (node.data) {
|
||||
} else if (node?.data) {
|
||||
innerImportJson.value = findNodePathByKey([importJson.value.root], node.data.id, 'data', 'id') as MinderJson;
|
||||
} else {
|
||||
innerImportJson.value = findNodePathByKey([importJson.value.root], node.id, 'data', 'id') as MinderJson;
|
||||
innerImportJson.value = findNodePathByKey([importJson.value.root], node?.id, 'data', 'id') as MinderJson;
|
||||
}
|
||||
window.minder.importJson(innerImportJson.value);
|
||||
const root: MinderJsonNode = window.minder.getRoot();
|
||||
|
@ -203,7 +202,7 @@
|
|||
}
|
||||
|
||||
watch(
|
||||
() => minderStore.event.timestamp,
|
||||
() => minderStore.event.eventId,
|
||||
() => {
|
||||
if (minderStore.event.name === MinderEventName.HOTBOX && minderStore.event.nodePosition) {
|
||||
const nodeDomWidth = minderStore.event.nodeDom?.getBoundingClientRect().width || 0;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<span></span>
|
||||
<template #content>
|
||||
<a-radio-group
|
||||
v-if="currentNodeTags.length > 0 && tags.length > 0"
|
||||
v-if="tags.length > 0"
|
||||
v-model:model-value="currentNodeTags[0]"
|
||||
type="button"
|
||||
size="mini"
|
||||
|
@ -212,7 +212,7 @@
|
|||
const menuPopupOffset = ref<TriggerPopupTranslate>([0, 0]);
|
||||
|
||||
watch(
|
||||
() => minderStore.event.timestamp,
|
||||
() => minderStore.event.eventId,
|
||||
async () => {
|
||||
if (window.minder) {
|
||||
let nodePosition: MinderNodePosition | undefined;
|
||||
|
|
|
@ -16,7 +16,7 @@ export interface MinderJsonNodeData {
|
|||
text: string;
|
||||
resource?: string[];
|
||||
expandState?: 'collapse' | 'expand';
|
||||
priority?: number | string;
|
||||
priority?: number;
|
||||
// 前端渲染字段
|
||||
isNew?: boolean; // 是否脑图新增节点,需要在初始化脑图数据时标记已存在节点为 false 以区分是否新增节点
|
||||
changed?: boolean; // 脑图节点是否发生过变化
|
||||
|
|
|
@ -13,7 +13,7 @@ const useMinderStore = defineStore('minder', {
|
|||
state: (): MinderState => ({
|
||||
event: {
|
||||
name: '' as MinderEventName,
|
||||
timestamp: 0,
|
||||
eventId: '',
|
||||
params: '',
|
||||
nodePosition: {
|
||||
x: 0,
|
||||
|
@ -49,7 +49,7 @@ const useMinderStore = defineStore('minder', {
|
|||
this.event = {
|
||||
name,
|
||||
params,
|
||||
timestamp: Date.now(),
|
||||
eventId: getGenerateId(),
|
||||
nodePosition: position,
|
||||
nodeDom,
|
||||
nodes,
|
||||
|
|
|
@ -17,7 +17,7 @@ export interface MinderNodePosition {
|
|||
|
||||
export interface MinderCustomEvent {
|
||||
name: MinderEventName;
|
||||
timestamp: number;
|
||||
eventId: string;
|
||||
params?: any;
|
||||
nodePosition?: MinderNodePosition;
|
||||
nodeDom?: HTMLElement;
|
||||
|
|
|
@ -580,6 +580,7 @@ export function deleteNodes<T>(
|
|||
treeArr: TreeNode<T>[],
|
||||
targetKeys: (string | number)[],
|
||||
deleteCondition?: (node: TreeNode<T>, parent?: TreeNode<T>) => boolean,
|
||||
deleteCallBack?: (node: TreeNode<T>) => void,
|
||||
customKey = 'key'
|
||||
): boolean {
|
||||
let hasDeleted = false;
|
||||
|
@ -589,6 +590,9 @@ export function deleteNodes<T>(
|
|||
const node = tree[i];
|
||||
if (targetKeysSet.has(node[customKey])) {
|
||||
if (deleteCondition && deleteCondition(node, node.parent)) {
|
||||
if (deleteCallBack) {
|
||||
deleteCallBack(node);
|
||||
}
|
||||
tree.splice(i, 1); // 直接删除当前节点
|
||||
hasDeleted = true;
|
||||
targetKeysSet.delete(node[customKey]); // 删除后从集合中移除
|
||||
|
|
|
@ -927,7 +927,8 @@
|
|||
return item;
|
||||
});
|
||||
if (
|
||||
(!props.disabledExceptParam || !props.disabledParamValue) &&
|
||||
!props.disabledExceptParam &&
|
||||
!props.disabledParamValue &&
|
||||
hasNoIdItem &&
|
||||
!filterKeyValParams(arr, defaultLineData.value, !props.selectable).lastDataIsDefault &&
|
||||
!props.isTreeTable
|
||||
|
@ -935,7 +936,7 @@
|
|||
addTableLine(arr.length - 1, false, true);
|
||||
}
|
||||
} else {
|
||||
if (props.disabledExceptParam) return;
|
||||
if (props.disabledExceptParam || props.disabledParamValue) return;
|
||||
const id = getGenerateId();
|
||||
paramsData.value = [
|
||||
{
|
||||
|
|
|
@ -282,6 +282,9 @@
|
|||
scenario.value.steps,
|
||||
checkedKeys.value,
|
||||
(node) => !node.isQuoteScenarioStep,
|
||||
(node) => {
|
||||
delete scenario.value.stepDetails[node.id];
|
||||
},
|
||||
'uniqueId'
|
||||
);
|
||||
if (deleteResult) {
|
||||
|
|
|
@ -990,6 +990,7 @@
|
|||
maskClosable: false,
|
||||
onBeforeOk: async () => {
|
||||
deleteNode(steps.value, node.uniqueId, 'uniqueId');
|
||||
delete stepDetails.value[node.id];
|
||||
scenario.value.unSaved = true;
|
||||
},
|
||||
hideCancel: false,
|
||||
|
|
|
@ -219,7 +219,7 @@
|
|||
:module-id="props.activeFolder"
|
||||
:modules-count="props.modulesCount"
|
||||
:module-name="props.moduleName"
|
||||
@save="emitTableParams"
|
||||
@save="handleMinderSave"
|
||||
/>
|
||||
<MsDrawer v-model:visible="visible" :width="480" :mask="false">
|
||||
{{ nodeData.text }}
|
||||
|
@ -390,7 +390,7 @@
|
|||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'init', params: CaseModuleQueryParams): void;
|
||||
(e: 'init', params: CaseModuleQueryParams, refreshModule?: boolean): void;
|
||||
(e: 'import', type: 'Excel' | 'Xmind'): void;
|
||||
}>();
|
||||
|
||||
|
@ -894,14 +894,22 @@
|
|||
};
|
||||
}
|
||||
// 获取父组件模块数量
|
||||
async function emitTableParams() {
|
||||
async function emitTableParams(refreshModule = false) {
|
||||
const tableParams = await initTableParams();
|
||||
emit('init', {
|
||||
...tableParams,
|
||||
current: propsRes.value.msPagination?.current,
|
||||
pageSize: propsRes.value.msPagination?.pageSize,
|
||||
filter: propsRes.value.filter,
|
||||
});
|
||||
emit(
|
||||
'init',
|
||||
{
|
||||
...tableParams,
|
||||
current: propsRes.value.msPagination?.current,
|
||||
pageSize: propsRes.value.msPagination?.pageSize,
|
||||
filter: propsRes.value.filter,
|
||||
},
|
||||
refreshModule
|
||||
);
|
||||
}
|
||||
|
||||
function handleMinderSave() {
|
||||
emitTableParams(true);
|
||||
}
|
||||
|
||||
const tableSelected = ref<(string | number)[]>([]);
|
||||
|
|
|
@ -285,7 +285,10 @@
|
|||
/**
|
||||
* 右侧表格数据刷新后,若当前展示的是模块,则刷新模块树的统计数量
|
||||
*/
|
||||
function initModulesCount(params: TableQueryParams) {
|
||||
function initModulesCount(params: TableQueryParams, refreshModule = false) {
|
||||
if (refreshModule) {
|
||||
caseTreeRef.value.initModules();
|
||||
}
|
||||
featureCaseStore.getCaseModulesCount(params);
|
||||
featureCaseStore.getRecycleModulesCount(params);
|
||||
tableFilterParams.value = { ...params };
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
</MsCard>
|
||||
<!-- special-height的174: 上面卡片高度158 + mt的16 -->
|
||||
<MsCard class="mt-[16px]" :special-height="174" simple has-breadcrumb no-content-padding>
|
||||
<Plan v-if="activeTab === 'plan'" :plan-id="planId" @refresh="initDetail" />
|
||||
<Plan v-if="activeTab === 'plan'" :plan-id="planId" :status="detail.status || 'PREPARED'" @refresh="initDetail" />
|
||||
<FeatureCase
|
||||
v-if="activeTab === 'featureCase'"
|
||||
ref="featureCaseRef"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="flex h-full flex-col p-[16px]">
|
||||
<MsNotRemind tip="testPlan.planTip" class="mb-[16px]" type="info" visited-key="testPlanTip" />
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<MsTestPlanMinder :plan-id="props.planId" @save="emit('refresh')" />
|
||||
<MsTestPlanMinder :plan-id="props.planId" :status="props.status" @save="emit('refresh')" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -13,6 +13,7 @@
|
|||
|
||||
const props = defineProps<{
|
||||
planId: string;
|
||||
status: string;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'refresh'): void;
|
||||
|
|
Loading…
Reference in New Issue