From 8d9d85addbb9e410f811466c5adb0fab96567f0c Mon Sep 17 00:00:00 2001 From: TechQuery Date: Wed, 12 Jul 2023 04:36:54 +0800 Subject: [PATCH] [optimize] simplify Scroll List components with Query Filter --- components/Activity/ActivityList.tsx | 51 ++++++++-------- components/Activity/AwardList.tsx | 7 ++- components/Activity/EnrollmentList.tsx | 4 +- components/Message/MessageList.tsx | 2 +- components/Team/TeamAdministratorTable.tsx | 61 ++++--------------- components/Team/TeamAwardList.tsx | 2 +- components/Team/TeamParticipantTable.tsx | 35 +---------- components/Team/TeamWorkList.tsx | 7 +-- components/User/UserList.tsx | 2 +- components/layout/ScrollList.tsx | 30 +-------- .../[name]/team/[tid]/manage/participant.tsx | 14 ++++- .../[name]/team/[tid]/manage/role.tsx | 17 +++++- 12 files changed, 76 insertions(+), 156 deletions(-) diff --git a/components/Activity/ActivityList.tsx b/components/Activity/ActivityList.tsx index 94a6ff14..2a03660b 100644 --- a/components/Activity/ActivityList.tsx +++ b/components/Activity/ActivityList.tsx @@ -1,21 +1,21 @@ -import { observer } from 'mobx-react'; +import { ScrollList } from 'mobx-restful-table'; +import { FC, PureComponent } from 'react'; import { Col, Row } from 'react-bootstrap'; import { Activity, - ActivityFilter, ActivityListType, ActivityModel, } from '../../models/Activity'; import platformAdmin from '../../models/PlatformAdmin'; import sessionStore from '../../models/Session'; import { i18n } from '../../models/Translation'; -import { XScrollList, XScrollListProps } from '../layout/ScrollList'; +import { XScrollListProps } from '../layout/ScrollList'; import { ActivityCard, ActivityCardProps } from './ActivityCard'; const { t } = i18n; -export interface ActivityListProps +export interface ActivityListLayoutProps extends XScrollListProps, Pick { type?: ActivityListType; @@ -23,13 +23,13 @@ export interface ActivityListProps userId?: string; } -export const ActivityListLayout = ({ +export const ActivityListLayout: FC = ({ size, type = 'online', defaultData = [], userId, ...props -}: ActivityListProps) => ( +}) => ( ); -@observer -export default class ActivityList extends XScrollList { - store = new ActivityModel(); - - filter: ActivityFilter = { - userId: this.props.userId, - listType: this.props.type, - }; +export type ActivityListProps = ActivityListLayoutProps; - constructor(props: ActivityListProps) { - super(props); - - this.boot(); +export default class ActivityList extends PureComponent { + store = new ActivityModel(); - if (props.type === 'admin' && !platformAdmin.isPlatformAdmin) + componentDidMount() { + if (this.props.type === 'admin' && !platformAdmin.isPlatformAdmin) platformAdmin.checkAuthorization(); } @@ -86,15 +78,22 @@ export default class ActivityList extends XScrollList { this.props.onDelete?.(name); }; - renderList() { - const { allItems } = this.store; + render() { + const { userId, type } = this.props; return ( - ( + + )} /> ); } diff --git a/components/Activity/AwardList.tsx b/components/Activity/AwardList.tsx index 2e9d7874..2d50b086 100644 --- a/components/Activity/AwardList.tsx +++ b/components/Activity/AwardList.tsx @@ -1,9 +1,9 @@ import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Button, Image, Table } from 'react-bootstrap'; - import { ScrollList, ScrollListProps } from 'mobx-restful-table'; import { FC, PureComponent } from 'react'; +import { Button, Image, Table } from 'react-bootstrap'; + import { Award } from '../../models/Award'; import { i18n } from '../../models/Translation'; import styles from '../../styles/Table.module.less'; @@ -80,7 +80,8 @@ export const AwardListLayout: FC = ({ ); -export type AwardListProps = ScrollListProps & AwardListLayoutProps; +export type AwardListProps = Pick, 'store'> & + AwardListLayoutProps; export class AwardList extends PureComponent { onEdit = (id: string) => { diff --git a/components/Activity/EnrollmentList.tsx b/components/Activity/EnrollmentList.tsx index 0c835a52..e6e26ff0 100644 --- a/components/Activity/EnrollmentList.tsx +++ b/components/Activity/EnrollmentList.tsx @@ -87,9 +87,7 @@ export const EnrollmentListLayout: FC = ({ ); -export interface EnrollmentListProps - extends ScrollListProps, - EnrollmentListLayoutProps { +export interface EnrollmentListProps extends EnrollmentListLayoutProps { activity: string; } diff --git a/components/Message/MessageList.tsx b/components/Message/MessageList.tsx index a119b818..5473b6ef 100644 --- a/components/Message/MessageList.tsx +++ b/components/Message/MessageList.tsx @@ -106,7 +106,7 @@ export const MessageListLayout: FC = ({ ); -export type MessageListProps = ScrollListProps & +export type MessageListProps = Pick, 'store'> & MessageListLayoutProps; @observer diff --git a/components/Team/TeamAdministratorTable.tsx b/components/Team/TeamAdministratorTable.tsx index 60718073..b0e17de0 100644 --- a/components/Team/TeamAdministratorTable.tsx +++ b/components/Team/TeamAdministratorTable.tsx @@ -1,28 +1,23 @@ import { observer } from 'mobx-react'; +import { FC } from 'react'; import { Form, Table } from 'react-bootstrap'; import sessionStore from '../../models/Session'; -import { - MembershipStatus, - TeamMember, - TeamMemberFilter, - TeamMemberModel, -} from '../../models/Team'; +import { TeamMember } from '../../models/Team'; import { i18n } from '../../models/Translation'; import styles from '../../styles/Table.module.less'; import { convertDatetime } from '../../utils/time'; -import { XScrollList, XScrollListProps } from '../layout/ScrollList'; +import { XScrollListProps } from '../layout/ScrollList'; const { t } = i18n; -export interface TeamAdministratorTableProps +export interface TeamAdministratorTableLayoutProps extends XScrollListProps { - store: TeamMemberModel; onUpdateRole?: (userId: string, role: 'admin' | 'member') => any; onPopUpUpdateRoleModal?: (userId: string) => any; } -const TableHeads = [ +const TableHeads = () => [ '#', t('nick_name'), t('mail'), @@ -33,23 +28,20 @@ const TableHeads = [ t('role_type'), ]; -const RoleName = { +const RoleName = () => ({ member: t('member'), admin: t('admin'), -}; +}); -export const TeamAdministratorTableLayout = observer( - ({ - defaultData = [], - onUpdateRole, - }: Omit) => { +export const TeamAdministratorTableLayout: FC = + observer(({ defaultData = [], onUpdateRole }) => { const { id: currentUserId } = sessionStore?.user || {}; return ( - {TableHeads.map((data, idx) => ( + {TableHeads().map((data, idx) => ( ))} @@ -87,7 +79,7 @@ export const TeamAdministratorTableLayout = observer( } defaultValue={role} > - {Object.entries(RoleName).map(([key, value]) => ( + {Object.entries(RoleName()).map(([key, value]) => ( @@ -106,33 +98,4 @@ export const TeamAdministratorTableLayout = observer(
{data}
); - }, -); - -@observer -export class TeamAdministratorTable extends XScrollList { - store = this.props.store; - - filter: TeamMemberFilter = { - status: MembershipStatus.APPROVED, - }; - - constructor(props: TeamAdministratorTableProps) { - super(props); - - this.boot(); - } - - onUpdateRole: TeamAdministratorTableProps['onUpdateRole'] = (userId, role) => - this.store.updateRole(userId, role); - - renderList() { - return ( - - ); - } -} + }); diff --git a/components/Team/TeamAwardList.tsx b/components/Team/TeamAwardList.tsx index a0035e3f..ff606ba2 100644 --- a/components/Team/TeamAwardList.tsx +++ b/components/Team/TeamAwardList.tsx @@ -31,7 +31,7 @@ const TeamAwardListLayout: FC = ({
); -export type TeamAwardListProps = ScrollListProps & +export type TeamAwardListProps = Pick, 'store'> & TeamAwardListLayoutProps; export class TeamAwardList extends PureComponent { diff --git a/components/Team/TeamParticipantTable.tsx b/components/Team/TeamParticipantTable.tsx index cb781026..06572206 100644 --- a/components/Team/TeamParticipantTable.tsx +++ b/components/Team/TeamParticipantTable.tsx @@ -1,12 +1,7 @@ -import { ScrollList, ScrollListProps } from 'mobx-restful-table'; -import { FC, PureComponent } from 'react'; +import { FC } from 'react'; import { Form, Table } from 'react-bootstrap'; -import { - MembershipStatus, - TeamMember, - TeamMemberModel, -} from '../../models/Team'; +import { MembershipStatus, TeamMember } from '../../models/Team'; import { i18n } from '../../models/Translation'; import styles from '../../styles/Table.module.less'; import { convertDatetime } from '../../utils/time'; @@ -102,29 +97,3 @@ export const TeamParticipantTableLayout: FC< ); - -export interface TeamParticipantTableProps - extends ScrollListProps, - TeamParticipantTableLayoutProps { - store: TeamMemberModel; -} - -export class TeamParticipantTable extends PureComponent { - onApprove: TeamParticipantTableProps['onApprove'] = (userId, status) => - this.props.store.approveOne(userId, status); - - render() { - return ( - ( - - )} - /> - ); - } -} diff --git a/components/Team/TeamWorkList.tsx b/components/Team/TeamWorkList.tsx index 9acbeb10..c8ba81ef 100644 --- a/components/Team/TeamWorkList.tsx +++ b/components/Team/TeamWorkList.tsx @@ -1,6 +1,6 @@ import { faCalendarDay } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { ScrollList, ScrollListProps } from 'mobx-restful-table'; +import { ScrollList } from 'mobx-restful-table'; import { FC, PureComponent } from 'react'; import { Button, @@ -116,10 +116,7 @@ export const TeamWorkListLayout: FC = ({ ); -export type TeamWorkListProps = ScrollListProps & - TeamWorkListLayoutProps; - -export class TeamWorkList extends PureComponent { +export class TeamWorkList extends PureComponent { store = activityStore.teamOf(this.props.activity).workOf(this.props.team); onDelete = (id?: string) => diff --git a/components/User/UserList.tsx b/components/User/UserList.tsx index a5ab2006..5a14c98c 100644 --- a/components/User/UserList.tsx +++ b/components/User/UserList.tsx @@ -88,7 +88,7 @@ export const UserListLayout: FC = ({ ); -export type UserListProps = ScrollListProps & +export type UserListProps = Pick, 'store'> & UserListLayoutProps; export class UserList extends PureComponent { diff --git a/components/layout/ScrollList.tsx b/components/layout/ScrollList.tsx index 4ec10271..e4ab0894 100644 --- a/components/layout/ScrollList.tsx +++ b/components/layout/ScrollList.tsx @@ -1,36 +1,8 @@ -import { Loading } from 'idea-react'; -import { observable } from 'mobx'; import { DataObject } from 'mobx-restful'; -import { ScrollList, ScrollListProps } from 'mobx-restful-table'; - -import { i18n } from '../../models/Translation'; +import { ScrollListProps } from 'mobx-restful-table'; export interface XScrollListProps extends Pick, 'defaultData'> { selectedIds?: string[]; onSelect?: (selectedIds: string[]) => any; } - -export abstract class XScrollList< - P extends XScrollListProps, -> extends ScrollList

{ - translator = i18n; - - @observable - selectedIds: string[] = []; - - onSelect = (list: string[]) => - (this.selectedIds = list) && this.props.onSelect?.(list); - - render() { - const { downloading, uploading } = this.store; - - return ( - <> - {(downloading > 0 || uploading > 0) && } - - {super.render()} - - ); - } -} diff --git a/pages/activity/[name]/team/[tid]/manage/participant.tsx b/pages/activity/[name]/team/[tid]/manage/participant.tsx index 5e817b01..5253b421 100644 --- a/pages/activity/[name]/team/[tid]/manage/participant.tsx +++ b/pages/activity/[name]/team/[tid]/manage/participant.tsx @@ -1,4 +1,5 @@ import { observer } from 'mobx-react'; +import { ScrollList } from 'mobx-restful-table'; import { InferGetServerSidePropsType } from 'next'; import { PureComponent } from 'react'; @@ -6,7 +7,7 @@ import { TeamManageBaseRouterProps, TeamManageFrame, } from '../../../../../../components/Team/TeamManageFrame'; -import { TeamParticipantTable } from '../../../../../../components/Team/TeamParticipantTable'; +import { TeamParticipantTableLayout } from '../../../../../../components/Team/TeamParticipantTable'; import activityStore from '../../../../../../models/Activity'; import { i18n } from '../../../../../../models/Translation'; import { withRoute, withTranslation } from '../../../../../api/core'; @@ -37,7 +38,16 @@ export default class TeamParticipantPage extends PureComponent< path={resolvedUrl} title={t('team_registration')} > - + ( + store.approveOne(userId, status)} + /> + )} + /> ); } diff --git a/pages/activity/[name]/team/[tid]/manage/role.tsx b/pages/activity/[name]/team/[tid]/manage/role.tsx index 7b07772c..7b73774e 100644 --- a/pages/activity/[name]/team/[tid]/manage/role.tsx +++ b/pages/activity/[name]/team/[tid]/manage/role.tsx @@ -1,14 +1,16 @@ import { observable } from 'mobx'; import { observer } from 'mobx-react'; +import { ScrollList } from 'mobx-restful-table'; import { InferGetServerSidePropsType } from 'next'; import { PureComponent } from 'react'; -import { TeamAdministratorTable } from '../../../../../../components/Team/TeamAdministratorTable'; +import { TeamAdministratorTableLayout } from '../../../../../../components/Team/TeamAdministratorTable'; import { TeamManageBaseRouterProps, TeamManageFrame, } from '../../../../../../components/Team/TeamManageFrame'; import activityStore from '../../../../../../models/Activity'; +import { MembershipStatus } from '../../../../../../models/Team'; import { i18n } from '../../../../../../models/Translation'; import { withRoute, withTranslation } from '../../../../../api/core'; @@ -41,9 +43,18 @@ export default class TeamAdministratorPage extends PureComponent< path={resolvedUrl} title={t('role_management')} > - (this.userId = userId)} + filter={{ status: MembershipStatus.APPROVED }} + renderList={allItems => ( + store.updateRole(userId, role)} + onPopUpUpdateRoleModal={userId => (this.userId = userId)} + /> + )} /> );