fix(all): 修复bugs

This commit is contained in:
baiqi 2024-04-17 19:51:35 +08:00 committed by 刘瑞斌
parent 6a6bcc381f
commit e64630f330
36 changed files with 548 additions and 475 deletions

View File

@ -175,7 +175,7 @@ export function addRepositoryFile(data: AddRepositoryFileParams) {
// 更新存储库文件
export function updateRepositoryFile(id: string) {
return MSR.get({ url: UpdateRepositoryFileUrl, params: id });
return MSR.get<string>({ url: UpdateRepositoryFileUrl, params: id });
}
// 获取存储库信息

View File

@ -273,3 +273,13 @@
}
}
}
/** 表格 **/
.ms-table--special-small() {
:deep(.arco-table-cell) {
padding: 8px;
}
:deep(#ms-table-footer-wrapper) {
margin-top: 8px;
}
}

View File

@ -14,12 +14,8 @@
</div>
</template>
<div class="flex h-full w-full">
<div class="h-full w-[180px] bg-white">
<a-menu
class="mr-[16px] w-[180px] min-w-[180px] bg-white p-[4px]"
:default-selected-keys="[defaultModule]"
@menu-item-click="clickModule"
>
<div class="flex h-full w-[180px] flex-col bg-white">
<a-menu class="ms-message-menu" :default-selected-keys="[defaultModule]" @menu-item-click="clickModule">
<a-menu-item :key="'all'">
<div class="flex items-center justify-between">
<span>{{ t('ms.message.all') }}</span>
@ -33,16 +29,18 @@
</div>
</a-menu-item>
</a-menu>
<div class="case flex-1">
<a-divider direction="horizontal" margin="8px" />
<div class="flex items-center px-[20px]" :class="{ clickable: 'hovered' }" @click="openMessageManage">
<MsIcon type="icon-icon_setting_filled" class="folder-icon" />
<div class="mt-auto">
<div
class="flex cursor-pointer items-center border-t border-[var(--color-text-n8)] px-[20px] py-[16px]"
@click="openMessageManage"
>
<MsIcon type="icon-icon_setting_filled" class="text-[var(--color-text-4)]" />
<div class="folder-name mx-[4px]">{{ t('ms.message.setting') }}</div>
</div>
</div>
</div>
<a-divider direction="vertical" margin="8px"></a-divider>
<div class="flex-1 justify-between p-[24px]">
<a-divider direction="vertical" :margin="0"></a-divider>
<div class="flex-1 justify-between overflow-x-hidden p-[16px]">
<a-radio-group v-model="position" type="button" @change="changeShowType">
<a-radio value="all">{{ t('ms.message.list.all') }}</a-radio>
<a-radio value="mentioned_me">{{ t('ms.message.list.me', { var: '@' }) }}</a-radio>
@ -54,7 +52,7 @@
<MsIcon type="icon-icon_logs_outlined" class="mr-1 font-[16px] text-[rgb(var(--primary-5))]" />
{{ t('ms.message.make.as.read') }}
</a-button>
<div class="mt-[26px] flex">
<div class="mt-[16px] flex">
<MsList
v-model:data="messageHistoryList"
mode="remote"
@ -69,112 +67,68 @@
@reach-bottom="handleReachBottom"
>
<template #item="{ item }">
<span class="p-[23px]">
<div v-if="item.type === 'MENTIONED_ME'">
<div class="flex items-center">
<MSAvatar :avatar="item.avatar" />
<div class="ml-[8px] flex">
<a-tooltip v-if="translateTextToPX(item.subject) > 300">
<template #content>
<span>
{{ item.subject }}
</span>
</template>
<div class="one-line-text font-medium text-[var(--color-text-2)]" style="max-width: 300px">{{
item.subject
}}</div>
</a-tooltip>
<div v-else class="font-medium text-[var(--color-text-2)]">{{ item.subject }}</div>
<div class="font-medium text-[rgb(var(--primary-5))]"
>&nbsp;&nbsp;{{ t('ms.message.me', { var: '@' }) }}</div
>
<div v-if="item.type === 'MENTIONED_ME'" class="ms-message-item">
<div class="flex items-center">
<MSAvatar v-if="item.avatar" :avatar="item.avatar" :word="item.userName" />
<div class="ml-[8px] flex">
<div class="text-[var(--color-text-2)]">
{{ item.subject }}
</div>
</div>
<div class="ml-[50px] flex items-center">
<a-tooltip v-if="translateTextToPX(item.userName) > 300">
<template #content>
<span>
{{ item.userName }}
</span>
</template>
<div class="one-line-text font-medium text-[var(--color-text-2)]" style="max-width: 300px">{{
item.userName
}}</div>
</a-tooltip>
<div v-else class="font-medium text-[var(--color-text-2)]">{{ item.userName }}</div>
<div class="font-medium text-[var(--color-text-2)]">{{ item.subject }}</div>
<MsButton @click="handleNameClick(item)">
<a-tooltip :content="item.resourceName" :mouse-enter-delay="300">
<div class="one-line-text max-w-[300px]">
{{ item.resourceName }}
</div>
</a-tooltip>
</MsButton>
</div>
<div class="ml-[50px] flex items-center">
{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}
<div class="font-medium text-[rgb(var(--primary-5))]"
>&nbsp;&nbsp;{{ t('ms.message.me', { var: '@' }) }}</div
>
</div>
</div>
<div v-else>
<div class="flex items-center">
<a-badge v-if="item.status === 'UNREAD'" :count="9" dot :offset="[6, -2]">
<a-tooltip v-if="translateTextToPX(item.subject) > 300">
<template #content>
<span>
{{ item.subject }}
</span>
</template>
<div class="one-line-text max-w-[300px] font-medium text-[var(--color-text-1)]">{{
item.subject
}}</div>
</a-tooltip>
<div v-else class="one-line-text max-w-[300px] font-medium text-[var(--color-text-1)]">{{
item.subject
}}</div>
<div class="flex items-center">
<div class="text-[var(--color-text-2)]">{{ item.content.split(':')[0] }}</div>
<div v-if="item.operation.includes('DELETE')" class="text-[var(--color-text-1)]">
{{ item.resourceName }}
</div>
<MsButton v-else @click="handleNameClick(item)">
<a-tooltip :content="item.resourceName" :mouse-enter-delay="300">
<div class="one-line-text">
{{ item.resourceName }}
</div>
</a-tooltip>
</MsButton>
</div>
<div class="flex items-center text-[var(--color-text-4)]">
{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</div>
</div>
<div v-else class="ms-message-item">
<MSAvatar v-if="item.avatar" :avatar="item.avatar" :word="item.userName" />
<div class="ml-[8px] flex flex-col">
<div class="flex items-center overflow-x-hidden">
<a-badge v-if="item.status === 'UNREAD'" :count="9" dot :offset="[6, -2]" class="w-full">
<div class="font-medium leading-[22px] text-[var(--color-text-1)]">
{{ item.subject }}
</div>
</a-badge>
<a-tooltip v-if="item.status === 'READ' && translateTextToPX(item.subject) > 300">
<template #content>
<span>
{{ item.subject }}
</span>
</template>
<div class="one-line-text max-w-[300px] font-medium text-[var(--color-text-1)]">{{
item.subject
}}</div>
<a-tooltip v-else-if="item.status === 'READ'" :content="item.subject">
<div class="font-medium leading-[22px] text-[var(--color-text-1)]">
{{ item.subject }}
</div>
</a-tooltip>
<div
v-if="item.status === 'READ' && translateTextToPX(item.subject) <= 300"
class="one-line-text max-w-[300px] font-medium text-[var(--color-text-1)]"
>
{{ item.subject }}</div
>
</div>
<div class="flex items-center">
<a-tooltip v-if="translateTextToPX(item.userName) > 300">
<template #content>
<span>
{{ item.userName }}
</span>
</template>
<div class="one-line-text font-medium text-[var(--color-text-2)]" style="max-width: 300px">{{
item.userName
}}</div>
</a-tooltip>
<div v-else class="font-medium text-[var(--color-text-2)]">{{ item.userName }}</div>
<div class="font-medium text-[var(--color-text-2)]">{{ item.subject }}</div>
<MsButton @click="handleNameClick(item)">
<div class="text-[var(--color-text-2)]">{{ item.content.split(':')[0] }}</div>
<div v-if="item.operation.includes('DELETE')" class="text-[var(--color-text-1)]">
{{ item.resourceName }}
</div>
<MsButton v-else @click="handleNameClick(item)">
<a-tooltip :content="item.resourceName" :mouse-enter-delay="300">
<div class="one-line-text max-w-[300px]">
<div class="one-line-text">
{{ item.resourceName }}
</div>
</a-tooltip>
</MsButton>
</div>
<div class="flex items-center">
<div class="flex items-center text-[var(--color-text-4)]">
{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</div>
</div>
</span>
</div>
</template>
</MsList>
</div>
@ -204,31 +158,37 @@
} from '@/api/modules/message';
import { getMessageList } from '@/api/modules/project-management/messageManagement';
import { useI18n } from '@/hooks/useI18n';
import usePathMap from '@/hooks/usePathMap';
import { translateTextToPX } from '@/utils/css';
import useOpenNewPage from '@/hooks/useOpenNewPage';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import { MessageItem } from '@/models/projectManagement/message';
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
import { MessageResourceType } from '@/enums/messageEnum';
import {
ApiTestRouteEnum,
BugManagementRouteEnum,
CaseManagementRouteEnum,
ProjectManagementRouteEnum,
} from '@/enums/routeEnum';
import useAppStore from '../../../store/modules/app';
import useUserStore from '../../../store/modules/user';
const options = ref<OptionItem[]>([]);
const messageHistoryList = ref<MessageHistoryItem[]>([]);
const appStore = useAppStore();
const userStore = useUserStore();
const projectId = ref<string>(appStore.currentProjectId);
const props = defineProps<{
visible: boolean;
}>();
const emit = defineEmits<{
(e: 'update:visible', val: boolean): void;
}>();
const appStore = useAppStore();
const userStore = useUserStore();
const router = useRouter();
const { t } = useI18n();
const { jumpRouteByMapKey, getRouteMapByAlias } = usePathMap();
const { openNewPage } = useOpenNewPage();
const innerVisible = useVModel(props, 'visible', emit);
const projectId = ref<string>(appStore.currentProjectId);
const position = ref('all');
const options = ref<OptionItem[]>([]);
const messageHistoryList = ref<MessageHistoryItem[]>([]);
const noMoreData = ref<boolean>(false);
const moduleList = ref<MessageItem[]>([]);
const defaultModule = ref<string>('all');
@ -330,7 +290,7 @@
}
//
function changeShowType(value: string | number | boolean, ev: Event) {
function changeShowType(value: string | number | boolean) {
messageHistoryList.value = [];
pageNation.value.current = 1;
loadMessageHistoryList(value as string, currentResourceType.value);
@ -381,21 +341,34 @@
return count;
}
const resourceTypeRouteMap = {
[MessageResourceType.BUG_TASK]: BugManagementRouteEnum.BUG_MANAGEMENT_DETAIL,
[MessageResourceType.BUG_SYNC_TASK]: BugManagementRouteEnum.BUG_MANAGEMENT_DETAIL,
[MessageResourceType.FUNCTIONAL_CASE_TASK]: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_DETAIL,
[MessageResourceType.CASE_REVIEW_TASK]: CaseManagementRouteEnum.CASE_MANAGEMENT_REVIEW_DETAIL,
[MessageResourceType.API_DEFINITION_TASK]: ApiTestRouteEnum.API_TEST_MANAGEMENT,
[MessageResourceType.API_SCENARIO_TASK]: ApiTestRouteEnum.API_TEST_SCENARIO,
};
//
function handleNameClick(item: MessageHistoryItem) {
const routeQuery: Record<string, any> = {
orgId: item.organizationId,
pId: item.projectId,
id: item.resourceId,
};
if (item.organizationId === 'SYSTEM') {
delete routeQuery.organizationId;
}
if (item.projectId === 'SYSTEM' || item.projectId === 'ORGANIZATION') {
delete routeQuery.projectId;
}
const routeMap = getRouteMapByAlias(item.resourceType);
jumpRouteByMapKey(routeMap?.key, routeQuery, true);
if (item.resourceType === MessageResourceType.API_DEFINITION_TASK) {
delete routeQuery.id;
if (item.operation.includes('CASE')) {
routeQuery.cId = item.resourceId;
} else if (!item.operation.includes('MOCK')) {
routeQuery.dId = item.resourceId;
}
}
const route = resourceTypeRouteMap[item.resourceType];
openNewPage(route, routeQuery);
}
//
@ -425,6 +398,28 @@
);
</script>
<style lang="less">
.ms-drawer {
.ms-message-menu {
@apply bg-white;
.arco-menu-inner {
padding: 16px;
}
}
.ms-message-item {
@apply flex;
padding: 8px;
&:not(:last-child) {
margin-bottom: 16px;
}
&:hover {
background-color: var(--color-text-n9);
}
}
}
</style>
<style lang="less" scoped>
.right-align {
float: right;
@ -440,15 +435,4 @@
box-sizing: border-box;
line-height: 1.8715;
}
.case {
/* 底部样式 */
position: fixed;
bottom: 0;
padding: 20px;
text-align: center;
}
.clickable {
cursor: pointer;
transition: background-color 0.3s ease;
}
</style>

View File

@ -35,6 +35,12 @@
block-node
default-expand-all
:selectable="false"
:virtual-list-props="{
height: '100%',
threshold: 200,
fixedSize: true,
buffer: 15, // 10 padding
}"
@check="onSelect"
>
<template #title="nodeData">

View File

@ -554,7 +554,6 @@
@apply cursor-default;
}
}
overflow-y: auto;
}
}
</style>

View File

@ -13,7 +13,7 @@
:size="props.size"
class="bg-[rgb(var(--primary-1))] text-[rgb(var(--primary-6))]"
>
<slot>{{ userStore.name?.substring(0, 4) }}</slot>
<slot>{{ props.word?.substring(0, 4) || userStore.name?.substring(0, 4) }}</slot>
</a-avatar>
<a-avatar v-else :image-url="avatar" :size="props.size"></a-avatar>
</template>
@ -29,6 +29,7 @@
defineProps<{
avatar?: 'default' | 'word' | string;
size?: number;
word?: string; //
}>(),
{
avatar: 'default',

View File

@ -210,7 +210,8 @@
</a-table>
<div
v-if="showBatchAction || !!attrs.showPagination"
class="mt-[16px] flex h-[32px] flex-row flex-nowrap items-center"
id="ms-table-footer-wrapper"
class="mt-[16px] flex h-[32px] w-full flex-row flex-nowrap items-center overflow-hidden"
:class="{ 'justify-between': showBatchAction }"
>
<span v-if="props.actionConfig && selectedCount > 0 && !showBatchAction" class="title text-[var(--color-text-2)]">
@ -225,21 +226,20 @@
class="flex-1"
:select-row-count="selectedCount"
:action-config="props.actionConfig"
wrapper-id="ms-table-footer-wrapper"
@batch-action="handleBatchAction"
@clear="emit('clearSelector')"
/>
</div>
<div class="min-w-[500px]">
<ms-pagination
v-if="!!attrs.showPagination"
size="small"
v-bind="(attrs.msPagination as MsPaginationI)"
:simple="!!showBatchAction"
:show-jumper="(attrs.msPagination as MsPaginationI).total / (attrs.msPagination as MsPaginationI).pageSize > 5"
@change="pageChange"
@page-size-change="pageSizeChange"
/>
</div>
<ms-pagination
v-if="!!attrs.showPagination"
:size="props.paginationSize || 'small'"
v-bind="(attrs.msPagination as MsPaginationI)"
:simple="!!showBatchAction"
:show-jumper="(attrs.msPagination as MsPaginationI).total / (attrs.msPagination as MsPaginationI).pageSize > 5"
@change="pageChange"
@page-size-change="pageSizeChange"
/>
</div>
<ColumnSelector
v-if="props.showSetting"
@ -316,6 +316,7 @@
spanAll?: boolean;
showSelectorAll?: boolean;
firstColumnWidth?: number; //
paginationSize?: 'small' | 'mini' | 'medium' | 'large';
}>();
const emit = defineEmits<{
(e: 'batchAction', value: BatchActionParams, queryParams: BatchActionQueryParams): void;

View File

@ -8,7 +8,7 @@
class="ml-[12px]"
:class="{
'arco-btn-outline--danger': element.danger,
'ml-[16px]': idx === 0,
'ml-[8px]': idx === 0,
}"
type="outline"
@click="handleSelect(element)"
@ -24,7 +24,7 @@
class="ml-[12px]"
:class="{
'arco-btn-outline--danger': element.danger,
'ml-[16px]': idx === 0,
'ml-[8px]': idx === 0,
}"
type="outline"
@click="handleSelect"
@ -41,7 +41,7 @@
</a-dropdown>
<!-- baseAction多菜单选择 -->
</template>
<div v-if="moreActionLength > 0" class="drop-down relative ml-[16px] inline-block">
<div v-if="moreActionLength > 0" class="drop-down relative ml-[8px] inline-block">
<a-dropdown position="tr" @select="handleSelect">
<a-button type="outline"><MsIcon type="icon-icon_more_outlined" /></a-button>
<template #content>
@ -58,7 +58,7 @@
</template>
</a-dropdown>
</div>
<a-button class="clear-btn ml-[16px]" type="text" @click="emit('clear')">{{ t('msTable.batch.clear') }}</a-button>
<a-button class="clear-btn ml-[8px]" type="text" @click="emit('clear')">{{ t('msTable.batch.clear') }}</a-button>
</div>
</template>
@ -79,6 +79,7 @@
const props = defineProps<{
selectRowCount?: number;
actionConfig?: BatchActionConfig;
wrapperId: string;
}>();
const emit = defineEmits<{
(e: 'batchAction', value: BatchActionParams): void;
@ -120,7 +121,8 @@
computedStatus.value = true;
return;
}
const wrapperWidth = getNodeWidth(refWrapper.value);
const wrapperWidth = (document.querySelector(`#${props.wrapperId}`)?.clientWidth || 0) - 370; // 370
const childNodeList = [].slice.call(refWrapper.value.children) as HTMLElement[];
@ -140,24 +142,24 @@
// title100px
totalWidth += 100;
} else if (isDropDown) {
// dropDown48px + MarginLeft 16px
totalWidth += 64;
// dropDown48px + MarginLeft 8px
totalWidth += 56;
} else if (isClearBtn) {
// 60px + MarginLeft 16px
totalWidth += 76;
// 60px + MarginLeft 8px
totalWidth += 68;
} else {
// + marginLeft 16px
totalWidth += getNodeWidth(node) + 16;
menuItemIndex++;
// + marginLeft 8px
totalWidth += getNodeWidth(node) + 8;
}
if (totalWidth > wrapperWidth) {
const value = menuItemIndex - 1;
const value = isClearBtn ? menuItemIndex - 1 : menuItemIndex - 2;
baseAction.value = allAction.value.slice(0, value);
moreAction.value = allAction.value.slice(value);
handleMoreActionLength();
computedStatus.value = false;
return;
}
menuItemIndex++;
}
moreAction.value = props.actionConfig?.moreAction || [];
baseAction.value = props.actionConfig?.baseAction || [];

View File

@ -106,6 +106,7 @@ export interface MsTableProps<T> {
showJumpMethod?: boolean; // 是否展示跳转方法
isSimpleSetting?: boolean; // 是否是简单的设置
filterIconAlignLeft?: boolean; // 筛选图标是否靠左
paginationSize?: 'small' | 'mini' | 'medium' | 'large';
[key: string]: any;
}

View File

@ -0,0 +1,18 @@
export enum MessageResourceType {
TEST_PLAN_TASK = 'TEST_PLAN_TASK',
TEST_PLAN_REPORT_TASK = 'TEST_PLAN_REPORT_TASK',
BUG_TASK = 'BUG_TASK',
BUG_SYNC_TASK = 'BUG_SYNC_TASK',
FUNCTIONAL_CASE_TASK = 'FUNCTIONAL_CASE_TASK',
CASE_REVIEW_TASK = 'CASE_REVIEW_TASK',
API_DEFINITION_TASK = 'API_DEFINITION_TASK',
API_SCENARIO_TASK = 'API_SCENARIO_TASK',
API_REPORT_TASK = 'API_REPORT_TASK',
UI_SCENARIO_TASK = 'UI_SCENARIO_TASK',
UI_REPORT_TASK = 'UI_REPORT_TASK',
LOAD_TEST_TASK = 'LOAD_TEST_TASK',
LOAD_REPORT_TASK = 'LOAD_REPORT_TASK',
SCHEDULE_TASK = 'SCHEDULE_TASK',
}
export default {};

View File

@ -23,4 +23,3 @@ export enum ExecutionMethodsLabel {
API = 'project.taskCenter.interfaceCall', // 接口调用
BATCH = 'project.taskCenter.batchExecution', // 批量执行
}
export default {};

View File

@ -49,7 +49,7 @@ const BugManagement: AppRouteRecordRaw = {
],
},
},
// 创建用例成功
// 缺陷创建成功
{
path: 'create-success',
name: BugManagementRouteEnum.BUG_MANAGEMENT_CREATE_SUCCESS,

View File

@ -89,7 +89,10 @@
<div class="flex items-center justify-between">
<div class="flex items-center">
<div class="text-[var(--color-text-1)]">{{ t('apiTestDebug.matchResult') }}</div>
<a-tooltip :content-style="{ maxWidth: '500px' }">
<a-tooltip
v-if="expressionForm.extractType === RequestExtractExpressionEnum.REGEX"
:content-style="{ maxWidth: '500px' }"
>
<icon-question-circle
class="ml-[4px] cursor-pointer text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-5))]"
size="16"

View File

@ -842,7 +842,7 @@
return item;
});
const lastTwoIsSame =
arr.length === 1 ||
(arr.length === 1 && !hasNoIdItem) ||
(arr.length >= 2 && filterKeyValParams([arr[arr.length - 2]], arr[arr.length - 1]).lastDataIsDefault);
if (
hasNoIdItem &&

View File

@ -18,7 +18,7 @@
type="line"
></a-switch>
<div class="ml-[8px] text-[var(--color-text-1)]">{{ t('apiTestDebug.openGlobalPostCondition') }}</div>
<a-tooltip :content="t('apiTestDebug.openGlobalPostConditionTip')" position="left">
<a-tooltip :content="props.tipContent || t('apiTestDebug.openGlobalPostConditionTip')" position="left">
<icon-question-circle
class="ml-[4px] text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-5))]"
size="16"
@ -47,6 +47,7 @@
isScenario?: boolean; //
disabled?: boolean;
sqlCodeEditorHeight?: string;
tipContent?: string;
}>();
const emit = defineEmits<{
(e: 'update:params', params: ExecuteConditionProcessor[]): void;

View File

@ -16,7 +16,7 @@
type="line"
></a-switch>
<div class="ml-[8px] text-[var(--color-text-1)]">{{ t('apiTestDebug.openGlobalPrecondition') }}</div>
<a-tooltip :content="t('apiTestDebug.openGlobalPreconditionTip')" position="left">
<a-tooltip :content="props.tipContent || t('apiTestDebug.openGlobalPreconditionTip')" position="left">
<icon-question-circle
class="ml-[4px] text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-5))]"
size="16"
@ -42,6 +42,7 @@
isScenario?: boolean; //
disabled?: boolean;
sqlCodeEditorHeight?: string;
tipContent?: string;
}>();
const emit = defineEmits<{
(e: 'update:config', params: ExecuteConditionConfig): void;

View File

@ -1,6 +1,6 @@
<template>
<div :class="['p-[0_16px_16px_16px]', props.class]">
<div class="mb-[16px] flex items-center justify-end">
<div :class="['p-[0_16px_8px_16px]', props.class]">
<div class="mb-[8px] flex items-center justify-end">
<div class="flex items-center gap-[8px]">
<a-input-search
v-model:model-value="keyword"
@ -507,7 +507,7 @@
]),
showSelectAll: !props.readOnly,
draggable: hasAnyPermission(['PROJECT_API_DEFINITION:READ+UPDATE']) ? { type: 'handle', width: 32 } : undefined,
heightUsed: 308,
heightUsed: 256,
showSubdirectory: true,
},
(item) => ({
@ -977,4 +977,5 @@
}
}
}
.ms-table--special-small();
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="flex flex-1 flex-col overflow-hidden">
<div v-if="activeApiTab.id === 'all'" class="flex-1 pt-[16px]">
<div v-if="activeApiTab.id === 'all'" class="flex-1 pt-[8px]">
<apiTable
:active-module="props.activeModule"
:offspring-ids="props.offspringIds"

View File

@ -25,7 +25,7 @@
<MsFormTable
v-show="headerShowType === 'table'"
:columns="headerColumns"
:data="previewDetail.headers || []"
:data="previewDetail.headers?.filter((e) => e.key !== '') || []"
:selectable="false"
/>
<MsCodeEditor
@ -64,7 +64,7 @@
<MsFormTable
v-show="queryShowType === 'table'"
:columns="queryRestColumns"
:data="previewDetail.query || []"
:data="previewDetail.query?.filter((e) => e.key !== '') || []"
:selectable="false"
/>
<MsCodeEditor
@ -102,7 +102,7 @@
</div>
<MsFormTable
v-show="restShowType === 'table'"
:columns="queryRestColumns"
:columns="queryRestColumns?.filter((e) => e.key !== '')"
:data="previewDetail.rest || []"
:selectable="false"
/>
@ -204,7 +204,7 @@
<MsFormTable
v-show="pluginShowType === 'table'"
:columns="pluginTableColumns"
:data="pluginTableData"
:data="pluginTableData?.filter((e) => e.key !== '')"
:selectable="false"
/>
<MsCodeEditor
@ -315,7 +315,11 @@
{{ t('apiTestDebug.responseHeader') }}
</div>
</div>
<MsFormTable :columns="responseHeaderColumns" :data="activeResponse?.headers || []" :selectable="false" />
<MsFormTable
:columns="responseHeaderColumns"
:data="activeResponse?.headers?.filter((e) => e.key !== '') || []"
:selectable="false"
/>
</div>
</template>
<a-spin v-else :loading="previewDetail.executeLoading" class="h-[calc(100%-45px)] w-full pb-[18px]">
@ -657,12 +661,14 @@
const bodyTableData = computed(() => {
switch (previewDetail.value.body.bodyType) {
case RequestBodyFormat.FORM_DATA:
return (previewDetail.value.body.formDataBody?.formValues || []).map((e) => ({
...e,
value: e.paramType === RequestParamsType.FILE ? e.files?.map((file) => file.fileName).join('、') : e.value,
}));
return (previewDetail.value.body.formDataBody?.formValues || [])
.map((e) => ({
...e,
value: e.paramType === RequestParamsType.FILE ? e.files?.map((file) => file.fileName).join('、') : e.value,
}))
?.filter((e) => e.key !== '');
case RequestBodyFormat.WWW_FORM:
return previewDetail.value.body.wwwFormBody?.formValues || [];
return previewDetail.value.body.wwwFormBody?.formValues?.filter((e) => e.key !== '') || [];
case RequestBodyFormat.BINARY:
return [
{

View File

@ -1,6 +1,6 @@
<template>
<div class="overflow-hidden p-[16px_22px]">
<div :class="['mb-[16px]', 'flex', 'items-center', props.isApi ? 'justify-between' : 'justify-end']">
<div class="overflow-hidden p-[8px_22px]">
<div :class="['mb-[8px]', 'flex', 'items-center', props.isApi ? 'justify-between' : 'justify-end']">
<a-button
v-show="props.isApi"
v-permission="['PROJECT_API_DEFINITION_CASE:READ+ADD']"
@ -601,7 +601,7 @@
draggable: hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ+UPDATE'])
? { type: 'handle', width: 32 }
: undefined,
heightUsed: props.isApi ? 356 : 308,
heightUsed: 256,
showSubdirectory: true,
});
const batchActions = {
@ -1039,4 +1039,5 @@
}
}
}
.ms-table--special-small();
</style>

View File

@ -29,6 +29,7 @@
</template>
</MsEditableTab>
<environmentSelect
v-show="activeApiTab.id !== 'all'"
ref="environmentSelectRef"
v-model:current-env="activeApiTab.environmentId"
:set-default-env="false"

View File

@ -5,6 +5,7 @@
v-model:config="preProcessorConfig"
:is-definition="false"
sql-code-editor-height="300px"
:tip-content="t('apiScenario.openGlobalPreConditionTip')"
is-scenario
@change="emit('change', true)"
/>
@ -16,6 +17,7 @@
:is-definition="false"
:layout="activeLayout"
sql-code-editor-height="300px"
:tip-content="t('apiScenario.openGlobalPostConditionTip')"
is-scenario
@change="emit('change', false)"
/>
@ -27,12 +29,16 @@
import postcondition from '@/views/api-test/components/requestComposition/postcondition.vue';
import precondition from '@/views/api-test/components/requestComposition/precondition.vue';
import { useI18n } from '@/hooks/useI18n';
import { ExecuteConditionConfig } from '@/models/apiTest/common';
const emit = defineEmits<{
(e: 'change', isChangePre: boolean): void;
}>();
const { t } = useI18n();
const activeLayout = ref<'horizontal' | 'vertical'>('vertical');
const preProcessorConfig = defineModel<ExecuteConditionConfig>('preProcessorConfig', {
required: true,

View File

@ -1,6 +1,6 @@
<template>
<div :class="['p-[16px_16px]', props.class]">
<div class="mb-[16px] flex items-center justify-between">
<div :class="['p-[8px_16px]', props.class]">
<div class="mb-[8px] flex items-center justify-between">
<div class="flex items-center"> </div>
<div class="items-right flex gap-[8px]">
<a-input-search
@ -893,8 +893,9 @@
]),
showSelectAll: !props.readOnly,
draggable: hasAnyPermission(['PROJECT_API_SCENARIO:READ+UPDATE']) ? { type: 'handle', width: 32 } : undefined,
heightUsed: 374,
heightUsed: 256,
showSubdirectory: true,
paginationSize: 'mini',
},
(item) => ({
...item,
@ -1186,12 +1187,14 @@
await resetScheduleConfig(record);
showScheduleModal.value = true;
}
async function deleteScenarioSchedule(scenarioId: string) {
try {
await deleteScheduleConfig(scenarioId);
Message.success(t('common.deleteSuccess'));
loadScenarioList(false);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
@ -1540,4 +1543,5 @@
}
}
}
.ms-table--special-small();
</style>

View File

@ -1,6 +1,6 @@
<template>
<MsCard no-content-padding simple>
<div class="flex items-center justify-between p-[24px_24px_8px_24px]">
<div class="flex items-center justify-between p-[8px_16px_8px_16px]">
<MsEditableTab
v-model:active-tab="activeScenarioTab"
v-model:tabs="scenarioTabs"
@ -68,14 +68,16 @@
</div>
</template>
<template #second>
<ScenarioTable
ref="apiTableRef"
:active-module="activeModule"
:offspring-ids="offspringIds"
@refresh-module-tree="refreshTree"
@open-scenario="openScenarioTab"
@create-scenario="() => newTab()"
/>
<div class="overflow-x-hidden">
<ScenarioTable
ref="apiTableRef"
:active-module="activeModule"
:offspring-ids="offspringIds"
@refresh-module-tree="refreshTree"
@open-scenario="openScenarioTab"
@create-scenario="() => newTab()"
/>
</div>
</template>
</MsSplitBox>
</div>
@ -623,7 +625,7 @@
<style scoped lang="less">
.pageWrap {
height: calc(100% - 65px);
height: calc(100% - 54px);
border-radius: var(--border-radius-large);
@apply bg-white;
.case {

View File

@ -193,6 +193,10 @@ export default {
'apiScenario.deleteStepConfirmWithChildren':
'Are you sure you want to delete the selected step and all substeps within the step?',
'apiScenario.quoteScenarioStepNotAllowDelete': 'Substeps that reference a scenario cannot be deleted',
'apiScenario.openGlobalPostConditionTip':
'It is closed by default. If it is closed, the global post-processing will not be executed when running this interface.',
'apiScenario.openGlobalPreConditionTip':
'It is closed by default. If it is closed, the global prefix will not be executed when running this interface.',
// Execution History
'apiScenario.executeHistory.searchPlaceholder': 'Search by ID or name',
'apiScenario.executeHistory.num': 'No.',

View File

@ -184,6 +184,8 @@ export default {
'apiScenario.deleteStepConfirm': '确认删除 {name} 吗?',
'apiScenario.deleteStepConfirmWithChildren': '确认删除所选步骤以及步骤内所有子步骤?',
'apiScenario.quoteScenarioStepNotAllowDelete': '引用场景的子步骤不能删除',
'apiScenario.openGlobalPostConditionTip': '默认关闭,关闭则运行该接口时不执行全局后置',
'apiScenario.openGlobalPreConditionTip': '默认关闭,关闭则运行该接口时不执行全局前置',
// 执行历史
'apiScenario.executeHistory.searchPlaceholder': '通过ID或名称搜索',
'apiScenario.executeHistory.num': '序号',

View File

@ -1,143 +1,145 @@
<template>
<MsCard simple>
<MsAdvanceFilter
v-model:keyword="keyword"
:search-placeholder="t('caseManagement.featureCase.searchByNameAndId')"
:filter-config-list="filterConfigList"
:row-count="filterRowCount"
@keyword-search="fetchData"
@adv-search="handleAdvSearch"
@refresh="handleAdvSearch"
>
<template #left>
<div class="flex gap-[12px]">
<a-button v-permission="['PROJECT_BUG:READ+ADD']" type="primary" @click="handleCreate"
>{{ t('bugManagement.createBug') }}
<MsCard simple no-content-padding>
<div class="h-full p-[16px]">
<MsAdvanceFilter
v-model:keyword="keyword"
:search-placeholder="t('caseManagement.featureCase.searchByNameAndId')"
:filter-config-list="filterConfigList"
:row-count="filterRowCount"
@keyword-search="fetchData"
@adv-search="handleAdvSearch"
@refresh="handleAdvSearch"
>
<template #left>
<div class="flex gap-[12px]">
<a-button v-permission="['PROJECT_BUG:READ+ADD']" type="primary" @click="handleCreate"
>{{ t('bugManagement.createBug') }}
</a-button>
<a-button v-if="currentPlatform !== 'Local'" :loading="!isComplete" type="outline" @click="handleSync"
>{{ t('bugManagement.syncBug') }}
</a-button>
</div>
</template>
</MsAdvanceFilter>
<MsBaseTable
class="mt-[8px]"
v-bind="propsRes"
:action-config="tableBatchActions"
v-on="propsEvent"
@batch-action="handleTableBatch"
@sorter-change="saveSort"
>
<!-- ID -->
<template #num="{ record, rowIndex }">
<a-button type="text" class="px-0" size="mini" @click="handleShowDetail(record.id, rowIndex)">
{{ record.num }}
</a-button>
<a-button v-if="currentPlatform !== 'Local'" :loading="!isComplete" type="outline" @click="handleSync"
>{{ t('bugManagement.syncBug') }}
</template>
<template #operation="{ record }">
<div class="flex flex-nowrap items-center">
<span v-permission="['PROJECT_BUG:READ+UPDATE']" class="flex flex-row items-center">
<MsButton class="!mr-0" :disabled="currentPlatform !== record.platform" @click="handleEdit(record)">
{{ t('common.edit') }}
</MsButton>
<a-divider class="!mx-2 h-[12px]" direction="vertical" />
</span>
<span v-permission="['PROJECT_BUG:READ+ADD']" class="flex flex-row items-center">
<MsButton class="!mr-0" :disabled="currentPlatform !== record.platform" @click="handleCopy(record)">
{{ t('common.copy') }}
</MsButton>
<a-divider class="!mx-2 h-[12px]" direction="vertical" />
</span>
<MsTableMoreAction
v-permission="['PROJECT_BUG:READ+DELETE']"
:list="moreActionList"
trigger="click"
@select="handleMoreActionSelect($event, record)"
/>
</div>
</template>
<template #relationCaseCount="{ record, rowIndex }">
<a-button type="text" class="px-0" size="mini" @click="showRelateCaseCount(record.id, rowIndex)">
{{ record.relationCaseCount }}
</a-button>
</div>
</template>
</MsAdvanceFilter>
<MsBaseTable
class="mt-[16px]"
v-bind="propsRes"
:action-config="tableBatchActions"
v-on="propsEvent"
@batch-action="handleTableBatch"
@sorter-change="saveSort"
>
<!-- ID -->
<template #num="{ record, rowIndex }">
<a-button type="text" class="px-0" @click="handleShowDetail(record.id, rowIndex)">{{ record.num }}</a-button>
</template>
<template #operation="{ record }">
<div class="flex flex-nowrap items-center">
<span v-permission="['PROJECT_BUG:READ+UPDATE']" class="flex flex-row items-center">
<MsButton class="!mr-0" :disabled="currentPlatform !== record.platform" @click="handleEdit(record)">{{
t('common.edit')
}}</MsButton>
<a-divider class="!mx-2 h-[12px]" direction="vertical" />
</span>
<span v-permission="['PROJECT_BUG:READ+ADD']" class="flex flex-row items-center">
<MsButton class="!mr-0" :disabled="currentPlatform !== record.platform" @click="handleCopy(record)">{{
t('common.copy')
}}</MsButton>
<a-divider class="!mx-2 h-[12px]" direction="vertical" />
</span>
<MsTableMoreAction
v-permission="['PROJECT_BUG:READ+DELETE']"
:list="moreActionList"
trigger="click"
@select="handleMoreActionSelect($event, record)"
/>
</div>
</template>
</template>
<template #relationCaseCount="{ record, rowIndex }">
<a-button type="text" class="px-0" @click="showRelateCaseCount(record.id, rowIndex)">{{
record.relationCaseCount
}}</a-button>
</template>
<template #createUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="createUserFilterVisible"
v-model:status-filters="createUserFilterValue"
:title="(columnConfig.title as string)"
:list="createUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #createUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="createUserFilterVisible"
v-model:status-filters="createUserFilterValue"
:title="(columnConfig.title as string)"
:list="createUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #updateUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="updateUserFilterVisible"
v-model:status-filters="updateUserFilterValue"
:title="(columnConfig.title as string)"
:list="updateUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #updateUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="updateUserFilterVisible"
v-model:status-filters="updateUserFilterValue"
:title="(columnConfig.title as string)"
:list="updateUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #handleUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="handleUserFilterVisible"
v-model:status-filters="handleUserFilterValue"
:title="(columnConfig.title as string)"
:list="handleUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #handleUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="handleUserFilterVisible"
v-model:status-filters="handleUserFilterValue"
:title="(columnConfig.title as string)"
:list="handleUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #statusFilter="{ columnConfig }">
<TableFilter
v-model:visible="statusFilterVisible"
v-model:status-filters="statusFilterValue"
:title="(columnConfig.title as string)"
:list="statusFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #statusFilter="{ columnConfig }">
<TableFilter
v-model:visible="statusFilterVisible"
v-model:status-filters="statusFilterValue"
:title="(columnConfig.title as string)"
:list="statusFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #severityFilter="{ columnConfig }">
<TableFilter
v-model:visible="severityFilterVisible"
v-model:status-filters="severityFilterValue"
:title="(columnConfig.title as string)"
:list="severityFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #empty> </template>
</MsBaseTable>
<template #severityFilter="{ columnConfig }">
<TableFilter
v-model:visible="severityFilterVisible"
v-model:status-filters="severityFilterValue"
:title="(columnConfig.title as string)"
:list="severityFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
</MsBaseTable>
</div>
</MsCard>
<a-modal
v-model:visible="syncVisible"
@ -218,7 +220,7 @@
import { useIntervalFn } from '@vueuse/core';
import { Message, TableData } from '@arco-design/web-vue';
import { MsAdvanceFilter, timeSelectOptions } from '@/components/pure/ms-advance-filter';
import { timeSelectOptions } from '@/components/pure/ms-advance-filter';
import { BackEndEnum, FilterFormItem, FilterResult, FilterType } from '@/components/pure/ms-advance-filter/type';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsCard from '@/components/pure/ms-card/index.vue';
@ -501,7 +503,8 @@
selectable: true,
noDisable: false,
showSetting: true,
heightUsed: 380,
heightUsed: 256,
paginationSize: 'mini',
},
(record: TableData) => ({
...record,
@ -893,4 +896,5 @@
:deep(.arco-divider-vertical) {
margin: 0 8px;
}
.ms-table--special-small();
</style>

View File

@ -1,130 +1,132 @@
<template>
<MsCard simple>
<MsAdvanceFilter
v-model:keyword="keyword"
:search-placeholder="t('bugManagement.recycle.searchPlaceholder')"
:filter-config-list="filterConfigList"
:row-count="filterRowCount"
@keyword-search="fetchData"
@refresh="fetchData('')"
>
<template #left>
<div></div>
</template>
</MsAdvanceFilter>
<MsBaseTable
class="mt-[16px]"
v-bind="propsRes"
:action-config="tableAction"
v-on="propsEvent"
@batch-action="handleTableBatch"
>
<template #operation="{ record }">
<div class="flex flex-row flex-nowrap">
<MsButton class="!mr-0" @click="handleRecover(record)">{{ t('bugManagement.recycle.recover') }}</MsButton>
<a-divider direction="vertical" />
<MsButton class="!mr-0" @click="handleDelete(record)">{{
t('bugManagement.recycle.permanentlyDelete')
}}</MsButton>
</div>
</template>
<MsCard simple no-content-padding>
<div class="h-full p-[16px]">
<MsAdvanceFilter
v-model:keyword="keyword"
:search-placeholder="t('bugManagement.recycle.searchPlaceholder')"
:filter-config-list="filterConfigList"
:row-count="filterRowCount"
@keyword-search="fetchData"
@refresh="fetchData('')"
>
<template #left>
<div></div>
</template>
</MsAdvanceFilter>
<MsBaseTable
class="mt-[16px]"
v-bind="propsRes"
:action-config="tableAction"
v-on="propsEvent"
@batch-action="handleTableBatch"
>
<template #operation="{ record }">
<div class="flex flex-row flex-nowrap">
<MsButton class="!mr-0" @click="handleRecover(record)">{{ t('bugManagement.recycle.recover') }}</MsButton>
<a-divider direction="vertical" />
<MsButton class="!mr-0" @click="handleDelete(record)">{{
t('bugManagement.recycle.permanentlyDelete')
}}</MsButton>
</div>
</template>
<template #deleteTimeColumn="{ record }">
{{ dayjs(record.deleteTime).format('YYYY-MM-DD HH:mm:ss') || '-' }}
</template>
<template #deleteTimeColumn="{ record }">
{{ dayjs(record.deleteTime).format('YYYY-MM-DD HH:mm:ss') || '-' }}
</template>
<template #createUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="createUserFilterVisible"
v-model:status-filters="createUserFilterValue"
:title="(columnConfig.title as string)"
:list="createUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #createUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="createUserFilterVisible"
v-model:status-filters="createUserFilterValue"
:title="(columnConfig.title as string)"
:list="createUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #updateUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="updateUserFilterVisible"
v-model:status-filters="updateUserFilterValue"
:title="(columnConfig.title as string)"
:list="updateUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #updateUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="updateUserFilterVisible"
v-model:status-filters="updateUserFilterValue"
:title="(columnConfig.title as string)"
:list="updateUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #deleteUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="deleteUserFilterVisible"
v-model:status-filters="deleteUserFilterValue"
:title="(columnConfig.title as string)"
:list="deleteUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #deleteUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="deleteUserFilterVisible"
v-model:status-filters="deleteUserFilterValue"
:title="(columnConfig.title as string)"
:list="deleteUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #handleUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="handleUserFilterVisible"
v-model:status-filters="handleUserFilterValue"
:title="(columnConfig.title as string)"
:list="handleUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #handleUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="handleUserFilterVisible"
v-model:status-filters="handleUserFilterValue"
:title="(columnConfig.title as string)"
:list="handleUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #statusFilter="{ columnConfig }">
<TableFilter
v-model:visible="statusFilterVisible"
v-model:status-filters="statusFilterValue"
:title="(columnConfig.title as string)"
:list="statusFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #statusFilter="{ columnConfig }">
<TableFilter
v-model:visible="statusFilterVisible"
v-model:status-filters="statusFilterValue"
:title="(columnConfig.title as string)"
:list="statusFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #severityFilter="{ columnConfig }">
<TableFilter
v-model:visible="severityFilterVisible"
v-model:status-filters="severityFilterValue"
:title="(columnConfig.title as string)"
:list="severityFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #severityFilter="{ columnConfig }">
<TableFilter
v-model:visible="severityFilterVisible"
v-model:status-filters="severityFilterValue"
:title="(columnConfig.title as string)"
:list="severityFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
</template>
</TableFilter>
</template>
<template #empty> </template>
</MsBaseTable>
<template #empty> </template>
</MsBaseTable>
</div>
</MsCard>
</template>
@ -377,6 +379,7 @@
noDisable: true,
showSetting: true,
scroll: { x: '1900px' },
heightUsed: 256,
},
(record: TableData) => ({
...record,
@ -548,3 +551,7 @@
fetchData();
});
</script>
<style lang="less" scoped>
.ms-table--special-small();
</style>

View File

@ -39,7 +39,7 @@
v-bind="propsRes"
ref="tableRef"
filter-icon-align-left
class="mt-4"
class="mt-[8px]"
:action-config="tableBatchActions"
@selected-change="handleTableSelect"
v-on="propsEvent"
@ -67,6 +67,7 @@
v-model:model-value="record.caseLevel"
:placeholder="t('common.pleaseSelect')"
class="param-input w-full"
size="mini"
@change="() => handleStatusChange(record)"
>
<template #label>
@ -97,7 +98,12 @@
trigger="click"
@popup-visible-change="handleFilterHidden"
>
<a-button type="text" class="arco-btn-text--secondary p-[8px_4px]" @click="executeResultFilterVisible = true">
<a-button
type="text"
class="arco-btn-text--secondary p-[8px_4px]"
size="mini"
@click="executeResultFilterVisible = true"
>
<div class="font-medium">
{{ t(columnConfig.title as string) }}
</div>
@ -106,7 +112,7 @@
<template #content>
<div class="arco-table-filters-content">
<div class="ml-[6px] flex items-center justify-start px-[6px] py-[2px]">
<a-checkbox-group v-model:model-value="executeResultFilters" direction="vertical" size="small">
<a-checkbox-group v-model:model-value="executeResultFilters" direction="vertical" size="mini">
<a-checkbox v-for="key of Object.keys(executionResultMap)" :key="key" :value="key">
<MsIcon
:type="executionResultMap[key]?.icon || ''"
@ -202,6 +208,7 @@
v-model:model-value="record.lastExecuteResult"
:placeholder="t('common.pleaseSelect')"
class="param-input w-full"
size="mini"
@change="() => handleStatusChange(record)"
>
<template #label>
@ -228,6 +235,7 @@
height: 200,
},
}"
size="mini"
@change="(value) => handleChangeModule(record, value)"
>
<template #tree-slot-title="node">
@ -899,9 +907,10 @@
tableKey: TableKeyEnum.CASE_MANAGEMENT_TABLE,
selectable: true,
showSetting: true,
heightUsed: 380,
heightUsed: 256,
enableDrag: true,
showSubdirectory: true,
paginationSize: 'mini',
},
(record) => {
return {
@ -1688,4 +1697,5 @@
flex-direction: row;
justify-content: space-between;
}
.ms-table--special-small();
</style>

View File

@ -1,6 +1,6 @@
<template>
<MsCard simple no-content-padding>
<div class="flex items-center border-b border-[var(--color-text-n8)] p-[24px_24px_16px_24px]">
<div class="flex items-center border-b border-[var(--color-text-n8)] p-[8px_24px]">
<a-button v-permission="['FUNCTIONAL_CASE:READ+ADD']" type="primary" @click="caseDetail">
{{ t('caseManagement.featureCase.creatingCase') }}
</a-button>
@ -11,10 +11,10 @@
{{ t('caseManagement.featureCase.importXmind') }}
</a-button> -->
</div>
<div class="pageWrap relative h-[calc(100%-73px)]">
<div class="pageWrap relative h-[calc(100%-49px)]">
<MsSplitBox>
<template #first>
<div class="p-[24px] pb-0">
<div class="p-[8px_24px] pb-0">
<div class="feature-case h-[100%]">
<a-input-search
v-model:model-value="groupKeyword"
@ -92,7 +92,7 @@
</div>
</template>
<template #second>
<div class="p-[24px]">
<div class="p-[8px_24px]">
<CaseTable
ref="caseTableRef"
:active-folder="activeFolder"

View File

@ -1,6 +1,6 @@
<template>
<div class="px-[24px] py-[16px]">
<div class="mb-[16px]">
<div class="px-[24px] py-[8px]">
<div class="mb-[8px]">
<MsAdvanceFilter
v-model:keyword="keyword"
:filter-config-list="filterConfigList"
@ -92,13 +92,13 @@
</template>
<template #num="{ record }">
<a-tooltip :content="`${record.num}`">
<a-button type="text" class="px-0" @click="openDetail(record.id)">
<a-button type="text" class="px-0" size="mini" @click="openDetail(record.id)">
<div class="one-line-text max-w-[168px]">{{ record.num }}</div>
</a-button>
</a-tooltip>
</template>
<template #status="{ record }">
<statusTag :status="record.status" />
<statusTag :status="record.status" size="small" />
</template>
<template #reviewPassRule="{ record }">
{{
@ -496,8 +496,9 @@
showSetting: true,
selectable: true,
showSelectAll: true,
heightUsed: 344,
heightUsed: 256,
showSubdirectory: true,
paginationSize: 'mini',
},
(item) => {
return {
@ -764,4 +765,6 @@
}
</script>
<style lang="less" scoped></style>
<style lang="less" scoped>
.ms-table--special-small();
</style>

View File

@ -1,5 +1,5 @@
<template>
<a-tag :color="statusMap[props.status]?.color" :class="statusMap[props.status]?.class">
<a-tag :color="statusMap[props.status]?.color" :class="statusMap[props.status]?.class" :size="props.size">
{{ t(statusMap[props.status]?.label) }}
</a-tag>
</template>
@ -11,6 +11,7 @@
const props = defineProps<{
status: ReviewStatus;
size?: 'small' | 'medium' | 'large';
}>();
const { t } = useI18n();

View File

@ -1,6 +1,6 @@
<template>
<MsCard simple no-content-padding>
<div class="flex items-center justify-between border-b border-[var(--color-text-n8)] p-[24px_24px_16px_24px]">
<div class="flex items-center justify-between border-b border-[var(--color-text-n8)] p-[8px_24px]">
<a-button v-permission="['CASE_REVIEW:READ+ADD']" type="primary" @click="goCreateReview">
{{ t('caseManagement.caseReview.create') }}
</a-button>
@ -10,7 +10,7 @@
<a-radio value="createByMe">{{ t('caseManagement.caseReview.myCreate') }}</a-radio>
</a-radio-group>
</div>
<div class="relative h-[calc(100%-73px)]">
<div class="relative h-[calc(100%-49px)]">
<MsSplitBox>
<template #first>
<div class="px-[24px] py-[16px]">

View File

@ -114,13 +114,11 @@
</template>
<script lang="ts" setup>
import { computed, defineModel, ref } from 'vue';
import { Message } from '@arco-design/web-vue';
import { driverOptionFun, validateDatabaseEnv } from '@/api/modules/project-management/envManagement';
import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store';
import useLicenseStore from '@/store/modules/setting/license';
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
import { getGenerateId } from '@/utils';
@ -141,7 +139,6 @@
const loading = ref(false);
const driverOption = ref<{ label: string; value: string }[]>([]);
const appStore = useAppStore();
const licenseStore = useLicenseStore();
const emit = defineEmits<{
(e: 'cancel', shouldSearch: boolean): void;
@ -282,7 +279,7 @@
form.value = {
...currentItem,
id: '',
dataSource: `copy_${currentItem.dataSource}`,
dataSource: `copy_${currentItem.dataSource}`.substring(0, 255),
};
} else {
form.value = {

View File

@ -371,9 +371,10 @@
async function upgradeRepositoryFile() {
try {
fileLoading.value = true;
await updateRepositoryFile(innerFileId.value);
const res = await updateRepositoryFile(innerFileId.value);
Message.success(t('common.updateSuccess'));
detailDrawerRef.value?.initDetail();
innerFileId.value = res;
detailDrawerRef.value?.initDetail(res);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);

View File

@ -1,10 +1,7 @@
import type { MsTableColumn } from '@/components/pure/ms-table/type';
import { useAppStore } from '@/store';
import { TaskCenterEnum } from '@/enums/taskCenter';
const appStore = useAppStore();
export const TaskStatus = {
[TaskCenterEnum.API_CASE]: {
SUCCESS: {