fix(core): incorrect permissions displayed in member management (#10269)

This commit is contained in:
JimmFly
2025-02-19 16:58:06 +08:00
committed by GitHub
parent 5b768d9091
commit 487158b9ca
4 changed files with 50 additions and 27 deletions

View File

@@ -1,8 +1,14 @@
import { Menu, MenuItem, MenuTrigger, Tooltip } from '@affine/component'; import {
Menu,
MenuItem,
MenuTrigger,
notify,
Tooltip,
} from '@affine/component';
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks'; import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks';
import { DocGrantedUsersService } from '@affine/core/modules/permissions'; import { DocGrantedUsersService } from '@affine/core/modules/permissions';
import { ShareInfoService } from '@affine/core/modules/share-doc'; import { ShareInfoService } from '@affine/core/modules/share-doc';
import { DocRole } from '@affine/graphql'; import { DocRole, UserFriendlyError } from '@affine/graphql';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import { track } from '@affine/track'; import { track } from '@affine/track';
import { InformationIcon } from '@blocksuite/icons/rc'; import { InformationIcon } from '@blocksuite/icons/rc';
@@ -47,33 +53,41 @@ export const MembersPermission = ({
); );
const showTips = const showTips =
docDefaultRole === DocRole.Reader || docDefaultRole === DocRole.Editor; docDefaultRole === DocRole.Reader || docDefaultRole === DocRole.Editor;
const changePermission = useCallback( const changePermission = useAsyncCallback(
async (docRole: DocRole) => { async (docRole: DocRole) => {
try {
track.$.sharePanel.$.modifyDocDefaultRole(); track.$.sharePanel.$.modifyDocDefaultRole();
await docGrantedUsersService.updateDocDefaultRole(docRole); await docGrantedUsersService.updateDocDefaultRole(docRole);
shareInfoService.shareInfo.revalidate(); shareInfoService.shareInfo.revalidate();
} catch (error) {
const err = UserFriendlyError.fromAnyError(error);
notify.error({
title: err.name,
message: err.message,
});
}
}, },
[docGrantedUsersService, shareInfoService.shareInfo] [docGrantedUsersService, shareInfoService.shareInfo]
); );
const selectManage = useAsyncCallback(async () => { const selectManage = useCallback(() => {
await changePermission(DocRole.Manager); changePermission(DocRole.Manager);
}, [changePermission]); }, [changePermission]);
const selectEdit = useAsyncCallback(async () => { const selectEdit = useCallback(() => {
if (hittingPaywall) { if (hittingPaywall) {
openPaywallModal?.(); openPaywallModal?.();
return; return;
} }
await changePermission(DocRole.Editor); changePermission(DocRole.Editor);
}, [changePermission, hittingPaywall, openPaywallModal]); }, [changePermission, hittingPaywall, openPaywallModal]);
const selectRead = useAsyncCallback(async () => { const selectRead = useCallback(() => {
if (hittingPaywall) { if (hittingPaywall) {
openPaywallModal?.(); openPaywallModal?.();
return; return;
} }
await changePermission(DocRole.Reader); changePermission(DocRole.Reader);
}, [changePermission, hittingPaywall, openPaywallModal]); }, [changePermission, hittingPaywall, openPaywallModal]);
return ( return (

View File

@@ -121,15 +121,21 @@ export const MembersRow = ({ onClick }: { onClick: () => void }) => {
className={clsx(styles.rowContainerStyle, 'clickable')} className={clsx(styles.rowContainerStyle, 'clickable')}
onClick={onClick} onClick={onClick}
> >
{docOwner ? (
<>
<div className={styles.memberContainerStyle}> <div className={styles.memberContainerStyle}>
<Avatar <Avatar
url={docOwner?.user.avatarUrl || ''} url={docOwner.user.avatarUrl || ''}
name={docOwner?.user.name} name={docOwner.user.name}
size={24} size={24}
/> />
<span>{docOwner?.user.name}</span> <span>{docOwner.user.name}</span>
</div> </div>
<div className={styles.OwnerStyle}>{t['Owner']()}</div> <div className={styles.OwnerStyle}>{t['Owner']()}</div>
</>
) : (
<div>{t['com.affine.share-menu.invite-editor.manage-members']()}</div>
)}
<div className={styles.IconButtonStyle}> <div className={styles.IconButtonStyle}>
<ArrowRightSmallIcon /> <ArrowRightSmallIcon />
</div> </div>

View File

@@ -9,7 +9,6 @@ import {
useConfirmModal, useConfirmModal,
} from '@affine/component'; } from '@affine/component';
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks'; import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks';
import { AuthService } from '@affine/core/modules/cloud';
import { DocService } from '@affine/core/modules/doc'; import { DocService } from '@affine/core/modules/doc';
import { import {
DocGrantedUsersService, DocGrantedUsersService,
@@ -31,16 +30,15 @@ export const MemberItem = ({
openPaywallModal, openPaywallModal,
hittingPaywall, hittingPaywall,
grantedUser, grantedUser,
canManageUsers,
}: { }: {
grantedUser: GrantedUser; grantedUser: GrantedUser;
hittingPaywall: boolean; hittingPaywall: boolean;
canManageUsers: boolean;
openPaywallModal: () => void; openPaywallModal: () => void;
}) => { }) => {
const user = grantedUser.user; const user = grantedUser.user;
const session = useService(AuthService).session; const disableManage = grantedUser.role === DocRole.Owner || !canManageUsers;
const account = useLiveData(session.account$);
const disableManage =
account?.id === user.id || grantedUser.role === DocRole.Owner;
const role = useMemo(() => { const role = useMemo(() => {
switch (grantedUser.role) { switch (grantedUser.role) {

View File

@@ -66,6 +66,7 @@ export const MemberManagement = ({
grantedUserList={grantedUserList} grantedUserList={grantedUserList}
grantedUserCount={grantedUserCount} grantedUserCount={grantedUserCount}
loadMore={loadMore} loadMore={loadMore}
canManageUsers={canManageUsers}
/> />
) : ( ) : (
<Skeleton className={styles.scrollableRootStyle} /> <Skeleton className={styles.scrollableRootStyle} />
@@ -90,8 +91,10 @@ const MemberList = ({
grantedUserList, grantedUserList,
grantedUserCount, grantedUserCount,
loadMore, loadMore,
canManageUsers,
}: { }: {
hittingPaywall: boolean; hittingPaywall: boolean;
canManageUsers: boolean;
grantedUserList: GrantedUser[]; grantedUserList: GrantedUser[];
grantedUserCount?: number; grantedUserCount?: number;
openPaywallModal: () => void; openPaywallModal: () => void;
@@ -105,10 +108,11 @@ const MemberList = ({
grantedUser={data} grantedUser={data}
openPaywallModal={openPaywallModal} openPaywallModal={openPaywallModal}
hittingPaywall={hittingPaywall} hittingPaywall={hittingPaywall}
canManageUsers={canManageUsers}
/> />
); );
}, },
[hittingPaywall, openPaywallModal] [canManageUsers, hittingPaywall, openPaywallModal]
); );
return ( return (
<div className={styles.memberListStyle}> <div className={styles.memberListStyle}>
@@ -119,6 +123,7 @@ const MemberList = ({
grantedUser={item} grantedUser={item}
openPaywallModal={openPaywallModal} openPaywallModal={openPaywallModal}
hittingPaywall={hittingPaywall} hittingPaywall={hittingPaywall}
canManageUsers={canManageUsers}
/> />
)) ))
) : ( ) : (