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