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

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

@ -90,6 +90,7 @@ export {
} from './manager/ui';
// model
export * as model from './model/__all__';
export { fetchAvailableServices } from './model/common';
export { fetchGlobalConfig } from './model/config';
export {
@ -118,6 +119,10 @@ export {
createGroupPanel,
modifyGroupPanel,
deleteGroupPanel,
createGroupRole,
deleteGroupRole,
updateGroupRoleName,
updateGroupRolePermission,
} from './model/group';
export type {
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,
});
}
/**
*
* @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,
} from '@/components/FullModal/Field';
import { IconBtn } from '@/components/IconBtn';
import { Loading } from '@/components/Loading';
import { PillTabPane, PillTabs } from '@/components/PillTabs';
import { UserListItem } from '@/components/UserListItem';
import { Button, Input } from 'antd';
import React, { useCallback, useMemo, useState } from 'react';
import { Icon } from 'tailchat-design';
import { t, useGroupInfo, useSearch, useUserInfoList } from 'tailchat-shared';
import { permissionList } from './const';
import { PermissionItem } from './PermissionItem';
import { RoleItem } from './RoleItem';
import { useModifyPermission } from './useModifyPermission';
const permissionList = [
{
key: 'core.message',
title: t('发送消息'),
desc: t('允许成员在文字频道发送消息'),
default: true,
},
];
import { useRoleActions } from './useRoleActions';
interface GroupPermissionProps {
groupId: string;
@ -43,115 +37,130 @@ export const GroupRole: React.FC<GroupPermissionProps> = React.memo((props) => {
});
const currentRoleInfo = useMemo(
() => roles.find((r) => r._id === roleId),
[roleId]
[roles, roleId]
);
const currentRolePermissions = useMemo(
() => currentRoleInfo?.permissions ?? [],
[roleId]
[currentRoleInfo]
);
const { isEditing, editingPermission, handleSwitchPermission } =
useModifyPermission(currentRolePermissions);
const handleAddMember = useCallback(() => {}, []);
const {
loading,
handleCreateRole,
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) => {
console.log('text', text);
const handleResetPermission = useCallback(() => {
setEditingPermission(
permissionList.filter((p) => p.default === true).map((p) => p.key)
);
}, []);
return (
<div className="flex h-full">
<div className="pr-2 mr-2 w-40 border-r border-white border-opacity-20">
{/* 角色列表 */}
<RoleItem active={roleId === ''} onClick={() => setRoleId('')}>
{t('所有人')}
</RoleItem>
{roles.map((r) => (
<RoleItem
key={r._id}
active={roleId === r._id}
onClick={() => setRoleId(r._id)}
>
{r.name}
<Loading spinning={loading}>
<div className="flex h-full">
<div className="pr-2 mr-2 w-40 border-r border-white border-opacity-20">
{/* 角色列表 */}
<RoleItem active={roleId === ''} onClick={() => setRoleId('')}>
{t('所有人')}
</RoleItem>
))}
<RoleItem active={false}>{t('添加角色')}</RoleItem>
</div>
{roles.map((r) => (
<RoleItem
key={r._id}
active={roleId === r._id}
onClick={() => setRoleId(r._id)}
>
{r.name}
</RoleItem>
))}
<div className="flex-1 overflow-y-auto">
<PillTabs>
<PillTabPane key="summary" tab="概述">
{/* 权限概述 */}
{currentRoleInfo && (
<div className="px-2">
<FullModalField
title={t('角色名称')}
value={currentRoleInfo.name}
editable={true}
renderEditor={DefaultFullModalInputEditorRender}
onSave={handleChangeRoleName}
/>
<RoleItem active={false} onClick={handleCreateRole}>
{t('添加角色')}
</RoleItem>
</div>
<div className="flex-1 overflow-y-auto">
<PillTabs defaultActiveKey="permission">
<PillTabPane key="summary" tab={t('概述')} disabled={!roleId}>
{/* 权限概述 */}
{currentRoleInfo && (
<div className="px-2">
<FullModalField
title={t('角色名称')}
value={currentRoleInfo.name}
editable={true}
renderEditor={DefaultFullModalInputEditorRender}
onSave={handleChangeRoleName}
/>
</div>
)}
</PillTabPane>
<PillTabPane key="permission" tab={t('权限')}>
<div className="mb-2 space-x-2 text-right">
<Button onClick={handleResetPermission}>
{t('重置为默认值')}
</Button>
<Button
type="primary"
disabled={!isEditing}
onClick={() => handleSavePermission(editingPermission)}
>
{t('保存')}
</Button>
</div>
)}
</PillTabPane>
<PillTabPane key="permission" tab="权限">
<div className="mb-2">
<Button onClick={handleResetPermission}>
{t('重置为默认值')}
</Button>
<Button
type="primary"
disabled={!isEditing}
onClick={handleSavePermission}
>
{t('保存')}
</Button>
</div>
{/* 权限详情 */}
{permissionList.map((p) => (
<PermissionItem
key={p.key}
title={p.title}
desc={p.desc}
checked={editingPermission.includes(p.key)}
onChange={(checked) => handleSwitchPermission(p.key, checked)}
/>
))}
</PillTabPane>
<PillTabPane key="member" tab="管理成员" disabled={!roleId}>
{/* 管理成员 */}
<div className="text-right mb-2 flex space-x-1">
<Input
placeholder={t('搜索成员')}
size="middle"
suffix={<Icon fontSize={20} color="grey" icon="mdi:magnify" />}
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
/>
{/* 权限详情 */}
{permissionList.map((p) => (
<PermissionItem
key={p.key}
title={p.title}
desc={p.desc}
checked={editingPermission.includes(p.key)}
onChange={(checked) => handleSwitchPermission(p.key, checked)}
/>
))}
</PillTabPane>
<PillTabPane key="member" tab={t('管理成员')} disabled={!roleId}>
{/* 管理成员 */}
<div className="text-right mb-2 flex space-x-1">
<Input
placeholder={t('搜索成员')}
size="middle"
suffix={
<Icon fontSize={20} color="grey" icon="mdi:magnify" />
}
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
/>
<Button type="primary" onClick={handleAddMember}>
{t('添加成员')}
</Button>
</div>
<Button type="primary" onClick={handleAddMember}>
{t('添加成员')}
</Button>
</div>
{(isSearching ? filterMembers : userInfoList).map((m) => (
<UserListItem
key={m._id}
userId={m._id}
actions={[<IconBtn key="remove" icon="mdi:close" />]}
/>
))}
</PillTabPane>
</PillTabs>
{(isSearching ? filterMembers : userInfoList).map((m) => (
<UserListItem
key={m._id}
userId={m._id}
actions={[<IconBtn key="remove" icon="mdi:close" />]}
/>
))}
</PillTabPane>
</PillTabs>
</div>
</div>
</div>
</Loading>
);
});
GroupRole.displayName = 'GroupRole';

@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import _isEqual from 'lodash/isEqual';
import _uniq from 'lodash/uniq';
import _without from 'lodash/without';
import { useAsyncFn } from 'tailchat-shared';
/**
*
@ -9,7 +10,7 @@ import _without from 'lodash/without';
export function useModifyPermission(originPermission: string[]) {
const [editingPermission, setEditingPermission] = useState<string[]>([]);
const isEditing = useMemo(
() => _isEqual(new Set(originPermission), new Set(editingPermission)),
() => !_isEqual(new Set(originPermission), new Set(editingPermission)),
[originPermission, editingPermission]
);
@ -28,5 +29,10 @@ export function useModifyPermission(originPermission: string[]) {
[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 { getUserJWT } from './utils/jwt-helper';
import _get from 'lodash/get';
import _debounce from 'lodash/debounce';
if (isDevelopment) {
import('source-ref-open-vscode');

Loading…
Cancel
Save