fix(测试计划): 部分 bug 修复

This commit is contained in:
baiqi 2024-05-24 16:46:37 +08:00 committed by 刘瑞斌
parent 8366bf33e3
commit 5e170ed146
20 changed files with 301 additions and 154 deletions

View File

@ -765,97 +765,6 @@
} }
} }
/** 分页 **/
.ms-pagination {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 16px;
&-list {
display: flex;
flex-direction: row;
gap: 8px;
}
&-jumper {
display: flex;
align-items: center;
padding: 2px 8px;
border-radius: var(--border-radius-small);
background: var(--color-text-n9);
gap: 8px;
.ms-pagination-jumper-input {
padding: 3px 8px;
width: 57px;
border: 1px solid var(--color-text-input-border);
border-radius: var(--border-radius-small);
color: var(--color-text-1);
background: var(--color-text-10);
box-sizing: border-box;
input {
padding-top: 0 !important;
padding-bottom: 0 !important;
height: 22px;
text-align: center;
}
}
&-text-goto,
&-total-page {
color: var(--color-text-2);
}
}
&-total {
color: var(--color-text-2);
}
&-options {
margin-left: 14px;
}
&-item {
display: flex;
justify-content: center;
align-items: center;
padding: 5px 10px;
min-width: 32px;
height: 32px;
box-sizing: border-box;
cursor: pointer;
&-previous {
margin-left: 14px;
}
&-ellipsis {
padding: 5px 0;
}
&-ellipsis:hover {
min-width: 32px;
height: 32px;
}
&:not(:last-child):not(:first-child):not(.arco-pagination-item-ellipsis) {
border: 1px solid var(--color-text-input-border);
border-radius: 3px;
}
&-active {
border-color: rgb(var(--primary-5)) !important;
color: rgb(var(--primary-5)) !important;
background-color: rgb(var(--primary-1)) !important;
}
}
&-simple {
&-jumper {
display: flex;
align-items: center;
}
}
&-size-mini {
font-size: 12px;
line-height: 16px;
.ms-pagination-item {
height: 24px;
}
.ms-pagination-jumper-input {
padding: 0;
}
}
}
/** 折叠面板样式 **/ /** 折叠面板样式 **/
.arco-collapse { .arco-collapse {
padding: 0; padding: 0;

View File

@ -125,7 +125,16 @@
</div> </div>
</template> </template>
</MsAdvanceFilter> </MsAdvanceFilter>
<ms-base-table v-bind="propsRes" no-disable class="mt-[16px]" v-on="propsEvent"> <ms-base-table
v-bind="propsRes"
:action-config="{
baseAction: [],
moreAction: [],
}"
no-disable
class="mt-[16px]"
v-on="propsEvent"
>
<template #num="{ record }"> <template #num="{ record }">
<a-tooltip :content="`${record.num}`"> <a-tooltip :content="`${record.num}`">
<a-button type="text" class="px-0" @click="openDetail(record.id)"> <a-button type="text" class="px-0" @click="openDetail(record.id)">
@ -682,6 +691,7 @@
innerProject.value = projectList.value[0].id; innerProject.value = projectList.value[0].id;
} }
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} }
} }

View File

@ -18,27 +18,41 @@
<div class="ms-description-item-label" :style="{ width: props.labelWidth || '120px' }"> <div class="ms-description-item-label" :style="{ width: props.labelWidth || '120px' }">
<slot name="item-label">{{ item.label }}</slot> <slot name="item-label">{{ item.label }}</slot>
</div> </div>
<div :class="item.isTag ? 'ms-description-item-value--tagline' : 'ms-description-item-value'"> <div :class="getValueClass(item)">
<slot name="item-value" :item="item"> <slot name="item-value" :item="item">
<template v-if="item.isTag"> <template v-if="item.isTag">
<slot name="tag" :item="item"> <slot name="tag" :item="item">
<a-tooltip <div class="w-[280px] overflow-hidden">
<a-overflow-list>
<MsTag
v-for="tag of Array.isArray(item.value) ? item.value : [item.value]" v-for="tag of Array.isArray(item.value) ? item.value : [item.value]"
:key="`${tag}`" :key="`${tag}`"
:content="(tag as string)"
>
<MsTag
:theme="item.tagTheme || 'outline'" :theme="item.tagTheme || 'outline'"
:type="item.tagType || 'primary'" :type="item.tagType || 'primary'"
:max-width="item.tagMaxWidth" :max-width="item.tagMaxWidth"
color="var(--color-text-n8)" color="var(--color-text-n8)"
:class="`mb-[8px] mr-[8px] font-normal !text-[var(--color-text-1)] ${item.tagClass || ''}`" :class="`mr-[8px] font-normal !text-[var(--color-text-1)] ${item.tagClass || ''}`"
:closable="item.closable" :closable="item.closable"
@close="emit('tagClose', tag, item)" @close="emit('tagClose', tag, item)"
> >
{{ tag }} {{ tag }}
</MsTag> </MsTag>
<template #overflow="{ number }">
<a-tooltip :content="(Array.isArray(item.value) ? item.value : [item.value]).join('')">
<MsTag
:theme="item.tagTheme || 'outline'"
:type="item.tagType || 'primary'"
:max-width="item.tagMaxWidth"
color="var(--color-text-n8)"
:class="`font-normal !text-[var(--color-text-1)] ${item.tagClass || ''}`"
tooltip-disabled
>
+{{ number }}
</MsTag>
</a-tooltip> </a-tooltip>
</template>
</a-overflow-list>
</div>
<span v-if="!item.showTagAdd" v-show="Array.isArray(item.value) && item.value.length === 0">-</span> <span v-if="!item.showTagAdd" v-show="Array.isArray(item.value) && item.value.length === 0">-</span>
<div v-else> <div v-else>
<template v-if="showTagInput"> <template v-if="showTagInput">
@ -81,7 +95,16 @@
</MsButton> </MsButton>
<template v-else> <template v-else>
<slot name="value" :item="item"> <slot name="value" :item="item">
{{ item.value === undefined || item.value === null || item.value?.toString() === '' ? '-' : item.value }} <a-tooltip
:content="`${item.value}`"
:disabled="item.value === undefined || item.value === null || item.value?.toString() === ''"
>
<div>
{{
item.value === undefined || item.value === null || item.value?.toString() === '' ? '-' : item.value
}}
</div>
</a-tooltip>
</slot> </slot>
<template v-if="item.showCopy"> <template v-if="item.showCopy">
<MsButton <MsButton
@ -144,6 +167,7 @@
column?: number; column?: number;
descriptions: Description[]; descriptions: Description[];
labelWidth?: string; labelWidth?: string;
oneLineValue?: boolean;
addTagFunc?: (val: string, item: Description) => Promise<void>; addTagFunc?: (val: string, item: Description) => Promise<void>;
}>(), }>(),
{ {
@ -158,6 +182,16 @@
const { t } = useI18n(); const { t } = useI18n();
const { copy } = useClipboard(); const { copy } = useClipboard();
function getValueClass(item: Description) {
if (item.isTag) {
return 'ms-description-item-value--tagline';
}
if (props.oneLineValue) {
return 'ms-description-item-value ms-description-item-value--one-line';
}
return 'ms-description-item-value';
}
async function copyValue(item: Description) { async function copyValue(item: Description) {
try { try {
await copy(Array.isArray(item.value) ? item.value.join(',') : item.value.toString()); await copy(Array.isArray(item.value) ? item.value.join(',') : item.value.toString());
@ -256,5 +290,8 @@
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
.ms-description-item-value--one-line {
-webkit-line-clamp: 1;
}
} }
</style> </style>

View File

@ -68,7 +68,16 @@
> >
<template #value="{ item }"> <template #value="{ item }">
<slot name="descValue" :item="item"> <slot name="descValue" :item="item">
{{ item.value === undefined || item.value === null || item.value?.toString() === '' ? '-' : item.value }} <a-tooltip
:content="`${item.value}`"
:disabled="item.value === undefined || item.value === null || item.value?.toString() === ''"
>
<div>
{{
item.value === undefined || item.value === null || item.value?.toString() === '' ? '-' : item.value
}}
</div>
</a-tooltip>
</slot> </slot>
</template> </template>
</MsDescription> </MsDescription>
@ -312,7 +321,7 @@
@apply h-full w-full overflow-auto; @apply h-full w-full overflow-auto;
.ms-scroll-bar(); .ms-scroll-bar();
min-width: 650px; min-width: 448px; // 480 - 32
min-height: 500px; min-height: 500px;
} }
.arco-scrollbar-track-direction-vertical { .arco-scrollbar-track-direction-vertical {

View File

@ -6,6 +6,7 @@ import PageOptions from './page-options.vue';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import './style.less';
import type { PageItemType } from './interface'; import type { PageItemType } from './interface';
import { Size } from './types'; import { Size } from './types';
import useSize from './useSize'; import useSize from './useSize';
@ -78,6 +79,14 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
/**
* @zh
* @en Whether it is simple mode
*/
simpleOnlyJumper: {
type: Boolean,
default: false,
},
/** /**
* @zh * @zh
* @en Whether to display the total number of data * @en Whether to display the total number of data
@ -329,13 +338,28 @@ export default defineComponent({
return ( return (
<ul class={`${prefixCls}-list`}> <ul class={`${prefixCls}-list`}>
{getPageItemElement('previous', { simple: true })} {getPageItemElement('previous', { simple: true })}
{pageList.value} {!props.simpleOnlyJumper && pageList.value}
{props.showMore && {props.simpleOnlyJumper ? (
<PageJumper
v-slots={{
'jumper-prepend': slots['jumper-prepend'],
'jumper-append': slots['jumper-append'],
}}
simple
disabled={props.disabled}
current={computedCurrent.value}
pages={pages.value}
size={mergedSize.value}
onChange={handleClick}
/>
) : (
props.showMore &&
!props.simple && !props.simple &&
getPageItemElement('more', { getPageItemElement('more', {
key: 'more', key: 'more',
step: props.bufferSize * 2 + 1, step: props.bufferSize * 2 + 1,
})} })
)}
{getPageItemElement('next', { simple: true })} {getPageItemElement('next', { simple: true })}
</ul> </ul>
); );
@ -380,12 +404,12 @@ export default defineComponent({
return ( return (
<div class={cls.value}> <div class={cls.value}>
{props.showTotal && !props.simple && ( {props.showTotal && !props.simple && !props.simpleOnlyJumper && (
<span class={`${prefixCls}-total`}> <span class={`${prefixCls}-total`}>
{slots.total?.({ total: props.total }) ?? t('msPagination.total', { total: props.total })} {slots.total?.({ total: props.total }) ?? t('msPagination.total', { total: props.total })}
</span> </span>
)} )}
{props.showPageSize && !props.simple && ( {props.showPageSize && !props.simple && !props.simpleOnlyJumper && (
<PageOptions <PageOptions
disabled={props.disabled} disabled={props.disabled}
sizeOptions={props.pageSizeOptions} sizeOptions={props.pageSizeOptions}
@ -396,7 +420,7 @@ export default defineComponent({
/> />
)} )}
{renderPager()} {renderPager()}
{!props.simple && !props.simple && props.showJumper && ( {!props.simple && props.showJumper && !props.simpleOnlyJumper && (
<PageJumper <PageJumper
v-slots={{ v-slots={{
'jumper-prepend': slots['jumper-prepend'], 'jumper-prepend': slots['jumper-prepend'],

View File

@ -0,0 +1,89 @@
/** 分页 **/
.ms-pagination {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 16px;
&-list {
display: flex;
flex-direction: row;
gap: 8px;
}
&-jumper {
display: flex;
align-items: center;
padding: 2px 8px;
border-radius: var(--border-radius-small);
background: var(--color-text-n9);
gap: 8px;
.ms-pagination-jumper-input {
padding: 3px 8px;
width: 57px;
border: 1px solid var(--color-text-input-border);
border-radius: var(--border-radius-small);
color: var(--color-text-1);
background: var(--color-text-10);
box-sizing: border-box;
input {
padding-top: 0 !important;
padding-bottom: 0 !important;
text-align: center;
}
}
&-text-goto,
&-total-page {
color: var(--color-text-2);
}
}
&-total {
color: var(--color-text-2);
}
&-options {
margin-left: 14px;
}
&-item {
display: flex;
justify-content: center;
align-items: center;
padding: 5px 10px;
min-width: 32px;
height: 32px;
box-sizing: border-box;
cursor: pointer;
&-previous {
margin-left: 14px;
}
&-ellipsis {
padding: 5px 0;
}
&-ellipsis:hover {
min-width: 32px;
height: 32px;
}
&:not(:last-child):not(:first-child):not(.arco-pagination-item-ellipsis) {
border: 1px solid var(--color-text-input-border);
border-radius: 3px;
}
&-active {
border-color: rgb(var(--primary-5)) !important;
color: rgb(var(--primary-5)) !important;
background-color: rgb(var(--primary-1)) !important;
}
}
&-simple {
&-jumper {
display: flex;
align-items: center;
}
}
&-size-mini {
font-size: 12px;
line-height: 16px;
.ms-pagination-item {
height: 24px;
}
.ms-pagination-jumper-input {
padding: 0;
}
}
}

View File

@ -90,7 +90,7 @@ export default function useTableProps<T>(
const sortItem = ref<object>({}); const sortItem = ref<object>({});
// 筛选 // 筛选
const filterItem = ref<object>({}); const filterItem = ref<Record<string, any>>({});
// keyword // keyword
const keyword = ref(''); const keyword = ref('');
@ -377,6 +377,7 @@ export default function useTableProps<T>(
filterItem.value = { ...getTableQueryParams().filter, [dataIndex]: filteredValues }; filterItem.value = { ...getTableQueryParams().filter, [dataIndex]: filteredValues };
} }
propsRes.value.filter = cloneDeep(filterItem.value); propsRes.value.filter = cloneDeep(filterItem.value);
propsRes.value.draggable = (filterItem.value[dataIndex] || []).length > 0 ? undefined : props?.draggable;
loadList(); loadList();
}, },
// 分页触发 // 分页触发

View File

@ -14,9 +14,14 @@
@close="emit('close')" @close="emit('close')"
> >
<slot name="icon"></slot> <slot name="icon"></slot>
<a-tooltip :disabled="props.tooltipDisabled">
<div class="one-line-text"> <div class="one-line-text">
<slot></slot> <slot></slot>
</div> </div>
<template #content>
<slot></slot>
</template>
</a-tooltip>
</a-tag> </a-tag>
</template> </template>
@ -39,6 +44,7 @@
maxWidth?: string; maxWidth?: string;
noMargin?: boolean; // tag noMargin?: boolean; // tag
closable?: boolean; // closable?: boolean; //
tooltipDisabled?: boolean; // tooltip
}>(), }>(),
{ {
type: 'default', type: 'default',

View File

@ -103,6 +103,7 @@
:api-detail="activeApiTab" :api-detail="activeApiTab"
:offspring-ids="props.offspringIds" :offspring-ids="props.offspringIds"
:member-options="memberOptions" :member-options="memberOptions"
:height-used="48"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane <a-tab-pane
@ -116,6 +117,7 @@
:offspring-ids="props.offspringIds" :offspring-ids="props.offspringIds"
:definition-detail="activeApiTab" :definition-detail="activeApiTab"
:protocol="activeApiTab.protocol" :protocol="activeApiTab.protocol"
:height-used="48"
is-api is-api
@debug="openApiTabAndDebugMock" @debug="openApiTabAndDebugMock"
/> />

View File

@ -336,6 +336,7 @@
apiDetail?: RequestParam; apiDetail?: RequestParam;
offspringIds: string[]; offspringIds: string[];
memberOptions: { label: string; value: string }[]; memberOptions: { label: string; value: string }[];
heightUsed?: number;
}>(); }>();
const caseExecute = ref(false); const caseExecute = ref(false);
@ -540,7 +541,7 @@
draggable: hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ+UPDATE']) draggable: hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ+UPDATE'])
? { type: 'handle', width: 32 } ? { type: 'handle', width: 32 }
: undefined, : undefined,
heightUsed: 282, heightUsed: (props.heightUsed || 0) + 282,
showSubdirectory: true, showSubdirectory: true,
paginationSize: 'mini', paginationSize: 'mini',
}); });

View File

@ -199,7 +199,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useClipboard } from '@vueuse/core'; import { useClipboard } from '@vueuse/core';
import { FormInstance, Message } from '@arco-design/web-vue'; import { FormInstance, Message } from '@arco-design/web-vue';
import dayjs from 'dayjs';
import MsButton from '@/components/pure/ms-button/index.vue'; import MsButton from '@/components/pure/ms-button/index.vue';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue'; import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
@ -241,6 +240,7 @@
definitionDetail: RequestParam; definitionDetail: RequestParam;
readOnly?: boolean; // readOnly?: boolean; //
protocol: string; // protocol: string; //
heightUsed?: number;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'init', params: any): void; (e: 'init', params: any): void;
@ -332,23 +332,18 @@
width: 200, width: 200,
}, },
]; ];
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable( const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getDefinitionMockPage, {
getDefinitionMockPage,
{
columns: props.readOnly ? columns : [], columns: props.readOnly ? columns : [],
scroll: { x: '100%' }, scroll: { x: '100%' },
tableKey: props.readOnly ? undefined : TableKeyEnum.API_TEST_MANAGEMENT_MOCK, tableKey: props.readOnly ? undefined : TableKeyEnum.API_TEST_MANAGEMENT_MOCK,
showSetting: !props.readOnly, showSetting: !props.readOnly,
selectable: true, selectable: true,
heightUsed: (props.heightUsed || 0) + 282,
showSelectAll: !props.readOnly, showSelectAll: !props.readOnly,
draggable: props.readOnly ? undefined : { type: 'handle', width: 32 }, draggable: props.readOnly ? undefined : { type: 'handle', width: 32 },
showSubdirectory: true, showSubdirectory: true,
}, paginationSize: 'mini',
(item) => ({ });
...item,
updateTime: dayjs(item.updateTime).format('YYYY-MM-DD HH:mm:ss'),
})
);
const batchActions = { const batchActions = {
baseAction: [ baseAction: [
{ {

View File

@ -2,8 +2,8 @@
<MsDrawer <MsDrawer
v-model:visible="visible" v-model:visible="visible"
:width="680" :width="680"
:title="t('apiScenario.quoteCsv')" :title="props.isSingle ? t('apiScenario.replaceCsv') : t('apiScenario.quoteCsv')"
:ok-text="t('common.quote')" :ok-text="props.isSingle ? t('common.replace') : t('common.quote')"
:ok-disabled="propsRes.selectedKeys.size === 0 && !selectedKey" :ok-disabled="propsRes.selectedKeys.size === 0 && !selectedKey"
@confirm="handleConfirm" @confirm="handleConfirm"
@close="handleClose" @close="handleClose"
@ -13,8 +13,8 @@
{{ record.scope === 'SCENARIO' ? t('apiScenario.scenario') : t('apiScenario.step') }} {{ record.scope === 'SCENARIO' ? t('apiScenario.scenario') : t('apiScenario.step') }}
</template> </template>
<template #file="{ record }"> <template #file="{ record }">
<a-tooltip :content="record.file?.name"> <a-tooltip :content="record.file?.fileAlias">
<div>{{ record.file?.name || '-' }}</div> <div>{{ record.file?.fileAlias || '-' }}</div>
</a-tooltip> </a-tooltip>
</template> </template>
</MsBaseTable> </MsBaseTable>

View File

@ -899,6 +899,7 @@
} else if (realStep !== null) { } else if (realStep !== null) {
realStep.csvIds = [...(realStep.csvIds || []), ...keys]; realStep.csvIds = [...(realStep.csvIds || []), ...keys];
} }
scenario.value.unSaved = true;
} }
} }

View File

@ -280,6 +280,7 @@ export default {
'apiScenario.confirmChange': 'Confirm changes', 'apiScenario.confirmChange': 'Confirm changes',
'apiScenario.changeScopeSuccess': 'Change successful', 'apiScenario.changeScopeSuccess': 'Change successful',
'apiScenario.quoteCsv': 'Quote CSV', 'apiScenario.quoteCsv': 'Quote CSV',
'apiScenario.replaceCsv': 'Replace CSV',
'apiScenario.csvQuote': 'CSV quote', 'apiScenario.csvQuote': 'CSV quote',
'apiScenario.csvNameNotNull': 'CSV name cannot be empty', 'apiScenario.csvNameNotNull': 'CSV name cannot be empty',
'apiScenario.csvFileNotNull': 'CSV file cannot be empty', 'apiScenario.csvFileNotNull': 'CSV file cannot be empty',

View File

@ -274,6 +274,7 @@ export default {
'apiScenario.confirmChange': '确认更改', 'apiScenario.confirmChange': '确认更改',
'apiScenario.changeScopeSuccess': '已更改', 'apiScenario.changeScopeSuccess': '已更改',
'apiScenario.quoteCsv': '引用 CSV', 'apiScenario.quoteCsv': '引用 CSV',
'apiScenario.replaceCsv': '替换 CSV',
'apiScenario.csvQuote': 'CSV 引用', 'apiScenario.csvQuote': 'CSV 引用',
'apiScenario.csvNameNotNull': 'CSV 名称不能为空', 'apiScenario.csvNameNotNull': 'CSV 名称不能为空',
'apiScenario.csvFileNotNull': 'CSV 文件不能为空', 'apiScenario.csvFileNotNull': 'CSV 文件不能为空',

View File

@ -28,7 +28,15 @@
</div> </div>
</div> </div>
<div> <div>
<ms-base-table ref="tableRef" v-bind="propsRes" v-on="propsEvent"> <ms-base-table
ref="tableRef"
v-bind="propsRes"
:action-config="{
baseAction: [],
moreAction: [],
}"
v-on="propsEvent"
>
<template #name="{ record }"> <template #name="{ record }">
<span class="one-line-text max-w-[300px]"> {{ record.name }}</span> <span class="one-line-text max-w-[300px]"> {{ record.name }}</span>
<a-popover title="" position="right" style="width: 480px"> <a-popover title="" position="right" style="width: 480px">

View File

@ -78,7 +78,8 @@
v-model:current="pageNation.current" v-model:current="pageNation.current"
:total="pageNation.total" :total="pageNation.total"
size="mini" size="mini"
simple show-jumper
simple-only-jumper
@change="loadCaseList" @change="loadCaseList"
@page-size-change="loadCaseList" @page-size-change="loadCaseList"
/> />

View File

@ -239,9 +239,9 @@
showInTable: true, showInTable: true,
width: 150, width: 150,
showDrag: true, showDrag: true,
filterConfig: { // filterConfig: {
options: triggerModeOptions.value, // options: triggerModeOptions.value,
}, // },
}, },
{ {
title: 'report.operator', title: 'report.operator',

View File

@ -63,6 +63,8 @@
:time-picker-props="{ :time-picker-props="{
defaultValue: ['00:00:00', '00:00:00'], defaultValue: ['00:00:00', '00:00:00'],
}" }"
:disabled-time="disabledTime"
@select="handleTimeSelect"
/> />
</a-form-item> </a-form-item>
<a-form-item field="tags" :label="t('common.tag')" class="w-[436px]"> <a-form-item field="tags" :label="t('common.tag')" class="w-[436px]">
@ -134,6 +136,7 @@
import { ref } from 'vue'; import { ref } from 'vue';
import { FormInstance, Message, TreeNodeData, ValidatedError } from '@arco-design/web-vue'; import { FormInstance, Message, TreeNodeData, ValidatedError } from '@arco-design/web-vue';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import dayjs from 'dayjs';
import MsButton from '@/components/pure/ms-button/index.vue'; import MsButton from '@/components/pure/ms-button/index.vue';
import MsDrawer from '@/components/pure/ms-drawer/index.vue'; import MsDrawer from '@/components/pure/ms-drawer/index.vue';
@ -149,6 +152,8 @@
import type { AddTestPlanParams, AssociateCaseRequest, SwitchListModel } from '@/models/testPlan/testPlan'; import type { AddTestPlanParams, AssociateCaseRequest, SwitchListModel } from '@/models/testPlan/testPlan';
import { testPlanTypeEnum } from '@/enums/testPlanEnum'; import { testPlanTypeEnum } from '@/enums/testPlanEnum';
import { DisabledTimeProps } from '@arco-design/web-vue/es/date-picker/interface';
const props = defineProps<{ const props = defineProps<{
planId?: string; planId?: string;
moduleTree?: ModuleTreeNode[]; moduleTree?: ModuleTreeNode[];
@ -190,6 +195,53 @@
return (nodeData as ModuleTreeNode).name.toLowerCase().indexOf(searchValue.toLowerCase()) > -1; return (nodeData as ModuleTreeNode).name.toLowerCase().indexOf(searchValue.toLowerCase()) > -1;
} }
const tempRange = ref<(Date | string | number | undefined)[]>([]);
function makeLessNumbers(value: number) {
const res = [];
for (let i = 0; i < value; i++) {
res.push(i);
}
return res;
}
function disabledTime(current: Date, type: 'start' | 'end'): DisabledTimeProps {
if (type === 'end') {
const currentDate = dayjs(current);
const startDate = dayjs(tempRange.value[0]);
//
return {
disabledHours: () => {
if (currentDate.isSame(startDate, 'D')) {
return makeLessNumbers(startDate.get('h'));
}
return [];
},
disabledMinutes: () => {
if (currentDate.isSame(startDate, 'D') && currentDate.isSame(startDate, 'h')) {
return makeLessNumbers(startDate.get('m'));
}
return [];
},
disabledSeconds: () => {
if (
currentDate.isSame(startDate, 'D') &&
currentDate.isSame(startDate, 'h') &&
currentDate.isSame(startDate, 'm')
) {
return makeLessNumbers(startDate.get('s'));
}
return [];
},
};
}
return {};
}
function handleTimeSelect(value: (Date | string | number | undefined)[]) {
tempRange.value = value;
}
const switchList: SwitchListModel[] = [ const switchList: SwitchListModel[] = [
{ {
key: 'repeatCase', key: 'repeatCase',

View File

@ -50,7 +50,8 @@
v-model:current="pageNation.current" v-model:current="pageNation.current"
:total="pageNation.total" :total="pageNation.total"
size="mini" size="mini"
simple show-jumper
simple-only-jumper
@change="loadCaseList" @change="loadCaseList"
@page-size-change="loadCaseList" @page-size-change="loadCaseList"
/> />
@ -84,7 +85,7 @@
class="relative mx-[16px] border-b" class="relative mx-[16px] border-b"
/> />
<div :class="[' flex-1', activeTab !== 'detail' ? 'tab-content' : 'overflow-hidden']"> <div :class="[' flex-1', activeTab !== 'detail' ? 'tab-content' : 'overflow-hidden']">
<MsDescription v-if="activeTab === 'baseInfo'" :descriptions="descriptions" :column="2"> <MsDescription v-if="activeTab === 'baseInfo'" :descriptions="descriptions" :column="2" one-line-value>
<template #value="{ item }"> <template #value="{ item }">
<template v-if="item.key === 'reviewStatus'"> <template v-if="item.key === 'reviewStatus'">
<MsIcon <MsIcon
@ -230,7 +231,6 @@
import { getBugList } from '@/api/modules/bug-management'; import { getBugList } from '@/api/modules/bug-management';
import { import {
associateBugToPlan, associateBugToPlan,
associatedBugPage,
getCaseDetail, getCaseDetail,
getPlanDetailFeatureCaseList, getPlanDetailFeatureCaseList,
getTestPlanDetail, getTestPlanDetail,