fix(全局): 补充操作列权限和用例评审权限&修改全局bug

This commit is contained in:
xinxin.wu 2024-02-05 15:13:23 +08:00 committed by 刘瑞斌
parent fbef87ad59
commit 87c2ee444b
37 changed files with 246 additions and 160 deletions

View File

@ -18,9 +18,9 @@
class="mr-[2px] text-xl text-[rgb(var(--danger-6))]"
/>
</slot>
<span :class="[titleClass]">
<div :class="[titleClass]">
{{ props.title || '' }}
</span>
</div>
</div>
<!-- 描述展示 -->
<div v-if="props.subTitleTip" class="ml-8 mt-2 text-sm text-[var(--color-text-2)]">
@ -59,7 +59,7 @@
/>
</a-form-item>
</a-form>
<div class="mt-4 flex flex-row flex-nowrap justify-end gap-2">
<div class="mb-1 mt-4 flex flex-row flex-nowrap justify-end gap-2">
<a-button type="secondary" size="mini" :disabled="props.loading" @click="handleCancel">
{{ props.cancelText || t('common.cancel') }}
</a-button>
@ -171,7 +171,7 @@
const titleClass = computed(() => {
return props.isDelete
? 'ml-2 font-medium text-[var(--color-text-1)] text-[14px]'
: 'mb-[8px] font-medium text-[var(--color-text-1)] text-[14px]';
: 'mb-[8px] font-medium text-[var(--color-text-1)] text-[14px] leading-[22px]';
});
watch(
@ -215,4 +215,8 @@
});
</script>
<style scoped lang="less"></style>
<style scoped lang="less">
:deep(.arco-trigger-content) {
padding: 16px;
}
</style>

View File

@ -53,8 +53,9 @@
</div>
<div class="flex-col">
<div v-for="item in nonSortColumn" :key="item.dataIndex" class="column-item">
<div>{{ t((item.title || item.columnTitle) as string) }}</div>
<div v-show="item.dataIndex !== 'operation'">{{ t((item.title || item.columnTitle) as string) }}</div>
<a-switch
v-show="item.dataIndex !== 'operation'"
v-model="item.showInTable"
size="small"
:disabled="item.dataIndex === 'name' || item.dataIndex === 'operation'"

View File

@ -95,12 +95,19 @@ export const pathMap: PathMapItem[] = [
level: MENU_LEVEL[2],
children: [
{
key: 'CASE_MANAGEMENT_CASE_DETAIL', // 功能测试-功能用例详情
key: 'CASE_MANAGEMENT_CASE_CREATE', // 功能测试-功能用例创建
locale: 'menu.caseManagement.featureCaseDetail',
route: RouteEnum.CASE_MANAGEMENT_CASE_DETAIL,
permission: [],
level: MENU_LEVEL[2],
},
{
key: 'CASE_MANAGEMENT_CASE_UPDATE', // 功能测试-功能用例更新
locale: 'menu.caseManagement.featureCaseEdit',
route: RouteEnum.CASE_MANAGEMENT_CASE_DETAIL,
permission: [],
level: MENU_LEVEL[2],
},
{
key: 'CASE_MANAGEMENT_CASE_CREATE_SUCCESS', // 功能测试-功能用例创建成功页面
locale: 'menu.caseManagement.featureCaseCreateSuccess',

View File

@ -68,7 +68,7 @@ export default {
'menu.settings.organization.userGroup': '用户组',
'menu.settings.organization.project': '项目',
'menu.settings.organization.serviceIntegration': '服务集成',
'menu.settings.organization.template': '模板',
'menu.settings.organization.template': '模板管理',
'menu.settings.organization.bugTemplate': '缺陷模板',
'menu.settings.organization.templateFieldSetting': '字段设置',
'menu.settings.organization.templateManagementList': '模板列表',

View File

@ -5,6 +5,7 @@
v-model:keyword="keyword"
:filter-config-list="filterConfigList"
:custom-fields-config-list="searchCustomFields"
:search-placeholder="t('caseManagement.featureCase.searchPlaceholder')"
:row-count="filterRowCount"
@keyword-search="fetchData"
@adv-search="handleAdvSearch"
@ -348,6 +349,10 @@
};
});
const hasOperationPermission = computed(() =>
hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE', 'FUNCTIONAL_CASE:READ+DELETE'])
);
const columns: MsTableColumn = [
{
'title': 'caseManagement.featureCase.tableColumnID',
@ -471,13 +476,13 @@
showDrag: true,
},
{
title: 'caseManagement.featureCase.tableColumnActions',
title: hasOperationPermission.value ? 'caseManagement.featureCase.tableColumnActions' : '',
slotName: 'operation',
dataIndex: 'operation',
fixed: 'right',
width: 260,
showInTable: true,
showDrag: false,
width: hasOperationPermission.value ? 260 : 50,
},
];

View File

@ -48,7 +48,10 @@
visible: boolean;
}>();
const emit = defineEmits(['update:visible']);
const emit = defineEmits<{
(e: 'update:visible', visible: boolean): void;
(e: 'success'): void;
}>();
const { t } = useI18n();
@ -93,6 +96,7 @@
request: { ...form.value, customFields: templateCustomFields.value },
fileList: [],
});
emit('success');
Message.success(t('caseManagement.featureCase.quicklyCreateDefectSuccess'));
if (!isContinue) {
handleDrawerCancel();

View File

@ -17,14 +17,14 @@
</div>
<div v-else class="font-medium">{{ t('caseManagement.featureCase.testPlanLinkList') }}</div>
<div class="mb-4">
<a-radio-group v-model:model-value="showType" type="button" class="file-show-type ml-[4px]">
<!-- <a-radio-group v-model:model-value="showType" type="button" class="file-show-type ml-[4px]">
<a-radio value="link" class="show-type-icon p-[2px]">{{
t('caseManagement.featureCase.directLink')
}}</a-radio>
<!-- <a-radio value="testPlan" class="show-type-icon p-[2px]">{{
<a-radio value="testPlan" class="show-type-icon p-[2px]">{{
t('caseManagement.featureCase.testPlan')
}}</a-radio> -->
</a-radio-group>
}}</a-radio>
</a-radio-group> -->
<a-input-search
v-model:model-value="keyword"
:placeholder="t('caseManagement.featureCase.searchByNameAndId')"
@ -85,7 +85,7 @@
</div>
</template>
</ms-base-table>
<AddDefectDrawer v-model:visible="showDrawer" />
<AddDefectDrawer v-model:visible="showDrawer" @success="getFetch()" />
<LinkDefectDrawer
v-model:visible="showLinkDrawer"
:case-id="props.caseId"
@ -106,7 +106,6 @@
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import type { MsTableColumn } from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable';
import MsRemoveButton from '@/components/business/ms-remove-button/MsRemoveButton.vue';
import AddDefectDrawer from './addDefectDrawer.vue';
import LinkDefectDrawer from './linkDefectDrawer.vue';
@ -117,10 +116,13 @@
} from '@/api/modules/case-management/featureCase';
import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store';
import useFeatureCaseStore from '@/store/modules/case/featureCase';
import { characterLimit } from '@/utils';
import type { TableQueryParams } from '@/models/common';
const featureCaseStore = useFeatureCaseStore();
const appStore = useAppStore();
const { t } = useI18n();
@ -256,13 +258,17 @@
enableDrag: true,
});
function getFetch() {
async function getFetch() {
if (showType.value === 'link') {
setLinkListParams({ keyword: keyword.value, projectId: appStore.currentProjectId, caseId: props.caseId });
loadLinkList();
await loadLinkList();
const { msPagination } = linkPropsRes.value;
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
} else {
setTestPlanListParams({ keyword: keyword.value, projectId: appStore.currentProjectId, caseId: props.caseId });
testPlanLinkList();
await testPlanLinkList();
const { msPagination } = testPlanPropsRes.value;
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
}
}
const cancelLoading = ref<boolean>(false);
@ -272,6 +278,7 @@
try {
if (showType.value === 'link') {
await cancelAssociatedDebug(id);
getFetch();
Message.success(t('caseManagement.featureCase.cancelLinkSuccess'));
}
} catch (error) {

View File

@ -5,7 +5,7 @@
<a-radio-group v-model="activeComment" type="button">
<a-radio value="caseComment">{{ t('caseManagement.featureCase.caseComment') }}</a-radio>
<a-radio value="reviewComment">{{ t('caseManagement.featureCase.reviewComment') }}</a-radio>
<a-radio value="executiveComment">{{ t('caseManagement.featureCase.executiveReview') }}</a-radio>
<!-- <a-radio value="executiveComment">{{ t('caseManagement.featureCase.executiveReview') }}</a-radio> -->
</a-radio-group>
</div>
</div>
@ -25,7 +25,7 @@
@update-or-add="handleUpdateOrAdd"
/>
<!-- 执行评论 -->
<MsComment v-else :comment-list="commentList" @delete="handleDelete" @update-or-add="handleUpdateOrAdd" />
<!-- <MsComment v-else :comment-list="commentList" @delete="handleDelete" @update-or-add="handleUpdateOrAdd" /> -->
</div>
</template>
@ -89,15 +89,13 @@
setCount(commentList.value);
break;
case 'reviewComment':
initReviewCommentList();
await initCommentList();
await initReviewCommentList();
setCount(reviewCommentList.value);
break;
case 'executiveComment':
await initCommentList();
setCount(commentList.value);
break;
default:
break;
}
@ -146,8 +144,10 @@
watch(
() => activeComment.value,
() => {
getAllCommentList();
(val) => {
if (val) {
getAllCommentList();
}
}
);

View File

@ -252,4 +252,5 @@ export default {
'caseManagement.featureCase.defectSource': 'defect Source',
'caseManagement.featureCase.sortSuccess': 'Sort successfully',
'caseManagement.featureCase.zentao': 'zentao',
'caseManagement.featureCase.searchPlaceholder': 'Search by id or name',
};

View File

@ -247,4 +247,5 @@ export default {
'caseManagement.featureCase.defectSource': '缺陷来源',
'caseManagement.featureCase.sortSuccess': '排序成功',
'caseManagement.featureCase.zentao': '禅道',
'caseManagement.featureCase.searchPlaceholder': '通过id或名称搜索',
};

View File

@ -82,7 +82,13 @@
{{ caseDetail.num }}{{ caseDetail.name }}
</div>
</a-tooltip>
<a-button type="outline" size="mini" class="arco-btn-outline--secondary" @click="editCaseVisible = true">
<a-button
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
type="outline"
size="mini"
class="arco-btn-outline--secondary"
@click="editCaseVisible = true"
>
{{ t('common.edit') }}
</a-button>
</div>

View File

@ -68,7 +68,7 @@
</div>
</template>
<template #action="{ record }">
<MsButton type="text" class="!mr-0" @click="review(record)">
<MsButton v-permission="['CASE_REVIEW:READ+REVIEW']" type="text" class="!mr-0" @click="review(record)">
{{ t('caseManagement.caseReview.review') }}
</MsButton>
<a-divider direction="vertical" :margin="8"></a-divider>
@ -80,7 +80,7 @@
type="error"
@confirm="(val, done) => handleDisassociateReviewCase(record, done)"
>
<MsButton type="text" class="!mr-0">
<MsButton v-permission="['CASE_REVIEW:READ+RELEVANCE']" type="text" class="!mr-0">
{{ t('caseManagement.caseReview.disassociate') }}
</MsButton>
</MsPopconfirm>
@ -88,7 +88,7 @@
<template v-if="keyword.trim() === ''" #empty>
<div class="flex w-full items-center justify-center p-[8px] text-[var(--color-text-4)]">
{{ t('caseManagement.caseReview.tableNoData') }}
<MsButton class="ml-[8px]" @click="createCase">
<MsButton v-permission="['FUNCTIONAL_CASE:READ+ADD']" class="ml-[8px]" @click="createCase">
{{ t('caseManagement.caseReview.crateCase') }}
</MsButton>
</div>
@ -271,6 +271,7 @@
import useTableStore from '@/hooks/useTableStore';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import { hasAnyPermission } from '@/utils/permission';
import { ReviewCaseItem, ReviewItem, ReviewPassRule, ReviewResult } from '@/models/caseManagement/caseReview';
import { BatchApiParams, ModuleTreeNode } from '@/models/common';
@ -293,12 +294,15 @@
const userStore = useUserStore();
const { t } = useI18n();
const { openModal } = useModal();
const keyword = ref('');
const showType = ref<'list' | 'mind'>('list');
const filterRowCount = ref(0);
const filterConfigList = ref<FilterFormItem[]>([]);
const tableParams = ref<Record<string, any>>({});
const hasOperationPermission = computed(() =>
hasAnyPermission(['CASE_REVIEW:READ+REVIEW', 'CASE_REVIEW:READ+RELEVANCE'])
);
const columns: MsTableColumn = [
{
title: 'ID',
@ -348,11 +352,11 @@
width: 150,
},
{
title: 'common.operation',
title: hasOperationPermission.value ? 'common.operation' : '',
slotName: 'action',
dataIndex: 'operation',
fixed: 'right',
width: 140,
width: hasOperationPermission.value ? 140 : 50,
},
];
const tableStore = useTableStore();

View File

@ -105,7 +105,12 @@
</a-tooltip>
</template>
<template #action="{ record }">
<MsButton type="text" class="!mr-0" @click="() => editReview(record)">
<MsButton
v-permission="['CASE_REVIEW:READ+UPDATE']"
type="text"
class="!mr-0"
@click="() => editReview(record)"
>
{{ t('common.edit') }}
</MsButton>
<!-- <a-divider direction="vertical" :margin="8"></a-divider>
@ -113,12 +118,16 @@
{{ t('common.export') }}
</MsButton> -->
<a-divider direction="vertical" :margin="8"></a-divider>
<MsTableMoreAction :list="getMoreAction(record.status)" @select="handleMoreActionSelect($event, record)" />
<MsTableMoreAction
v-permission="['CASE_REVIEW:READ+DELETE']"
:list="getMoreAction(record.status)"
@select="handleMoreActionSelect($event, record)"
/>
</template>
<template v-if="keyword.trim() === ''" #empty>
<div class="flex w-full items-center justify-center p-[8px] text-[var(--color-text-4)]">
{{ t('caseManagement.caseReview.tableNoData') }}
<MsButton class="ml-[8px]" @click="() => emit('goCreate')">
<MsButton v-permission="['CASE_REVIEW:READ+ADD']" class="ml-[8px]" @click="() => emit('goCreate')">
{{ t('caseManagement.caseReview.create') }}
</MsButton>
</div>
@ -183,6 +192,7 @@
import useTableStore from '@/hooks/useTableStore';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import { hasAnyPermission } from '@/utils/permission';
import {
ReviewDetailReviewersItem,
@ -212,7 +222,6 @@
(e: 'goCreate'): void;
(e: 'init', params: ReviewListQueryParams): void;
}>();
const userStore = useUserStore();
const appStore = useAppStore();
const router = useRouter();
@ -354,6 +363,10 @@
console.log(error);
}
});
const hasOperationPermission = computed(() =>
hasAnyPermission(['CASE_REVIEW:READ+UPDATE', 'CASE_REVIEW:READ+DELETE'])
);
const columns: MsTableColumn = [
{
title: 'ID',
@ -437,11 +450,11 @@
width: 350,
},
{
title: 'common.operation',
title: hasOperationPermission.value ? 'common.operation' : '',
slotName: 'action',
dataIndex: 'operation',
fixed: 'right',
width: 110,
width: hasOperationPermission.value ? 110 : 50,
},
];
const tableStore = useTableStore();
@ -565,6 +578,7 @@
label: 'common.delete',
eventTag: 'delete',
danger: true,
permission: ['CASE_REVIEW:READ+DELETE'],
},
];
}
@ -573,6 +587,7 @@
label: 'common.delete',
eventTag: 'delete',
danger: true,
permission: ['CASE_REVIEW:READ+DELETE'],
},
];
}

View File

@ -1,7 +1,11 @@
<template>
<a-form ref="dialogFormRef" :model="caseResultForm" layout="vertical">
<a-form-item field="reason" class="mb-[4px]">
<a-radio-group v-model:model-value="caseResultForm.result" @change="() => dialogFormRef?.resetFields()">
<a-radio-group
v-model:model-value="caseResultForm.result"
:disabled="!hasAnyPermission(['CASE_REVIEW:READ+REVIEW'])"
@change="() => dialogFormRef?.resetFields()"
>
<a-radio value="PASS">
<div class="inline-flex items-center">
<MsIcon type="icon-icon_succeed_filled" class="mr-[4px] text-[rgb(var(--success-6))]" />
@ -29,13 +33,20 @@
</a-radio-group>
</a-form-item>
<div class="flex w-full items-center">
<a-button type="secondary" class="p-[8px_6px]" size="small" @click="modalVisible = true">
<a-button
v-permission="['CASE_REVIEW:READ+REVIEW']"
type="secondary"
class="p-[8px_6px]"
size="small"
@click="modalVisible = true"
>
<icon-plus class="mr-[4px]" />
{{ t('caseManagement.caseReview.reason') }}
</a-button>
</div>
</a-form>
<a-button
v-permission="['CASE_REVIEW:READ+REVIEW']"
type="primary"
class="mt-[12px]"
:disabled="submitDisabled"
@ -77,6 +88,7 @@
import { editorUploadFile } from '@/api/modules/case-management/featureCase';
import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import { hasAnyPermission } from '@/utils/permission';
import { ReviewPassRule, ReviewResult } from '@/models/caseManagement/caseReview';

View File

@ -32,15 +32,20 @@
<a-switch v-model:model-value="onlyMine" size="small" class="mr-[8px]" type="line" />
{{ t('caseManagement.caseReview.onlyMine') }}
</div>
<MsButton type="button" status="default" @click="associateDrawerVisible = true">
<MsButton
v-permission="['CASE_REVIEW:READ+UPDATE']"
type="button"
status="default"
@click="associateDrawerVisible = true"
>
<MsIcon type="icon-icon_link-record_outlined1" class="mr-[8px]" />
{{ t('ms.case.associate.title') }}
</MsButton>
<MsButton type="button" status="default" @click="editReview">
<MsButton v-permission="['CASE_REVIEW:READ+UPDATE']" type="button" status="default" @click="editReview">
<MsIcon type="icon-icon_edit_outlined" class="mr-[8px]" />
{{ t('common.edit') }}
</MsButton>
<MsButton type="button" status="default" @click="copyReview">
<MsButton v-permission="['CASE_REVIEW:READ+ADD']" type="button" status="default" @click="copyReview">
<MsIcon type="icon-icon_copy_outlined" class="mr-[8px]" />
{{ t('common.copy') }}
</MsButton>
@ -296,6 +301,7 @@
label: t('caseManagement.caseReview.quickCreate'),
eventTag: 'createCase',
icon: 'icon-icon_add_outlined-1',
permission: ['FUNCTIONAL_CASE:READ+ADD'],
},
// {
// label: t('caseManagement.caseReview.createTestPlan'),
@ -310,6 +316,7 @@
eventTag: 'delete',
icon: 'icon-icon_delete-trash_outlined1',
danger: true,
permission: ['CASE_REVIEW:READ+DELETE'],
},
];
const moreAction = computed(() => {

View File

@ -1,7 +1,9 @@
<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]">
<a-button type="primary" @click="goCreateReview">{{ t('caseManagement.caseReview.create') }}</a-button>
<a-button v-permission="['CASE_REVIEW:READ+ADD']" type="primary" @click="goCreateReview">{{
t('caseManagement.caseReview.create')
}}</a-button>
<a-radio-group v-model:model-value="showType" type="button" class="file-show-type">
<a-radio value="all">{{ t('common.all') }}</a-radio>
<a-radio value="reviewByMe">{{ t('caseManagement.caseReview.waitMyReview') }}</a-radio>

View File

@ -99,6 +99,7 @@
import useModal from '@/hooks/useModal';
import { useAppStore, useTableStore } from '@/store';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type {
AddOrUpdateCommonScript,
@ -118,6 +119,10 @@
const keyword = ref<string>('');
const hasOperationPermission = computed(() =>
hasAnyPermission(['PROJECT_CUSTOM_FUNCTION:READ+UPDATE', 'PROJECT_CUSTOM_FUNCTION:READ+DELETE'])
);
const columns: MsTableColumn = [
{
title: 'project.commonScript.name',
@ -177,11 +182,11 @@
showDrag: true,
},
{
title: 'project.commonScript.tableColumnActions',
title: hasOperationPermission.value ? 'project.commonScript.tableColumnActions' : '',
slotName: 'operation',
dataIndex: 'operation',
fixed: 'right',
width: 140,
width: hasOperationPermission.value ? 140 : 50,
showInTable: true,
showDrag: false,
},

View File

@ -114,7 +114,9 @@
:all-names="[]"
@rename-finish="detailDrawerRef?.initDetail"
>
<MsButton class="!mr-0 ml-[8px]">{{ t('common.rename') }}</MsButton>
<MsButton v-permission="['PROJECT_FILE_MANAGEMENT:READ+UPDATE']" class="!mr-0 ml-[8px]">{{
t('common.rename')
}}</MsButton>
</popConfirm>
<template v-if="UploadAcceptEnum.image.includes(fileType)">
<a-divider
@ -248,6 +250,7 @@
import { useAppStore } from '@/store';
import useUserStore from '@/store/modules/user';
import { downloadByteFile, formatFileSize } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import { AssociationItem, FileDetail } from '@/models/projectManagement/file';
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
@ -395,6 +398,8 @@
}
}
const hasOperationPermission = computed(() => hasAnyPermission(['PROJECT_FILE_MANAGEMENT:READ+UPDATE']));
const activeTab = ref('case');
const caseColumns: MsTableColumn = [
@ -425,10 +430,10 @@
showTooltip: true,
},
{
title: 'common.operation',
title: hasOperationPermission.value ? 'common.operation' : '',
slotName: 'action',
fixed: 'right',
width: 130,
width: hasOperationPermission.value ? 130 : 50,
},
];
const {
@ -450,6 +455,7 @@
{
label: 'project.fileManagement.updateCaseFile',
eventTag: 'updateCaseFile',
permission: ['PROJECT_FILE_MANAGEMENT:READ+UPDATE'],
},
],
};

View File

@ -529,6 +529,13 @@
}
return jarFileActions;
}
const hasOperationPermission = computed(() =>
hasAnyPermission([
'PROJECT_FILE_MANAGEMENT:READ+UPDATE',
'PROJECT_FILE_MANAGEMENT:READ+DELETE',
'PROJECT_FILE_MANAGEMENT:READ+DOWNLOAD',
])
);
const columns: MsTableColumn = [
{
@ -582,11 +589,11 @@
width: 180,
},
{
title: 'common.operation',
title: hasOperationPermission.value ? 'common.operation' : '',
slotName: 'action',
dataIndex: 'operation',
fixed: 'right',
width: 120,
width: hasOperationPermission.value ? 120 : 50,
},
];
const tableStore = useTableStore();

View File

@ -129,7 +129,7 @@
const appStore = useAppStore();
const tableStore = useTableStore();
const lastProjectId = computed(() => appStore.currentProjectId);
const hasOperationPermission = computed(() => hasAnyPermission(['PROJECT_USER:READ+DELETE']));
const columns: MsTableColumn = [
{
title: 'project.member.tableColumnName',
@ -166,11 +166,11 @@
width: 150,
},
{
title: 'project.member.tableColumnActions',
title: hasOperationPermission.value ? 'project.member.tableColumnActions' : '',
slotName: 'operation',
fixed: 'right',
dataIndex: 'operation',
width: 100,
width: hasOperationPermission.value ? 100 : 50,
showDrag: false,
},
];

View File

@ -315,6 +315,10 @@
const keyword = ref('');
const hasOperationPermission = computed(() =>
hasAnyPermission(['PROJECT_VERSION:READ+UPDATE', 'PROJECT_VERSION:READ+DELETE'])
);
const columns: MsTableColumn = [
{
title: 'project.projectVersion.versionName',
@ -360,11 +364,11 @@
showTooltip: true,
},
{
title: 'common.operation',
title: hasOperationPermission.value ? 'common.operation' : '',
fixed: 'right',
slotName: 'action',
dataIndex: 'operation',
width: 80,
width: hasOperationPermission.value ? 80 : 50,
},
];
const { propsRes, propsEvent, loadList, setKeyword, setLoadListParams } = useTable(

View File

@ -146,6 +146,7 @@
import {
getCardList,
getCustomDetailFields,
getTemplateName,
getTotalFieldOptionList,
} from '@/views/setting/organization/template/components/fieldSetting';
@ -238,13 +239,19 @@
watchEffect(async () => {
if (isEdit.value && route.params.mode === 'copy') {
title.value = t('system.orgTemplate.copyTemplate');
title.value = t('system.orgTemplate.copyTemplate', {
type: getTemplateName('organization', route.query.type as string),
});
getClassifyField();
} else if (isEdit.value) {
title.value = t('menu.settings.organization.templateManagementEdit');
title.value = t('system.orgTemplate.editTemplateType', {
type: getTemplateName('organization', route.query.type as string),
});
getClassifyField();
} else {
title.value = t('menu.settings.organization.templateManagementDetail');
title.value = t('system.orgTemplate.createTemplateType', {
type: getTemplateName('organization', route.query.type as string),
});
}
});

View File

@ -12,31 +12,9 @@
/**
* @description 项目管理-模板-字段设置-首页
*/
import { useRoute } from 'vue-router';
import MsCard from '@/components/pure/ms-card/index.vue';
import FieldSetting from '@/views/setting/organization/template/components/fieldSetting.vue';
import { useAppStore } from '@/store';
import { getCardList } from '@/views/setting/organization/template/components/fieldSetting';
const route = useRoute();
const appStore = useAppStore();
//
const updateBreadcrumbList = () => {
const { breadcrumbList } = appStore;
const breadTitle = getCardList('project').find((item: any) => item.key === route.params.type);
if (breadTitle) {
breadcrumbList[0].locale = breadTitle.name;
appStore.setBreadcrumbList(breadcrumbList);
}
};
onMounted(() => {
updateBreadcrumbList();
});
</script>
<style scoped></style>

View File

@ -113,13 +113,13 @@
import { useAppStore, useTableStore } from '@/store';
import useTemplateStore from '@/store/modules/setting/template';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { DefinedFieldItem, OrdTemplateManagement } from '@/models/setting/template';
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import {
getCardList,
getCustomDetailFields,
getTotalFieldOptionList,
} from '@/views/setting/organization/template/components/fieldSetting';
@ -136,6 +136,10 @@
const sceneType = computed(() => route.query.type);
const hasOperationPermission = computed(() =>
hasAnyPermission(['PROJECT_TEMPLATE:READ+UPDATE', 'PROJECT_TEMPLATE:READ+DELETE'])
);
const fieldColumns: MsTableColumn = [
{
title: 'system.orgTemplate.columnTemplateName',
@ -168,11 +172,11 @@
showInTable: true,
},
{
title: 'system.orgTemplate.operation',
title: hasOperationPermission.value ? 'system.orgTemplate.operation' : '',
slotName: 'operation',
dataIndex: 'operation',
fixed: 'right',
width: 200,
width: hasOperationPermission.value ? 200 : 50,
showInTable: true,
showDrag: false,
},
@ -350,16 +354,6 @@
defectForm.value = { ...initDetailForm };
};
//
const updateBreadcrumbList = () => {
const { breadcrumbList } = appStore;
const breadTitle = getCardList('project').find((item: any) => item.key === route.query.type);
if (breadTitle) {
breadcrumbList[0].locale = breadTitle.name;
appStore.setBreadcrumbList(breadcrumbList);
}
};
const tableRef = ref();
function updateColumns() {
@ -374,7 +368,6 @@
}
onMounted(() => {
updateBreadcrumbList();
fetchData();
updateColumns();
});

View File

@ -154,6 +154,10 @@
const appStore = useAppStore();
const { t } = useI18n();
const lastOrganizationId = computed(() => appStore.currentOrgId);
const hasOrdMemberOperationPermission = computed(() =>
hasAnyPermission(['ORGANIZATION_MEMBER:READ+UPDATE', 'ORGANIZATION_MEMBER:READ+DELETE'])
);
const columns: MsTableColumn = [
{
title: 'organization.member.tableColunmEmail',
@ -205,11 +209,11 @@
showDrag: true,
},
{
title: 'organization.member.tableColunmActions',
title: hasOrdMemberOperationPermission.value ? 'organization.member.tableColunmActions' : '',
slotName: 'action',
dataIndex: 'operation',
fixed: 'right',
width: 140,
width: hasOrdMemberOperationPermission.value ? 140 : 50,
showInTable: true,
showDrag: false,
},

View File

@ -39,7 +39,7 @@
size="mini"
class="ml-3 px-0 text-sm"
type="text"
:disabled="!links.disabled"
:disabled="links.disabled"
@click.stop="jumpHandler(links)"
>
{{ t(links.name) }}
@ -73,7 +73,6 @@
import { useI18n } from '@/hooks/useI18n';
import useUserStore from '@/store/modules/user/index';
import { openWindow } from '@/utils/index';
import { hasAnyPermission } from '@/utils/permission';
import type { SkipTitle, StepListType } from '@/models/setting/serviceIntegration';
import { SettingRouteEnum } from '@/enums/routeEnum';
@ -81,8 +80,7 @@
const userStore = useUserStore();
const isHasSystemPermission = computed(() => {
const { systemPermissions } = userStore.currentRole;
return hasAnyPermission(systemPermissions, ['SYSTEM']) as boolean;
return userStore.isAdmin;
});
const { t } = useI18n();
@ -90,7 +88,7 @@
const cardContent = ref<StepListType[]>([
{
id: '1001',
icon: 'configplugin',
icon: 'downloadplugin',
title: 'organization.service.downloadPluginOrDev',
skipTitle: [
{
@ -111,14 +109,14 @@
},
{
id: '1002',
icon: 'downloadplugin',
icon: 'configplugin',
title: 'organization.service.configPlugin',
skipTitle: [
{
name: 'organization.service.jumpPlugin',
src: '',
active: true,
disabled: isHasSystemPermission.value,
disabled: !isHasSystemPermission.value,
},
],
step: '@/assets/images/ms_configplugin.jpg',

View File

@ -127,6 +127,11 @@ export function getCardList(type: string): Record<string, any>[] {
});
}
export function getTemplateName(type: string, scene: string) {
const dataList = getCardList(type);
return dataList.find((item) => item.key === scene)?.name;
}
// table名称展示图标类型表格展示类型
export const fieldIconAndName: fieldIconAndNameModal[] = [
{

View File

@ -150,6 +150,7 @@
import { useAppStore, useTableStore } from '@/store';
import useTemplateStore from '@/store/modules/setting/template';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { AddOrUpdateField, SeneType } from '@/models/setting/template';
import { TableKeyEnum } from '@/enums/tableEnum';
@ -166,9 +167,9 @@
const props = defineProps<{
mode: 'organization' | 'project';
deletePermission?: string[];
createPermission?: string[];
updatePermission?: string[];
deletePermission: string[];
createPermission: string[];
updatePermission: string[];
}>();
const currentOrd = computed(() => appStore.currentOrgId);
@ -185,6 +186,10 @@
}
});
const hasOperationPermission = computed(() =>
hasAnyPermission([...props.updatePermission, ...props.deletePermission])
);
const fieldColumns: MsTableColumn = [
{
title: 'system.orgTemplate.name',
@ -211,11 +216,11 @@
showInTable: true,
},
{
title: 'system.orgTemplate.operation',
title: hasOperationPermission.value ? 'system.orgTemplate.operation' : '',
slotName: 'operation',
dataIndex: 'operation',
fixed: 'right',
width: 200,
width: hasOperationPermission.value ? 200 : 50,
showInTable: true,
},
];

View File

@ -12,31 +12,9 @@
/**
* @description 系统管理-组织-模板管理-字段列表首页
*/
import { useRoute } from 'vue-router';
import MsCard from '@/components/pure/ms-card/index.vue';
import FieldSetting from '@/views/setting/organization/template/components/fieldSetting.vue';
import { useAppStore } from '@/store';
import { getCardList } from '@/views/setting/organization/template/components/fieldSetting';
const route = useRoute();
const appStore = useAppStore();
//
const updateBreadcrumbList = () => {
const { breadcrumbList } = appStore;
const breadTitle = getCardList('organization').find((item: any) => item.key === route.query.type);
if (breadTitle) {
breadcrumbList[0].locale = breadTitle.name;
appStore.setBreadcrumbList(breadcrumbList);
}
};
onMounted(() => {
updateBreadcrumbList();
});
</script>
<style scoped></style>

View File

@ -143,7 +143,7 @@
import type { ActionTemplateManage, CustomField, DefinedFieldItem } from '@/models/setting/template';
import { SettingRouteEnum } from '@/enums/routeEnum';
import { getCardList, getCustomDetailFields, getTotalFieldOptionList } from './fieldSetting';
import { getCardList, getCustomDetailFields, getTemplateName, getTotalFieldOptionList } from './fieldSetting';
const { t } = useI18n();
const route = useRoute();
@ -233,10 +233,14 @@
title.value = t('system.orgTemplate.copyTemplate');
getClassifyField();
} else if (isEdit.value) {
title.value = t('menu.settings.organization.templateManagementEdit');
title.value = t('system.orgTemplate.createTemplateType', {
type: getTemplateName('organization', route.query.type as string),
});
getClassifyField();
} else {
title.value = t('menu.settings.organization.templateManagementDetail');
title.value = t('menu.settings.organization.editTemplateType', {
type: getTemplateName('organization', route.query.type as string),
});
}
});

View File

@ -83,13 +83,12 @@
import { useAppStore, useTableStore } from '@/store';
import useTemplateStore from '@/store/modules/setting/template';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { OrdTemplateManagement } from '@/models/setting/template';
import { SettingRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { getCardList } from './fieldSetting';
const route = useRoute();
const { t } = useI18n();
const tableStore = useTableStore();
@ -100,6 +99,10 @@
const keyword = ref('');
const currentOrd = computed(() => appStore.currentOrgId);
const hasOperationPermission = computed(() =>
hasAnyPermission(['ORGANIZATION_TEMPLATE:READ+UPDATE', 'ORGANIZATION_TEMPLATE:READ+DELETE'])
);
const fieldColumns: MsTableColumn = [
{
title: 'system.orgTemplate.columnTemplateName',
@ -125,11 +128,11 @@
showInTable: true,
},
{
title: 'system.orgTemplate.operation',
title: hasOperationPermission.value ? 'system.orgTemplate.operation' : '',
slotName: 'operation',
dataIndex: 'operation',
fixed: 'right',
width: 200,
width: hasOperationPermission.value ? 200 : 50,
showInTable: true,
showDrag: false,
},
@ -249,16 +252,6 @@
});
};
//
const updateBreadcrumbList = () => {
const { breadcrumbList } = appStore;
const breadTitle = getCardList('organization').find((item: any) => item.key === route.query.type);
if (breadTitle) {
breadcrumbList[0].locale = breadTitle.name;
appStore.setBreadcrumbList(breadcrumbList);
}
};
const tableRef = ref();
const sceneType = computed(() => route.query.type);
@ -283,7 +276,6 @@
}
onMounted(() => {
updateBreadcrumbList();
fetchData();
updateColumns();
});

View File

@ -106,7 +106,9 @@ export default {
'system.orgTemplate.deleteTemplateTitle': 'Are you sure to delete { name }?',
'system.orgTemplate.apiInputPlaceholder': 'Please enter a third-party API',
'system.orgTemplate.apiFieldId': 'API field',
'system.orgTemplate.copyTemplate': 'Copy Template',
'system.orgTemplate.copyTemplate': 'copy{type}template',
'system.orgTemplate.createTemplateType': 'create{type}',
'system.orgTemplate.editTemplateType': 'edit{type}',
'system.orgTemplate.workFlowTip':
'Change the properties or workflow configuration of the event will take effect immediately on the related project. Exercise caution when performing this operation',
'system.orgTemplate.workFlowToolTip':

View File

@ -106,7 +106,9 @@ export default {
'system.orgTemplate.deleteTemplateTitle': '确认删除 {name} 吗?',
'system.orgTemplate.apiInputPlaceholder': '请输入第三方 API',
'system.orgTemplate.apiFieldId': 'API 字段',
'system.orgTemplate.copyTemplate': '复制模板',
'system.orgTemplate.copyTemplate': '复制{type}模板',
'system.orgTemplate.createTemplateType': '创建{type}',
'system.orgTemplate.editTemplateType': '编辑{type}',
'system.orgTemplate.workFlowTip': '更改事项的属性或工作流配置,会在相关项目立即生效,请谨慎操作',
'system.orgTemplate.workFlowToolTip': '列为缺陷所在状态,在列内“点击+”,可添加流转状态',
'system.orgTemplate.workFlowToolTipHover': 'hover 可更换初始状态,操作列可选择结束状态',

View File

@ -608,6 +608,7 @@
import { useTableStore } from '@/store';
import { characterLimit } from '@/utils';
import { scrollIntoView } from '@/utils/dom';
import { hasAnyPermission } from '@/utils/permission';
import type { AuthDetail, AuthForm, AuthItem, AuthType } from '@/models/setting/config';
import { TableKeyEnum } from '@/enums/tableEnum';
@ -618,11 +619,16 @@
const { openModal } = useModal();
const loading = ref(false);
const hasOperationPermission = computed(() =>
hasAnyPermission(['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE', 'SYSTEM_PARAMETER_SETTING_AUTH:READ+DELETE'])
);
const tableActions: ActionsItem[] = [
{
label: 'system.config.auth.delete',
eventTag: 'delete',
danger: true,
permission: ['SYSTEM_PARAMETER_SETTING_AUTH:READ+DELETE'],
},
];
const columns: MsTableColumn = [
@ -655,10 +661,10 @@
showInTable: true,
},
{
title: 'system.config.auth.action',
title: hasOperationPermission.value ? 'system.config.auth.action' : '',
slotName: 'action',
fixed: 'right',
width: 140,
width: hasOperationPermission.value ? 140 : 50,
dataIndex: 'operation',
showInTable: true,
},

View File

@ -117,7 +117,7 @@
<span>{{ getTime(record.updateTime) }}</span>
</template>
</a-table-column>
<a-table-column :width="180" fixed="right" :bordered="false">
<a-table-column v-if="hasOperationPluginPermission" :width="180" fixed="right" :bordered="false">
<template #title>
{{ t('system.plugin.tableColumnsActions') }}
</template>
@ -215,6 +215,7 @@
import useModal from '@/hooks/useModal';
import useVisit from '@/hooks/useVisit';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { DrawerConfig, PluginForms, PluginItem, PluginList, UpdatePluginModel } from '@/models/setting/plugin';
@ -226,6 +227,10 @@
const loading = ref<boolean>(false);
const expandedRowKeys = reactive([]);
const hasOperationPluginPermission = computed(() =>
hasAnyPermission(['SYSTEM_PLUGIN:READ+UPDATE', 'SYSTEM_PLUGIN:READ+DELETE'])
);
const config = ref<DrawerConfig>({
title: '',
pluginId: '',

View File

@ -97,6 +97,7 @@
import useModal from '@/hooks/useModal';
import { useTableStore } from '@/store';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { ResourcePoolDetail } from '@/models/setting/resourcePool';
import { TableKeyEnum } from '@/enums/tableEnum';
@ -104,6 +105,10 @@
const { t } = useI18n();
const router = useRouter();
const route = useRoute();
const hasOperationPoolPermission = computed(() =>
hasAnyPermission(['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE', 'SYSTEM_TEST_RESOURCE_POOL:READ+DELETE'])
);
const columns: MsTableColumn = [
{
title: 'system.resourcePool.tableColumnName',
@ -136,11 +141,11 @@
width: 180,
},
{
title: 'system.resourcePool.tableColumnActions',
title: hasOperationPoolPermission.value ? 'system.resourcePool.tableColumnActions' : '',
slotName: 'action',
dataIndex: 'operation',
fixed: 'right',
width: 140,
width: hasOperationPoolPermission.value ? 140 : 50,
},
];
const tableStore = useTableStore();

View File

@ -330,6 +330,10 @@
const { currentLocale } = useLocale();
const route = useRoute();
const hasOperationSysUserPermission = computed(() =>
hasAnyPermission(['SYSTEM_USER:READ+UPDATE', 'SYSTEM_USER:READ+DELETE'])
);
const columns: MsTableColumn = [
{
title: 'system.user.tableColumnEmail',
@ -365,11 +369,11 @@
dataIndex: 'enable',
},
{
title: 'system.user.tableColumnActions',
title: hasOperationSysUserPermission.value ? 'system.user.tableColumnActions' : '',
slotName: 'action',
dataIndex: 'operation',
fixed: 'right',
width: 110,
width: hasOperationSysUserPermission.value ? 110 : 50,
},
];
const tableStore = useTableStore();