feat: 权限列表的创建与保存

pull/49/head
moonrailgun 3 years ago
parent 5e07b02c9c
commit 9631081b65

@ -90,6 +90,7 @@ export {
} from './manager/ui'; } from './manager/ui';
// model // model
export * as model from './model/__all__';
export { fetchAvailableServices } from './model/common'; export { fetchAvailableServices } from './model/common';
export { fetchGlobalConfig } from './model/config'; export { fetchGlobalConfig } from './model/config';
export { export {
@ -118,6 +119,10 @@ export {
createGroupPanel, createGroupPanel,
modifyGroupPanel, modifyGroupPanel,
deleteGroupPanel, deleteGroupPanel,
createGroupRole,
deleteGroupRole,
updateGroupRoleName,
updateGroupRolePermission,
} from './model/group'; } from './model/group';
export type { export type {
GroupPanel, GroupPanel,

@ -0,0 +1,8 @@
export * as common from './common';
export * as config from './config';
export * as converse from './converse';
export * as friend from './friend';
export * as group from './group';
export * as message from './message';
export * as plugin from './plugin';
export * as user from './user';

@ -250,3 +250,69 @@ export async function deleteGroupPanel(groupId: string, panelId: string) {
panelId, panelId,
}); });
} }
/**
*
* @param groupId id
* @param roleName
* @param permission
*/
export async function createGroupRole(
groupId: string,
roleName: string,
permission: string[]
) {
await request.post('/api/group/createGroupRole', {
groupId,
roleName,
permission,
});
}
/**
*
* @param groupId Id
* @param roleId Id
*/
export async function deleteGroupRole(groupId: string, roleId: string) {
await request.post('/api/group/deleteGroupRole', {
groupId,
roleId,
});
}
/**
*
* @param groupId Id
* @param roleId Id
* @param roleName
*/
export async function updateGroupRoleName(
groupId: string,
roleId: string,
roleName: string
) {
await request.post('/api/group/updateGroupRoleName', {
groupId,
roleId,
roleName,
});
}
/**
*
* @param groupId Id
* @param roleId Id
* @param permissions
*/
export async function updateGroupRolePermission(
groupId: string,
roleId: string,
permissions: string[]
) {
await request.post('/api/group/updateGroupRolePermission', {
groupId,
roleId,
permissions,
});
}

@ -0,0 +1,10 @@
import { t } from 'tailchat-shared';
export const permissionList = [
{
key: 'core.message',
title: t('发送消息'),
desc: t('允许成员在文字频道发送消息'),
default: true,
},
];

@ -3,24 +3,18 @@ import {
FullModalField, FullModalField,
} from '@/components/FullModal/Field'; } from '@/components/FullModal/Field';
import { IconBtn } from '@/components/IconBtn'; import { IconBtn } from '@/components/IconBtn';
import { Loading } from '@/components/Loading';
import { PillTabPane, PillTabs } from '@/components/PillTabs'; import { PillTabPane, PillTabs } from '@/components/PillTabs';
import { UserListItem } from '@/components/UserListItem'; import { UserListItem } from '@/components/UserListItem';
import { Button, Input } from 'antd'; import { Button, Input } from 'antd';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { Icon } from 'tailchat-design'; import { Icon } from 'tailchat-design';
import { t, useGroupInfo, useSearch, useUserInfoList } from 'tailchat-shared'; import { t, useGroupInfo, useSearch, useUserInfoList } from 'tailchat-shared';
import { permissionList } from './const';
import { PermissionItem } from './PermissionItem'; import { PermissionItem } from './PermissionItem';
import { RoleItem } from './RoleItem'; import { RoleItem } from './RoleItem';
import { useModifyPermission } from './useModifyPermission'; import { useModifyPermission } from './useModifyPermission';
import { useRoleActions } from './useRoleActions';
const permissionList = [
{
key: 'core.message',
title: t('发送消息'),
desc: t('允许成员在文字频道发送消息'),
default: true,
},
];
interface GroupPermissionProps { interface GroupPermissionProps {
groupId: string; groupId: string;
@ -43,27 +37,37 @@ export const GroupRole: React.FC<GroupPermissionProps> = React.memo((props) => {
}); });
const currentRoleInfo = useMemo( const currentRoleInfo = useMemo(
() => roles.find((r) => r._id === roleId), () => roles.find((r) => r._id === roleId),
[roleId] [roles, roleId]
); );
const currentRolePermissions = useMemo( const currentRolePermissions = useMemo(
() => currentRoleInfo?.permissions ?? [], () => currentRoleInfo?.permissions ?? [],
[roleId] [currentRoleInfo]
); );
const { isEditing, editingPermission, handleSwitchPermission } = const {
useModifyPermission(currentRolePermissions); loading,
handleCreateRole,
const handleAddMember = useCallback(() => {}, []); handleSavePermission,
handleChangeRoleName,
} = useRoleActions(groupId, roleId);
const handleResetPermission = useCallback(() => {}, []); const {
isEditing,
editingPermission,
setEditingPermission,
handleSwitchPermission,
} = useModifyPermission(currentRolePermissions);
const handleSavePermission = useCallback(() => {}, []); const handleAddMember = useCallback(() => {}, []);
const handleChangeRoleName = useCallback((text) => { const handleResetPermission = useCallback(() => {
console.log('text', text); setEditingPermission(
permissionList.filter((p) => p.default === true).map((p) => p.key)
);
}, []); }, []);
return ( return (
<Loading spinning={loading}>
<div className="flex h-full"> <div className="flex h-full">
<div className="pr-2 mr-2 w-40 border-r border-white border-opacity-20"> <div className="pr-2 mr-2 w-40 border-r border-white border-opacity-20">
{/* 角色列表 */} {/* 角色列表 */}
@ -81,12 +85,14 @@ export const GroupRole: React.FC<GroupPermissionProps> = React.memo((props) => {
</RoleItem> </RoleItem>
))} ))}
<RoleItem active={false}>{t('添加角色')}</RoleItem> <RoleItem active={false} onClick={handleCreateRole}>
{t('添加角色')}
</RoleItem>
</div> </div>
<div className="flex-1 overflow-y-auto"> <div className="flex-1 overflow-y-auto">
<PillTabs> <PillTabs defaultActiveKey="permission">
<PillTabPane key="summary" tab="概述"> <PillTabPane key="summary" tab={t('概述')} disabled={!roleId}>
{/* 权限概述 */} {/* 权限概述 */}
{currentRoleInfo && ( {currentRoleInfo && (
<div className="px-2"> <div className="px-2">
@ -100,15 +106,15 @@ export const GroupRole: React.FC<GroupPermissionProps> = React.memo((props) => {
</div> </div>
)} )}
</PillTabPane> </PillTabPane>
<PillTabPane key="permission" tab="权限"> <PillTabPane key="permission" tab={t('权限')}>
<div className="mb-2"> <div className="mb-2 space-x-2 text-right">
<Button onClick={handleResetPermission}> <Button onClick={handleResetPermission}>
{t('重置为默认值')} {t('重置为默认值')}
</Button> </Button>
<Button <Button
type="primary" type="primary"
disabled={!isEditing} disabled={!isEditing}
onClick={handleSavePermission} onClick={() => handleSavePermission(editingPermission)}
> >
{t('保存')} {t('保存')}
</Button> </Button>
@ -125,13 +131,15 @@ export const GroupRole: React.FC<GroupPermissionProps> = React.memo((props) => {
/> />
))} ))}
</PillTabPane> </PillTabPane>
<PillTabPane key="member" tab="管理成员" disabled={!roleId}> <PillTabPane key="member" tab={t('管理成员')} disabled={!roleId}>
{/* 管理成员 */} {/* 管理成员 */}
<div className="text-right mb-2 flex space-x-1"> <div className="text-right mb-2 flex space-x-1">
<Input <Input
placeholder={t('搜索成员')} placeholder={t('搜索成员')}
size="middle" size="middle"
suffix={<Icon fontSize={20} color="grey" icon="mdi:magnify" />} suffix={
<Icon fontSize={20} color="grey" icon="mdi:magnify" />
}
value={searchText} value={searchText}
onChange={(e) => setSearchText(e.target.value)} onChange={(e) => setSearchText(e.target.value)}
/> />
@ -152,6 +160,7 @@ export const GroupRole: React.FC<GroupPermissionProps> = React.memo((props) => {
</PillTabs> </PillTabs>
</div> </div>
</div> </div>
</Loading>
); );
}); });
GroupRole.displayName = 'GroupRole'; GroupRole.displayName = 'GroupRole';

@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import _isEqual from 'lodash/isEqual'; import _isEqual from 'lodash/isEqual';
import _uniq from 'lodash/uniq'; import _uniq from 'lodash/uniq';
import _without from 'lodash/without'; import _without from 'lodash/without';
import { useAsyncFn } from 'tailchat-shared';
/** /**
* *
@ -9,7 +10,7 @@ import _without from 'lodash/without';
export function useModifyPermission(originPermission: string[]) { export function useModifyPermission(originPermission: string[]) {
const [editingPermission, setEditingPermission] = useState<string[]>([]); const [editingPermission, setEditingPermission] = useState<string[]>([]);
const isEditing = useMemo( const isEditing = useMemo(
() => _isEqual(new Set(originPermission), new Set(editingPermission)), () => !_isEqual(new Set(originPermission), new Set(editingPermission)),
[originPermission, editingPermission] [originPermission, editingPermission]
); );
@ -28,5 +29,10 @@ export function useModifyPermission(originPermission: string[]) {
[editingPermission] [editingPermission]
); );
return { isEditing, editingPermission, handleSwitchPermission }; return {
isEditing,
editingPermission,
setEditingPermission,
handleSwitchPermission,
};
} }

@ -0,0 +1,34 @@
import { model, t, useAsyncRequest } from 'tailchat-shared';
import { permissionList } from './const';
export function useRoleActions(groupId: string, roleId: string) {
const [{ loading: loading1 }, handleCreateRole] =
useAsyncRequest(async () => {
await model.group.createGroupRole(
groupId,
t('新身份组'),
permissionList.filter((p) => p.default).map((p) => p.key)
);
}, [groupId]);
const [{ loading: loading2 }, handleSavePermission] = useAsyncRequest(
async (permissions: string[]) => {
await model.group.updateGroupRolePermission(groupId, roleId, permissions);
},
[groupId, roleId]
);
const [{ loading: loading3 }, handleChangeRoleName] = useAsyncRequest(
async (newRoleName: string) => {
await model.group.updateGroupRoleName(groupId, roleId, newRoleName);
},
[groupId, roleId]
);
return {
loading: loading1 || loading2 || loading3,
handleCreateRole,
handleSavePermission,
handleChangeRoleName,
};
}

@ -20,7 +20,6 @@ import {
import { getPopupContainer } from './utils/dom-helper'; import { getPopupContainer } from './utils/dom-helper';
import { getUserJWT } from './utils/jwt-helper'; import { getUserJWT } from './utils/jwt-helper';
import _get from 'lodash/get'; import _get from 'lodash/get';
import _debounce from 'lodash/debounce';
if (isDevelopment) { if (isDevelopment) {
import('source-ref-open-vscode'); import('source-ref-open-vscode');

Loading…
Cancel
Save