feat: support pagination for member list (#4231)

This commit is contained in:
Qi
2023-09-12 03:37:59 +00:00
committed by GitHub
parent 9fe9efe465
commit 98429bf89e
21 changed files with 404 additions and 108 deletions
+1
View File
@@ -49,6 +49,7 @@
"react-dom": "18.2.0",
"react-error-boundary": "^4.0.11",
"react-is": "^18.2.0",
"react-paginate": "^8.2.0",
"rxjs": "^7.8.1"
},
"devDependencies": {
@@ -1,2 +1,3 @@
export * from './accept-invite-page';
export * from './invite-modal';
export * from './pagination';
@@ -15,50 +15,6 @@ export interface InviteModalProps {
isMutating: boolean;
}
const PermissionMenu = ({
currentPermission,
onChange,
}: {
currentPermission: Permission;
onChange: (permission: Permission) => void;
}) => {
console.log('currentPermission', currentPermission);
console.log('onChange', onChange);
return null;
// return (
// <Menu
// trigger="click"
// content={
// <>
// {Object.entries(Permission).map(([permission]) => {
// return (
// <MenuItem
// key={permission}
// onClick={() => {
// onChange(permission as Permission);
// }}
// >
// {permission}
// </MenuItem>
// );
// })}
// </>
// }
// >
// <MenuTrigger
// type="plain"
// style={{
// marginRight: -10,
// height: '100%',
// }}
// >
// {currentPermission}
// </MenuTrigger>
// </Menu>
// );
};
export const InviteModal = ({
open,
setOpen,
@@ -67,7 +23,7 @@ export const InviteModal = ({
}: InviteModalProps) => {
const t = useAFFiNEI18N();
const [inviteEmail, setInviteEmail] = useState('');
const [permission, setPermission] = useState(Permission.Write);
const [permission] = useState(Permission.Write);
const [isValidEmail, setIsValidEmail] = useState(true);
const handleCancel = useCallback(() => {
@@ -125,12 +81,6 @@ export const InviteModal = ({
onEnter={handleConfirm}
style={{ marginTop: 20 }}
size="large"
endFix={
<PermissionMenu
currentPermission={permission}
onChange={setPermission}
/>
}
/>
</div>
<div className={styles.inviteModalButtonContainer}>
@@ -0,0 +1,49 @@
import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons';
import clsx from 'clsx';
import { useCallback, useMemo } from 'react';
import ReactPaginate from 'react-paginate';
import * as styles from './styles.css';
export interface PaginationProps {
totalCount: number;
countPerPage: number;
onPageChange: (skip: number) => void;
}
export const Pagination = ({
totalCount,
countPerPage,
onPageChange,
}: PaginationProps) => {
const handlePageClick = useCallback(
(e: { selected: number }) => {
const newOffset = (e.selected * countPerPage) % totalCount;
onPageChange(newOffset);
},
[countPerPage, onPageChange, totalCount]
);
const pageCount = useMemo(
() => Math.ceil(totalCount / countPerPage),
[countPerPage, totalCount]
);
return (
<ReactPaginate
onPageChange={handlePageClick}
pageRangeDisplayed={3}
marginPagesDisplayed={2}
pageCount={pageCount}
previousLabel={<ArrowLeftSmallIcon />}
nextLabel={<ArrowRightSmallIcon />}
pageClassName={styles.pageItem}
previousClassName={clsx(styles.pageItem, 'label')}
nextClassName={clsx(styles.pageItem, 'label')}
breakLabel="..."
breakClassName={styles.pageItem}
containerClassName={styles.pagination}
activeClassName="active"
renderOnZeroPageCount={null}
/>
);
};
@@ -1,4 +1,4 @@
import { style } from '@vanilla-extract/css';
import { globalStyle, style } from '@vanilla-extract/css';
export const inviteModalTitle = style({
fontWeight: '600',
@@ -21,3 +21,48 @@ export const inviteName = style({
marginRight: '10px',
color: 'var(--affine-black)',
});
export const pagination = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
gap: '6px',
marginTop: 5,
});
export const pageItem = style({
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
width: '20px',
height: '20px',
fontSize: 'var(--affine-font-xs)',
color: 'var(--affine-text-primary-color)',
borderRadius: '4px',
selectors: {
'&:hover': {
background: 'var(--affine-hover-color)',
},
'&.active': {
color: 'var(--affine-primary-color)',
cursor: 'default',
pointerEvents: 'none',
},
'&.label': {
color: 'var(--affine-icon-color)',
fontSize: '16px',
},
'&.disabled': {
opacity: '.4',
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
},
});
globalStyle(`${pageItem} a`, {
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
});
@@ -0,0 +1,5 @@
query getMemberCountByWorkspaceId($workspaceId: String!) {
workspace(id: $workspaceId) {
memberCount
}
}
@@ -1,6 +1,6 @@
query getMembersByWorkspaceId($workspaceId: String!) {
query getMembersByWorkspaceId($workspaceId: String!, $skip: Int!, $take: Int!) {
workspace(id: $workspaceId) {
members {
members(skip: $skip, take: $take) {
id
name
email
+15 -2
View File
@@ -204,15 +204,28 @@ query getIsOwner($workspaceId: String!) {
}`,
};
export const getMemberCountByWorkspaceIdQuery = {
id: 'getMemberCountByWorkspaceIdQuery' as const,
operationName: 'getMemberCountByWorkspaceId',
definitionName: 'workspace',
containsFile: false,
query: `
query getMemberCountByWorkspaceId($workspaceId: String!) {
workspace(id: $workspaceId) {
memberCount
}
}`,
};
export const getMembersByWorkspaceIdQuery = {
id: 'getMembersByWorkspaceIdQuery' as const,
operationName: 'getMembersByWorkspaceId',
definitionName: 'workspace',
containsFile: false,
query: `
query getMembersByWorkspaceId($workspaceId: String!) {
query getMembersByWorkspaceId($workspaceId: String!, $skip: Int!, $take: Int!) {
workspace(id: $workspaceId) {
members {
members(skip: $skip, take: $take) {
id
name
email
+16
View File
@@ -206,8 +206,19 @@ export type GetIsOwnerQueryVariables = Exact<{
export type GetIsOwnerQuery = { __typename?: 'Query'; isOwner: boolean };
export type GetMemberCountByWorkspaceIdQueryVariables = Exact<{
workspaceId: Scalars['String']['input'];
}>;
export type GetMemberCountByWorkspaceIdQuery = {
__typename?: 'Query';
workspace: { __typename?: 'WorkspaceType'; memberCount: number };
};
export type GetMembersByWorkspaceIdQueryVariables = Exact<{
workspaceId: Scalars['String']['input'];
skip: Scalars['Int']['input'];
take: Scalars['Int']['input'];
}>;
export type GetMembersByWorkspaceIdQuery = {
@@ -493,6 +504,11 @@ export type Queries =
variables: GetIsOwnerQueryVariables;
response: GetIsOwnerQuery;
}
| {
name: 'getMemberCountByWorkspaceIdQuery';
variables: GetMemberCountByWorkspaceIdQueryVariables;
response: GetMemberCountByWorkspaceIdQuery;
}
| {
name: 'getMembersByWorkspaceIdQuery';
variables: GetMembersByWorkspaceIdQueryVariables;
+1
View File
@@ -570,5 +570,6 @@
"Workspace Settings with name": "{{name}}'s Settings",
"Workspace Type": "Workspace Type",
"You cannot delete the last workspace": "You cannot delete the last workspace",
"Removed successfully": "Removed successfully",
"Successfully enabled AFFiNE Cloud": "Successfully enabled AFFiNE Cloud"
}