refactor(系统设置): 重构系统用户组
This commit is contained in:
parent
409f1538a3
commit
7c12e2560d
|
@ -315,6 +315,13 @@
|
|||
border: 1px solid var(--color-text-input-border);
|
||||
}
|
||||
}
|
||||
.arco-checkbox-indeterminate .arco-checkbox-icon {
|
||||
border-color: rgba(var(--primary-7));
|
||||
background-color: rgba(var(--primary-1));
|
||||
&::after {
|
||||
background-color: rgb(var(--primary-7));
|
||||
}
|
||||
}
|
||||
.arco-checkbox-disabled,
|
||||
.arco-checkbox-disabled:hover {
|
||||
.arco-checkbox-icon {
|
||||
|
|
|
@ -73,11 +73,9 @@
|
|||
font-size: 12px;
|
||||
border-radius: 50%;
|
||||
color: var(--color-text-4);
|
||||
background-color: rgb(var(--primary-3));
|
||||
}
|
||||
.dropdown-icon:hover {
|
||||
color: rgb(var(--primary-5));
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -13,11 +13,9 @@ export interface CustomMoreActionItem {
|
|||
eventKey: string;
|
||||
name: string;
|
||||
}
|
||||
export interface PopVisibleItem {
|
||||
[key: string]: boolean;
|
||||
}
|
||||
|
||||
export type RenameType = 'rename' | 'auth';
|
||||
export type AuthScopeType = 'SYSTEM' | 'PROJECT' | 'ORGANIZATION';
|
||||
|
||||
export interface UserGroupItem {
|
||||
// 组ID
|
||||
|
@ -29,7 +27,7 @@ export interface UserGroupItem {
|
|||
// 是否是内置用户组
|
||||
internal: true;
|
||||
// 所属类型
|
||||
type: string;
|
||||
type: AuthScopeType;
|
||||
createTime: number;
|
||||
updateTime: number;
|
||||
// 创建人
|
||||
|
@ -59,8 +57,6 @@ export interface UserGroupPermissionItem {
|
|||
license: boolean;
|
||||
}
|
||||
|
||||
export type AuthScopeType = 'SYSTEM' | 'PROJECT' | 'ORGANIZATION';
|
||||
|
||||
// 用户组对应的权限配置
|
||||
export interface UserGroupAuthSetting {
|
||||
// 菜单项ID
|
||||
|
@ -122,3 +118,15 @@ export interface UserTableItem {
|
|||
deleted: boolean;
|
||||
[key: string]: string | boolean | number;
|
||||
}
|
||||
|
||||
export type MoreActionType = 'rename' | 'addMember' | 'create';
|
||||
|
||||
export interface PopVisibleItem {
|
||||
id?: string;
|
||||
visible: boolean;
|
||||
authScope: AuthScopeType;
|
||||
defaultName: string;
|
||||
}
|
||||
export interface PopVisible {
|
||||
[key: string]: PopVisibleItem;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { PopVisibleItem, RenameType, UserGroupItem } from '@/models/setting/usergroup';
|
||||
import { RenameType, UserGroupItem } from '@/models/setting/usergroup';
|
||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import AddUserModal from './addUserModal.vue';
|
||||
|
@ -94,6 +94,10 @@
|
|||
import { getOrgUserGroupList, deleteOrgUserGroup } from '@/api/modules/setting/usergroup';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
interface PopVisibleItem {
|
||||
[key: string]: boolean;
|
||||
}
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const store = useUserGroupStore();
|
||||
|
|
|
@ -163,4 +163,3 @@
|
|||
}
|
||||
}
|
||||
</style>
|
||||
@/store/modules/setting/system/usergroup
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="currentVisible"
|
||||
width="680px"
|
||||
:ok-text="t('system.userGroup.create')"
|
||||
unmount-on-close
|
||||
@cancel="handleCancel(false)"
|
||||
>
|
||||
<template #title> {{ t('system.userGroup.createUserGroup') }} </template>
|
||||
<div class="form">
|
||||
<a-form ref="formRef" :model="form" size="large" :style="{ width: '600px' }" layout="vertical">
|
||||
<a-form-item
|
||||
field="name"
|
||||
required
|
||||
:label="t('system.userGroup.userGroupName')"
|
||||
:rules="[
|
||||
{ required: true, message: t('system.userGroup.userGroupNameIsNotNone') },
|
||||
{ validator: validateName },
|
||||
]"
|
||||
>
|
||||
<a-input v-model="form.name" :placeholder="t('system.userGroup.pleaseInputUserGroupName')" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="type"
|
||||
:label="t('system.userGroup.authScope')"
|
||||
:rules="[{ required: true, message: t('system.userGroup.authScopeIsNotNone') }]"
|
||||
>
|
||||
<a-select v-model="form.type" :placeholder="t('system.userGroup.pleaseSelectAuthScope')">
|
||||
<a-option value="SYSTEM">{{ t('system.userGroup.SYSTEM') }}</a-option>
|
||||
<a-option value="ORGANIZATION">{{ t('system.userGroup.ORGANIZATION') }}</a-option>
|
||||
<a-option value="PROJECT">{{ t('system.userGroup.PROJECT') }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<a-button type="secondary" :disabled="loading" @click="handleCancel(false)">
|
||||
{{ t('common.cancel') }}
|
||||
</a-button>
|
||||
<a-button type="primary" :loading="loading" :disabled="form.name.length === 0" @click="handleOK">
|
||||
{{ t('common.add') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { reactive, ref, watchEffect } from 'vue';
|
||||
import { UserGroupItem } from '@/models/setting/usergroup';
|
||||
import { Message, type FormInstance, type ValidatedError } from '@arco-design/web-vue';
|
||||
import { updateOrAddUserGroup } from '@/api/modules/setting/usergroup';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
list: UserGroupItem[];
|
||||
}>();
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const loading = ref(false);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'cancel', shouldSearch: boolean): void;
|
||||
}>();
|
||||
|
||||
const form = reactive({
|
||||
name: '',
|
||||
type: '',
|
||||
});
|
||||
|
||||
const currentVisible = ref(props.visible);
|
||||
|
||||
const validateName = (value: string, callback: (error?: string) => void) => {
|
||||
if (value !== '') {
|
||||
const isExist = props.list.some((item) => item.name === value);
|
||||
if (isExist) {
|
||||
callback(t('system.userGroup.userGroupNameIsExist', { name: value }));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
currentVisible.value = props.visible;
|
||||
});
|
||||
const handleCancel = (shouldSearch: boolean) => {
|
||||
form.name = '';
|
||||
form.type = '';
|
||||
emit('cancel', shouldSearch);
|
||||
};
|
||||
|
||||
const handleOK = () => {
|
||||
formRef.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => {
|
||||
if (errors) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await updateOrAddUserGroup(form);
|
||||
if (res) {
|
||||
Message.success(t('system.userGroup.addUserGroupSuccess'));
|
||||
loading.value = false;
|
||||
handleCancel(true);
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<a-popover :popup-visible="currentVisible" position="bl" trigger="click" class="w-[276px]">
|
||||
<template #content>
|
||||
<div class="form">
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
size="large"
|
||||
layout="vertical"
|
||||
:label-col-props="{ span: 0 }"
|
||||
:wrapper-col-props="{ span: 24 }"
|
||||
>
|
||||
<a-form-item>
|
||||
<div class="text-[14px] text-[var(--color-text-1)]">{{
|
||||
props.id ? t('system.userGroup.rename') : t('system.userGroup.createUserGroup')
|
||||
}}</div>
|
||||
</a-form-item>
|
||||
<a-form-item field="name" :rules="[{ validator: validateName }]">
|
||||
<a-input
|
||||
v-model="form.name"
|
||||
class="w-[228px]"
|
||||
:placeholder="t('system.userGroup.pleaseInputUserGroupName')"
|
||||
@press-enter="handleBeforeOk"
|
||||
@keyup.esc="handleCancel"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
<div class="flex flex-row flex-nowrap justify-end gap-2">
|
||||
<a-button type="secondary" size="mini" :disabled="loading" @click="handleCancel">
|
||||
{{ t('common.cancel') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
:loading="loading"
|
||||
:disabled="form.name.length === 0"
|
||||
@click="handleBeforeOk"
|
||||
>
|
||||
{{ props.id ? t('common.rename') : t('common.create') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { reactive, ref, watchEffect } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import type { FormInstance, ValidatedError } from '@arco-design/web-vue';
|
||||
import { updateOrAddUserGroup } from '@/api/modules/setting/usergroup';
|
||||
import { UserGroupItem, AuthScopeType } from '@/models/setting/usergroup';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps<{
|
||||
id?: string;
|
||||
list: UserGroupItem[];
|
||||
visible: boolean;
|
||||
defaultName?: string;
|
||||
// 权限范围
|
||||
authScope: AuthScopeType;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'cancel', value: boolean): void;
|
||||
(e: 'submit', currentId: string): void;
|
||||
}>();
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const currentVisible = ref(props.visible);
|
||||
|
||||
const form = reactive({
|
||||
name: '',
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const validateName = (value: string | undefined, callback: (error?: string) => void) => {
|
||||
if (value === undefined || value === '') {
|
||||
callback(t('system.userGroup.userGroupNameIsNotNone'));
|
||||
} else {
|
||||
if (value === props.defaultName) {
|
||||
callback();
|
||||
} else {
|
||||
const isExist = props.list.some((item) => item.name === value);
|
||||
if (isExist) {
|
||||
callback(t('system.userGroup.userGroupNameIsExist', { name: value }));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
form.name = '';
|
||||
loading.value = false;
|
||||
emit('cancel', false);
|
||||
};
|
||||
|
||||
const handleBeforeOk = () => {
|
||||
formRef.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => {
|
||||
if (errors) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await updateOrAddUserGroup({ id: props.id, name: form.name, type: props.authScope });
|
||||
if (res) {
|
||||
Message.success(
|
||||
props.id ? t('system.userGroup.updateUserGroupSuccess') : t('system.userGroup.addUserGroupSuccess')
|
||||
);
|
||||
emit('submit', res.id);
|
||||
handleCancel();
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
watchEffect(() => {
|
||||
currentVisible.value = props.visible;
|
||||
form.name = props.defaultName || '';
|
||||
});
|
||||
</script>
|
|
@ -1,241 +0,0 @@
|
|||
<template>
|
||||
<a-input-search
|
||||
allow-clear
|
||||
class="w-[252px]"
|
||||
:placeholder="t('system.userGroup.searchHolder')"
|
||||
@press-enter="enterData"
|
||||
@search="searchData"
|
||||
/>
|
||||
<div class="mt-2 flex flex-col">
|
||||
<div class="flex h-[38px] items-center justify-between px-[8px] leading-[24px]">
|
||||
<div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.global') }}</div>
|
||||
<div class="cursor-pointer text-[rgb(var(--primary-5))]"
|
||||
><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup"
|
||||
/></div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
v-for="element in userGroupList"
|
||||
:key="element.id"
|
||||
class="flex h-[38px] cursor-pointer items-center"
|
||||
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
|
||||
@click="handleListItemClick(element)"
|
||||
>
|
||||
<popconfirm
|
||||
:visible="popVisible[element.id]"
|
||||
:loading="popLoading[element.id]"
|
||||
:type="popType"
|
||||
:default-name="popDefaultName"
|
||||
:list="userGroupList"
|
||||
@cancel="() => handlePopConfirmCancel(element.id)"
|
||||
@submit="(value: CustomMoreActionItem) => handlePopConfirmSubmit(value,element.id)"
|
||||
>
|
||||
<div class="flex grow flex-row justify-between px-[8px]">
|
||||
<a-tooltip :content="element.name">
|
||||
<div class="flex flex-row flex-nowrap">
|
||||
<div class="one-line-text max-w-[156px] text-[var(--color-text-1)]">{{ element.name }}</div>
|
||||
<div v-if="element.type" class="text-[var(--color-text-4)]"
|
||||
>({{ t(`system.userGroup.${element.type}`) }})</div
|
||||
>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
<div v-if="element.id === currentId && !element.internal">
|
||||
<MsTableMoreAction :list="customAction" @select="(value) => handleMoreAction(value, element.id)" />
|
||||
</div>
|
||||
</div>
|
||||
</popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AddUserModal :visible="addUserVisible" @cancel="addUserVisible = false" />
|
||||
<AddUserGroupModal :list="userGroupList" :visible="addUserGroupVisible" @cancel="handleAddUserGroupModalCancel" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { CustomMoreActionItem, PopVisibleItem, RenameType, UserGroupItem } from '@/models/setting/usergroup';
|
||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import AddUserModal from './addUserModal.vue';
|
||||
import AddUserGroupModal from './addUserGroupModal.vue';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import popconfirm from './popconfirm.vue';
|
||||
import useUserGroupStore from '@/store/modules/setting/system/usergroup';
|
||||
import { getUserGroupList, updateOrAddUserGroup, deleteUserGroup } from '@/api/modules/setting/usergroup';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const store = useUserGroupStore();
|
||||
const { openModal } = useModal();
|
||||
// 请求loading
|
||||
const currentId = ref('');
|
||||
const addUserVisible = ref(false);
|
||||
const addUserGroupVisible = ref(false);
|
||||
// 修改用户组名字,权限范围
|
||||
const popVisible = ref<PopVisibleItem>({});
|
||||
const popLoading = ref<PopVisibleItem>({});
|
||||
// 用户组和权限范围的状态
|
||||
const popType = ref<RenameType>('rename');
|
||||
const popDefaultName = ref('');
|
||||
// 用户列表
|
||||
const userGroupList = ref<UserGroupItem[]>([]);
|
||||
|
||||
const customAction: ActionsItem[] = [
|
||||
{
|
||||
label: 'system.userGroup.rename',
|
||||
danger: false,
|
||||
eventTag: 'rename',
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
},
|
||||
{
|
||||
label: 'system.userGroup.delete',
|
||||
danger: true,
|
||||
eventTag: 'delete',
|
||||
},
|
||||
];
|
||||
|
||||
// 点击用户组列表
|
||||
const handleListItemClick = (element: UserGroupItem) => {
|
||||
const { id, name, type, internal } = element;
|
||||
currentId.value = id;
|
||||
store.setInfo({
|
||||
currentName: name,
|
||||
currentTitle: type,
|
||||
currentId: id,
|
||||
currentType: type,
|
||||
currentInternal: internal,
|
||||
});
|
||||
};
|
||||
|
||||
// 用户组数据初始化
|
||||
const initData = async () => {
|
||||
try {
|
||||
const res = await getUserGroupList();
|
||||
if (res.length > 0) {
|
||||
userGroupList.value = res;
|
||||
handleListItemClick(res[0]);
|
||||
// 弹窗赋值
|
||||
const tmpObj: PopVisibleItem = {};
|
||||
res.forEach((element) => {
|
||||
tmpObj[element.id] = false;
|
||||
});
|
||||
popVisible.value = { ...tmpObj };
|
||||
popLoading.value = { ...tmpObj };
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
// 新增用户组
|
||||
const addUserGroup = () => {
|
||||
// eslint-disable-next-line no-console
|
||||
addUserGroupVisible.value = true;
|
||||
};
|
||||
// 点击更多操作
|
||||
const handleMoreAction = (item: ActionsItem, id: string) => {
|
||||
if (item.eventTag !== 'delete') {
|
||||
popType.value = item.eventTag as RenameType;
|
||||
const tmpObj = userGroupList.value.filter((ele) => ele.id === id)[0];
|
||||
popVisible.value = { ...popVisible.value, [id]: true };
|
||||
if (item.eventTag === 'rename') {
|
||||
popDefaultName.value = tmpObj.name;
|
||||
} else {
|
||||
popDefaultName.value = tmpObj.scopeId;
|
||||
}
|
||||
} else {
|
||||
openModal({
|
||||
type: 'error',
|
||||
title: t('system.userGroup.isDeleteUserGroup', { name: characterLimit(store.currentName) }),
|
||||
content: t('system.userGroup.beforeDeleteUserGroup'),
|
||||
okText: t('system.userGroup.confirmDelete'),
|
||||
cancelText: t('system.userGroup.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'danger',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await deleteUserGroup(id);
|
||||
Message.success(t('system.user.deleteUserSuccess'));
|
||||
initData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭confirm 弹窗
|
||||
const handlePopConfirmCancel = (id: string) => {
|
||||
popVisible.value = { ...popVisible.value, [id]: false };
|
||||
};
|
||||
// 修改用户组名字,权限范围
|
||||
const handlePopConfirmSubmit = async (item: CustomMoreActionItem, id: string) => {
|
||||
if (item.eventKey === 'rename') {
|
||||
// 修改用户组名字
|
||||
try {
|
||||
popLoading.value = { ...popLoading.value, [id]: true };
|
||||
const res = await updateOrAddUserGroup({ id, name: item.name });
|
||||
if (res) {
|
||||
initData();
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
} finally {
|
||||
popLoading.value = { ...popLoading.value, [id]: false };
|
||||
}
|
||||
} else {
|
||||
// 修改权限范围
|
||||
try {
|
||||
const res = await updateOrAddUserGroup({ id, scopeId: item.name });
|
||||
if (res) {
|
||||
initData();
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
popVisible.value = { ...popVisible.value, [id]: false };
|
||||
initData();
|
||||
};
|
||||
|
||||
function enterData(eve: Event) {
|
||||
if (!(eve.target as HTMLInputElement).value) {
|
||||
initData();
|
||||
return;
|
||||
}
|
||||
const keyword = (eve.target as HTMLInputElement).value;
|
||||
const tmpArr = userGroupList.value.filter((ele) => ele.name.includes(keyword));
|
||||
userGroupList.value = tmpArr;
|
||||
}
|
||||
function searchData(value: string) {
|
||||
if (!value) {
|
||||
initData();
|
||||
return;
|
||||
}
|
||||
const keyword = value;
|
||||
const tmpArr = userGroupList.value.filter((ele) => ele.name.includes(keyword));
|
||||
userGroupList.value = tmpArr;
|
||||
}
|
||||
|
||||
const handleAddUserGroupModalCancel = (shouldSearch: boolean) => {
|
||||
addUserGroupVisible.value = false;
|
||||
if (shouldSearch) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
initData();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,454 @@
|
|||
<template>
|
||||
<a-input-search
|
||||
class="w-[252px]"
|
||||
:placeholder="t('system.userGroup.searchHolder')"
|
||||
allow-clear
|
||||
@press-enter="enterData"
|
||||
@search="searchData"
|
||||
/>
|
||||
<div class="mt-2">
|
||||
<CreateUserGroupPopup
|
||||
:list="systemUserGroupList"
|
||||
:visible="systemUserGroupVisible"
|
||||
auth-scope="SYSTEM"
|
||||
@cancel="systemUserGroupVisible = false"
|
||||
@submit="handleCreateUserGroup"
|
||||
>
|
||||
<div class="flex items-center justify-between px-[4px] py-[7px]">
|
||||
<div class="flex flex-row items-center gap-1 text-[var(--color-text-4)]">
|
||||
<MsIcon
|
||||
v-if="systemToggle"
|
||||
class="cursor-pointer"
|
||||
type="icon-icon_expand-down_filled"
|
||||
size="12"
|
||||
@click="systemToggle = false"
|
||||
/>
|
||||
<MsIcon
|
||||
v-else
|
||||
class="cursor-pointer"
|
||||
type="icon-icon_expand-right_filled"
|
||||
size="12"
|
||||
@click="systemToggle = true"
|
||||
/>
|
||||
<div class="text-[14px]">
|
||||
{{ t('system.userGroup.systemUserGroup') }}
|
||||
</div>
|
||||
</div>
|
||||
<MsMoreAction :list="createSystemUGActionItem" @select="systemUserGroupVisible = true">
|
||||
<icon-plus-circle-fill class="text-[rgb(var(--primary-7))]" size="20" />
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
</CreateUserGroupPopup>
|
||||
<Transition>
|
||||
<div v-if="systemToggle">
|
||||
<div
|
||||
v-for="element in systemUserGroupList"
|
||||
:key="element.id"
|
||||
class="flex h-[38px] cursor-pointer items-center py-[7px] pl-[20px] pr-[4px]"
|
||||
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
|
||||
@click="handleListItemClick(element)"
|
||||
>
|
||||
<CreateUserGroupPopup
|
||||
:list="systemUserGroupList"
|
||||
v-bind="popVisible[element.id]"
|
||||
@cancel="handleRenameCancel(element)"
|
||||
@submit="handleRenameCancel(element, element.id)"
|
||||
>
|
||||
<div class="flex grow flex-row items-center justify-between">
|
||||
<a-tooltip :content="element.name">
|
||||
<div
|
||||
class="one-line-text max-w-[156px] text-[var(--color-text-1)]"
|
||||
:class="{ 'text-[rgb(var(--primary-7))]': element.id === currentId }"
|
||||
>{{ element.name }}</div
|
||||
>
|
||||
</a-tooltip>
|
||||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction :list="addMemberActionItem" @select="handleAddMember">
|
||||
<div class="icon-button">
|
||||
<MsIcon type="icon-icon_add_outlined" size="16" />
|
||||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction :list="moreAction" @select="(value) => handleMoreAction(value, element.id, 'SYSTEM')">
|
||||
<div class="icon-button">
|
||||
<MsIcon type="icon-icon_more_outlined" size="16" />
|
||||
</div>
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
</div>
|
||||
</CreateUserGroupPopup>
|
||||
</div>
|
||||
<a-divider class="my-[0px] mt-[6px]" />
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<CreateUserGroupPopup
|
||||
:list="orgUserGroupList"
|
||||
:visible="orgUserGroupVisible"
|
||||
auth-scope="ORGANIZATION"
|
||||
@cancel="orgUserGroupVisible = false"
|
||||
@submit="handleCreateUserGroup"
|
||||
>
|
||||
<div class="flex items-center justify-between px-[4px] py-[7px]">
|
||||
<div class="flex flex-row items-center gap-1 text-[var(--color-text-4)]">
|
||||
<MsIcon
|
||||
v-if="orgToggle"
|
||||
class="cursor-pointer"
|
||||
type="icon-icon_expand-down_filled"
|
||||
size="12"
|
||||
@click="orgToggle = false"
|
||||
/>
|
||||
<MsIcon
|
||||
v-else
|
||||
class="cursor-pointer"
|
||||
type="icon-icon_expand-right_filled"
|
||||
size="12"
|
||||
@click="orgToggle = true"
|
||||
/>
|
||||
<div class="text-[14px]">
|
||||
{{ t('system.userGroup.orgUserGroup') }}
|
||||
</div>
|
||||
</div>
|
||||
<MsMoreAction :list="createOrgUGActionItem" @select="orgUserGroupVisible = true">
|
||||
<icon-plus-circle-fill class="text-[rgb(var(--primary-7))]" size="20" />
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
</CreateUserGroupPopup>
|
||||
<Transition>
|
||||
<div v-if="orgToggle">
|
||||
<div
|
||||
v-for="element in orgUserGroupList"
|
||||
:key="element.id"
|
||||
class="flex h-[38px] cursor-pointer items-center py-[7px] pl-[20px] pr-[4px]"
|
||||
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
|
||||
@click="handleListItemClick(element)"
|
||||
>
|
||||
<CreateUserGroupPopup
|
||||
:list="orgUserGroupList"
|
||||
v-bind="popVisible[element.id]"
|
||||
@cancel="handleRenameCancel(element)"
|
||||
@submit="handleRenameCancel(element, element.id)"
|
||||
>
|
||||
<div class="flex grow flex-row items-center justify-between">
|
||||
<a-tooltip :content="element.name">
|
||||
<div
|
||||
class="one-line-text max-w-[156px] text-[var(--color-text-1)]"
|
||||
:class="{ 'text-[rgb(var(--primary-7))]': element.id === currentId }"
|
||||
>{{ element.name }}</div
|
||||
>
|
||||
</a-tooltip>
|
||||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction :list="addMemberActionItem" @select="handleAddMember">
|
||||
<div class="icon-button">
|
||||
<MsIcon type="icon-icon_add_outlined" size="16" />
|
||||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction
|
||||
:list="moreAction"
|
||||
@select="(value) => handleMoreAction(value, element.id, 'ORGANIZATION')"
|
||||
>
|
||||
<div class="icon-button">
|
||||
<MsIcon type="icon-icon_more_outlined" size="16" />
|
||||
</div>
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
</div>
|
||||
</CreateUserGroupPopup>
|
||||
</div>
|
||||
<a-divider class="my-[0px] mt-[6px]" />
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<CreateUserGroupPopup
|
||||
:list="projectUserGroupList"
|
||||
:visible="projectUserGroupVisible"
|
||||
auth-scope="PROJECT"
|
||||
@cancel="projectUserGroupVisible = false"
|
||||
@submit="handleCreateUserGroup"
|
||||
>
|
||||
<div class="flex items-center justify-between px-[4px] py-[7px]">
|
||||
<div class="flex flex-row items-center gap-1 text-[var(--color-text-4)]">
|
||||
<MsIcon
|
||||
v-if="projectToggle"
|
||||
class="cursor-pointer"
|
||||
type="icon-icon_expand-down_filled"
|
||||
size="12"
|
||||
@click="projectToggle = false"
|
||||
/>
|
||||
<MsIcon
|
||||
v-else
|
||||
class="cursor-pointer"
|
||||
type="icon-icon_expand-right_filled"
|
||||
size="12"
|
||||
@click="projectToggle = true"
|
||||
/>
|
||||
<div class="text-[14px]">
|
||||
{{ t('system.userGroup.projectUserGroup') }}
|
||||
</div>
|
||||
</div>
|
||||
<MsMoreAction :list="createProjectUGActionItem" @select="projectUserGroupVisible = true">
|
||||
<icon-plus-circle-fill class="text-[rgb(var(--primary-7))]" size="20" />
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
</CreateUserGroupPopup>
|
||||
<Transition>
|
||||
<div v-if="projectToggle">
|
||||
<div
|
||||
v-for="element in projectUserGroupList"
|
||||
:key="element.id"
|
||||
class="flex h-[38px] cursor-pointer items-center py-[7px] pl-[20px] pr-[4px]"
|
||||
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
|
||||
@click="handleListItemClick(element)"
|
||||
>
|
||||
<CreateUserGroupPopup
|
||||
:list="projectUserGroupList"
|
||||
v-bind="popVisible[element.id]"
|
||||
@cancel="handleRenameCancel(element)"
|
||||
@submit="handleRenameCancel(element, element.id)"
|
||||
>
|
||||
<div class="flex grow flex-row items-center justify-between">
|
||||
<a-tooltip :content="element.name">
|
||||
<div
|
||||
class="one-line-text max-w-[156px] text-[var(--color-text-1)]"
|
||||
:class="{ 'text-[rgb(var(--primary-7))]': element.id === currentId }"
|
||||
>{{ element.name }}</div
|
||||
>
|
||||
</a-tooltip>
|
||||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction :list="addMemberActionItem" @select="handleAddMember">
|
||||
<div class="icon-button">
|
||||
<MsIcon type="icon-icon_add_outlined" size="16" />
|
||||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction :list="moreAction" @select="(value) => handleMoreAction(value, element.id, 'PROJECT')">
|
||||
<div class="icon-button">
|
||||
<MsIcon type="icon-icon_more_outlined" size="16" />
|
||||
</div>
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
</div>
|
||||
</CreateUserGroupPopup>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
<AddUserModal :visible="userModalVisible" @cancel="userModalVisible = false" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import MsMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { UserGroupItem, PopVisible, PopVisibleItem, AuthScopeType } from '@/models/setting/usergroup';
|
||||
import { getUserGroupList, deleteUserGroup } from '@/api/modules/setting/usergroup';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import CreateUserGroupPopup from './createOrUpdateUserGroup.vue';
|
||||
import AddUserModal from './addUserModal.vue';
|
||||
import useUserGroupStore from '@/store/modules/setting/system/usergroup';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const store = useUserGroupStore();
|
||||
const { openModal } = useModal();
|
||||
|
||||
// 用户组列表
|
||||
const userGroupList = ref<UserGroupItem[]>([]);
|
||||
|
||||
const currentId = ref('');
|
||||
|
||||
const userModalVisible = ref(false);
|
||||
|
||||
// 气泡弹窗
|
||||
const popVisible = ref<PopVisible>({});
|
||||
|
||||
// 系统用户创建用户组visible
|
||||
const systemUserGroupVisible = ref(false);
|
||||
// 组织用户创建用户组visible
|
||||
const orgUserGroupVisible = ref(false);
|
||||
// 项目用户创建用户组visible
|
||||
const projectUserGroupVisible = ref(false);
|
||||
|
||||
// 系统用户组Toggle
|
||||
const systemToggle = ref(true);
|
||||
// 组织用户组Toggle
|
||||
const orgToggle = ref(true);
|
||||
// 项目用户组Toggle
|
||||
const projectToggle = ref(true);
|
||||
|
||||
// 系统用户组列表
|
||||
const systemUserGroupList = computed(() => {
|
||||
return userGroupList.value.filter((ele) => ele.type === 'SYSTEM');
|
||||
});
|
||||
// 组织用户组列表
|
||||
const orgUserGroupList = computed(() => {
|
||||
return userGroupList.value.filter((ele) => ele.type === 'ORGANIZATION');
|
||||
});
|
||||
// 项目用户组列表
|
||||
const projectUserGroupList = computed(() => {
|
||||
return userGroupList.value.filter((ele) => ele.type === 'PROJECT');
|
||||
});
|
||||
|
||||
const createSystemUGActionItem: ActionsItem[] = [
|
||||
{ label: 'system.userGroup.addSysUserGroup', eventTag: 'createUserGroup' },
|
||||
];
|
||||
const createOrgUGActionItem: ActionsItem[] = [
|
||||
{ label: 'system.userGroup.addOrgUserGroup', eventTag: 'createUserGroup' },
|
||||
];
|
||||
const createProjectUGActionItem: ActionsItem[] = [
|
||||
{ label: 'system.userGroup.addProjectUserGroup', eventTag: 'createUserGroup' },
|
||||
];
|
||||
|
||||
const addMemberActionItem: ActionsItem[] = [{ label: 'system.userGroup.addMember', eventTag: 'addMember' }];
|
||||
const moreAction: ActionsItem[] = [
|
||||
{
|
||||
label: 'system.userGroup.rename',
|
||||
danger: false,
|
||||
eventTag: 'rename',
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
},
|
||||
{
|
||||
label: 'system.userGroup.delete',
|
||||
danger: true,
|
||||
eventTag: 'delete',
|
||||
},
|
||||
];
|
||||
|
||||
// 点击用户组列表
|
||||
const handleListItemClick = (element: UserGroupItem) => {
|
||||
const { id, name, type, internal } = element;
|
||||
currentId.value = id;
|
||||
store.setInfo({
|
||||
currentName: name,
|
||||
currentTitle: type,
|
||||
currentId: id,
|
||||
currentType: type,
|
||||
currentInternal: internal,
|
||||
});
|
||||
};
|
||||
|
||||
// 用户组数据初始化
|
||||
const initData = async (id?: string) => {
|
||||
try {
|
||||
const res = await getUserGroupList();
|
||||
if (res.length > 0) {
|
||||
userGroupList.value = res;
|
||||
let tmpItem = res[0];
|
||||
if (id) {
|
||||
tmpItem = res.find((i) => i.id === id) || res[0];
|
||||
}
|
||||
handleListItemClick(tmpItem);
|
||||
// 弹窗赋值
|
||||
const tmpObj: PopVisible = {};
|
||||
res.forEach((element) => {
|
||||
tmpObj[element.id] = { visible: false, authScope: element.type, defaultName: '', id: element.id };
|
||||
});
|
||||
popVisible.value = tmpObj;
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
// 点击更多操作
|
||||
const handleMoreAction = (item: ActionsItem, id: string, authScope: AuthScopeType) => {
|
||||
if (item.eventTag === 'rename') {
|
||||
const tmpObj = userGroupList.value.filter((ele) => ele.id === id)[0];
|
||||
const visibleItem: PopVisibleItem = { visible: true, authScope, defaultName: tmpObj.name, id };
|
||||
popVisible.value[id] = visibleItem;
|
||||
}
|
||||
if (item.eventTag === 'delete') {
|
||||
openModal({
|
||||
type: 'error',
|
||||
title: t('system.userGroup.isDeleteUserGroup', { name: characterLimit(store.currentName) }),
|
||||
content: t('system.userGroup.beforeDeleteUserGroup'),
|
||||
okText: t('system.userGroup.confirmDelete'),
|
||||
cancelText: t('system.userGroup.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'danger',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await deleteUserGroup(id);
|
||||
Message.success(t('system.user.deleteUserSuccess'));
|
||||
initData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 点击添加成员
|
||||
const handleAddMember = () => {
|
||||
userModalVisible.value = true;
|
||||
};
|
||||
|
||||
function enterData(eve: Event) {
|
||||
if (!(eve.target as HTMLInputElement).value) {
|
||||
initData();
|
||||
return;
|
||||
}
|
||||
const keyword = (eve.target as HTMLInputElement).value;
|
||||
const tmpArr = userGroupList.value.filter((ele) => ele.name.includes(keyword));
|
||||
userGroupList.value = tmpArr;
|
||||
}
|
||||
function searchData(value: string) {
|
||||
if (!value) {
|
||||
initData();
|
||||
return;
|
||||
}
|
||||
const keyword = value;
|
||||
const tmpArr = userGroupList.value.filter((ele) => ele.name.includes(keyword));
|
||||
userGroupList.value = tmpArr;
|
||||
}
|
||||
const handleCreateUserGroup = (id: string) => {
|
||||
initData(id);
|
||||
};
|
||||
const handleRenameCancel = (element: UserGroupItem, id?: string) => {
|
||||
if (id) {
|
||||
initData(id);
|
||||
}
|
||||
popVisible.value[element.id].visible = false;
|
||||
};
|
||||
onMounted(() => {
|
||||
initData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.icon-increase {
|
||||
background-color: rgb(var(--primary-7));
|
||||
}
|
||||
.icon-button {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
color: rgb(var(--primary-7));
|
||||
}
|
||||
.icon-button:hover {
|
||||
background-color: rgb(var(--primary-9));
|
||||
}
|
||||
.v-enter-active,
|
||||
.v-leave-active {
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
.v-enter-from,
|
||||
.v-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
|
@ -1,142 +0,0 @@
|
|||
<template>
|
||||
<a-popconfirm
|
||||
:popup-visible="renameVisible"
|
||||
:ok-text="t('system.userGroup.confirm')"
|
||||
:cancel-text="t('system.userGroup.cancel')"
|
||||
:ok-loading="props.loading"
|
||||
:cancel-button-props="{ disabled: loading }"
|
||||
class="w-[276px]"
|
||||
position="bl"
|
||||
@before-ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
@popup-visible-change="() => (form.name = '')"
|
||||
>
|
||||
<template #icon>{{ null }}</template>
|
||||
<template #content>
|
||||
<a-form ref="formRef" :model="form" :label-col-props="{ span: 0 }" :wrapper-col-props="{ span: 24 }">
|
||||
<a-form-item>
|
||||
<div class="title">{{ message.title }}</div>
|
||||
</a-form-item>
|
||||
<a-form-item field="name" :rules="[{ validator: validateName }]">
|
||||
<a-input v-if="props.type === 'rename'" v-model="form.name" class="w-[234px]" />
|
||||
<a-select v-else v-model="form.name" class="w-[176px]">
|
||||
<a-option value="SYSTEM">{{ t('system.userGroup.SYSTEM') }}</a-option>
|
||||
<a-option value="ORGANIZATION">{{ t('system.userGroup.ORGANIZATION') }}</a-option>
|
||||
<a-option value="PROJECT">{{ t('system.userGroup.PROJECT') }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { watchEffect, ref, computed, onUnmounted } from 'vue';
|
||||
import { CustomMoreActionItem, RenameType, UserGroupItem } from '@/models/setting/usergroup';
|
||||
import { ValidatedError } from '@arco-design/web-vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const formRef = ref();
|
||||
const form = ref({
|
||||
name: '',
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
defaultName: string;
|
||||
type: RenameType;
|
||||
list: UserGroupItem[];
|
||||
loading: boolean;
|
||||
}>();
|
||||
|
||||
const validateName = (value: string | undefined, callback: (error?: string) => void) => {
|
||||
if (props.type === 'rename') {
|
||||
if (value === undefined || value === '') {
|
||||
callback(t('system.userGroup.userGroupNameIsNotNone'));
|
||||
} else {
|
||||
if (value === props.defaultName) {
|
||||
callback();
|
||||
} else {
|
||||
const isExist = props.list.some((item) => item.name === value);
|
||||
if (isExist) {
|
||||
callback(t('system.userGroup.userGroupNameIsExist', { name: value }));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
} else if (value === '') {
|
||||
callback(t('system.userGroup.userGroupAuthScopeIsNotNone'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const message = computed(() => {
|
||||
if (props.type === 'rename') {
|
||||
return {
|
||||
rule: t('system.userGroup.userGroupNameIsNotNone'),
|
||||
title: t('system.userGroup.rename'),
|
||||
};
|
||||
}
|
||||
return {
|
||||
rule: t('system.userGroup.userGroupAuthScopeIsNotNone'),
|
||||
title: t('system.userGroup.changeAuthScope'),
|
||||
};
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'submit', value: CustomMoreActionItem): Promise<void>;
|
||||
(e: 'cancel'): void;
|
||||
}>();
|
||||
|
||||
const renameVisible = ref(props.visible);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value.validate(async (errors: undefined | Record<string, ValidatedError>) => {
|
||||
if (!errors) {
|
||||
emit('submit', { eventKey: props.type, name: form.value.name });
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return false;
|
||||
};
|
||||
const handleCancel = () => {
|
||||
form.value.name = '';
|
||||
emit('cancel');
|
||||
};
|
||||
watchEffect(() => {
|
||||
renameVisible.value = props.visible;
|
||||
form.value.name = props.defaultName;
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
handleCancel();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.title {
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
.error-6 {
|
||||
color: rgb(var(--danger-6));
|
||||
&:hover {
|
||||
color: rgb(var(--danger-6));
|
||||
}
|
||||
}
|
||||
:deep(.arco-form-item) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.button-icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
color: rgb(var(--primary-5));
|
||||
background-color: rgb(var(--primary-9));
|
||||
}
|
||||
</style>
|
||||
@/models/setting/usergroup
|
|
@ -52,7 +52,7 @@
|
|||
import { useI18n } from '@/hooks/useI18n';
|
||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||
import useUserGroupStore from '@/store/modules/setting/system/usergroup';
|
||||
import UserGroupLeft from './components/index.vue';
|
||||
import UserGroupLeft from './components/ms-usergroup-list.vue';
|
||||
import UserTable from './components/userTable.vue';
|
||||
import AuthTable from './components/authTable.vue';
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
|
|
|
@ -4,11 +4,14 @@ export default {
|
|||
addUserGroupSuccess: 'Add user group success',
|
||||
updateUserGroupSuccess: 'Update user group success',
|
||||
searchHolder: 'Please input user group name',
|
||||
systemUserGroup: 'System user group',
|
||||
inSystem: 'In system',
|
||||
customUserGroup: 'Custom user group',
|
||||
addSystemUserGroup: 'Add system user group',
|
||||
addSystemUser: 'Add system user',
|
||||
addUser: 'Add user',
|
||||
addMember: 'Add member',
|
||||
createUserGroup: 'Create user group',
|
||||
emptyUserGroup:
|
||||
'There are currently no custom user groups available. Please click "Create" or "+" above to create a user group',
|
||||
rename: 'Rename',
|
||||
|
@ -18,7 +21,6 @@ export default {
|
|||
add: 'Add',
|
||||
cancel: 'Cancel',
|
||||
create: 'Create',
|
||||
createUserGroup: 'create user group',
|
||||
userGroupName: 'User group name',
|
||||
authScope: 'Auth scope',
|
||||
auth: 'Auth',
|
||||
|
@ -58,6 +60,11 @@ export default {
|
|||
removeName: 'Confirm to remove {name} this user',
|
||||
removeTip: 'After removal, the User Group permission will be lost',
|
||||
custom: 'Custom user group',
|
||||
projectUserGroup: 'Project user group',
|
||||
orgUserGroup: 'Organization user group',
|
||||
addSysUserGroup: 'Add system user group',
|
||||
addOrgUserGroup: 'Add organization user group',
|
||||
addProjectUserGroup: 'Add project user group',
|
||||
},
|
||||
},
|
||||
permission: {
|
||||
|
|
|
@ -3,6 +3,7 @@ export default {
|
|||
userGroup: {
|
||||
addUserGroupSuccess: '添加用户组成功',
|
||||
updateUserGroupSuccess: '更新用户组成功',
|
||||
systemUserGroup: '系统用户组',
|
||||
global: '全局用户组',
|
||||
searchHolder: '请输入用户组名称',
|
||||
inSystem: '系统内置',
|
||||
|
@ -10,6 +11,7 @@ export default {
|
|||
addSystemUserGroup: '添加系统用户组',
|
||||
addSystemUser: '添加系统用户',
|
||||
addUser: '添加成员',
|
||||
addMember: '添加成员',
|
||||
emptyUserGroup: '暂无自定义用户组,请点击上方创建或 “+” 创建用户组',
|
||||
rename: '重命名',
|
||||
changeAuthScope: '修改权限范围',
|
||||
|
@ -57,6 +59,11 @@ export default {
|
|||
removeName: '确认移除 {name} 这个用户吗',
|
||||
removeTip: '移除后,将失去用户组权限',
|
||||
custom: '自定义用户组',
|
||||
projectUserGroup: '项目用户组',
|
||||
orgUserGroup: '组织用户组',
|
||||
addSysUserGroup: '添加系统用户组',
|
||||
addOrgUserGroup: '添加组织用户组',
|
||||
addProjectUserGroup: '添加项目用户组',
|
||||
},
|
||||
},
|
||||
permission: {
|
||||
|
|
Loading…
Reference in New Issue