feat(系统管理): 权限&修改bug&补充xpack
This commit is contained in:
parent
43f8bfd268
commit
379f46c795
|
@ -27,6 +27,7 @@ import {
|
|||
DetailCaseUrl,
|
||||
DownloadExcelTemplateUrl,
|
||||
DownloadFileUrl,
|
||||
dragSortUrl,
|
||||
EditorUploadFileUrl,
|
||||
exportExcelCheckUrl,
|
||||
FollowerCaseUrl,
|
||||
|
@ -83,6 +84,7 @@ import type {
|
|||
DeleteCaseType,
|
||||
DemandItem,
|
||||
DetailCase,
|
||||
DragCase,
|
||||
ImportExcelType,
|
||||
ModulesTreeType,
|
||||
OperationFile,
|
||||
|
@ -401,4 +403,9 @@ export function importExcelCase(data: { request: ImportExcelType; fileList: File
|
|||
return MSR.uploadFile({ url: importExcelCaseUrl }, { request: data.request, fileList: data.fileList }, '');
|
||||
}
|
||||
|
||||
// 拖拽排序
|
||||
export function dragSort(data: DragCase) {
|
||||
return MSR.post({ url: dragSortUrl, data });
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
|
|
@ -143,3 +143,5 @@ export const PreviewEditorImageUrl = '/attachment/download/file';
|
|||
export const exportExcelCheckUrl = '/functional/case/pre-check/excel';
|
||||
// 导入excel文件
|
||||
export const importExcelCaseUrl = '/functional/case/import/excel';
|
||||
// 用例拖拽排序
|
||||
export const dragSortUrl = '/functional/case/edit/pos';
|
||||
|
|
|
@ -313,6 +313,7 @@
|
|||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 200,
|
||||
},
|
||||
|
@ -321,6 +322,7 @@
|
|||
dataIndex: 'name',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
width: 300,
|
||||
|
|
|
@ -188,6 +188,7 @@
|
|||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 200,
|
||||
},
|
||||
|
@ -196,6 +197,7 @@
|
|||
dataIndex: 'name',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
width: 300,
|
||||
|
@ -206,6 +208,7 @@
|
|||
slotName: 'method',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 200,
|
||||
},
|
||||
|
|
|
@ -145,6 +145,7 @@
|
|||
dataIndex: 'createTime',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showInTable: true,
|
||||
width: 300,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
</div>
|
||||
<a-tooltip :content="t('ms.personal.maxTip')" position="right" :disabled="apiKeyList.length < 5">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_PERSONAL_API_KEY:READ+ADD']"
|
||||
type="outline"
|
||||
class="w-[60px]"
|
||||
:disabled="apiKeyList.length >= 5"
|
||||
|
@ -63,12 +64,18 @@
|
|||
</div>
|
||||
<div class="flex items-center justify-between px-[16px]">
|
||||
<MsTableMoreAction :list="actions" trigger="click" @select="handleMoreActionSelect($event, item)">
|
||||
<a-button size="mini" type="outline" class="arco-btn-outline--secondary">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_PERSONAL_API_KEY:READ+UPDATE']"
|
||||
size="mini"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
>
|
||||
{{ t('common.setting') }}
|
||||
</a-button>
|
||||
</MsTableMoreAction>
|
||||
<a-switch
|
||||
v-model:model-value="item.enable"
|
||||
v-permission="['SYSTEM_PERSONAL_API_KEY:READ+UPDATE']"
|
||||
size="small"
|
||||
:before-change="() => handleBeforeEnableChange(item)"
|
||||
type="line"
|
||||
|
@ -77,7 +84,9 @@
|
|||
</div>
|
||||
<div v-if="apiKeyList.length === 0" class="col-span-2 flex w-full items-center justify-center p-[44px]">
|
||||
{{ t('ms.personal.nodata') }}
|
||||
<MsButton type="text" class="ml-[8px]" @click="newApiKey">{{ t('common.new') }}</MsButton>
|
||||
<MsButton v-permission="['SYSTEM_PERSONAL_API_KEY:READ+ADD']" type="text" class="ml-[8px]" @click="newApiKey">{{
|
||||
t('common.new')
|
||||
}}</MsButton>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
name: 'apiKey',
|
||||
title: t('ms.personal.apiKey'),
|
||||
level: 2,
|
||||
permission: ['SYSTEM_PERSONAL_API_KEY:READ'],
|
||||
},
|
||||
{
|
||||
name: 'local',
|
||||
|
|
|
@ -21,8 +21,13 @@
|
|||
import usePermission from '@/hooks/usePermission';
|
||||
import appClientMenus from '@/router/app-menus';
|
||||
import { useAppStore } from '@/store';
|
||||
import useLicenseStore from '@/store/modules/setting/license';
|
||||
import { listenerRouteChange } from '@/utils/route-listener';
|
||||
|
||||
import { RouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
const licenseStore = useLicenseStore();
|
||||
|
||||
const copyRouters = cloneDeep(appClientMenus) as RouteRecordRaw[];
|
||||
const permission = usePermission();
|
||||
const appStore = useAppStore();
|
||||
|
@ -79,9 +84,17 @@
|
|||
(item) => name && item?.name && (name as string).includes(item.name as string)
|
||||
);
|
||||
}
|
||||
appStore.setTopMenus(
|
||||
currentParent?.children?.filter((item) => permission.accessRouter(item) && item.meta?.isTopMenu)
|
||||
);
|
||||
|
||||
const filterMenuTopRouter = currentParent?.children
|
||||
?.filter((item: any) => permission.accessRouter(item) && item.meta?.isTopMenu)
|
||||
.filter((item: any) => {
|
||||
if (item.name === RouteEnum.SETTING_SYSTEM_AUTHORIZED_MANAGEMENT) {
|
||||
return licenseStore.hasLicense();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
appStore.setTopMenus(filterMenuTopRouter);
|
||||
setCurrentTopMenu(name as string);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div v-if="props.title" class="mb-2 font-medium">{{ props.title }}</div>
|
||||
<div class="menu">
|
||||
<div
|
||||
v-for="(item, index) of props.menuList"
|
||||
v-for="(item, index) of innerMenuList"
|
||||
:key="item.name"
|
||||
class="menu-item px-2"
|
||||
:class="{
|
||||
|
@ -26,6 +26,8 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
const props = defineProps<{
|
||||
title?: string;
|
||||
defaultKey?: string;
|
||||
|
@ -33,6 +35,7 @@
|
|||
title: string;
|
||||
level: number;
|
||||
name: string;
|
||||
permission?: string[];
|
||||
}[];
|
||||
activeClass?: string;
|
||||
}>();
|
||||
|
@ -42,6 +45,10 @@
|
|||
|
||||
const currentKey = ref(props.defaultKey);
|
||||
|
||||
const innerMenuList = computed(() => {
|
||||
return props.menuList.filter((item: any) => hasAnyPermission(item.permission));
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.defaultKey,
|
||||
(val) => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<MsCard class="mb-[16px]" :title="props.title" hide-back hide-footer auto-height no-content-padding no-bottom-radius>
|
||||
<a-tabs v-model:active-key="innerTab" class="no-content">
|
||||
<a-tab-pane v-for="item of tabList" :key="item.key" :title="item.title" />
|
||||
<a-tab-pane v-for="item of permissionTabList" :key="item.key" :title="item.title" />
|
||||
</a-tabs>
|
||||
</MsCard>
|
||||
</template>
|
||||
|
@ -11,15 +11,21 @@
|
|||
|
||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
const props = defineProps<{
|
||||
activeTab: string;
|
||||
title?: string;
|
||||
tabList: { key: string; title: string }[];
|
||||
tabList: { key: string; title: string; permission?: string[] }[];
|
||||
}>();
|
||||
const emit = defineEmits(['update:activeTab']);
|
||||
|
||||
const innerTab = ref(props.activeTab);
|
||||
|
||||
const permissionTabList = computed(() => {
|
||||
return props.tabList.filter((item: any) => hasAnyPermission(item.permission));
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.activeTab,
|
||||
(val) => {
|
||||
|
|
|
@ -324,3 +324,10 @@ export interface ValidateInfo {
|
|||
successCount: number;
|
||||
errorMessages: errorMessagesType[];
|
||||
}
|
||||
// 拖拽排序
|
||||
export interface DragCase {
|
||||
projectId: string;
|
||||
targetId: string;
|
||||
moveMode: 'BEFORE' | 'AFTER' | 'APPEND'[]; // 拖拽类型
|
||||
moveId: string;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ export interface SkipTitle {
|
|||
name: string;
|
||||
src: string;
|
||||
active: boolean; // 是否激活
|
||||
disabled: boolean;
|
||||
}
|
||||
|
||||
export interface StepListType {
|
||||
|
|
|
@ -192,7 +192,7 @@ const ProjectManagement: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/project-management/fileManagement/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.projectManagement.fileManagement',
|
||||
roles: ['*'],
|
||||
roles: ['PROJECT_FILE_MANAGEMENT:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
@ -203,7 +203,7 @@ const ProjectManagement: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/project-management/messageManagement/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.projectManagement.messageManagement',
|
||||
roles: ['*'],
|
||||
roles: ['PROJECT_MESSAGE:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -34,7 +34,7 @@ const Setting: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/setting/system/user/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.settings.system.user',
|
||||
roles: ['*'],
|
||||
roles: ['SYSTEM_USER:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
@ -64,7 +64,7 @@ const Setting: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/setting/system/config/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.settings.system.parameter',
|
||||
roles: ['*'],
|
||||
roles: ['SYSTEM_PARAMETER_SETTING_BASE:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
@ -74,7 +74,7 @@ const Setting: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/setting/system/resourcePool/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.settings.system.resourcePool',
|
||||
roles: ['*'],
|
||||
roles: ['SYSTEM_TEST_RESOURCE_POOL:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
@ -84,7 +84,7 @@ const Setting: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/setting/system/resourcePool/detail.vue'),
|
||||
meta: {
|
||||
locale: 'menu.settings.system.resourcePoolDetail',
|
||||
roles: ['*'],
|
||||
roles: ['SYSTEM_TEST_RESOURCE_POOL:READ'],
|
||||
breadcrumbs: [
|
||||
{
|
||||
name: SettingRouteEnum.SETTING_SYSTEM_RESOURCE_POOL,
|
||||
|
|
|
@ -24,8 +24,7 @@ const useLicenseStore = defineStore('license', {
|
|||
if (!result || !result.status || !result.license || !result.license.count) {
|
||||
return;
|
||||
}
|
||||
// this.setLicenseStatus(result.status);
|
||||
this.setLicenseStatus('fail');
|
||||
this.setLicenseStatus(result.status);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
dataIndex: 'createUser',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
showDrag: true,
|
||||
|
@ -116,6 +117,7 @@
|
|||
dataIndex: 'updateUser',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
showInTable: true,
|
||||
|
@ -125,6 +127,7 @@
|
|||
dataIndex: 'updateTime',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
showInTable: true,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
v-model:visible="showDrawerVisible"
|
||||
:width="1200"
|
||||
:footer="false"
|
||||
:mask="false"
|
||||
:title="t('caseManagement.featureCase.caseDetailTitle', { id: detailInfo?.id, name: detailInfo?.name })"
|
||||
:detail-id="props.detailId"
|
||||
:detail-index="props.detailIndex"
|
||||
|
@ -11,7 +12,6 @@
|
|||
:pagination="props.pagination"
|
||||
:table-data="props.tableData"
|
||||
:page-change="props.pageChange"
|
||||
:mask-closable="false"
|
||||
@loaded="loadedCase"
|
||||
>
|
||||
<template #titleLeft>
|
||||
|
@ -534,6 +534,15 @@
|
|||
const changeHandler = debounce(() => {
|
||||
tabDetailRef.value.handleOK();
|
||||
}, 300);
|
||||
|
||||
watch(
|
||||
() => props.detailId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
updateSuccess();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
|
|
@ -25,12 +25,17 @@
|
|||
v-if="showType === 'list'"
|
||||
v-bind="propsRes"
|
||||
ref="tableRef"
|
||||
filter-icon-align-left
|
||||
class="mt-4"
|
||||
:action-config="tableBatchActions"
|
||||
@selected-change="handleTableSelect"
|
||||
v-on="propsEvent"
|
||||
@batch-action="handleTableBatch"
|
||||
@change="changeHandler"
|
||||
>
|
||||
<template #num="{ record, rowIndex }">
|
||||
<span class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</span>
|
||||
</template>
|
||||
<template #name="{ record, rowIndex }">
|
||||
<a-button type="text" class="px-0" @click="showCaseDetail(record.id, rowIndex)">{{ record.name }}</a-button>
|
||||
</template>
|
||||
|
@ -78,8 +83,11 @@
|
|||
</a-tooltip>
|
||||
</template>
|
||||
<!-- 渲染自定义字段开始TODO -->
|
||||
<!-- <template v-for="item in customFieldsColumns" :key="item.slotName" #[item.slotName]="{ record }">
|
||||
</template> -->
|
||||
<template v-for="item in customFieldsColumns" :key="item.slotName" #[item.slotName]="{ record }">
|
||||
<a-tooltip :content="getTableFields(record.customFields, item)" position="top" :mouse-enter-delay="100" mini>
|
||||
<div>{{ getTableFields(record.customFields, item) }}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<!-- 渲染自定义字段结束 -->
|
||||
<template #operation="{ record }">
|
||||
<MsButton v-permission="['FUNCTIONAL_CASE:READ+UPDATE']" @click="operateCase(record, 'edit')">{{
|
||||
|
@ -186,7 +194,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { Message, TableChangeExtra, TableData } from '@arco-design/web-vue';
|
||||
|
||||
import { CustomTypeMaps, MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
|
||||
import { FilterFormItem, FilterResult, FilterType } from '@/components/pure/ms-advance-filter/type';
|
||||
|
@ -213,6 +221,7 @@
|
|||
batchDeleteCase,
|
||||
batchMoveToModules,
|
||||
deleteCaseRequest,
|
||||
dragSort,
|
||||
getCaseDefaultFields,
|
||||
getCaseDetail,
|
||||
getCaseList,
|
||||
|
@ -230,12 +239,13 @@
|
|||
CaseModuleQueryParams,
|
||||
CustomAttributes,
|
||||
DemandItem,
|
||||
DragCase,
|
||||
} from '@/models/caseManagement/featureCase';
|
||||
import type { TableQueryParams } from '@/models/common';
|
||||
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
||||
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { getCaseLevels, getReviewStatusClass, getStatusText } from './utils';
|
||||
import { getCaseLevels, getReviewStatusClass, getStatusText, getTableFields } from './utils';
|
||||
import { LabelValue } from '@arco-design/web-vue/es/tree-select/interface';
|
||||
|
||||
const { openModal } = useModal();
|
||||
|
@ -332,16 +342,19 @@
|
|||
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnID',
|
||||
dataIndex: 'num',
|
||||
width: 200,
|
||||
showInTable: true,
|
||||
sortable: {
|
||||
'title': 'caseManagement.featureCase.tableColumnID',
|
||||
'slotName': 'num',
|
||||
'dataIndex': 'num',
|
||||
'width': 200,
|
||||
'showInTable': true,
|
||||
'sortable': {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
ellipsis: true,
|
||||
showDrag: false,
|
||||
'filter-icon-align-left': true,
|
||||
'showTooltip': true,
|
||||
'ellipsis': true,
|
||||
'showDrag': false,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnName',
|
||||
|
@ -353,6 +366,7 @@
|
|||
editType: ColumnEditTypeEnum.INPUT,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
ellipsis: true,
|
||||
showDrag: false,
|
||||
|
@ -411,6 +425,7 @@
|
|||
dataIndex: 'updateTime',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showInTable: true,
|
||||
width: 200,
|
||||
|
@ -972,17 +987,18 @@
|
|||
async function getDefaultFields() {
|
||||
const result = await getCaseDefaultFields(currentProjectId.value);
|
||||
initDefaultFields.value = result.customFields;
|
||||
customFieldsColumns = initDefaultFields.value.map((item: any) => {
|
||||
return {
|
||||
title: item.fieldName,
|
||||
slotName: item.fieldId as string,
|
||||
dataIndex: item.fieldId,
|
||||
showTooltip: true,
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 300,
|
||||
};
|
||||
});
|
||||
customFieldsColumns = initDefaultFields.value
|
||||
.filter((item: any) => !item.internal)
|
||||
.map((item: any) => {
|
||||
return {
|
||||
title: item.fieldName,
|
||||
slotName: item.fieldId as string,
|
||||
dataIndex: item.fieldId,
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 300,
|
||||
};
|
||||
});
|
||||
|
||||
fullColumns = [
|
||||
...columns.slice(0, columns.length - 1),
|
||||
|
@ -1072,7 +1088,6 @@
|
|||
...detailResult,
|
||||
moduleId: value,
|
||||
customFields: getCustomMaps(detailResult),
|
||||
tags: JSON.parse(detailResult.tags),
|
||||
},
|
||||
fileList: [],
|
||||
};
|
||||
|
@ -1104,6 +1119,36 @@
|
|||
initData();
|
||||
};
|
||||
|
||||
// 拖拽排序
|
||||
async function changeHandler(data: TableData[], extra: TableChangeExtra, currentData: TableData[]) {
|
||||
if (extra && extra.dragTarget?.id) {
|
||||
const params: DragCase = {
|
||||
projectId: currentProjectId.value,
|
||||
targetId: '',
|
||||
moveMode: 'BEFORE',
|
||||
moveId: extra.dragTarget.id as string,
|
||||
};
|
||||
const index = currentData.findIndex((item: any) => item.raw.id === extra.dragTarget?.id);
|
||||
|
||||
if (index > -1 && currentData[index + 1].raw) {
|
||||
params.moveMode = 'AFTER';
|
||||
params.targetId = currentData[index + 1].raw.id;
|
||||
} else if (index > -1 && !currentData[index + 1].raw) {
|
||||
if (index > -1 && currentData[index - 1].raw) {
|
||||
params.moveMode = 'BEFORE';
|
||||
params.targetId = currentData[index - 1].raw.id;
|
||||
}
|
||||
}
|
||||
try {
|
||||
await dragSort(params);
|
||||
Message.success(t('caseManagement.featureCase.sortSuccess'));
|
||||
initData();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (route.query.id) {
|
||||
showCaseDetail(route.query.id as string, 0);
|
||||
|
|
|
@ -237,6 +237,7 @@
|
|||
showInTable: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
ellipsis: true,
|
||||
|
@ -251,6 +252,7 @@
|
|||
width: 300,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
ellipsis: true,
|
||||
showDrag: false,
|
||||
|
@ -325,6 +327,7 @@
|
|||
showInTable: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 200,
|
||||
showDrag: true,
|
||||
|
@ -343,6 +346,7 @@
|
|||
dataIndex: 'updateTime',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showInTable: true,
|
||||
width: 200,
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
dataIndex: 'reviewName',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
width: 300,
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 200,
|
||||
},
|
||||
|
@ -263,6 +264,7 @@
|
|||
dataIndex: 'name',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showTooltip: true,
|
||||
width: 300,
|
||||
|
|
|
@ -132,4 +132,31 @@ export function getCaseLevels(customFields: CustomAttributes[]): CaseLevel {
|
|||
);
|
||||
}
|
||||
|
||||
// 处理自定义字段
|
||||
export function getTableFields(customFields: any, itemDataIndex: any) {
|
||||
const multipleExcludes = ['MULTIPLE_SELECT', 'CHECKBOX', 'MULTIPLE_MEMBER'];
|
||||
const selectExcludes = ['MEMBER', 'RADIO', 'SELECT'];
|
||||
|
||||
const currentColumnData = customFields.find((item: any) => itemDataIndex.dataIndex === item.fieldId);
|
||||
// 处理多选项
|
||||
if (multipleExcludes.includes(currentColumnData.type)) {
|
||||
const selectValue = JSON.parse(currentColumnData.defaultValue);
|
||||
return currentColumnData.options
|
||||
.filter((item: any) => selectValue.includes(item.value))
|
||||
.map((it: any) => it.text)
|
||||
.join(',');
|
||||
}
|
||||
if (currentColumnData.type === 'MULTIPLE_INPUT') {
|
||||
// 处理标签形式
|
||||
return JSON.parse(currentColumnData.defaultValue).join(',');
|
||||
}
|
||||
if (selectExcludes.includes(currentColumnData.type)) {
|
||||
return currentColumnData.options
|
||||
.filter((item: any) => currentColumnData.defaultValue === item.value)
|
||||
.map((it: any) => it.text)
|
||||
.join();
|
||||
}
|
||||
return currentColumnData.defaultValue;
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
|
|
@ -250,4 +250,5 @@ export default {
|
|||
'caseManagement.featureCase.cancelDependencyContent': 'Cancel after impact test plan related statistics',
|
||||
'caseManagement.featureCase.associatedSuccess': 'Associated with success',
|
||||
'caseManagement.featureCase.defectSource': 'defect Source',
|
||||
'caseManagement.featureCase.sortSuccess': 'Sort successfully',
|
||||
};
|
||||
|
|
|
@ -245,4 +245,5 @@ export default {
|
|||
'caseManagement.featureCase.cancelDependencyContent': '取消后,影响测试计划相关统计',
|
||||
'caseManagement.featureCase.associatedSuccess': '关联成功',
|
||||
'caseManagement.featureCase.defectSource': '缺陷来源',
|
||||
'caseManagement.featureCase.sortSuccess': '排序成功',
|
||||
};
|
||||
|
|
|
@ -93,14 +93,14 @@
|
|||
|
||||
const loginConfig = useStorage('login-config', {
|
||||
rememberPassword: true,
|
||||
username: 'admin',
|
||||
password: 'Calong@2015',
|
||||
username: '',
|
||||
password: '',
|
||||
});
|
||||
|
||||
const userInfo = reactive({
|
||||
authenticate: 'LOCAL',
|
||||
username: 'admin',
|
||||
password: 'Calong@2015',
|
||||
username: '',
|
||||
password: '',
|
||||
});
|
||||
|
||||
const handleSubmit = async ({
|
||||
|
|
|
@ -164,6 +164,7 @@
|
|||
dataIndex: 'createTime',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showInTable: true,
|
||||
width: 300,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<MsIcon type="icon-icon-maybe_outlined" class="mr-[8px] cursor-pointer hover:text-[rgb(var(--primary-5))]" />
|
||||
</a-tooltip>
|
||||
<MsButton
|
||||
v-permission="['PROJECT_FILE_MANAGEMENT:READ+DOWNLOAD']"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="!rounded-[var(--border-radius-small)] !text-[var(--color-text-1)]"
|
||||
|
@ -39,6 +40,7 @@
|
|||
</MsButton>
|
||||
<MsButton
|
||||
v-if="detail?.storage === 'GIT'"
|
||||
v-permission="['PROJECT_FILE_MANAGEMENT:READ+UPDATE']"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="!rounded-[var(--border-radius-small)] !text-[var(--color-text-1)]"
|
||||
|
@ -132,7 +134,9 @@
|
|||
:all-names="[]"
|
||||
@update-desc-finish="detailDrawerRef?.initDetail"
|
||||
>
|
||||
<MsButton class="ml-[8px]"><MsIcon type="icon-icon_edit_outlined"></MsIcon></MsButton>
|
||||
<MsButton v-permission="['PROJECT_FILE_MANAGEMENT:READ+UPDATE']" class="ml-[8px]"
|
||||
><MsIcon type="icon-icon_edit_outlined"></MsIcon
|
||||
></MsButton>
|
||||
</popConfirm>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -167,7 +171,12 @@
|
|||
v-on="caseTableEvent"
|
||||
>
|
||||
<template #action="{ record }">
|
||||
<MsButton type="text" class="mr-[8px]" @click="updateCase(record)">
|
||||
<MsButton
|
||||
v-permission="['PROJECT_FILE_MANAGEMENT:READ+UPDATE']"
|
||||
type="text"
|
||||
class="mr-[8px]"
|
||||
@click="updateCase(record)"
|
||||
>
|
||||
{{ t('project.fileManagement.updateCaseFile') }}
|
||||
</MsButton>
|
||||
</template>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<template>
|
||||
<div class="flex h-[calc(100vh-88px)] flex-col overflow-hidden p-[24px]">
|
||||
<div class="header">
|
||||
<a-button type="primary" @click="handleAddClick">{{ t('project.fileManagement.addFile') }}</a-button>
|
||||
<a-button v-permission="['PROJECT_FILE_MANAGEMENT:READ+ADD']" type="primary" @click="handleAddClick">{{
|
||||
t('project.fileManagement.addFile')
|
||||
}}</a-button>
|
||||
<div class="header-right">
|
||||
<a-select v-model="tableFileType" class="w-[240px]" :loading="fileTypeLoading" @change="searchList">
|
||||
<template #prefix>
|
||||
|
@ -562,15 +564,18 @@
|
|||
{
|
||||
label: 'project.fileManagement.download',
|
||||
eventTag: 'download',
|
||||
permission: ['PROJECT_FILE_MANAGEMENT:READ+DOWNLOAD'],
|
||||
},
|
||||
{
|
||||
label: 'project.fileManagement.move',
|
||||
eventTag: 'move',
|
||||
permission: ['PROJECT_FILE_MANAGEMENT:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'project.fileManagement.delete',
|
||||
eventTag: 'delete',
|
||||
danger: true,
|
||||
permission: ['PROJECT_FILE_MANAGEMENT:READ+DELETE'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -579,11 +584,13 @@
|
|||
{
|
||||
label: 'project.fileManagement.download',
|
||||
eventTag: 'download',
|
||||
permission: ['PROJECT_FILE_MANAGEMENT:READ+DOWNLOAD'],
|
||||
},
|
||||
{
|
||||
label: 'project.fileManagement.delete',
|
||||
eventTag: 'delete',
|
||||
danger: true,
|
||||
permission: ['PROJECT_FILE_MANAGEMENT:READ+DELETE'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
>
|
||||
<template #footer>
|
||||
<div class="mb-[6px] mt-[4px] p-[3px_8px]">
|
||||
<MsButton type="text" @click="emit('createRobot')">
|
||||
<MsButton v-permission="['PROJECT_MESSAGE:READ+ADD']" type="text" @click="emit('createRobot')">
|
||||
<MsIcon type="icon-icon_add_outlined" class="mr-[8px] text-[rgb(var(--primary-6))]" size="14" />
|
||||
{{ t('project.messageManagement.createBot') }}
|
||||
</MsButton>
|
||||
|
@ -86,6 +86,7 @@
|
|||
<div v-if="!record.children && record.projectRobotConfigMap?.[dataIndex as string]" class="flex items-center">
|
||||
<a-switch
|
||||
v-model:model-value="record.projectRobotConfigMap[dataIndex as string].enable"
|
||||
v-permission="['PROJECT_MESSAGE:READ+UPDATE']"
|
||||
:before-change="(val) => handleChangeIntercept(!!val, record, dataIndex as string)"
|
||||
size="small"
|
||||
type="line"
|
||||
|
@ -104,7 +105,13 @@
|
|||
/>
|
||||
</template>
|
||||
</a-popover>
|
||||
<MsButton type="button" @click="editRobot(record, dataIndex as string)">{{ t('common.setting') }}</MsButton>
|
||||
<MsButton
|
||||
v-permission="['PROJECT_MESSAGE:READ+UPDATE']"
|
||||
v-xpack
|
||||
type="button"
|
||||
@click="editRobot(record, dataIndex as string)"
|
||||
>{{ t('common.setting') }}</MsButton
|
||||
>
|
||||
</div>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<span class="text-[14px]">{{ t('project.messageManagement.notRemind') }}</span>
|
||||
</template>
|
||||
</a-alert>
|
||||
<a-button type="primary" class="mb-[16px]" @click="handleCreateClick">
|
||||
<a-button v-permission="['PROJECT_MESSAGE:READ+ADD']" type="primary" class="mb-[16px]" @click="handleCreateClick">
|
||||
{{ t('project.messageManagement.createBot') }}
|
||||
</a-button>
|
||||
<div
|
||||
|
@ -52,6 +52,7 @@
|
|||
<div class="flex items-center justify-between leading-[24px]">
|
||||
<div v-if="!['IN_SITE', 'MAIL'].includes(robot.platform)">
|
||||
<a-button
|
||||
v-permission="['PROJECT_MESSAGE:READ+UPDATE']"
|
||||
type="outline"
|
||||
size="mini"
|
||||
class="arco-btn-outline--secondary mr-[8px]"
|
||||
|
@ -59,7 +60,13 @@
|
|||
>
|
||||
{{ t('common.edit') }}
|
||||
</a-button>
|
||||
<a-button type="outline" size="mini" class="arco-btn-outline--secondary" @click="delRobot(robot)">
|
||||
<a-button
|
||||
v-permission="['PROJECT_MESSAGE:READ+DELETE']"
|
||||
type="outline"
|
||||
size="mini"
|
||||
class="arco-btn-outline--secondary"
|
||||
@click="delRobot(robot)"
|
||||
>
|
||||
{{ t('common.delete') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
|
|
@ -25,16 +25,22 @@
|
|||
<div class="flex items-center justify-between">
|
||||
<span class="font-normal">{{ t(item.title) }}</span>
|
||||
<span>
|
||||
<a-button
|
||||
v-for="links of item.skipTitle"
|
||||
:key="links.name"
|
||||
size="mini"
|
||||
class="ml-3 px-0 text-sm"
|
||||
type="text"
|
||||
@click.stop="jumpHandler(links)"
|
||||
<a-tooltip
|
||||
:content="isHasSystemPermission ? '' : t('organization.service.noPermissionsTip')"
|
||||
position="bottom"
|
||||
>
|
||||
{{ t(links.name) }}
|
||||
</a-button>
|
||||
<a-button
|
||||
v-for="links of item.skipTitle"
|
||||
:key="links.name"
|
||||
size="mini"
|
||||
class="ml-3 px-0 text-sm"
|
||||
type="text"
|
||||
:disabled="!links.disabled"
|
||||
@click.stop="jumpHandler(links)"
|
||||
>
|
||||
{{ t(links.name) }}
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-xs text-[var(--color-text-4)]">
|
||||
|
@ -61,11 +67,20 @@
|
|||
import ServiceList from './components/serviceList.vue';
|
||||
|
||||
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';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const isHasSystemPermission = computed(() => {
|
||||
const { systemPermissions } = userStore.currentRole;
|
||||
return hasAnyPermission(systemPermissions, ['SYSTEM']) as boolean;
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const cardContent = ref<StepListType[]>([
|
||||
|
@ -78,11 +93,13 @@
|
|||
name: 'organization.service.developmentDoc',
|
||||
src: 'https://github.com/metersphere/metersphere-platform-plugin/wiki/%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97',
|
||||
active: false,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
name: 'organization.service.downPlugin',
|
||||
src: 'https://github.com/metersphere/metersphere-platform-plugin',
|
||||
active: false,
|
||||
disabled: false,
|
||||
},
|
||||
],
|
||||
step: '@/assets/images/ms_plugindownload.jpg',
|
||||
|
@ -97,6 +114,7 @@
|
|||
name: 'organization.service.jumpPlugin',
|
||||
src: '',
|
||||
active: true,
|
||||
disabled: isHasSystemPermission.value,
|
||||
},
|
||||
],
|
||||
step: '@/assets/images/ms_configplugin.jpg',
|
||||
|
|
|
@ -50,4 +50,5 @@ export default {
|
|||
'organization.service.closeSuccess': 'Disable successfully',
|
||||
'organization.service.configSuccess': 'Configuration successfully',
|
||||
'organization.service.updateSuccess': 'Update successfully',
|
||||
'organization.service.noPermissionsTip': 'You do not have operation permission, please contact the administrator',
|
||||
};
|
||||
|
|
|
@ -45,4 +45,5 @@ export default {
|
|||
'organization.service.closeSuccess': '禁用成功',
|
||||
'organization.service.configSuccess': '配置成功',
|
||||
'organization.service.updateSuccess': '更新成功',
|
||||
'organization.service.noPermissionsTip': '您没有操作权限,请联系管理员',
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<MsCard :loading="loading" simple>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<a-button type="primary" @click="createAuth">
|
||||
<a-button v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+ADD']" type="primary" @click="createAuth">
|
||||
{{ t('system.config.auth.add') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
@ -11,12 +11,24 @@
|
|||
<a-button type="text" class="px-0" @click="openAuthDetail(record.id)">{{ record.name }}</a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<MsButton @click="editAuth(record)">{{ t('system.config.auth.edit') }}</MsButton>
|
||||
<MsButton v-if="record.enable" @click="disabledAuth(record)">
|
||||
<MsButton v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE']" @click="editAuth(record)">{{
|
||||
t('system.config.auth.edit')
|
||||
}}</MsButton>
|
||||
<MsButton
|
||||
v-if="record.enable"
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE']"
|
||||
@click="disabledAuth(record)"
|
||||
>
|
||||
{{ t('system.config.auth.disable') }}
|
||||
</MsButton>
|
||||
<MsButton v-else @click="enableAuth(record)">{{ t('system.config.auth.enable') }}</MsButton>
|
||||
<MsTableMoreAction :list="tableActions" @select="handleSelect($event, record)"></MsTableMoreAction>
|
||||
<MsButton v-else v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE']" @click="enableAuth(record)">{{
|
||||
t('system.config.auth.enable')
|
||||
}}</MsButton>
|
||||
<MsTableMoreAction
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+DELETE']"
|
||||
:list="tableActions"
|
||||
@select="handleSelect($event, record)"
|
||||
></MsTableMoreAction>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</MsCard>
|
||||
|
|
|
@ -3,7 +3,12 @@
|
|||
<MsCard class="mb-[16px]" :loading="baseloading" simple auto-height>
|
||||
<div class="mb-[16px] flex justify-between">
|
||||
<div class="text-[var(--color-text-000)]">{{ t('system.config.baseInfo') }}</div>
|
||||
<a-button type="outline" size="mini" @click="baseInfoDrawerVisible = true">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_BASE:READ+UPDATE']"
|
||||
type="outline"
|
||||
size="mini"
|
||||
@click="baseInfoDrawerVisible = true"
|
||||
>
|
||||
{{ t('system.config.update') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
@ -12,7 +17,12 @@
|
|||
<MsCard class="mb-[16px]" :loading="emailLoading" simple auto-height>
|
||||
<div class="mb-[16px] flex justify-between">
|
||||
<div class="text-[var(--color-text-000)]">{{ t('system.config.emailConfig') }}</div>
|
||||
<a-button type="outline" size="mini" @click="emailConfigDrawerVisible = true">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_BASE:READ+UPDATE']"
|
||||
type="outline"
|
||||
size="mini"
|
||||
@click="emailConfigDrawerVisible = true"
|
||||
>
|
||||
{{ t('system.config.update') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
|
|
@ -39,7 +39,12 @@
|
|||
<div class="config-content">
|
||||
<div class="config-title !mb-[8px] flex items-center justify-between">
|
||||
{{ t('system.config.page.pagePreview') }}
|
||||
<MsButton class="!leading-none" @click="resetLoginPageConfig">{{ t('system.config.page.reset') }}</MsButton>
|
||||
<MsButton
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE']"
|
||||
class="!leading-none"
|
||||
@click="resetLoginPageConfig"
|
||||
>{{ t('system.config.page.reset') }}</MsButton
|
||||
>
|
||||
</div>
|
||||
<!-- 登录页预览盒子 -->
|
||||
<div :class="['config-preview', currentLocale === 'en-US' ? 'config-preview--en' : '']">
|
||||
|
@ -90,7 +95,12 @@
|
|||
size-unit="KB"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary" size="mini">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE']"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
size="mini"
|
||||
>
|
||||
{{ t('system.config.page.replace') }}
|
||||
</a-button>
|
||||
</MsUpload>
|
||||
|
@ -118,7 +128,12 @@
|
|||
size-unit="KB"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary" size="mini">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE']"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
size="mini"
|
||||
>
|
||||
{{ t('system.config.page.replace') }}
|
||||
</a-button>
|
||||
</MsUpload>
|
||||
|
@ -148,7 +163,12 @@
|
|||
size-unit="MB"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary" size="mini">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE']"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
size="mini"
|
||||
>
|
||||
{{ t('system.config.page.replace') }}
|
||||
</a-button>
|
||||
</MsUpload>
|
||||
|
@ -199,7 +219,12 @@
|
|||
<div class="config-content border border-solid border-[var(--color-text-n8)] !bg-white">
|
||||
<div class="config-title !mb-[8px] flex items-center justify-between">
|
||||
{{ t('system.config.page.pagePreview') }}
|
||||
<MsButton class="!leading-none" @click="resetPlatformConfig">{{ t('system.config.page.reset') }}</MsButton>
|
||||
<MsButton
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE']"
|
||||
class="!leading-none"
|
||||
@click="resetPlatformConfig"
|
||||
>{{ t('system.config.page.reset') }}</MsButton
|
||||
>
|
||||
</div>
|
||||
<!-- 平台主页预览盒子 -->
|
||||
<div :class="['config-preview', '!h-[290px]', currentLocale === 'en-US' ? '!h-[340px]' : '']">
|
||||
|
@ -252,7 +277,12 @@
|
|||
size-unit="MB"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary" size="mini">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE']"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
size="mini"
|
||||
>
|
||||
{{ t('system.config.page.replace') }}
|
||||
</a-button>
|
||||
</MsUpload>
|
||||
|
@ -299,8 +329,10 @@
|
|||
class="fixed bottom-0 right-[16px] z-[999] flex justify-between bg-white p-[24px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]"
|
||||
:style="{ width: `calc(100% - ${menuWidth + 16}px)` }"
|
||||
>
|
||||
<a-button type="secondary" @click="resetAll">{{ t('system.config.page.resetAll') }}</a-button>
|
||||
<a-button type="primary" @click="beforeSave">
|
||||
<a-button v-permission="['SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE']" type="secondary" @click="resetAll">{{
|
||||
t('system.config.page.resetAll')
|
||||
}}</a-button>
|
||||
<a-button v-permission="['SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE']" type="primary" @click="beforeSave">
|
||||
{{ t('system.config.page.save') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
const isInitMemoryCleanup = ref(activeTab.value === 'memoryCleanup');
|
||||
const authConfigRef = ref<AuthConfigInstance | null>();
|
||||
const tabList = ref([
|
||||
{ key: 'baseConfig', title: t('system.config.baseConfig') },
|
||||
{ key: 'pageConfig', title: t('system.config.pageConfig') },
|
||||
{ key: 'authConfig', title: t('system.config.authConfig') },
|
||||
{ key: 'memoryCleanup', title: t('system.config.memoryCleanup') },
|
||||
{ key: 'baseConfig', title: t('system.config.baseConfig'), permission: ['SYSTEM_PARAMETER_SETTING_BASE:READ'] },
|
||||
{ key: 'pageConfig', title: t('system.config.pageConfig'), permission: ['SYSTEM_PARAMETER_SETTING_DISPLAY:READ'] },
|
||||
{ key: 'authConfig', title: t('system.config.authConfig'), permission: ['SYSTEM_PARAMETER_SETTING_AUTH:READ'] },
|
||||
{ key: 'memoryCleanup', title: t('system.config.memoryCleanup'), permission: [] },
|
||||
]);
|
||||
|
||||
watch(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<MsCard :loading="loading" simple>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<a-button v-xpack type="primary" @click="addPool">
|
||||
<a-button v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+ADD']" v-xpack type="primary" @click="addPool">
|
||||
{{ t('system.resourcePool.createPool') }}
|
||||
</a-button>
|
||||
<a-input-search
|
||||
|
@ -18,12 +18,25 @@
|
|||
<a-button type="text" class="px-0" @click="showPoolDetail(record.id)">{{ record.name }}</a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<MsButton @click="editPool(record)">{{ t('system.resourcePool.editPool') }}</MsButton>
|
||||
<MsButton v-if="record.enable" v-xpack @click="disabledPool(record)">
|
||||
<MsButton v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']" @click="editPool(record)">{{
|
||||
t('system.resourcePool.editPool')
|
||||
}}</MsButton>
|
||||
<MsButton
|
||||
v-if="record.enable"
|
||||
v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']"
|
||||
v-xpack
|
||||
@click="disabledPool(record)"
|
||||
>
|
||||
{{ t('system.resourcePool.tableDisable') }}
|
||||
</MsButton>
|
||||
<MsButton v-else v-xpack @click="enablePool(record)">{{ t('system.resourcePool.tableEnable') }}</MsButton>
|
||||
<MsTableMoreAction :list="tableActions" @select="handleSelect($event, record)"></MsTableMoreAction>
|
||||
<MsButton v-else v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']" v-xpack @click="enablePool(record)">{{
|
||||
t('system.resourcePool.tableEnable')
|
||||
}}</MsButton>
|
||||
<MsTableMoreAction
|
||||
v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+DELETE']"
|
||||
:list="tableActions"
|
||||
@select="handleSelect($event, record)"
|
||||
></MsTableMoreAction>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</MsCard>
|
||||
|
@ -40,7 +53,13 @@
|
|||
show-description
|
||||
>
|
||||
<template #tbutton>
|
||||
<a-button type="outline" size="mini" :disabled="drawerLoading" @click="editPool(activePool)">
|
||||
<a-button
|
||||
v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']"
|
||||
type="outline"
|
||||
size="mini"
|
||||
:disabled="drawerLoading"
|
||||
@click="editPool(activePool)"
|
||||
>
|
||||
{{ t('system.resourcePool.editPool') }}
|
||||
</a-button>
|
||||
</template>
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
<MsCard simple>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<a-button class="mr-3" type="primary" @click="showUserModal('create')">
|
||||
<a-button v-permission="['SYSTEM_USER:READ+ADD']" class="mr-3" type="primary" @click="showUserModal('create')">
|
||||
{{ t('system.user.createUser') }}
|
||||
</a-button>
|
||||
<a-button class="mr-3" type="outline" @click="showEmailInviteModal">
|
||||
<a-button v-permission="['SYSTEM_USER_INVITE']" class="mr-3" type="outline" @click="showEmailInviteModal">
|
||||
{{ t('system.user.emailInvite') }}
|
||||
</a-button>
|
||||
<a-button class="mr-3" type="outline" @click="showImportModal">{{ t('system.user.importUser') }}</a-button>
|
||||
<a-button v-permission="['SYSTEM_USER:READ+IMPORT']" class="mr-3" type="outline" @click="showImportModal">{{
|
||||
t('system.user.importUser')
|
||||
}}</a-button>
|
||||
</div>
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
|
@ -28,10 +30,14 @@
|
|||
<template #action="{ record }">
|
||||
<template v-if="!record.enable">
|
||||
<MsButton @click="enableUser(record)">{{ t('system.user.enable') }}</MsButton>
|
||||
<MsButton @click="deleteUser(record)">{{ t('system.user.delete') }}</MsButton>
|
||||
<MsButton v-permission="['SYSTEM_USER:READ+DELETE']" @click="deleteUser(record)">{{
|
||||
t('system.user.delete')
|
||||
}}</MsButton>
|
||||
</template>
|
||||
<template v-else>
|
||||
<MsButton @click="showUserModal('edit', record)">{{ t('system.user.editUser') }}</MsButton>
|
||||
<MsButton v-permission="['SYSTEM_USER:READ+UPDATE']" @click="showUserModal('edit', record)">{{
|
||||
t('system.user.editUser')
|
||||
}}</MsButton>
|
||||
<MsTableMoreAction :list="tableActions" @select="handleSelect($event, record)"></MsTableMoreAction>
|
||||
</template>
|
||||
</template>
|
||||
|
@ -470,28 +476,34 @@
|
|||
{
|
||||
label: 'system.user.batchActionAddProject',
|
||||
eventTag: 'batchAddProject',
|
||||
permission: ['SYSTEM_USER:READ+ADD'],
|
||||
},
|
||||
{
|
||||
label: 'system.user.batchActionAddUserGroup',
|
||||
eventTag: 'batchAddUserGroup',
|
||||
permission: ['SYSTEM_USER:READ+ADD'],
|
||||
},
|
||||
{
|
||||
label: 'system.user.batchActionAddOrganization',
|
||||
eventTag: 'batchAddOrganization',
|
||||
permission: ['SYSTEM_USER:READ+ADD'],
|
||||
},
|
||||
],
|
||||
moreAction: [
|
||||
{
|
||||
label: 'system.user.resetPassword',
|
||||
eventTag: 'resetPassword',
|
||||
permission: ['SYSTEM_USER:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'system.user.disable',
|
||||
eventTag: 'disabled',
|
||||
permission: ['SYSTEM_USER:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'system.user.enable',
|
||||
eventTag: 'enable',
|
||||
permission: ['SYSTEM_USER:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
|
@ -500,6 +512,7 @@
|
|||
label: 'system.user.delete',
|
||||
eventTag: 'delete',
|
||||
danger: true,
|
||||
permission: ['SYSTEM_USER:READ+DELETE'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -121,6 +121,7 @@
|
|||
editType: ColumnEditTypeEnum.INPUT,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
ellipsis: true,
|
||||
showDrag: false,
|
||||
|
@ -186,6 +187,7 @@
|
|||
showInTable: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 200,
|
||||
showDrag: true,
|
||||
|
|
Loading…
Reference in New Issue