feat(测试计划): 脑图执行用例优化-快捷键和样式
--story=1015918 --user=吕梦园 https://www.tapd.cn/55049933/prong/stories/view/1155049933001015918
This commit is contained in:
parent
a63d9e811a
commit
a2cf676081
|
@ -19,7 +19,7 @@
|
|||
>
|
||||
<template #extractMenu>
|
||||
<!-- 缺陷 -->
|
||||
<a-dropdown position="bl">
|
||||
<a-dropdown trigger="hover" position="bl">
|
||||
<a-tooltip
|
||||
v-if="
|
||||
props.canEdit &&
|
||||
|
@ -166,6 +166,7 @@
|
|||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsDescription, { Description } from '@/components/pure/ms-description/index.vue';
|
||||
import useShortCut from '@/components/pure/ms-minder-editor/hooks/useShortCut';
|
||||
import MsMinderEditor from '@/components/pure/ms-minder-editor/minderEditor.vue';
|
||||
import type { MinderJson, MinderJsonNode, MinderJsonNodeData } from '@/components/pure/ms-minder-editor/props';
|
||||
import {
|
||||
|
@ -178,6 +179,7 @@
|
|||
setPriorityView,
|
||||
} from '@/components/pure/ms-minder-editor/script/tool/utils';
|
||||
import { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||
import { getMinderOperationParams } from '@/components/business/ms-minders/caseReviewMinder/utils';
|
||||
import Attachment from '@/components/business/ms-minders/featureCaseMinder/attachment.vue';
|
||||
import useMinderBaseApi from '@/components/business/ms-minders/featureCaseMinder/useMinderBaseApi';
|
||||
import BugList from './bugList.vue';
|
||||
|
@ -189,7 +191,13 @@
|
|||
import ExecuteSubmit from '@/views/test-plan/testPlan/detail/featureCase/detail/executeSubmit.vue';
|
||||
|
||||
import { getCasePlanMinder } from '@/api/modules/case-management/caseReview';
|
||||
import { associateBugToPlan, executeHistory, getCaseDetail, runFeatureCase } from '@/api/modules/test-plan/testPlan';
|
||||
import {
|
||||
associateBugToPlan,
|
||||
batchExecuteCase,
|
||||
executeHistory,
|
||||
getCaseDetail,
|
||||
runFeatureCase,
|
||||
} from '@/api/modules/test-plan/testPlan';
|
||||
import { defaultExecuteForm } from '@/config/testPlan';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
@ -201,7 +209,11 @@
|
|||
import type { StepList } from '@/models/caseManagement/featureCase';
|
||||
import type { TableQueryParams } from '@/models/common';
|
||||
import { ModuleTreeNode } from '@/models/common';
|
||||
import type { ExecuteFeatureCaseFormParams, ExecuteHistoryItem } from '@/models/testPlan/testPlan';
|
||||
import type {
|
||||
BatchExecuteFeatureCaseParams,
|
||||
ExecuteFeatureCaseFormParams,
|
||||
ExecuteHistoryItem,
|
||||
} from '@/models/testPlan/testPlan';
|
||||
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
import { MinderEventName, MinderKeyEnum } from '@/enums/minderEnum';
|
||||
|
@ -305,16 +317,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initCaseTree();
|
||||
// 固定标签颜色
|
||||
window.minder._resourceColorMapping = {
|
||||
[executionResultMap.SUCCESS.statusText]: 4,
|
||||
[executionResultMap.ERROR.statusText]: 5,
|
||||
[executionResultMap.BLOCKED.statusText]: 6,
|
||||
};
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.activeModule,
|
||||
() => {
|
||||
|
@ -549,11 +551,17 @@
|
|||
const executeVisible = ref(false);
|
||||
// 更新用例的实际结果节点
|
||||
function updateCaseActualResultNode(node: MinderJsonNode, content: string) {
|
||||
const actualResultNode = node.children?.find((item: MinderJsonNode) =>
|
||||
let actualResultNode = node.children?.find((item: MinderJsonNode) =>
|
||||
item.data?.resource?.includes(actualResultTag)
|
||||
);
|
||||
if (actualResultNode) {
|
||||
actualResultNode.setData('text', content ?? '').render();
|
||||
} else {
|
||||
actualResultNode = createNode(
|
||||
{ resource: [actualResultTag], text: content ?? '', id: `actualResult-${node.data?.id}` },
|
||||
node
|
||||
);
|
||||
handleRenderNode(node, [actualResultNode]);
|
||||
}
|
||||
}
|
||||
function isActualResultNode(node: MinderJsonNode) {
|
||||
|
@ -584,6 +592,24 @@
|
|||
}
|
||||
emit('refreshPlan');
|
||||
}
|
||||
async function handleShortCutExecute(status: LastExecuteResults) {
|
||||
const selectedNodes: MinderJsonNode = window.minder.getSelectedNode();
|
||||
if (!selectedNodes?.data?.resource?.includes(caseTag)) return;
|
||||
try {
|
||||
await batchExecuteCase({
|
||||
projectId: appStore.currentProjectId,
|
||||
testPlanId: props.planId,
|
||||
lastExecResult: status,
|
||||
content: '',
|
||||
...getMinderOperationParams(selectedNodes),
|
||||
} as BatchExecuteFeatureCaseParams);
|
||||
// 更新
|
||||
handleExecuteDone(status, '');
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
const stepExecuteModelVisible = ref(false);
|
||||
const caseNodeAboveSelectStep = ref(); // 选中的步骤节点对应的用例节点信息
|
||||
|
@ -835,6 +861,32 @@
|
|||
extraVisible.value = false;
|
||||
}
|
||||
|
||||
const { unbindShortcuts } = useShortCut(
|
||||
{
|
||||
executeToError: () => {
|
||||
handleShortCutExecute(LastExecuteResults.ERROR);
|
||||
},
|
||||
executeToBlocked: () => {
|
||||
handleShortCutExecute(LastExecuteResults.BLOCKED);
|
||||
},
|
||||
executeToSuccess: () => {
|
||||
handleShortCutExecute(LastExecuteResults.SUCCESS);
|
||||
},
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
initCaseTree();
|
||||
// 固定标签颜色
|
||||
window.minder._resourceColorMapping = {
|
||||
[executionResultMap.SUCCESS.statusText]: 4,
|
||||
[executionResultMap.ERROR.statusText]: 5,
|
||||
[executionResultMap.BLOCKED.statusText]: 6,
|
||||
};
|
||||
unbindShortcuts();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
initCaseTree,
|
||||
});
|
||||
|
|
|
@ -1,7 +1,17 @@
|
|||
import type { MinderJsonNode } from '../props';
|
||||
import useMinderOperation, { type MinderOperationProps } from './useMinderOperation';
|
||||
|
||||
type ShortcutKey = 'expand' | 'enter' | 'appendSiblingNode' | 'appendChildNode' | 'undo' | 'redo' | 'delete';
|
||||
type ShortcutKey =
|
||||
| 'expand'
|
||||
| 'enter'
|
||||
| 'appendSiblingNode'
|
||||
| 'appendChildNode'
|
||||
| 'undo'
|
||||
| 'redo'
|
||||
| 'delete'
|
||||
| 'executeToSuccess'
|
||||
| 'executeToBlocked'
|
||||
| 'executeToError';
|
||||
// 快捷键事件映射,combinationShortcuts中定义了组合键事件,key为组合键,value为事件名称;
|
||||
type Shortcuts = {
|
||||
[key in ShortcutKey]?: () => void;
|
||||
|
@ -11,6 +21,7 @@ export default function useShortCut(shortcuts: Shortcuts, options: MinderOperati
|
|||
const { minderCopy, minderCut, minderPaste } = useMinderOperation(options);
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
event.preventDefault();
|
||||
const nodes: MinderJsonNode[] = window.minder.getSelectedNodes();
|
||||
if (nodes.length === 0) {
|
||||
return;
|
||||
|
@ -41,19 +52,26 @@ export default function useShortCut(shortcuts: Shortcuts, options: MinderOperati
|
|||
'tab': 'appendChildNode',
|
||||
'backspace': 'delete',
|
||||
};
|
||||
// 业务快捷键
|
||||
const businessShortcuts: { [key: string]: ShortcutKey } = {
|
||||
s: 'executeToSuccess', // 执行结果为成功
|
||||
b: 'executeToBlocked', // 执行结果为阻塞
|
||||
e: 'executeToError', // 执行结果为失败
|
||||
};
|
||||
|
||||
let action;
|
||||
if (isCtrlOrCmd && combinationShortcuts[key]) {
|
||||
// 执行组合键事件
|
||||
const action = combinationShortcuts[key];
|
||||
if (shortcuts[action]) {
|
||||
shortcuts[action]!();
|
||||
}
|
||||
action = combinationShortcuts[key];
|
||||
} else if (singleShortcuts[key]) {
|
||||
// 执行单键事件
|
||||
const action = singleShortcuts[key];
|
||||
if (shortcuts[action]) {
|
||||
shortcuts[action]!();
|
||||
action = singleShortcuts[key];
|
||||
} else if (businessShortcuts[key]) {
|
||||
// 执行业务快捷键事件
|
||||
action = businessShortcuts[key];
|
||||
}
|
||||
if (action && shortcuts[action]) {
|
||||
shortcuts[action]!();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
class="ms-minder-dropdown"
|
||||
:popup-translate="[0, 4]"
|
||||
position="bl"
|
||||
trigger="click"
|
||||
trigger="hover"
|
||||
@select="(val) => handleMinderMenuSelect(val)"
|
||||
>
|
||||
<a-tooltip :content="t('common.more')">
|
||||
|
|
|
@ -29,60 +29,8 @@ interface IJumpingRuntime {
|
|||
container: HTMLElement;
|
||||
}
|
||||
|
||||
// Nice: http://unixpapa.com/js/key.html
|
||||
function isIntendToInput(e: KeyboardEvent): boolean {
|
||||
if (e.ctrlKey || e.metaKey || e.altKey) return false;
|
||||
|
||||
// a-zA-Z
|
||||
if (e.keyCode >= 65 && e.keyCode <= 90) return true;
|
||||
|
||||
// 0-9 以及其上面的符号
|
||||
if (e.keyCode >= 48 && e.keyCode <= 57) return true;
|
||||
|
||||
// 小键盘区域 (除回车外)
|
||||
if (e.keyCode !== 108 && e.keyCode >= 96 && e.keyCode <= 111) return true;
|
||||
|
||||
// 小键盘区域 (除回车外)
|
||||
// @yinheli from pull request
|
||||
if (e.keyCode !== 108 && e.keyCode >= 96 && e.keyCode <= 111) return true;
|
||||
|
||||
// 输入法
|
||||
if (e.keyCode === 229 || e.keyCode === 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function JumpingRuntime(this: IJumpingRuntime): void {
|
||||
const { fsm, minder, receiver } = this;
|
||||
const receiverElement = receiver.element;
|
||||
// normal -> *
|
||||
receiver.listen('normal', (e: KeyboardEvent) => {
|
||||
// 为了防止处理进入edit模式而丢失处理的首字母,此时receiver必须为enable
|
||||
receiver.enable();
|
||||
/**
|
||||
* check
|
||||
* @editor Naixor
|
||||
* @Date 2015-12-2
|
||||
*/
|
||||
switch (e.type) {
|
||||
case 'keydown': {
|
||||
if (minder.getSelectedNode()) {
|
||||
if (isIntendToInput(e)) {
|
||||
return fsm.jump('input', 'user-input');
|
||||
}
|
||||
} else {
|
||||
receiverElement.innerHTML = '';
|
||||
}
|
||||
// normal -> normal shortcut
|
||||
// fsm.jump('normal', 'shortcut-handle', e); TODO: 未来需要支持自定义快捷键处理逻辑
|
||||
break;
|
||||
}
|
||||
case 'keyup': {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
});
|
||||
const { fsm, receiver } = this;
|
||||
|
||||
// input => normal
|
||||
receiver.listen('input', (e: KeyboardEvent) => {
|
||||
|
|
Loading…
Reference in New Issue