feat(测试计划): 脑图失败重试&报告展示重试结果
This commit is contained in:
parent
420a826697
commit
fe28bcc27d
|
@ -183,7 +183,11 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item class="hidden-item">
|
<a-form-item class="hidden-item">
|
||||||
<div class="flex items-center gap-[8px]">
|
<div class="flex items-center gap-[8px]">
|
||||||
<a-switch v-model:model-value="configForm.retryOnFail" size="small"></a-switch>
|
<a-switch
|
||||||
|
v-model:model-value="configForm.retryOnFail"
|
||||||
|
:disabled="configForm.level === 2 && configForm.extended"
|
||||||
|
size="small"
|
||||||
|
></a-switch>
|
||||||
<div>{{ t('ms.minders.failRetry') }}</div>
|
<div>{{ t('ms.minders.failRetry') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -201,6 +205,7 @@
|
||||||
:step="1"
|
:step="1"
|
||||||
:min="1"
|
:min="1"
|
||||||
:precision="0"
|
:precision="0"
|
||||||
|
:disabled="configForm.level === 2 && configForm.extended"
|
||||||
size="small"
|
size="small"
|
||||||
class="w-[120px]"
|
class="w-[120px]"
|
||||||
></a-input-number>
|
></a-input-number>
|
||||||
|
@ -218,6 +223,7 @@
|
||||||
:step="100"
|
:step="100"
|
||||||
:min="0"
|
:min="0"
|
||||||
:precision="0"
|
:precision="0"
|
||||||
|
:disabled="configForm.level === 2 && configForm.extended"
|
||||||
size="small"
|
size="small"
|
||||||
class="w-[120px]"
|
class="w-[120px]"
|
||||||
></a-input-number>
|
></a-input-number>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
:class="[props.class, props.noContent ? 'no-content' : '']"
|
:class="[props.class, props.noContent ? 'no-content' : '']"
|
||||||
@change="(val) => handleTabClick(val as string)"
|
@change="(val) => handleTabClick(val as string)"
|
||||||
>
|
>
|
||||||
<a-tab-pane v-for="item of props.contentTabList" :key="item.value" :title="item.label">
|
<a-tab-pane v-for="item of props.contentTabList" :key="item.value" :title="`${item.label}`">
|
||||||
<template v-if="props.showBadge" #title>
|
<template v-if="props.showBadge" #title>
|
||||||
<a-badge
|
<a-badge
|
||||||
v-if="props.getTextFunc(item.value) !== ''"
|
v-if="props.getTextFunc(item.value) !== ''"
|
||||||
|
@ -27,8 +27,11 @@
|
||||||
<div
|
<div
|
||||||
v-for="item of props.contentTabList"
|
v-for="item of props.contentTabList"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
class="ms-tab--button-item"
|
class="ms-tab-button-item"
|
||||||
:class="item.value === tempActiveKey ? 'ms-tab--button-item--active' : ''"
|
:class="[
|
||||||
|
item.value === tempActiveKey ? 'ms-tab-button-item--active' : '',
|
||||||
|
props.buttonSize === 'small' ? 'ms-tab--button-item--small' : '',
|
||||||
|
]"
|
||||||
@click="handleTabClick(item.value)"
|
@click="handleTabClick(item.value)"
|
||||||
>
|
>
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
|
@ -40,23 +43,28 @@
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
mode?: 'origin' | 'button';
|
mode?: 'origin' | 'button';
|
||||||
contentTabList: { label: string; value: string }[];
|
contentTabList: { label: string | number; value: string | number }[];
|
||||||
class?: string;
|
class?: string;
|
||||||
getTextFunc?: (value: any) => string;
|
getTextFunc?: (value: any) => string;
|
||||||
noContent?: boolean;
|
noContent?: boolean;
|
||||||
showBadge?: boolean;
|
showBadge?: boolean;
|
||||||
changeInterceptor?: (newVal: string, oldVal: string, done: () => void) => void;
|
changeInterceptor?: (newVal: string | number, oldVal: string | number, done: () => void) => void;
|
||||||
|
buttonSize?: 'small' | 'default';
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
mode: 'origin',
|
mode: 'origin',
|
||||||
showBadge: true,
|
showBadge: true,
|
||||||
getTextFunc: (value: any) => value,
|
getTextFunc: (value: any) => value,
|
||||||
class: '',
|
class: '',
|
||||||
|
buttonSize: 'default',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'change', value: string | number): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
// 实际值,用于最终确认修改的 tab 值
|
// 实际值,用于最终确认修改的 tab 值
|
||||||
const activeKey = defineModel<string>('activeKey', {
|
const activeKey = defineModel<string | number>('activeKey', {
|
||||||
default: '',
|
default: '',
|
||||||
});
|
});
|
||||||
// 临时值,用于组件内部变更,但未影响到实际值
|
// 临时值,用于组件内部变更,但未影响到实际值
|
||||||
|
@ -69,7 +77,7 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleTabClick(value: string) {
|
function handleTabClick(value: string | number) {
|
||||||
if (value === activeKey.value) {
|
if (value === activeKey.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +93,7 @@
|
||||||
// 不存在拦截器,直接修改实际值
|
// 不存在拦截器,直接修改实际值
|
||||||
activeKey.value = value;
|
activeKey.value = value;
|
||||||
}
|
}
|
||||||
|
emit('change', activeKey.value);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -107,7 +116,7 @@
|
||||||
@apply flex;
|
@apply flex;
|
||||||
|
|
||||||
border-radius: var(--border-radius-small);
|
border-radius: var(--border-radius-small);
|
||||||
.ms-tab--button-item {
|
.ms-tab-button-item {
|
||||||
@apply cursor-pointer;
|
@apply cursor-pointer;
|
||||||
|
|
||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
|
@ -128,7 +137,12 @@
|
||||||
color: rgb(var(--primary-5));
|
color: rgb(var(--primary-5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ms-tab--button-item--active {
|
.ms-tab--button-item--small {
|
||||||
|
padding: 1px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
.ms-tab-button-item--active {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
border: 1px solid rgb(var(--primary-5)) !important;
|
border: 1px solid rgb(var(--primary-5)) !important;
|
||||||
color: rgb(var(--primary-5));
|
color: rgb(var(--primary-5));
|
||||||
|
|
|
@ -1,33 +1,43 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col" @click.stop="() => {}">
|
<div class="flex flex-col" @click.stop="() => {}">
|
||||||
<div class="response-header">
|
<div class="response-header">
|
||||||
<div v-if="isShowLoopControl" class="flex w-full items-center justify-start bg-white p-4" @click.stop="() => {}">
|
<div
|
||||||
<a-pagination
|
v-if="isShowLoopControl"
|
||||||
v-model:page-size="controlPageSize"
|
class="flex w-full items-center justify-start bg-white pb-[8px] pt-[16px]"
|
||||||
v-model:current="controlCurrent"
|
@click.stop="() => {}"
|
||||||
:total="controlTotal"
|
>
|
||||||
size="mini"
|
<MsTab
|
||||||
show-total
|
v-if="isFailedRetry"
|
||||||
:show-jumper="controlTotal > 5"
|
v-model:activeKey="controlCurrent"
|
||||||
|
:content-tab-list="controlTotalList"
|
||||||
|
mode="button"
|
||||||
|
button-size="small"
|
||||||
|
@change="loadControlLoop"
|
||||||
|
/>
|
||||||
|
<loopPagination
|
||||||
|
v-else
|
||||||
|
v-model:current-loop="controlCurrent"
|
||||||
|
:loop-total="controlTotal"
|
||||||
|
class="!mb-0"
|
||||||
@change="loadControlLoop"
|
@change="loadControlLoop"
|
||||||
/>
|
/>
|
||||||
<!-- <loopPagination v-model:current-loop="controlCurrent" :loop-total="controlTotal" /> -->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex w-full items-center justify-between rounded bg-[var(--color-text-n9)] p-4">
|
<div class="flex w-full items-center justify-between rounded bg-[var(--color-text-n9)] p-4">
|
||||||
<div class="font-medium">
|
<div class="font-medium">
|
||||||
<span
|
<span
|
||||||
:class="{ 'text-[rgb(var(--primary-5))]': activeType === 'ResContent' }"
|
:class="{ 'text-[rgb(var(--primary-5))]': activeType === 'ResContent' }"
|
||||||
@click.stop="setActiveType('ResContent')"
|
@click.stop="setActiveType('ResContent')"
|
||||||
>{{ t('report.detail.api.resContent') }}</span
|
|
||||||
>
|
>
|
||||||
|
{{ t('report.detail.api.resContent') }}
|
||||||
|
</span>
|
||||||
<span
|
<span
|
||||||
v-if="total > 0"
|
v-if="total > 0"
|
||||||
:class="{ 'text-[rgb(var(--primary-5))]': activeType === 'SubRequest' }"
|
:class="{ 'text-[rgb(var(--primary-5))]': activeType === 'SubRequest' }"
|
||||||
@click.stop="setActiveType('SubRequest')"
|
@click.stop="setActiveType('SubRequest')"
|
||||||
>
|
>
|
||||||
<a-divider direction="vertical" :margin="8"></a-divider>
|
<a-divider direction="vertical" :margin="8"></a-divider>
|
||||||
{{ t('report.detail.api.subRequest') }}</span
|
{{ t('report.detail.api.subRequest') }}
|
||||||
>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row gap-6 text-center">
|
<div class="flex flex-row gap-6 text-center">
|
||||||
<a-popover position="left" content-class="response-popover-content">
|
<a-popover position="left" content-class="response-popover-content">
|
||||||
|
@ -121,7 +131,9 @@
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
|
import MsTab from '@/components/pure/ms-tab/index.vue';
|
||||||
import result from '@/views/api-test/components/requestComposition/response/result.vue';
|
import result from '@/views/api-test/components/requestComposition/response/result.vue';
|
||||||
|
import loopPagination from '@/views/api-test/scenario/components/common/loopPagination.vue';
|
||||||
|
|
||||||
import { reportCaseStepDetail, reportStepDetail } from '@/api/modules/api-test/report';
|
import { reportCaseStepDetail, reportStepDetail } from '@/api/modules/api-test/report';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
@ -337,7 +349,24 @@
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
const controlPageSize = ref(1);
|
const controlTotalList = computed(() => {
|
||||||
|
return Array.from({ length: controlTotal.value }, (v, k) => {
|
||||||
|
if (k === 0) {
|
||||||
|
return {
|
||||||
|
value: k + 1,
|
||||||
|
label: t('apiTestDebug.first'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
value: k + 1,
|
||||||
|
label: `${t('apiTestDebug.retry')} ${k}`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const isFailedRetry = computed(() => {
|
||||||
|
return !!props.stepItem?.stepChildren?.some((item) => item.requestName.includes('MsRetry_')); // 是否包含重试前缀
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 循环次数控制器
|
* 循环次数控制器
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -213,4 +213,6 @@ export default {
|
||||||
'apiTestDebug.standardAdditionsTip':
|
'apiTestDebug.standardAdditionsTip':
|
||||||
'Writing format: parameter name, type, required, parameter value; multiple records separated by newlines',
|
'Writing format: parameter name, type, required, parameter value; multiple records separated by newlines',
|
||||||
'apiTestDebug.quickAdditions': 'Quick',
|
'apiTestDebug.quickAdditions': 'Quick',
|
||||||
|
'apiTestDebug.first': 'First',
|
||||||
|
'apiTestDebug.retry': 'Retry',
|
||||||
};
|
};
|
||||||
|
|
|
@ -199,4 +199,6 @@ export default {
|
||||||
'apiTestDebug.standardAdditions': '标准添加',
|
'apiTestDebug.standardAdditions': '标准添加',
|
||||||
'apiTestDebug.standardAdditionsTip': '书写格式:参数名,类型,必填,参数值;多条记录换行分隔',
|
'apiTestDebug.standardAdditionsTip': '书写格式:参数名,类型,必填,参数值;多条记录换行分隔',
|
||||||
'apiTestDebug.quickAdditions': '快捷添加',
|
'apiTestDebug.quickAdditions': '快捷添加',
|
||||||
|
'apiTestDebug.first': '首次',
|
||||||
|
'apiTestDebug.retry': '重试',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mb-4 flex h-[36px] items-center justify-between">
|
<div class="flex h-[36px] items-center justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="mr-2 font-medium leading-[36px]">{{ t('report.detail.api.reportDetail') }}</div>
|
<div class="mr-2 font-medium leading-[36px]">{{ t('report.detail.api.reportDetail') }}</div>
|
||||||
<a-radio-group v-model:model-value="innerActiveTab" type="button" size="small">
|
<a-radio-group v-model:model-value="innerActiveTab" type="button" size="small">
|
||||||
|
|
|
@ -128,25 +128,21 @@
|
||||||
<span v-show="step.requestTime !== null" class="resTime">
|
<span v-show="step.requestTime !== null" class="resTime">
|
||||||
{{ t('report.detail.api.responseTime') }}
|
{{ t('report.detail.api.responseTime') }}
|
||||||
<a-popover position="left" content-class="response-popover-content">
|
<a-popover position="left" content-class="response-popover-content">
|
||||||
<span class="resTimeCount ml-2"
|
<span class="resTimeCount ml-2">
|
||||||
>{{ step.requestTime !== null ? formatDuration(step.requestTime).split('-')[0] : '-'
|
{{ step.requestTime !== null ? formatDuration(step.requestTime).split('-')[0] : '-' }}
|
||||||
}}{{
|
{{ step.requestTime !== null ? formatDuration(step.requestTime).split('-')[1] : 'ms' }}
|
||||||
step.requestTime !== null ? formatDuration(step.requestTime).split('-')[1] : 'ms'
|
</span>
|
||||||
}}</span
|
|
||||||
>
|
|
||||||
<template #content>
|
<template #content>
|
||||||
<span v-show="step.requestTime !== null" class="resTime">
|
<span v-show="step.requestTime !== null" class="resTime">
|
||||||
{{ t('report.detail.api.responseTime') }}
|
{{ t('report.detail.api.responseTime') }}
|
||||||
<span class="resTimeCount ml-2"
|
<span class="resTimeCount ml-2">
|
||||||
>{{ step.requestTime !== null ? formatDuration(step.requestTime).split('-')[0] : '-'
|
{{ step.requestTime !== null ? formatDuration(step.requestTime).split('-')[0] : '-' }}
|
||||||
}}{{
|
{{ step.requestTime !== null ? formatDuration(step.requestTime).split('-')[1] : 'ms' }}
|
||||||
step.requestTime !== null ? formatDuration(step.requestTime).split('-')[1] : 'ms'
|
</span>
|
||||||
}}</span
|
</span>
|
||||||
></span
|
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
</a-popover></span
|
</a-popover>
|
||||||
>
|
</span>
|
||||||
<span v-show="step.responseSize !== null" class="resSize">
|
<span v-show="step.responseSize !== null" class="resSize">
|
||||||
{{ t('report.detail.api.responseSize') }}
|
{{ t('report.detail.api.responseSize') }}
|
||||||
<a-popover position="left" content-class="response-popover-content">
|
<a-popover position="left" content-class="response-popover-content">
|
||||||
|
@ -157,8 +153,8 @@
|
||||||
<span class="resTimeCount ml-2">{{ step.responseSize || 0 }} bytes</span></span
|
<span class="resTimeCount ml-2">{{ step.responseSize || 0 }} bytes</span></span
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</a-popover></span
|
</a-popover>
|
||||||
>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,10 +5,18 @@
|
||||||
'border border-solid border-[var(--color-text-n8)]': props.showType === 'API',
|
'border border-solid border-[var(--color-text-n8)]': props.showType === 'API',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
<div v-if="isFailedRetry" class="mb-[8px]">
|
||||||
|
<MsTab
|
||||||
|
v-model:activeKey="controlCurrent"
|
||||||
|
:content-tab-list="controlTotalList"
|
||||||
|
mode="button"
|
||||||
|
button-size="small"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<!-- 步骤树 -->
|
<!-- 步骤树 -->
|
||||||
<StepTree
|
<StepTree
|
||||||
ref="stepTreeRef"
|
ref="stepTreeRef"
|
||||||
v-model:steps="tiledList"
|
v-model:steps="currentTiledList"
|
||||||
v-model:expandedKeys="expandedKeys"
|
v-model:expandedKeys="expandedKeys"
|
||||||
:show-type="props.showType"
|
:show-type="props.showType"
|
||||||
:active-type="props.activeType"
|
:active-type="props.activeType"
|
||||||
|
@ -36,9 +44,12 @@
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { cloneDeep, debounce } from 'lodash-es';
|
import { cloneDeep, debounce } from 'lodash-es';
|
||||||
|
|
||||||
|
import MsTab from '@/components/pure/ms-tab/index.vue';
|
||||||
import StepDrawer from './step/stepDrawer.vue';
|
import StepDrawer from './step/stepDrawer.vue';
|
||||||
import StepTree from './step/stepTree.vue';
|
import StepTree from './step/stepTree.vue';
|
||||||
|
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
import type { ReportDetail, ScenarioItemType } from '@/models/apiTest/report';
|
import type { ReportDetail, ScenarioItemType } from '@/models/apiTest/report';
|
||||||
import { ScenarioStepType } from '@/enums/apiEnum';
|
import { ScenarioStepType } from '@/enums/apiEnum';
|
||||||
|
|
||||||
|
@ -52,6 +63,8 @@
|
||||||
getReportStepDetail?: (...args: any) => Promise<any>; // 获取步骤的详情内容接口
|
getReportStepDetail?: (...args: any) => Promise<any>; // 获取步骤的详情内容接口
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const tiledList = ref<ScenarioItemType[]>([]);
|
const tiledList = ref<ScenarioItemType[]>([]);
|
||||||
|
|
||||||
const isExpandAll = ref(false); // 是否展开全部
|
const isExpandAll = ref(false); // 是否展开全部
|
||||||
|
@ -82,6 +95,37 @@
|
||||||
originTreeData.value = cloneDeep(tiledList.value);
|
originTreeData.value = cloneDeep(tiledList.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const controlCurrent = ref(0);
|
||||||
|
const isFailedRetry = computed(() => {
|
||||||
|
// 所有步骤 id 相同且带有重试前缀,说明是单个用例的重试结果
|
||||||
|
return (
|
||||||
|
props.reportDetail.children.every((item) => item.stepId === props.reportDetail.children[0].stepId) &&
|
||||||
|
props.reportDetail.children.some((item) => item.requestName?.includes('MsRetry_'))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const currentTiledList = computed(() => {
|
||||||
|
if (isFailedRetry.value === false) {
|
||||||
|
// 不是失败重试结果
|
||||||
|
return tiledList.value;
|
||||||
|
}
|
||||||
|
// 失败重试的结果
|
||||||
|
return [tiledList.value[controlCurrent.value]];
|
||||||
|
});
|
||||||
|
const controlTotalList = computed(() => {
|
||||||
|
return Array.from({ length: props.reportDetail.children.length }, (v, k) => {
|
||||||
|
if (k === 0) {
|
||||||
|
return {
|
||||||
|
value: k,
|
||||||
|
label: t('apiTestDebug.first'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
value: k,
|
||||||
|
label: `${t('apiTestDebug.retry')} ${k}`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.reportDetail,
|
() => props.reportDetail,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
show-total
|
show-total
|
||||||
size="mini"
|
size="mini"
|
||||||
class="loop-pagination"
|
class="loop-pagination"
|
||||||
|
@change="() => emit('change', currentLoop)"
|
||||||
>
|
>
|
||||||
<template #total="{ total }">
|
<template #total="{ total }">
|
||||||
<div
|
<div
|
||||||
|
@ -31,6 +32,9 @@
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
loopTotal: number;
|
loopTotal: number;
|
||||||
}>();
|
}>();
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'change', value: number): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
|
|
@ -90,18 +90,18 @@
|
||||||
<template #default="{ detail, loading }">
|
<template #default="{ detail, loading }">
|
||||||
<div ref="wrapperRef" class="bg-white">
|
<div ref="wrapperRef" class="bg-white">
|
||||||
<div class="header relative h-[48px] border-b pl-2">
|
<div class="header relative h-[48px] border-b pl-2">
|
||||||
<div class="max-w-[calc(100%-72px)]"
|
<div class="max-w-[calc(100%-72px)]">
|
||||||
><MsTab
|
<MsTab
|
||||||
v-model:active-key="activeTab"
|
v-model:active-key="activeTab"
|
||||||
:content-tab-list="tabSetting"
|
:content-tab-list="tabSetting"
|
||||||
:get-text-func="getTotal"
|
:get-text-func="getTotal"
|
||||||
class="no-content relative"
|
class="no-content relative"
|
||||||
@change="clickMenu"
|
@change="clickMenu"
|
||||||
/></div>
|
/>
|
||||||
|
</div>
|
||||||
<span class="display-setting h-full text-[var(--color-text-2)]" @click="showMenuSetting">{{
|
<span class="display-setting h-full text-[var(--color-text-2)]" @click="showMenuSetting">
|
||||||
t('caseManagement.featureCase.detailDisplaySetting')
|
{{ t('caseManagement.featureCase.detailDisplaySetting') }}
|
||||||
}}</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
@ -247,9 +247,9 @@
|
||||||
const commentInputIsActive = computed(() => commentInputRef.value?.isActive);
|
const commentInputIsActive = computed(() => commentInputRef.value?.isActive);
|
||||||
|
|
||||||
const tabSetting = ref<TabItemType[]>([]);
|
const tabSetting = ref<TabItemType[]>([]);
|
||||||
const activeTab = ref<string>('detail');
|
const activeTab = ref<string | number>('detail');
|
||||||
|
|
||||||
function clickMenu(key: string) {
|
function clickMenu(key: string | number) {
|
||||||
activeTab.value = key;
|
activeTab.value = key;
|
||||||
featureCaseStore.setActiveTab(key);
|
featureCaseStore.setActiveTab(key);
|
||||||
switch (activeTab.value) {
|
switch (activeTab.value) {
|
||||||
|
|
|
@ -509,7 +509,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeTabInterceptor(newVal: string, oldVal: string, done: () => void) {
|
function changeTabInterceptor(newVal: string | number, oldVal: string | number, done: () => void) {
|
||||||
if (oldVal === 'plan' && minderStore.minderUnsaved) {
|
if (oldVal === 'plan' && minderStore.minderUnsaved) {
|
||||||
openModal({
|
openModal({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
|
|
Loading…
Reference in New Issue