mirror of https://github.com/msgbyte/tailchat
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.8 KiB
TypeScript
136 lines
3.8 KiB
TypeScript
import { PermissionList } from '@/components/PermissionList';
|
|
import { Button } from 'antd';
|
|
import clsx from 'clsx';
|
|
import React, { PropsWithChildren, useMemo, useState } from 'react';
|
|
import {
|
|
ALL_PERMISSION,
|
|
getDefaultPermissionList,
|
|
GroupPanelType,
|
|
t,
|
|
useAppSelector,
|
|
useEvent,
|
|
useLazyValue,
|
|
} from 'tailchat-shared';
|
|
import { LoadingSpinner } from '@/components/LoadingSpinner';
|
|
|
|
interface AdvanceGroupPanelPermissionProps {
|
|
height?: number;
|
|
groupId: string;
|
|
panelId: string;
|
|
onChange: (
|
|
permissionMap: Record<string | typeof ALL_PERMISSION, string[]> | undefined
|
|
) => void;
|
|
}
|
|
|
|
export const AdvanceGroupPanelPermission: React.FC<AdvanceGroupPanelPermissionProps> =
|
|
React.memo((props) => {
|
|
const [selectedRoleId, setSelectedRoleId] = useState<
|
|
typeof ALL_PERMISSION | string
|
|
>(ALL_PERMISSION);
|
|
|
|
const roles = useAppSelector((state) => {
|
|
const groupInfo = state.group.groups[props.groupId];
|
|
return groupInfo.roles;
|
|
});
|
|
|
|
const panelInfo = useAppSelector((state) => {
|
|
const groupInfo = state.group.groups[props.groupId];
|
|
const panelInfo = groupInfo.panels.find((p) => p.id === props.panelId);
|
|
|
|
return panelInfo;
|
|
});
|
|
|
|
const permissionMap: Record<string | typeof ALL_PERMISSION, string[]> =
|
|
useMemo(() => {
|
|
if (!panelInfo) {
|
|
return { [ALL_PERMISSION]: getDefaultPermissionList() };
|
|
} else {
|
|
return {
|
|
[ALL_PERMISSION]:
|
|
panelInfo.fallbackPermissions ?? getDefaultPermissionList(),
|
|
...panelInfo.permissionMap,
|
|
};
|
|
}
|
|
}, [panelInfo]);
|
|
|
|
const [editPermissionMap, setEditPermissionMap] = useLazyValue(
|
|
permissionMap,
|
|
props.onChange
|
|
);
|
|
|
|
const handleUpdatePermissionMap = useEvent((permissions: string[]) => {
|
|
const newMap = { ...editPermissionMap, [selectedRoleId]: permissions };
|
|
setEditPermissionMap(newMap);
|
|
});
|
|
|
|
const handleSyncWithGroup = useEvent(() => {
|
|
setEditPermissionMap({
|
|
[ALL_PERMISSION]: getDefaultPermissionList(),
|
|
});
|
|
props.onChange(undefined);
|
|
});
|
|
|
|
if (!panelInfo) {
|
|
return <LoadingSpinner />;
|
|
}
|
|
|
|
return (
|
|
<div className="flex" style={{ width: 540 }}>
|
|
<div>
|
|
<RoleItem
|
|
active={selectedRoleId === ALL_PERMISSION}
|
|
onClick={() => setSelectedRoleId(ALL_PERMISSION)}
|
|
>
|
|
{t('所有人')}
|
|
</RoleItem>
|
|
{roles.map((r) => (
|
|
<RoleItem
|
|
key={r._id}
|
|
active={selectedRoleId === r._id}
|
|
onClick={() => setSelectedRoleId(r._id)}
|
|
>
|
|
{r.name}
|
|
</RoleItem>
|
|
))}
|
|
</div>
|
|
<div className="flex-1 overflow-auto" style={{ height: props.height }}>
|
|
<div className="text-right">
|
|
<Button onClick={handleSyncWithGroup}>{t('重置为默认权限')}</Button>
|
|
</div>
|
|
<PermissionList
|
|
panelType={
|
|
panelInfo.type === GroupPanelType.PLUGIN
|
|
? panelInfo.pluginPanelName
|
|
: panelInfo.type
|
|
}
|
|
value={editPermissionMap[selectedRoleId] ?? []}
|
|
onChange={handleUpdatePermissionMap}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
});
|
|
AdvanceGroupPanelPermission.displayName = 'AdvanceGroupPanelPermission';
|
|
|
|
const RoleItem: React.FC<
|
|
PropsWithChildren<{
|
|
active: boolean;
|
|
onClick?: () => void;
|
|
}>
|
|
> = React.memo((props) => {
|
|
return (
|
|
<div
|
|
className={clsx(
|
|
'px-2 py-1 rounded cursor-pointer mb-1 hover:bg-black hover:bg-opacity-20',
|
|
{
|
|
'bg-black bg-opacity-20': props.active,
|
|
}
|
|
)}
|
|
onClick={props.onClick}
|
|
>
|
|
{props.children}
|
|
</div>
|
|
);
|
|
});
|
|
RoleItem.displayName = 'RoleItem';
|