fix(server): wrong member count query (#4506)

This commit is contained in:
liuyi
2023-09-26 10:36:08 -05:00
committed by GitHub
parent a633fb6dea
commit 4a03fa65d1
4 changed files with 106 additions and 67 deletions

View File

@@ -21,7 +21,14 @@ import { Tooltip } from '@toeverything/components/tooltip';
import clsx from 'clsx'; import clsx from 'clsx';
import { useSetAtom } from 'jotai'; import { useSetAtom } from 'jotai';
import type { ReactElement } from 'react'; import type { ReactElement } from 'react';
import { Suspense, useCallback, useMemo, useState } from 'react'; import {
Suspense,
useCallback,
useLayoutEffect,
useMemo,
useRef,
useState,
} from 'react';
import { ErrorBoundary } from 'react-error-boundary'; import { ErrorBoundary } from 'react-error-boundary';
import type { CheckedUser } from '../../../hooks/affine/use-current-user'; import type { CheckedUser } from '../../../hooks/affine/use-current-user';
@@ -96,6 +103,20 @@ export const CloudWorkspaceMembersPanel = ({
[invite, pushNotification, t] [invite, pushNotification, t]
); );
const listContainerRef = useRef<HTMLDivElement | null>(null);
const [memberListHeight, setMemberListHeight] = useState<number | null>(null);
useLayoutEffect(() => {
if (
memberCount > COUNT_PER_PAGE &&
listContainerRef.current &&
memberListHeight === null
) {
const rect = listContainerRef.current.getBoundingClientRect();
setMemberListHeight(rect.height);
}
}, [listContainerRef, memberCount, memberListHeight]);
const onRevoke = useCallback<OnRevoke>( const onRevoke = useCallback<OnRevoke>(
async memberId => { async memberId => {
const res = await revokeMemberPermission(memberId); const res = await revokeMemberPermission(memberId);
@@ -129,7 +150,11 @@ export const CloudWorkspaceMembersPanel = ({
) : null} ) : null}
</SettingRow> </SettingRow>
<div className={style.membersPanel}> <div
className={style.membersPanel}
ref={listContainerRef}
style={memberListHeight ? { height: memberListHeight } : {}}
>
<Suspense fallback={<MemberListFallback memberCount={memberCount} />}> <Suspense fallback={<MemberListFallback memberCount={memberCount} />}>
<MemberList <MemberList
workspaceId={workspaceId} workspaceId={workspaceId}
@@ -139,11 +164,13 @@ export const CloudWorkspaceMembersPanel = ({
/> />
</Suspense> </Suspense>
{memberCount > COUNT_PER_PAGE && (
<Pagination <Pagination
totalCount={memberCount} totalCount={memberCount}
countPerPage={COUNT_PER_PAGE} countPerPage={COUNT_PER_PAGE}
onPageChange={onPageChange} onPageChange={onPageChange}
/> />
)}
</div> </div>
</> </>
); );
@@ -186,7 +213,7 @@ const MemberList = ({
const currentUser = useCurrentUser(); const currentUser = useCurrentUser();
return ( return (
<> <div className={style.memberList}>
{members.map(member => ( {members.map(member => (
<MemberItem <MemberItem
key={member.id} key={member.id}
@@ -196,7 +223,7 @@ const MemberList = ({
onRevoke={onRevoke} onRevoke={onRevoke}
/> />
))} ))}
</> </div>
); );
}; };
@@ -225,8 +252,11 @@ const MemberItem = ({
}, [currentUser.id, isOwner, member.id, t]); }, [currentUser.id, isOwner, member.id, t]);
return ( return (
<> <div
<div key={member.id} className={style.listItem} data-testid="member-item"> key={member.id}
className={style.memberListItem}
data-testid="member-item"
>
<Avatar <Avatar
size={36} size={36}
url={member.avatarUrl} url={member.avatarUrl}
@@ -272,7 +302,6 @@ const MemberItem = ({
</IconButton> </IconButton>
</Menu> </Menu>
</div> </div>
</>
); );
}; };

View File

@@ -93,14 +93,17 @@ export const membersFallback = style({
color: 'var(--affine-primary-color)', color: 'var(--affine-primary-color)',
}); });
export const membersPanel = style({ export const membersPanel = style({
marginTop: '24px',
padding: '4px', padding: '4px',
borderRadius: '12px', borderRadius: '12px',
background: 'var(--affine-background-primary-color)', background: 'var(--affine-background-primary-color)',
border: '1px solid var(--affine-border-color)', border: '1px solid var(--affine-border-color)',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
}); });
export const listItem = style({ export const memberList = style({});
export const memberListItem = style({
padding: '0 4px 0 16px', padding: '0 4px 0 16px',
height: '58px', height: '58px',
display: 'flex', display: 'flex',
@@ -155,7 +158,7 @@ export const memberEmail = style({
}); });
export const iconButton = style({}); export const iconButton = style({});
globalStyle(`${listItem}:hover ${iconButton}`, { globalStyle(`${memberListItem}:hover ${iconButton}`, {
opacity: 1, opacity: 1,
pointerEvents: 'all', pointerEvents: 'all',
}); });

View File

@@ -174,6 +174,9 @@ export class WorkspaceResolver {
return this.prisma.userWorkspacePermission.count({ return this.prisma.userWorkspacePermission.count({
where: { where: {
workspaceId: workspace.id, workspaceId: workspace.id,
userId: {
not: null,
},
}, },
}); });
} }
@@ -214,6 +217,9 @@ export class WorkspaceResolver {
const data = await this.prisma.userWorkspacePermission.findMany({ const data = await this.prisma.userWorkspacePermission.findMany({
where: { where: {
workspaceId: workspace.id, workspaceId: workspace.id,
userId: {
not: null,
},
}, },
skip, skip,
take: take || 8, take: take || 8,

View File

@@ -173,6 +173,15 @@ type Query {
} }
type Mutation { type Mutation {
signUp(name: String!, email: String!, password: String!): UserType!
signIn(email: String!, password: String!): UserType!
changePassword(token: String!, newPassword: String!): UserType!
changeEmail(token: String!): UserType!
sendChangePasswordEmail(email: String!, callbackUrl: String!): Boolean!
sendSetPasswordEmail(email: String!, callbackUrl: String!): Boolean!
sendChangeEmail(email: String!, callbackUrl: String!): Boolean!
sendVerifyChangeEmail(token: String!, email: String!, callbackUrl: String!): Boolean!
"""Create a new workspace""" """Create a new workspace"""
createWorkspace(init: Upload!): WorkspaceType! createWorkspace(init: Upload!): WorkspaceType!
@@ -196,14 +205,6 @@ type Mutation {
removeAvatar: RemoveAvatar! removeAvatar: RemoveAvatar!
deleteAccount: DeleteAccount! deleteAccount: DeleteAccount!
addToNewFeaturesWaitingList(type: NewFeaturesKind!, email: String!): AddToNewFeaturesWaitingList! addToNewFeaturesWaitingList(type: NewFeaturesKind!, email: String!): AddToNewFeaturesWaitingList!
signUp(name: String!, email: String!, password: String!): UserType!
signIn(email: String!, password: String!): UserType!
changePassword(token: String!, newPassword: String!): UserType!
changeEmail(token: String!): UserType!
sendChangePasswordEmail(email: String!, callbackUrl: String!): Boolean!
sendSetPasswordEmail(email: String!, callbackUrl: String!): Boolean!
sendChangeEmail(email: String!, callbackUrl: String!): Boolean!
sendVerifyChangeEmail(token: String!, email: String!, callbackUrl: String!): Boolean!
} }
"""The `Upload` scalar type represents a file upload.""" """The `Upload` scalar type represents a file upload."""