feat(项目管理): 用户组静态页面
This commit is contained in:
parent
ae5839b653
commit
65b1360b46
|
@ -0,0 +1,61 @@
|
||||||
|
import MSR from '@/api/http/index';
|
||||||
|
import * as ugUrl from '@/api/requrls/project-management/usergroup';
|
||||||
|
import { TableQueryParams, CommonList } from '@/models/common';
|
||||||
|
import {
|
||||||
|
UserGroupItem,
|
||||||
|
SystemUserGroupParams,
|
||||||
|
UserGroupAuthSetting,
|
||||||
|
SaveGlobalUSettingData,
|
||||||
|
UserTableItem,
|
||||||
|
} from '@/models/setting/usergroup';
|
||||||
|
|
||||||
|
// 项目-创建或修改用户组
|
||||||
|
export function updateOrAddUserGroup(data: SystemUserGroupParams) {
|
||||||
|
return MSR.post<UserGroupItem>({
|
||||||
|
url: data.id ? ugUrl.updateUrl : ugUrl.addUrl,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目-获取用户组列表
|
||||||
|
export function postUserGroupList(data: TableQueryParams) {
|
||||||
|
return MSR.post<CommonList<UserGroupItem>>({ url: ugUrl.listUserGroupUrl, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目-删除用户组
|
||||||
|
export function deleteUserGroup(id: string) {
|
||||||
|
return MSR.get<string>({ url: `${ugUrl.deleteUrl}${id}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目-获取需要关联的用户选项
|
||||||
|
export function getUserGroupOption(organizationId: string, roleId: string, keyword: string) {
|
||||||
|
return MSR.get<UserTableItem[]>({
|
||||||
|
url: `${ugUrl.getMemberOptionsUrl}${organizationId}/${roleId}`,
|
||||||
|
params: { keyword },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目-编辑用户组对应的权限配置
|
||||||
|
export function saveUSetting(data: SaveGlobalUSettingData) {
|
||||||
|
return MSR.post<UserGroupAuthSetting[]>({ url: ugUrl.updatePermissionUrl, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目-获取用户组对应的权限
|
||||||
|
export function postAuthByUserGroup(data: TableQueryParams) {
|
||||||
|
return MSR.post<CommonList<UserTableItem[]>>({ url: ugUrl.listPermissionUrl, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目-获取用户组对应的用户列表
|
||||||
|
export function postUserByUserGroup(data: TableQueryParams) {
|
||||||
|
return MSR.post<CommonList<UserTableItem[]>>({ url: ugUrl.listMemberUrl, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目-删除用户组对应的用户
|
||||||
|
export function deleteUserFromUserGroup(data: { userRoleId: string; userIds: string[]; organizationId: string }) {
|
||||||
|
return MSR.post<CommonList<UserTableItem[]>>({ url: ugUrl.removeMemberUrl, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目-添加用户到用户组
|
||||||
|
export function addUserToUserGroup(data: { userRoleId: string; userIds: string[]; organizationId: string }) {
|
||||||
|
return MSR.post<string>({ url: ugUrl.addMemberUrl, data });
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
export const updateUrl = '/user/role/project/update';
|
||||||
|
export const addUrl = '/user/role/project/add';
|
||||||
|
export const removeMemberUrl = '/user/role/project/remove-member';
|
||||||
|
export const updatePermissionUrl = '/user/role/project/permission/update';
|
||||||
|
export const listMemberUrl = '/user/role/project/list-member';
|
||||||
|
export const addMemberUrl = '/user/role/project/add-member';
|
||||||
|
export const listPermissionUrl = '/user/role/project/permission/setting/';
|
||||||
|
export const listUserGroupUrl = '/user/role/project/list/';
|
||||||
|
export const getMemberOptionsUrl = '/api/project-management/usergroup/getMemberOptions';
|
||||||
|
export const deleteUrl = '/api/project-management/usergroup/delete';
|
|
@ -57,6 +57,7 @@
|
||||||
{
|
{
|
||||||
title: 'system.userGroup.operation',
|
title: 'system.userGroup.operation',
|
||||||
slotName: 'action',
|
slotName: 'action',
|
||||||
|
dataIndex: 'operation',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
width: 200,
|
width: 200,
|
||||||
},
|
},
|
||||||
|
|
|
@ -103,7 +103,12 @@
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<div class="edit-icon">
|
<div class="edit-icon">
|
||||||
<MsIcon
|
<MsIcon
|
||||||
v-if="item.editType && editActiveKey !== `${item.dataIndex}${rowIndex}` && !record.deleted"
|
v-if="
|
||||||
|
item.editType &&
|
||||||
|
editActiveKey !== `${item.dataIndex}${rowIndex}` &&
|
||||||
|
!record.deleted &&
|
||||||
|
!record.internal
|
||||||
|
"
|
||||||
class="ml-2 cursor-pointer"
|
class="ml-2 cursor-pointer"
|
||||||
:class="{ 'ms-table-edit-active': editActiveKey === rowIndex }"
|
:class="{ 'ms-table-edit-active': editActiveKey === rowIndex }"
|
||||||
type="icon-icon_edit_outlined"
|
type="icon-icon_edit_outlined"
|
||||||
|
|
|
@ -17,8 +17,6 @@ export interface MsTableColumnData extends TableColumnData {
|
||||||
showDrag?: boolean;
|
showDrag?: boolean;
|
||||||
// 是否展示在表格上
|
// 是否展示在表格上
|
||||||
showInTable?: boolean;
|
showInTable?: boolean;
|
||||||
// 是否可编辑
|
|
||||||
editable?: boolean;
|
|
||||||
// 是否展示tooltip
|
// 是否展示tooltip
|
||||||
showTooltip?: boolean;
|
showTooltip?: boolean;
|
||||||
// 启用Title 默认为启用
|
// 启用Title 默认为启用
|
||||||
|
|
|
@ -272,8 +272,10 @@ export default function useTableProps<T>(
|
||||||
});
|
});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
|
// TODO 等UI出图,表格设置里加入分页配置等操作
|
||||||
const { heightUsed } = propsRes.value;
|
const { heightUsed } = propsRes.value;
|
||||||
propsRes.value.scroll = { ...propsRes.value.scroll, y: appStore.innerHeight - (heightUsed || 294) };
|
const currentY = appStore.innerHeight - (heightUsed || 294);
|
||||||
|
propsRes.value.scroll = { ...propsRes.value.scroll, y: currentY };
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -15,6 +15,7 @@ export enum TableKeyEnum {
|
||||||
SYSTEM_PROJECT = 'systemProject',
|
SYSTEM_PROJECT = 'systemProject',
|
||||||
SYSTEM_LOG = 'systemLog',
|
SYSTEM_LOG = 'systemLog',
|
||||||
PROJECT_MEMBER = 'projectMember',
|
PROJECT_MEMBER = 'projectMember',
|
||||||
|
PROJECT_USER_GROUP = 'projectUserGroup',
|
||||||
ORGANIZATION_MEMBER = 'organizationMember',
|
ORGANIZATION_MEMBER = 'organizationMember',
|
||||||
ORGANIZATION_PROJECT = 'organizationProject',
|
ORGANIZATION_PROJECT = 'organizationProject',
|
||||||
ORGANIZATION_PROJECT_USER_DRAWER = 'organizationProjectUserDrawer',
|
ORGANIZATION_PROJECT_USER_DRAWER = 'organizationProjectUserDrawer',
|
||||||
|
|
|
@ -48,4 +48,6 @@ export default {
|
||||||
'common.leave': 'Leave',
|
'common.leave': 'Leave',
|
||||||
'common.rename': 'Rename',
|
'common.rename': 'Rename',
|
||||||
'common.noData': 'No data',
|
'common.noData': 'No data',
|
||||||
|
'common.internal': 'Internal',
|
||||||
|
'common.custom': 'Custom',
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,4 +50,6 @@ export default {
|
||||||
'common.leave': '离开',
|
'common.leave': '离开',
|
||||||
'common.rename': '重命名',
|
'common.rename': '重命名',
|
||||||
'common.noData': '暂无数据',
|
'common.noData': '暂无数据',
|
||||||
|
'common.internal': '内部',
|
||||||
|
'common.custom': '自定义',
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="currentVisible"
|
||||||
|
title-align="start"
|
||||||
|
class="ms-modal-form ms-modal-medium"
|
||||||
|
:ok-text="t('system.organization.addMember')"
|
||||||
|
unmount-on-close
|
||||||
|
@cancel="handleCancel(false)"
|
||||||
|
>
|
||||||
|
<template #title> {{ t('system.organization.addMember') }} </template>
|
||||||
|
<div class="form">
|
||||||
|
<a-form ref="formRef" :model="form" size="large" :style="{ width: '600px' }" layout="vertical">
|
||||||
|
<a-form-item
|
||||||
|
field="name"
|
||||||
|
:label="t('system.organization.member')"
|
||||||
|
:rules="[{ required: true, message: t('system.organization.addMemberRequired') }]"
|
||||||
|
>
|
||||||
|
<MsUserSelector
|
||||||
|
v-model:value="form.name"
|
||||||
|
:type="UserRequesetTypeEnum.ORGANIZATION_PROJECT"
|
||||||
|
:load-option-params="{ organizationId: currentOrgId, projectId: props.projectId }"
|
||||||
|
disabled-key="memberFlag"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<a-button type="secondary" :loading="loading" @click="handleCancel(false)">
|
||||||
|
{{ t('common.cancel') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="primary" :loading="loading" :disabled="form.name.length === 0" @click="handleAddMember">
|
||||||
|
{{ t('common.add') }}
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { reactive, ref, watchEffect, onUnmounted, computed } from 'vue';
|
||||||
|
import { addProjectMemberByOrg } from '@/api/modules/setting/organizationAndProject';
|
||||||
|
import { Message, type FormInstance, type ValidatedError } from '@arco-design/web-vue';
|
||||||
|
import MsUserSelector from '@/components/business/ms-user-selector/index.vue';
|
||||||
|
import { UserRequesetTypeEnum } from '@/components/business/ms-user-selector/utils';
|
||||||
|
import { useAppStore } from '@/store';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const props = defineProps<{
|
||||||
|
visible: boolean;
|
||||||
|
projectId?: string;
|
||||||
|
}>();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
const currentOrgId = computed(() => appStore.currentOrgId);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'cancel', shouldSearch: boolean): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const currentVisible = ref(props.visible);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
name: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
currentVisible.value = props.visible;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleCancel = (shouldSearch: boolean) => {
|
||||||
|
form.name = [];
|
||||||
|
emit('cancel', shouldSearch);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddMember = () => {
|
||||||
|
formRef.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => {
|
||||||
|
if (errors) {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
const { projectId } = props;
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
await addProjectMemberByOrg({ userIds: form.name, projectId });
|
||||||
|
Message.success(t('system.organization.addSuccess'));
|
||||||
|
handleCancel(true);
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
form.name = [];
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.option-name {
|
||||||
|
color: var(--color-text-1);
|
||||||
|
}
|
||||||
|
.option-email {
|
||||||
|
color: var(--color-text-4);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,7 @@
|
||||||
|
export default {
|
||||||
|
'project.usergroup.add': 'Add User Group',
|
||||||
|
'project.usergroup.searchUser': 'Search User',
|
||||||
|
'project.usergroup.name': 'User Group Name',
|
||||||
|
'project.usergroup.memberCount': 'Member Count',
|
||||||
|
'project.userGroup.viewAuth': 'View Auth',
|
||||||
|
};
|
|
@ -0,0 +1,7 @@
|
||||||
|
export default {
|
||||||
|
'project.userGroup.add': '添加用户组',
|
||||||
|
'project.userGroup.searchUser': '通过名称搜索',
|
||||||
|
'project.userGroup.name': '用户组名称',
|
||||||
|
'project.userGroup.memberCount': '成员数',
|
||||||
|
'project.userGroup.viewAuth': '查看权限',
|
||||||
|
};
|
|
@ -1,9 +1,157 @@
|
||||||
<template>
|
<template>
|
||||||
<div> 用户组 waiting for development</div>
|
<div class="flex flex-row items-center justify-between">
|
||||||
|
<a-button type="primary" @click="addUserGroup">{{ t('project.userGroup.add') }}</a-button>
|
||||||
|
<a-input-search
|
||||||
|
v-model="keyword"
|
||||||
|
:placeholder="t('project.userGroup.searchUser')"
|
||||||
|
class="w-[240px]"
|
||||||
|
allow-clear
|
||||||
|
@press-enter="fetchData"
|
||||||
|
@search="fetchData"
|
||||||
|
></a-input-search>
|
||||||
|
</div>
|
||||||
|
<MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent">
|
||||||
|
<template #name="{ record }">
|
||||||
|
<div class="flex flex-row items-center gap-[4px]">
|
||||||
|
<div class="one-text-line">{{ record.name }}</div>
|
||||||
|
<div class="ml-1 text-[var(--color-text-4)]">{{
|
||||||
|
`(${record.internal ? t('common.internal') : t('common.custom')})`
|
||||||
|
}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #memberCount="{ record }">
|
||||||
|
<span class="cursor-pointer text-[rgb(var(--primary-5))]" @click="showUserDrawer(record)">{{
|
||||||
|
record.memberCount
|
||||||
|
}}</span>
|
||||||
|
</template>
|
||||||
|
<template #operation="{ record }">
|
||||||
|
<MsButton @click="showAuthDrawer(record)">{{ t('project.userGroup.viewAuth') }}</MsButton>
|
||||||
|
<a-divider />
|
||||||
|
<MsButton @click="handleDelete(record)">{{ t('common.delete') }}</MsButton>
|
||||||
|
</template>
|
||||||
|
</MsBaseTable>
|
||||||
|
<a-drawer
|
||||||
|
:width="680"
|
||||||
|
:visible="authVisible"
|
||||||
|
unmount-on-close
|
||||||
|
:footer="false"
|
||||||
|
:title="t('system.organization.addMember')"
|
||||||
|
:mask="false"
|
||||||
|
class="ms-drawer-no-mask"
|
||||||
|
@cancel="authVisible = false"
|
||||||
|
>
|
||||||
|
<AuthTable :current="currentItem" />
|
||||||
|
</a-drawer>
|
||||||
|
<UserDrawer
|
||||||
|
:visible="userVisible"
|
||||||
|
:rganization-id="appStore.currentOrgId"
|
||||||
|
:project-id="appStore.currentProjectId"
|
||||||
|
:user-group-id="currentItem.id"
|
||||||
|
@cancel="userVisible = false"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
|
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
import AuthTable from '@/components/business/ms-user-group-comp/authTable.vue';
|
||||||
|
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
|
import { useTableStore, useAppStore } from '@/store';
|
||||||
|
import { UserGroupItem, CurrentUserGroupItem } from '@/models/setting/usergroup';
|
||||||
|
import { AuthScopeEnum } from '@/enums/commonEnum';
|
||||||
|
import { postUserGroupList, deleteUserGroup } from '@/api/modules/project-management/usergroup';
|
||||||
|
import UserDrawer from './userDrawer.vue';
|
||||||
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
|
import useModal from '@/hooks/useModal';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
const { openDeleteModal } = useModal();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
const tableStore = useTableStore();
|
||||||
|
|
||||||
|
const keyword = ref('');
|
||||||
|
const currentItem = ref<CurrentUserGroupItem>({
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
type: AuthScopeEnum.PROJECT,
|
||||||
|
internal: true,
|
||||||
|
});
|
||||||
|
const authVisible = ref(false);
|
||||||
|
const userVisible = ref(false);
|
||||||
|
const addUserGroupVisible = ref(false);
|
||||||
|
|
||||||
|
const userGroupUsercolumns: MsTableColumn = [
|
||||||
|
{
|
||||||
|
title: 'project.userGroup.name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
slotName: 'name',
|
||||||
|
showTooltip: true,
|
||||||
|
editType: ColumnEditTypeEnum.INPUT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'project.userGroup.memberCount',
|
||||||
|
slotName: 'memberCount',
|
||||||
|
showDrag: true,
|
||||||
|
dataIndex: 'memberCount',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'common.operation',
|
||||||
|
slotName: 'operation',
|
||||||
|
dataIndex: 'operation',
|
||||||
|
fixed: 'right',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
tableStore.initColumn(TableKeyEnum.PROJECT_USER_GROUP, userGroupUsercolumns, 'drawer');
|
||||||
|
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(postUserGroupList, {
|
||||||
|
tableKey: TableKeyEnum.PROJECT_USER_GROUP,
|
||||||
|
selectable: false,
|
||||||
|
noDisable: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
setKeyword(keyword.value);
|
||||||
|
await loadList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const addUserGroup = () => {
|
||||||
|
addUserGroupVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const showAuthDrawer = (record: UserGroupItem) => {
|
||||||
|
currentItem.value = record;
|
||||||
|
authVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const showUserDrawer = (record: UserGroupItem) => {
|
||||||
|
currentItem.value = record;
|
||||||
|
userVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = (record: UserGroupItem) => {
|
||||||
|
openDeleteModal({
|
||||||
|
title: t('system.organization.deleteName', { name: record.name }),
|
||||||
|
content: t('system.organization.deleteTip'),
|
||||||
|
onBeforeOk: async () => {
|
||||||
|
try {
|
||||||
|
await deleteUserGroup(record.id);
|
||||||
|
Message.success(t('common.deleteSuccess'));
|
||||||
|
fetchData();
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
setLoadListParams({ projectId: appStore.currentProjectId });
|
||||||
|
fetchData();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
<template>
|
||||||
|
<a-drawer
|
||||||
|
:width="680"
|
||||||
|
:visible="currentVisible"
|
||||||
|
unmount-on-close
|
||||||
|
:footer="false"
|
||||||
|
:title="t('system.organization.addMember')"
|
||||||
|
:mask="false"
|
||||||
|
class="ms-drawer-no-mask"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div class="flex flex-row justify-between">
|
||||||
|
<a-button type="primary" @click="handleAddMember">
|
||||||
|
{{ t('system.organization.addMember') }}
|
||||||
|
</a-button>
|
||||||
|
<a-input-search
|
||||||
|
v-model:model-value="keyword"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('system.user.searchUser')"
|
||||||
|
class="w-[230px]"
|
||||||
|
@search="searchUser"
|
||||||
|
@press-enter="searchUser"
|
||||||
|
></a-input-search>
|
||||||
|
</div>
|
||||||
|
<ms-base-table class="mt-[16px]" v-bind="propsRes" v-on="propsEvent">
|
||||||
|
<template #name="{ record }">
|
||||||
|
<span>{{ record.name }}</span>
|
||||||
|
<span v-if="record.adminFlag" class="ml-[4px] text-[var(--color-text-4)]">{{
|
||||||
|
`(${t('common.admin')})`
|
||||||
|
}}</span>
|
||||||
|
</template>
|
||||||
|
<template #operation="{ record }">
|
||||||
|
<MsRemoveButton
|
||||||
|
:title="t('system.organization.removeName', { name: record.name })"
|
||||||
|
:sub-title-tip="t('system.organization.removeTip')"
|
||||||
|
@ok="handleRemove(record)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</ms-base-table>
|
||||||
|
</div>
|
||||||
|
</a-drawer>
|
||||||
|
<AddUserModal
|
||||||
|
:project-id="props.projectId"
|
||||||
|
:organization-id="props.organizationId"
|
||||||
|
:visible="userVisible"
|
||||||
|
@cancel="handleHideUserModal"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { postProjectMemberByProjectId, deleteProjectMemberByOrg } from '@/api/modules/setting/organizationAndProject';
|
||||||
|
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { watch, ref } from 'vue';
|
||||||
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
|
import AddUserModal from './addUserModal.vue';
|
||||||
|
import { TableData, Message } from '@arco-design/web-vue';
|
||||||
|
import MsRemoveButton from '@/components/business/ms-remove-button/MsRemoveButton.vue';
|
||||||
|
|
||||||
|
export interface projectDrawerProps {
|
||||||
|
visible: boolean;
|
||||||
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
|
}
|
||||||
|
const { t } = useI18n();
|
||||||
|
const props = defineProps<projectDrawerProps>();
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'cancel'): void;
|
||||||
|
(e: 'requestFetchData'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const currentVisible = ref(props.visible);
|
||||||
|
|
||||||
|
const userVisible = ref(false);
|
||||||
|
|
||||||
|
const keyword = ref('');
|
||||||
|
|
||||||
|
const projectColumn: MsTableColumn = [
|
||||||
|
{
|
||||||
|
title: 'system.organization.userName',
|
||||||
|
slotName: 'name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
showTooltip: true,
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'system.organization.email',
|
||||||
|
dataIndex: 'email',
|
||||||
|
showTooltip: true,
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'system.organization.phone',
|
||||||
|
dataIndex: 'phone',
|
||||||
|
},
|
||||||
|
{ title: 'system.organization.operation', slotName: 'operation' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(postProjectMemberByProjectId, {
|
||||||
|
heightUsed: 240,
|
||||||
|
columns: projectColumn,
|
||||||
|
scroll: { x: '100%' },
|
||||||
|
selectable: false,
|
||||||
|
noDisable: false,
|
||||||
|
pageSimple: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
async function searchUser() {
|
||||||
|
setKeyword(keyword.value);
|
||||||
|
await loadList();
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('cancel');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
await loadList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddMember = () => {
|
||||||
|
userVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleHideUserModal = (shouldSearch: boolean) => {
|
||||||
|
userVisible.value = false;
|
||||||
|
if (shouldSearch) {
|
||||||
|
fetchData();
|
||||||
|
emit('requestFetchData');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemove = async (record: TableData) => {
|
||||||
|
try {
|
||||||
|
if (props.projectId) {
|
||||||
|
await deleteProjectMemberByOrg(props.projectId, record.id);
|
||||||
|
}
|
||||||
|
Message.success(t('common.removeSuccess'));
|
||||||
|
fetchData();
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
watch(
|
||||||
|
() => props.projectId,
|
||||||
|
() => {
|
||||||
|
setLoadListParams({ projectId: props.projectId });
|
||||||
|
fetchData();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(visible) => {
|
||||||
|
currentVisible.value = visible;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
:deep(.custom-height) {
|
||||||
|
height: 100vh !important;
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -25,7 +25,9 @@
|
||||||
<MsUserAdminDiv :is-admin="record.projectCreateUserIsAdmin" :name="record.createUser" />
|
<MsUserAdminDiv :is-admin="record.projectCreateUserIsAdmin" :name="record.createUser" />
|
||||||
</template>
|
</template>
|
||||||
<template #memberCount="{ record }">
|
<template #memberCount="{ record }">
|
||||||
<span class="primary-color" @click="showUserDrawer(record)">{{ record.memberCount }}</span>
|
<span class="cursor-pointer text-[rgb(var(--primary-5))]" @click="showUserDrawer(record)">{{
|
||||||
|
record.memberCount
|
||||||
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #operation="{ record }">
|
<template #operation="{ record }">
|
||||||
<template v-if="record.deleted">
|
<template v-if="record.deleted">
|
||||||
|
@ -313,10 +315,3 @@
|
||||||
fetchData();
|
fetchData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.primary-color {
|
|
||||||
color: rgb(var(--primary-5));
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
Loading…
Reference in New Issue