fix: 缺陷管理bug修复&用例紧急bug修复
This commit is contained in:
parent
1faaa395e8
commit
5ceec82c42
|
@ -239,3 +239,8 @@ export function cancelAssociation(id: string) {
|
|||
export function getChangeHistoryList(data: TableQueryParams) {
|
||||
return MSR.post({ url: bugURL.getChangeHistoryListUrl, data });
|
||||
}
|
||||
|
||||
// 校验跳转用例权限
|
||||
export function checkCasePermission(projectId: string, caseType: string) {
|
||||
return MSR.get({ url: `${bugURL.checkCasePermissionUrl}/${projectId}/${caseType}` });
|
||||
}
|
||||
|
|
|
@ -73,3 +73,6 @@ export const getUnrelatedModuleTreeCountUrl = '/bug/case/un-relate/module/count'
|
|||
|
||||
// 缺陷管理-变更历史-列表
|
||||
export const getChangeHistoryListUrl = '/bug/history/page';
|
||||
|
||||
// 缺陷用例跳转用例是否具备权限
|
||||
export const checkCasePermissionUrl = '/bug/case/check-permission';
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
'commentWrapper': props.isUseBottom,
|
||||
}"
|
||||
>
|
||||
<div v-if="props.isShowAvatar" class="mr-3 inline-block"> <MsAvatar avatar="word"></MsAvatar></div>
|
||||
<div v-if="props.isShowAvatar" class="mr-3 inline-block"> <MsAvatar :avatar="userStore.avatar"></MsAvatar></div>
|
||||
<div class="w-full items-center">
|
||||
<a-input
|
||||
v-if="!isActive"
|
||||
|
@ -37,6 +37,7 @@
|
|||
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useUserStore } from '@/store';
|
||||
|
||||
defineOptions({ name: 'MsCommentInput' });
|
||||
|
||||
|
@ -48,9 +49,8 @@
|
|||
}>();
|
||||
|
||||
const currentContent = defineModel<string>('defaultValue', { default: '' });
|
||||
|
||||
const commentIds = defineModel<string[]>('noticeUserIds', { default: [] });
|
||||
|
||||
const userStore = useUserStore();
|
||||
const emit = defineEmits<{
|
||||
(event: 'publish', value: string): void;
|
||||
(event: 'cancel'): void;
|
||||
|
|
|
@ -279,6 +279,7 @@
|
|||
} from './type';
|
||||
import type { TableChangeExtra, TableColumnData, TableData } from '@arco-design/web-vue';
|
||||
import type { TableOperationColumn } from '@arco-design/web-vue/es/table/interface';
|
||||
import { log } from 'console';
|
||||
|
||||
const batchLeft = ref('10px');
|
||||
const { t } = useI18n();
|
||||
|
@ -398,6 +399,23 @@
|
|||
tmpArr = props.columns;
|
||||
}
|
||||
currentColumns.value = arr || tmpArr;
|
||||
// 如果是完全没有列展示除了固定列需要对操作列宽度进行限制和浮动位置限制
|
||||
if (props.showSetting) {
|
||||
const isNoDragColumns = currentColumns.value.filter((item) => item.showDrag).length;
|
||||
if (!isNoDragColumns) {
|
||||
currentColumns.value = tmpArr.map((item: any) => {
|
||||
if (item.slotName === SpecialColumnEnum.OPERATION || item.slotName === SpecialColumnEnum.ACTION) {
|
||||
return {
|
||||
...item,
|
||||
fixed: '',
|
||||
};
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('InitColumn failed', error);
|
||||
|
|
|
@ -19,33 +19,36 @@
|
|||
<template #titleRight="{ loading }">
|
||||
<div class="rightButtons flex items-center">
|
||||
<MsButton
|
||||
v-permission="['PROJECT_BUG:READ+UPDATE']"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
:disabled="loading"
|
||||
:loading="editLoading"
|
||||
:disabled="loading"
|
||||
@click="updateHandler"
|
||||
>
|
||||
<MsIcon type="icon-icon_edit_outlined" class="mr-1 font-[16px]" />
|
||||
{{ t('common.edit') }}
|
||||
</MsButton>
|
||||
<MsButton
|
||||
v-permission="['PROJECT_BUG:READ+UPDATE']"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
:disabled="loading"
|
||||
:loading="shareLoading"
|
||||
:disabled="loading"
|
||||
@click="shareHandler"
|
||||
>
|
||||
<MsIcon type="icon-icon_share1" class="mr-1 font-[16px]" />
|
||||
{{ t('caseManagement.featureCase.share') }}
|
||||
</MsButton>
|
||||
<MsButton
|
||||
v-permission="['PROJECT_BUG:READ+UPDATE']"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
:disabled="loading"
|
||||
:loading="followLoading"
|
||||
:disabled="loading"
|
||||
@click="followHandler"
|
||||
>
|
||||
<MsIcon
|
||||
|
@ -154,7 +157,10 @@
|
|||
content-class="tags-class"
|
||||
>
|
||||
<a-form-item field="tags" :label="t('system.orgTemplate.tags')">
|
||||
<MsTagsInput v-model:model-value="tags" />
|
||||
<MsTagsInput
|
||||
v-model:model-value="tags"
|
||||
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
|
@ -213,6 +219,7 @@
|
|||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore } from '@/store';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { BugEditCustomField, BugEditFormObject, BugTemplateRequest } from '@/models/bug-management';
|
||||
import { SelectValue } from '@/models/projectManagement/menuManagement';
|
||||
|
@ -274,6 +281,7 @@
|
|||
props: {
|
||||
modelValue: valueObj[item.fieldId],
|
||||
options: item.platformOptionJson ? JSON.parse(item.platformOptionJson) : item.options,
|
||||
disabled: !hasAnyPermission(['PROJECT_BUG:READ+UPDATE']),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
|
@ -95,12 +95,14 @@
|
|||
import {
|
||||
batchAssociation,
|
||||
cancelAssociation,
|
||||
checkCasePermission,
|
||||
getAssociatedList,
|
||||
getModuleTree,
|
||||
getUnAssociatedList,
|
||||
} from '@/api/modules/bug-management';
|
||||
import { postTabletList } from '@/api/modules/project-management/menuManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { NO_RESOURCE_ROUTE_NAME } from '@/router/constants';
|
||||
import { useAppStore } from '@/store';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
|
||||
|
@ -276,12 +278,21 @@
|
|||
await loadList();
|
||||
}
|
||||
|
||||
function openDetail(id: string) {
|
||||
window.open(
|
||||
`${window.location.origin}#${
|
||||
router.resolve({ name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE }).fullPath
|
||||
}?id=${id}`
|
||||
);
|
||||
async function openDetail(id: string) {
|
||||
try {
|
||||
const res = await checkCasePermission(currentProjectId.value, 'FUNCTIONAL');
|
||||
if (res) {
|
||||
window.open(
|
||||
`${window.location.origin}#${
|
||||
router.resolve({ name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE }).fullPath
|
||||
}?id=${id}`
|
||||
);
|
||||
} else {
|
||||
window.open(`${window.location.origin}#${router.resolve({ name: NO_RESOURCE_ROUTE_NAME }).fullPath}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
v-model:raw="form.description"
|
||||
v-model:filed-ids="fileIds"
|
||||
:disabled="!contentEditAble"
|
||||
:placeholder="t('bugManagement.edit.contentPlaceholder')"
|
||||
:placeholder="t('editor.placeholder')"
|
||||
:upload-image="handleUploadImage"
|
||||
/>
|
||||
<div v-else v-dompurify-html="form?.description || '-'" class="markdown-body"></div>
|
||||
|
@ -41,7 +41,7 @@
|
|||
v-if="contentEditAble"
|
||||
v-model:raw="item.defaultValue"
|
||||
:disabled="!contentEditAble"
|
||||
:placeholder="t('bugManagement.edit.contentPlaceholder')"
|
||||
:placeholder="t('editor.placeholder')"
|
||||
/>
|
||||
<div v-else v-dompurify-html="item?.defaultValue || '-'" class="markdown-body"></div>
|
||||
</div>
|
||||
|
|
|
@ -48,12 +48,11 @@
|
|||
];
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getChangeHistoryList, {
|
||||
heightUsed: 240,
|
||||
heightUsed: 380,
|
||||
columns,
|
||||
scroll: { x: '100%' },
|
||||
selectable: false,
|
||||
noDisable: false,
|
||||
pageSimple: true,
|
||||
debug: true,
|
||||
});
|
||||
|
||||
|
|
|
@ -393,6 +393,7 @@
|
|||
}
|
||||
const res = await getTemplateById(param);
|
||||
await getFormRules(res.customFields);
|
||||
isLoading.value = false;
|
||||
isPlatformDefaultTemplate.value = res.platformDefault;
|
||||
if (isPlatformDefaultTemplate.value) {
|
||||
const systemFields = res.customFields.filter((field) => field.platformSystemField);
|
||||
|
@ -402,16 +403,18 @@
|
|||
});
|
||||
}
|
||||
getFormRules(res.customFields.filter((field) => !field.platformSystemField));
|
||||
isLoading.value = false;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getTemplateOptions = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await getTemplateOption(appStore.currentProjectId);
|
||||
templateOption.value = res.map((item) => {
|
||||
if (item.enableDefault && !isEdit.value) {
|
||||
|
@ -427,6 +430,8 @@
|
|||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -211,7 +211,6 @@
|
|||
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';
|
||||
import MsExportDrawer from '@/components/pure/ms-export-drawer/index.vue';
|
||||
import { MsExportDrawerMap, MsExportDrawerOption } from '@/components/pure/ms-export-drawer/types';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
|
@ -220,7 +219,6 @@
|
|||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import BatchEditModal from './components/batchEditModal.vue';
|
||||
import BugDetailDrawer from './components/bug-detail-drawer.vue';
|
||||
import DeleteModal from './components/deleteModal.vue';
|
||||
import TableFilter from '@/views/case-management/caseManagementFeature/components/tableFilter.vue';
|
||||
|
||||
import {
|
||||
|
@ -246,12 +244,17 @@
|
|||
downloadByteFile,
|
||||
tableParamsToRequestParams,
|
||||
} from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { BugEditCustomField, BugListItem, BugOptionItem } from '@/models/bug-management';
|
||||
import { RouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { log } from 'console';
|
||||
|
||||
const { t } = useI18n();
|
||||
const MsExportDrawer = defineAsyncComponent(() => import('@/components/pure/ms-export-drawer/index.vue'));
|
||||
const DeleteModal = defineAsyncComponent(() => import('./components/deleteModal.vue'));
|
||||
|
||||
const tableStore = useTableStore();
|
||||
const appStore = useAppStore();
|
||||
|
@ -355,7 +358,7 @@
|
|||
title: 'bugManagement.ID',
|
||||
dataIndex: 'num',
|
||||
slotName: 'num',
|
||||
width: 80,
|
||||
width: 200,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
|
@ -366,7 +369,7 @@
|
|||
{
|
||||
title: 'bugManagement.bugName',
|
||||
dataIndex: 'title',
|
||||
width: 200,
|
||||
width: 300,
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
|
@ -484,6 +487,7 @@
|
|||
showJumpMethod: true,
|
||||
noDisable: false,
|
||||
showSetting: true,
|
||||
heightUsed: 380,
|
||||
},
|
||||
(record: TableData) => ({
|
||||
...record,
|
||||
|
@ -576,8 +580,15 @@
|
|||
};
|
||||
|
||||
const checkSyncStatus = async () => {
|
||||
const { complete } = await getSyncStatus(appStore.currentProjectId);
|
||||
isComplete.value = complete;
|
||||
if (!hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const { complete } = await getSyncStatus(appStore.currentProjectId);
|
||||
isComplete.value = complete;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
/** 同步缺陷 */
|
||||
const { pause, resume } = useIntervalFn(() => {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<template #titleRight="{ loading }">
|
||||
<div class="rightButtons flex items-center">
|
||||
<MsButton
|
||||
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
|
@ -35,6 +36,7 @@
|
|||
{{ t('common.edit') }}
|
||||
</MsButton>
|
||||
<MsButton
|
||||
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
|
@ -46,6 +48,7 @@
|
|||
{{ t('caseManagement.featureCase.share') }}
|
||||
</MsButton>
|
||||
<MsButton
|
||||
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||
|
|
|
@ -398,7 +398,7 @@
|
|||
value: userStore.id || '',
|
||||
},
|
||||
];
|
||||
if (item.defaultValue === 'CREATE_USER') {
|
||||
if (item.defaultValue === 'CREATE_USER' || item.defaultValue.includes('CREATE_USER')) {
|
||||
initValue = item.type === 'MEMBER' ? userStore.id : [userStore.id];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
t('caseManagement.featureCase.createDefect')
|
||||
}}</span>
|
||||
</template>
|
||||
<a-button v-permission="['FUNCTIONAL_CASE:READ+UPDATE']" class="mr-3" type="primary" @click="linkDefect">
|
||||
<a-button
|
||||
v-permission="hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE'])"
|
||||
class="mr-3"
|
||||
type="primary"
|
||||
@click="linkDefect"
|
||||
>
|
||||
{{ t('caseManagement.featureCase.linkDefect') }}
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
@ -134,12 +139,12 @@
|
|||
</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()"
|
||||
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 }}
|
||||
|
@ -148,12 +153,12 @@
|
|||
</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()"
|
||||
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 }}
|
||||
|
@ -163,12 +168,12 @@
|
|||
|
||||
<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()"
|
||||
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 }}
|
||||
|
@ -221,6 +226,7 @@
|
|||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { BugOptionItem } from '@/models/bug-management';
|
||||
import type { TableQueryParams } from '@/models/common';
|
||||
|
|
|
@ -199,7 +199,7 @@ export function initFormCreate(customFields: CustomAttributes[], permission: str
|
|||
value: userStore.id || '',
|
||||
},
|
||||
];
|
||||
currentDefaultValue = item.defaultValue;
|
||||
currentDefaultValue = tempValue;
|
||||
} else {
|
||||
currentDefaultValue = JSON.parse(item.defaultValue);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue