feat: pagination options (#20)

* feat: pagination options

* fix: data: {list, total}
This commit is contained in:
chenos 2020-11-21 23:49:59 +08:00 committed by GitHub
parent 85e42f95a5
commit 578454d07f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 94 additions and 27 deletions

View File

@ -13,6 +13,7 @@ interface Params {
associatedKey?: string | number; associatedKey?: string | number;
fields?: any; fields?: any;
filter?: any; filter?: any;
[key: string]: any;
} }
interface Handler { interface Handler {

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { useState } from 'react';
import { PageHeader, Tabs, Button, Statistic, Descriptions } from 'antd'; import { PageHeader, Tabs, Button, Statistic, Descriptions } from 'antd';
import { CollectionTabPane } from './CollectionTabPane'; import { CollectionTabPane } from './CollectionTabPane';
import { getPathName, redirectTo } from './utils'; import { getPathName, redirectTo } from './utils';
@ -15,7 +15,9 @@ export function CollectionSingle(props) {
const { data = {}, loading } = useRequest(() => activeTab && api.resource(activeTab.collection_name).getPageInfo({ const { data = {}, loading } = useRequest(() => activeTab && api.resource(activeTab.collection_name).getPageInfo({
resourceKey: item.itemId, resourceKey: item.itemId,
})); }));
console.log(data);
const [activing, setActiving] = useState(false);
if (!activeTab) { if (!activeTab) {
return null; return null;
} }
@ -45,12 +47,16 @@ export function CollectionSingle(props) {
<Tabs size={'small'} <Tabs size={'small'}
defaultActiveKey={`${activeTab.name}`} defaultActiveKey={`${activeTab.name}`}
onTabClick={(activeKey) => { onTabClick={(activeKey) => {
setActiving(true);
redirectTo({ redirectTo({
...props.match.params, ...props.match.params,
lastItem: { lastItem: {
tabName: activeKey, tabName: activeKey,
}, },
}); });
setTimeout(() => {
setActiving(false);
}, 2)
}} }}
> >
{tabs.map(tab => <Tabs.TabPane tab={tab.title} key={`${tab.name}`} />)} {tabs.map(tab => <Tabs.TabPane tab={tab.title} key={`${tab.name}`} />)}
@ -58,7 +64,7 @@ export function CollectionSingle(props) {
} }
/> />
<div className={'collection-content'}> <div className={'collection-content'}>
<CollectionTabPane {...props} pageInfo={data} activeTab={activeTab}/> <CollectionTabPane {...props} loading={activing} pageInfo={data} activeTab={activeTab}/>
</div> </div>
</div> </div>
); );

View File

@ -1,10 +1,10 @@
import React from 'react'; import React, { useEffect, useState } from 'react';
import ViewFactory from '@/components/views'; import ViewFactory from '@/components/views';
import { PageHeader, Tabs, Button, Statistic, Descriptions } from 'antd'; import { PageHeader, Tabs, Button, Statistic, Descriptions } from 'antd';
import { useRequest, request, Spin } from '@nocobase/client'; import { useRequest, request, Spin } from '@nocobase/client';
export function CollectionTabPane(props) { export function CollectionTabPane(props) {
const { pageInfo = {}, activeTab = {}, item = {} } = props; const { loading, pageInfo = {}, activeTab = {}, item = {} } = props;
const { viewName, association, collection_name, field = {} } = activeTab; const { viewName, association, collection_name, field = {} } = activeTab;
const { sourceKey = 'id' } = field; const { sourceKey = 'id' } = field;
@ -19,7 +19,9 @@ export function CollectionTabPane(props) {
params['resourceKey'] = item.itemId; params['resourceKey'] = item.itemId;
} }
console.log(activeTab); if (loading) {
return <Spin/>;
}
return ( return (
<div> <div>

View File

@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { Table as AntdTable, Card } from 'antd'; import { Table as AntdTable, Card, Pagination } from 'antd';
import { Actions } from '@/components/actions'; import { Actions } from '@/components/actions';
import ViewFactory from '@/components/views'; import ViewFactory from '@/components/views';
import { useRequest } from 'umi'; import { useRequest } from 'umi';
@ -26,14 +26,30 @@ export function SimpleTable(props: SimpleTableProps) {
associatedName, associatedName,
associatedKey, associatedKey,
} = props; } = props;
const { rowKey = 'id', fields = [], rowViewName, actions = [] } = schema; const { rowKey = 'id', fields = [], rowViewName, actions = [], paginated = true, defaultPageSize = 10 } = schema;
const { sourceKey = 'id' } = activeTab.field||{}; const { sourceKey = 'id' } = activeTab.field||{};
const drawerRef = useRef<any>(); const drawerRef = useRef<any>();
const name = associatedName ? `${associatedName}.${resourceName}` : resourceName; const { data, loading, pagination, mutate } = useRequest((params = {}) => {
const { data, mutate } = useRequest(() => api.resource(name).list({ const { current, pageSize, ...restParams } = params;
associatedKey, const name = associatedName ? `${associatedName}.${resourceName}` : resourceName;
})); return api.resource(name).list({
console.log(activeTab); associatedKey,
page: paginated ? current : 1,
perPage: paginated ? pageSize : -1,
})
.then(({data = [], meta = {}}) => {
return {
data: {
list: data,
total: meta.count||data.length,
},
};
});
}, {
paginated,
defaultPageSize,
});
console.log(schema, data);
const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const onChange = (selectedRowKeys: React.ReactText[]) => { const onChange = (selectedRowKeys: React.ReactText[]) => {
setSelectedRowKeys(selectedRowKeys); setSelectedRowKeys(selectedRowKeys);
@ -45,6 +61,7 @@ export function SimpleTable(props: SimpleTableProps) {
onChange, onChange,
} }
} }
console.log('rowViewName', {rowViewName})
return ( return (
<Card bordered={false}> <Card bordered={false}>
<Actions {...props} style={{ marginBottom: 14 }} actions={actions}/> <Actions {...props} style={{ marginBottom: 14 }} actions={actions}/>
@ -54,9 +71,10 @@ export function SimpleTable(props: SimpleTableProps) {
reference={drawerRef} reference={drawerRef}
/> />
<AntdTable <AntdTable
columns={fields2columns(fields)}
dataSource={data}
rowKey={rowKey} rowKey={rowKey}
loading={loading}
columns={fields2columns(fields)}
dataSource={data?.list||(data as any)}
components={components({data, mutate})} components={components({data, mutate})}
onRow={(record) => ({ onRow={(record) => ({
onClick: () => { onClick: () => {
@ -64,8 +82,14 @@ export function SimpleTable(props: SimpleTableProps) {
drawerRef.current.getData(record[rowKey]); drawerRef.current.getData(record[rowKey]);
} }
})} })}
pagination={false}
{...tableProps} {...tableProps}
/> />
{paginated && (
<div>
<Pagination {...pagination} showQuickJumper showSizeChanger size={'default'}/>
</div>
)}
</Card> </Card>
); );
} }

View File

@ -14,7 +14,7 @@ export const DragHandle = sortableHandle(() => (
<MenuOutlined style={{ cursor: 'pointer', color: '#999' }} /> <MenuOutlined style={{ cursor: 'pointer', color: '#999' }} />
)); ));
export const components = ({data, mutate}) => { export const components = ({data = {}, mutate}: {data: any, mutate: any}) => {
return { return {
body: { body: {
wrapper: props => ( wrapper: props => (
@ -23,8 +23,11 @@ export const components = ({data, mutate}) => {
helperClass="row-dragging" helperClass="row-dragging"
onSortEnd={({ oldIndex, newIndex }) => { onSortEnd={({ oldIndex, newIndex }) => {
if (oldIndex !== newIndex) { if (oldIndex !== newIndex) {
const newData = arrayMove([].concat(data), oldIndex, newIndex).filter(el => !!el); const list = arrayMove([].concat(data.list), oldIndex, newIndex).filter(el => !!el);
mutate(newData); mutate({
...data,
list,
});
} }
}} }}
{...props} {...props}
@ -32,7 +35,7 @@ export const components = ({data, mutate}) => {
), ),
row: ({ className, style, ...restProps }) => { row: ({ className, style, ...restProps }) => {
// function findIndex base on Table rowKey props and should always be a right array index // function findIndex base on Table rowKey props and should always be a right array index
const index = findIndex(data, (x: any) => x.id === restProps['data-row-key']); const index = findIndex(data.list, (x: any) => x.id === restProps['data-row-key']);
return <SortableItem index={index} {...restProps} />; return <SortableItem index={index} {...restProps} />;
}, },
}, },

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Table as AntdTable, Card } from 'antd'; import { Table as AntdTable, Card, Pagination } from 'antd';
import { redirectTo } from '@/components/pages/CollectionLoader/utils'; import { redirectTo } from '@/components/pages/CollectionLoader/utils';
import { Actions } from '@/components/actions'; import { Actions } from '@/components/actions';
import { request, useRequest } from 'umi'; import { request, useRequest } from 'umi';
@ -41,11 +41,31 @@ export function Table(props: TableProps) {
associatedName, associatedName,
associatedKey, associatedKey,
} = props; } = props;
const { fields, defaultTabName, rowKey = 'id', actions = [] } = schema; const { fields, defaultTabName, rowKey = 'id', actions = [], paginated = true, defaultPageSize = 10 } = schema;
const name = associatedName ? `${associatedName}.${resourceName}` : resourceName; const name = associatedName ? `${associatedName}.${resourceName}` : resourceName;
const { data, mutate } = useRequest(() => api.resource(name).list({ // const { data, mutate } = useRequest(() => api.resource(name).list({
associatedKey, // associatedKey,
})); // }));
const { data, loading, pagination, mutate } = useRequest((params = {}) => {
const { current, pageSize, ...restParams } = params;
const name = associatedName ? `${associatedName}.${resourceName}` : resourceName;
return api.resource(name).list({
associatedKey,
page: paginated ? current : 1,
perPage: paginated ? pageSize : -1,
})
.then(({data = [], meta = {}}) => {
return {
data: {
list: data,
total: meta.count||data.length,
},
};
});
}, {
paginated,
defaultPageSize,
});
const { sourceKey = 'id' } = activeTab.field||{}; const { sourceKey = 'id' } = activeTab.field||{};
console.log(props); console.log(props);
const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]);
@ -63,9 +83,9 @@ export function Table(props: TableProps) {
<Card bordered={false}> <Card bordered={false}>
<Actions {...props} style={{ marginBottom: 14 }} actions={actions}/> <Actions {...props} style={{ marginBottom: 14 }} actions={actions}/>
<AntdTable <AntdTable
dataSource={data}
rowKey={rowKey} rowKey={rowKey}
columns={fields2columns(fields)} columns={fields2columns(fields)}
dataSource={data?.list||(data as any)}
components={components({data, mutate})} components={components({data, mutate})}
onRow={(data) => ({ onRow={(data) => ({
onClick: () => { onClick: () => {
@ -78,8 +98,14 @@ export function Table(props: TableProps) {
}); });
}, },
})} })}
pagination={false}
{...tableProps} {...tableProps}
/> />
{paginated && (
<div>
<Pagination {...pagination} showQuickJumper showSizeChanger size={'default'}/>
</div>
)}
</Card> </Card>
); );
} }

View File

@ -1,5 +1,5 @@
import React from 'react'; import React, { useEffect, useState } from 'react';
import api from '@/api-client'; import api from '@/api-client';
import { useRequest } from 'umi'; import { useRequest } from 'umi';
import { Spin } from '@nocobase/client'; import { Spin } from '@nocobase/client';
@ -51,7 +51,6 @@ export default function ViewFactory(props: ViewProps) {
}, { }, {
refreshDeps: [associatedName, resourceName, viewName], refreshDeps: [associatedName, resourceName, viewName],
}); });
console.log(data);
if (loading) { if (loading) {
return <Spin/>; return <Spin/>;
} }

View File

@ -91,6 +91,7 @@ export default {
actionNames: ['create', 'destroy'], actionNames: ['create', 'destroy'],
detailsViewName: 'details', detailsViewName: 'details',
updateViewName: 'form', updateViewName: 'form',
paginated: false,
}, },
{ {
type: 'table', type: 'table',

View File

@ -102,6 +102,7 @@ export default {
actionNames: ['create', 'destroy'], actionNames: ['create', 'destroy'],
detailsViewName: 'details', detailsViewName: 'details',
updateViewName: 'form', updateViewName: 'form',
paginated: false,
}, },
{ {
type: 'table', type: 'table',

View File

@ -97,6 +97,7 @@ export default {
actionNames: ['create', 'destroy'], actionNames: ['create', 'destroy'],
detailsViewName: 'details', detailsViewName: 'details',
updateViewName: 'form', updateViewName: 'form',
paginated: false,
}, },
{ {
type: 'table', type: 'table',

View File

@ -110,6 +110,7 @@ export default {
actionNames: ['create', 'destroy'], actionNames: ['create', 'destroy'],
detailsViewName: 'details', detailsViewName: 'details',
updateViewName: 'form', updateViewName: 'form',
paginated: false,
}, },
{ {
type: 'table', type: 'table',

View File

@ -210,6 +210,7 @@ export default {
actionNames: ['create', 'destroy'], actionNames: ['create', 'destroy'],
detailsViewName: 'details', detailsViewName: 'details',
updateViewName: 'form', updateViewName: 'form',
paginated: false,
}, },
{ {
type: 'table', type: 'table',

View File

@ -77,6 +77,7 @@ export default {
template: 'SimpleTable', template: 'SimpleTable',
detailsViewName: 'details', detailsViewName: 'details',
updateViewName: 'permission_form', updateViewName: 'permission_form',
paginated: false,
}, },
{ {
type: 'table', type: 'table',