feat(测试计划): 测试计划详情-功能用例详情-执行内容展示调整优化

This commit is contained in:
xinxin.wu 2024-08-30 15:52:11 +08:00 committed by Craftsman
parent a3f70d1f64
commit ae1b6ddb02
4 changed files with 155 additions and 83 deletions

View File

@ -12,7 +12,6 @@
* import rehypeStringify from 'rehype-stringify';
* return unified().use(rehypeParse).use(rehypeFormat).use(rehypeStringify).processSync(content.value);
*/
import { useRoute } from 'vue-router';
import { useDebounceFn, useVModel } from '@vueuse/core';
import type { MsFileItem } from '@/components/pure/ms-upload/types';
@ -71,7 +70,6 @@
import * as fastq from 'fastq';
const { t } = useI18n();
const route = useRoute();
type Task = {
file: File;
process: (permalink: string, fileId: string) => void;
@ -91,6 +89,7 @@
previewUrl?: string;
editable?: boolean;
limitLength?: number;
autoFocus?: boolean;
}>(),
{
raw: '',
@ -109,6 +108,8 @@
(event: 'update:filedIds', value: string[]): void;
(event: 'update', value: string): void;
(event: 'update:commentIds', value: string): void;
(event: 'blur', eveValue: FocusEvent): void;
(event: 'focus', eveValue: FocusEvent): void;
}>();
const imagesNodesIds = useVModel(props, 'filedIds', emit);
@ -149,6 +150,16 @@
}
);
watch(
() => props.autoFocus,
(val) => {
editor.value?.setOptions({ autofocus: val });
},
{
immediate: true,
}
);
const attachmentSelectorModal = ref(false);
const selectedImagesNode = ref<string>();
const selectedCommentNode = ref<string>();
@ -385,11 +396,20 @@
limit: props.limitLength || null,
}),
],
autofocus: false,
autofocus: props.autoFocus,
editable: props.editable,
onUpdate: () => {
debounceOnUpdate();
},
onBlur: ({ event }) => {
//
if (!event.relatedTarget) {
emit('blur', event);
}
},
onFocus: ({ event }) => {
emit('focus', event);
},
editorProps: {
handleDrop: (view, event: DragEvent, _, moved) => {
if (!moved && event.dataTransfer && event.dataTransfer.files) {

View File

@ -1,15 +1,29 @@
<template>
<a-form :model="form">
<a-form-item field="lastExecResult" class="mb-[8px]">
<a-radio-group v-model:model-value="form.lastExecResult">
<a-radio v-for="item in executionResultList" :key="item.key" :value="item.key">
<ExecuteResult :execute-result="item.key" />
</a-radio>
</a-radio-group>
<div class="flex w-full items-center justify-between">
<a-radio-group v-model:model-value="form.lastExecResult">
<a-radio v-for="item in executionResultList" :key="item.key" :value="item.key">
<ExecuteResult :execute-result="item.key" />
</a-radio>
</a-radio-group>
<slot name="headerRight"></slot>
</div>
</a-form-item>
<a-form-item field="content" asterisk-position="end" class="mb-0">
<div class="flex w-full items-center">
<a-textarea
v-if="props.isDblclickPlaceholder && !achievedForm"
v-model="form.content"
allow-clear
:placeholder="t('testPlan.featureCase.richTextDblclickPlaceholder')"
:auto-size="{ minRows: 1 }"
style="resize: vertical"
:max-length="1000"
@click="achievedForm = true"
/>
<MsRichText
v-if="!props.isDblclickPlaceholder || achievedForm"
v-model:raw="form.content"
v-model:commentIds="form.commentIds"
v-model:filedIds="form.planCommentFileIds"
@ -17,12 +31,14 @@
:preview-url="`${PreviewEditorImageUrl}/${appStore.currentProjectId}`"
:auto-height="false"
class="w-full"
:auto-focus="true"
:max-height="props.richTextMaxHeight"
:placeholder="
props.isDblclickPlaceholder
? t('testPlan.featureCase.richTextDblclickPlaceholder')
: t('editor.placeholder')
"
@blur="blurHandler"
/>
</div>
</a-form-item>
@ -48,10 +64,18 @@
richTextMaxHeight?: string;
}>();
const emit = defineEmits<{
(e: 'dblclick'): void;
}>();
const form = defineModel<ExecuteFeatureCaseFormParams>('form', {
required: true,
});
const achievedForm = defineModel<boolean>('achieved', {
default: false,
});
const { t } = useI18n();
const appStore = useAppStore();
@ -65,6 +89,21 @@
});
return data;
}
function blurHandler() {
if (props.isDblclickPlaceholder && !form.value.content) {
achievedForm.value = false;
}
}
watch(
() => achievedForm.value,
(val) => {
if (val && props.isDblclickPlaceholder) {
emit('dblclick');
}
}
);
</script>
<style lang="less" scoped>

View File

@ -1,5 +1,15 @@
<template>
<ExecuteForm v-model:form="form" is-dblclick-placeholder class="execute-form" />
<ExecuteForm
v-model:achieved="achievedForm"
v-model:form="form"
is-dblclick-placeholder
class="execute-form"
@dblclick="dblclickHandler"
>
<template #headerRight>
<slot name="headerRight"></slot>
</template>
</ExecuteForm>
<a-button type="primary" class="mt-[12px]" :loading="submitLoading" @click="() => submit()">
{{ t('caseManagement.caseReview.commitResult') }}
</a-button>
@ -59,9 +69,8 @@
const modalVisible = ref(false);
const submitLoading = ref(false);
//
onMounted(() => {
function dblclickHandler() {
nextTick(() => {
const editorContent = document.querySelector('.execute-form')?.querySelector('.editor-content');
useEventListener(editorContent, 'dblclick', () => {
@ -69,7 +78,7 @@
dialogForm.value = cloneDeep(form.value);
});
});
});
}
watch(
() => props.stepExecutionResult,
@ -93,12 +102,15 @@
}
);
const achievedForm = ref<boolean>(false);
function cancel(e: Event) {
// /
if (!(e.target as any)?.classList.contains('arco-modal-wrapper')) {
dialogForm.value = { ...defaultExecuteForm };
}
form.value = cloneDeep(dialogForm.value);
achievedForm.value = false;
}
//
@ -128,6 +140,7 @@
modalVisible.value = false;
Message.success(t('common.updateSuccess'));
form.value = { ...defaultExecuteForm };
achievedForm.value = false;
emit('done', params.lastExecResult, params.content ?? '');
} catch (error) {
// eslint-disable-next-line no-console

View File

@ -116,83 +116,83 @@
v-if="canEdit && hasAnyPermission(['PROJECT_TEST_PLAN:READ+EXECUTE'])"
class="z-[101] px-[16px] py-[8px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]"
>
<div class="mb-[12px] flex items-center justify-between">
<div class="font-medium text-[var(--color-text-1)]">
{{ t('testPlan.featureCase.startExecution') }}
</div>
<div class="flex items-center">
<a-switch v-model:model-value="autoNext" size="small" />
<div class="mx-[8px]">{{ t('caseManagement.caseReview.autoNext') }}</div>
<a-tooltip position="top">
<template #content>
<div>{{ t('testPlan.featureCase.autoNextTip1') }}</div>
<div>{{ t('testPlan.featureCase.autoNextTip2') }}</div>
</template>
<icon-question-circle
class="text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-4))]"
size="16"
/>
</a-tooltip>
<MsTag type="danger" theme="light" size="medium" class="ml-4">
<MsIcon type="icon-icon_defect" class="!text-[14px] text-[rgb(var(--danger-6))]" size="16" />
<span class="ml-1 text-[rgb(var(--danger-6))]"> {{ t('testPlan.featureCase.bug') }}</span>
<span class="ml-1 text-[rgb(var(--danger-6))]">{{ caseDetail.bugListCount }}</span>
</MsTag>
<a-dropdown @select="handleSelect">
<a-button
v-if="hasAllPermission(['PROJECT_BUG:READ', 'PROJECT_TEST_PLAN:READ+EXECUTE'])"
type="outline"
size="small"
class="ml-1"
>
<template #icon> <icon-plus class="text-[12px]" /> </template>
</a-button>
<template #content>
<a-doption
v-permission="['PROJECT_BUG:READ+ADD']"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+ADD'])"
value="new"
>{{ t('common.newCreate') }}</a-doption
>
<a-doption
v-if="createdBugCount > 0 && hasAnyPermission(['PROJECT_BUG:READ'])"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ'])"
value="link"
>{{ t('common.associated') }}</a-doption
>
<a-popover v-else title="" position="left">
<a-doption
v-if="createdBugCount < 1 && hasAnyPermission(['PROJECT_BUG:READ'])"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ'])"
value="link"
>{{ t('common.associated') }}</a-doption
>
<template #content>
<div class="flex items-center text-[14px]">
<span class="text-[var(--color-text-4)]">{{
t('testPlan.featureCase.noBugDataTooltip')
}}</span>
<MsButton
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+ADD'])"
type="text"
@click="handleSelect('new')"
>
{{ t('testPlan.featureCase.noBugDataNewBug') }}
</MsButton>
</div>
</template>
</a-popover>
</template>
</a-dropdown>
</div>
</div>
<ExecuteSubmit
:id="activeId"
:case-id="activeCaseId"
:test-plan-id="route.query.id as string"
:step-execution-result="stepExecutionResult"
@done="executeDone"
/>
>
<template #headerRight>
<div class="mb-[12px] flex items-center justify-between">
<div class="flex items-center">
<a-switch v-model:model-value="autoNext" size="small" />
<div class="mx-[8px]">{{ t('caseManagement.caseReview.autoNext') }}</div>
<a-tooltip position="top">
<template #content>
<div>{{ t('testPlan.featureCase.autoNextTip1') }}</div>
<div>{{ t('testPlan.featureCase.autoNextTip2') }}</div>
</template>
<icon-question-circle
class="text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-4))]"
size="16"
/>
</a-tooltip>
<MsTag type="danger" theme="light" size="medium" class="ml-4">
<MsIcon type="icon-icon_defect" class="!text-[14px] text-[rgb(var(--danger-6))]" size="16" />
<span class="ml-1 text-[rgb(var(--danger-6))]"> {{ t('testPlan.featureCase.bug') }}</span>
<span class="ml-1 text-[rgb(var(--danger-6))]">{{ caseDetail.bugListCount }}</span>
</MsTag>
<a-dropdown @select="handleSelect">
<a-button
v-if="hasAllPermission(['PROJECT_BUG:READ', 'PROJECT_TEST_PLAN:READ+EXECUTE'])"
type="outline"
size="small"
class="ml-1"
>
<template #icon> <icon-plus class="text-[12px]" /> </template>
</a-button>
<template #content>
<a-doption
v-permission="['PROJECT_BUG:READ+ADD']"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+ADD'])"
value="new"
>{{ t('common.newCreate') }}</a-doption
>
<a-doption
v-if="createdBugCount > 0 && hasAnyPermission(['PROJECT_BUG:READ'])"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ'])"
value="link"
>{{ t('common.associated') }}</a-doption
>
<a-popover v-else title="" position="left">
<a-doption
v-if="createdBugCount < 1 && hasAnyPermission(['PROJECT_BUG:READ'])"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ'])"
value="link"
>{{ t('common.associated') }}</a-doption
>
<template #content>
<div class="flex items-center text-[14px]">
<span class="text-[var(--color-text-4)]">{{
t('testPlan.featureCase.noBugDataTooltip')
}}</span>
<MsButton
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+ADD'])"
type="text"
@click="handleSelect('new')"
>
{{ t('testPlan.featureCase.noBugDataNewBug') }}
</MsButton>
</div>
</template>
</a-popover>
</template>
</a-dropdown>
</div>
</div>
</template>
</ExecuteSubmit>
</div>
</div>
<BugList