feat: add server-side pagination (#312)

Signed-off-by: “seriouszyx” <seriouszyx@foxmail.com>
This commit is contained in:
Yixiang Zhao
2021-11-06 11:32:22 +08:00
committed by GitHub
parent 7520b71198
commit b1db47bad1
28 changed files with 444 additions and 103 deletions

View File

@ -27,28 +27,33 @@ class ApplicationListPage extends React.Component {
this.state = {
classes: props,
applications: null,
total: 0,
};
}
UNSAFE_componentWillMount() {
this.getApplications();
this.getApplications(1, 10);
}
getApplications() {
ApplicationBackend.getApplications("admin")
getApplications(page, pageSize) {
ApplicationBackend.getApplications("admin", page, pageSize)
.then((res) => {
this.setState({
applications: res,
});
if (res.status === "ok") {
this.setState({
applications: res.data,
total: res.data2
});
}
});
}
newApplication() {
var randomName = Math.random().toString(36).slice(-6)
return {
owner: "admin", // this.props.account.applicationname,
name: `application_${this.state.applications.length}`,
name: `application_${randomName}`,
createdTime: moment().format(),
displayName: `New Application - ${this.state.applications.length}`,
displayName: `New Application - ${randomName}`,
logo: "https://cdn.casbin.com/logo/logo_1024x256.png",
enablePassword: true,
enableSignUp: true,
@ -75,6 +80,7 @@ class ApplicationListPage extends React.Component {
Setting.showMessage("success", `Application added successfully`);
this.setState({
applications: Setting.prependRow(this.state.applications, newApplication),
total: this.state.total + 1
});
}
)
@ -89,6 +95,7 @@ class ApplicationListPage extends React.Component {
Setting.showMessage("success", `Application deleted successfully`);
this.setState({
applications: Setting.deleteRow(this.state.applications, i),
total: this.state.total - 1
});
}
)
@ -213,9 +220,18 @@ class ApplicationListPage extends React.Component {
},
];
const paginationProps = {
total: this.state.total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.total),
onChange: (page, pageSize) => this.getApplications(page, pageSize),
onShowSizeChange: (current, size) => this.getApplications(current, size),
};
return (
<div>
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={applications} rowKey="name" size="middle" bordered pagination={{pageSize: 100}}
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={applications} rowKey="name" size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Applications")}&nbsp;&nbsp;&nbsp;&nbsp;

View File

@ -26,28 +26,33 @@ class OrganizationListPage extends React.Component {
this.state = {
classes: props,
organizations: null,
total: 0
};
}
UNSAFE_componentWillMount() {
this.getOrganizations();
this.getOrganizations(1, 10);
}
getOrganizations() {
OrganizationBackend.getOrganizations("admin")
getOrganizations(page, pageSize) {
OrganizationBackend.getOrganizations("admin", page, pageSize)
.then((res) => {
this.setState({
organizations: res,
});
if (res.status === "ok") {
this.setState({
organizations: res.data,
total: res.data2
});
}
});
}
newOrganization() {
var randomName = Math.random().toString(36).slice(-6)
return {
owner: "admin", // this.props.account.organizationname,
name: `organization_${this.state.organizations.length}`,
name: `organization_${randomName}`,
createdTime: moment().format(),
displayName: `New Organization - ${this.state.organizations.length}`,
displayName: `New Organization - ${randomName}`,
websiteUrl: "https://door.casbin.com",
favicon: "https://cdn.casbin.com/static/favicon.ico",
passwordType: "plain",
@ -64,6 +69,7 @@ class OrganizationListPage extends React.Component {
Setting.showMessage("success", `Organization added successfully`);
this.setState({
organizations: Setting.prependRow(this.state.organizations, newOrganization),
total: this.state.total + 1
});
}
)
@ -78,6 +84,7 @@ class OrganizationListPage extends React.Component {
Setting.showMessage("success", `Organization deleted successfully`);
this.setState({
organizations: Setting.deleteRow(this.state.organizations, i),
total: this.state.total - 1
});
}
)
@ -197,9 +204,18 @@ class OrganizationListPage extends React.Component {
},
];
const paginationProps = {
total: this.state.total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.total),
onChange: (page, pageSize) => this.getOrganizations(page, pageSize),
onShowSizeChange: (current, size) => this.getOrganizations(current, size),
};
return (
<div>
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={organizations} rowKey="name" size="middle" bordered pagination={{pageSize: 100}}
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={organizations} rowKey="name" size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Organizations")}&nbsp;&nbsp;&nbsp;&nbsp;

View File

@ -27,28 +27,33 @@ class ProviderListPage extends React.Component {
this.state = {
classes: props,
providers: null,
total: 0,
};
}
UNSAFE_componentWillMount() {
this.getProviders();
this.getProviders(1, 10);
}
getProviders() {
ProviderBackend.getProviders("admin")
getProviders(page, pageSize) {
ProviderBackend.getProviders("admin", page, pageSize)
.then((res) => {
this.setState({
providers: res,
});
if (res.status === "ok") {
this.setState({
providers: res.data,
total: res.data2
});
}
});
}
newProvider() {
var randomName = Math.random().toString(36).slice(-6)
return {
owner: "admin", // this.props.account.providername,
name: `provider_${this.state.providers.length}`,
name: `provider_${randomName}`,
createdTime: moment().format(),
displayName: `New Provider - ${this.state.providers.length}`,
displayName: `New Provider - ${randomName}`,
category: "OAuth",
type: "GitHub",
method: "Normal",
@ -68,6 +73,7 @@ class ProviderListPage extends React.Component {
Setting.showMessage("success", `Provider added successfully`);
this.setState({
providers: Setting.prependRow(this.state.providers, newProvider),
total: this.state.total + 1
});
}
)
@ -82,6 +88,7 @@ class ProviderListPage extends React.Component {
Setting.showMessage("success", `Provider deleted successfully`);
this.setState({
providers: Setting.deleteRow(this.state.providers, i),
total: this.state.total - 1
});
}
)
@ -212,9 +219,18 @@ class ProviderListPage extends React.Component {
},
];
const paginationProps = {
total: this.state.total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.total),
onChange: (page, pageSize) => this.getProviders(page, pageSize),
onShowSizeChange: (current, size) => this.getProviders(current, size),
};
return (
<div>
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={providers} rowKey="name" size="middle" bordered pagination={{pageSize: 100}}
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={providers} rowKey="name" size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Providers")}&nbsp;&nbsp;&nbsp;&nbsp;

View File

@ -25,19 +25,23 @@ class RecordListPage extends React.Component {
this.state = {
classes: props,
records: null,
total: 0,
};
}
UNSAFE_componentWillMount() {
this.getRecords();
this.getRecords(1, 10);
}
getRecords() {
RecordBackend.getRecords()
getRecords(page, pageSize) {
RecordBackend.getRecords(page, pageSize)
.then((res) => {
this.setState({
records: res,
});
if (res.status === "ok") {
this.setState({
records: res.data,
total: res.data2
});
}
});
}
@ -124,9 +128,18 @@ class RecordListPage extends React.Component {
},
];
const paginationProps = {
total: this.state.total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.total),
onChange: (page, pageSize) => this.getRecords(page, pageSize),
onShowSizeChange: (current, size) => this.getRecords(current, size),
};
return (
<div>
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={records} rowKey="id" size="middle" bordered pagination={{pageSize: 100}}
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={records} rowKey="id" size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Records")}&nbsp;&nbsp;&nbsp;&nbsp;

View File

@ -29,19 +29,23 @@ class ResourceListPage extends React.Component {
resources: null,
fileList: [],
uploading: false,
total: 0,
};
}
UNSAFE_componentWillMount() {
this.getResources();
this.getResources(1, 10);
}
getResources() {
ResourceBackend.getResources(this.props.account.owner, this.props.account.name)
getResources(page, pageSize) {
ResourceBackend.getResources(this.props.account.owner, this.props.account.name, page, pageSize)
.then((res) => {
this.setState({
resources: res,
});
if (res.status === "ok") {
this.setState({
resources: res.data,
total: res.data2
});
}
});
}
@ -51,6 +55,7 @@ class ResourceListPage extends React.Component {
Setting.showMessage("success", `Resource deleted successfully`);
this.setState({
resources: Setting.deleteRow(this.state.resources, i),
total: this.state.total - 1
});
}
)
@ -260,9 +265,18 @@ class ResourceListPage extends React.Component {
},
];
const paginationProps = {
total: this.state.total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.total),
onChange: (page, pageSize) => this.getResources(page, pageSize),
onShowSizeChange: (current, size) => this.getResources(current, size),
};
return (
<div>
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={resources} rowKey="name" size="middle" bordered pagination={{pageSize: 100}}
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={resources} rowKey="name" size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Resources")}&nbsp;&nbsp;&nbsp;&nbsp;

View File

@ -26,26 +26,30 @@ class TokenListPage extends React.Component {
this.state = {
classes: props,
tokens: null,
total: 0,
};
}
UNSAFE_componentWillMount() {
this.getTokens();
this.getTokens(1, 10);
}
getTokens() {
TokenBackend.getTokens("admin")
getTokens(page, pageSize) {
TokenBackend.getTokens("admin", page, pageSize)
.then((res) => {
this.setState({
tokens: res,
});
if (res.status === "ok") {
this.setState({
tokens: res.data,
total: res.data2
});
}
});
}
newToken() {
return {
owner: "admin", // this.props.account.tokenname,
name: `token_${this.state.tokens.length}`,
name: `token_${Math.random().toString(36).slice(-6)}`,
createdTime: moment().format(),
application: "app-built-in",
accessToken: "",
@ -62,6 +66,7 @@ class TokenListPage extends React.Component {
Setting.showMessage("success", `Token added successfully`);
this.setState({
tokens: Setting.prependRow(this.state.tokens, newToken),
total: this.state.total + 1
});
}
)
@ -76,6 +81,7 @@ class TokenListPage extends React.Component {
Setting.showMessage("success", `Token deleted successfully`);
this.setState({
tokens: Setting.deleteRow(this.state.tokens, i),
total: this.state.total - 1
});
}
)
@ -217,9 +223,18 @@ class TokenListPage extends React.Component {
},
];
const paginationProps = {
total: this.state.total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.total),
onChange: (page, pageSize) => this.getTokens(page, pageSize),
onShowSizeChange: (current, size) => this.getTokens(current, size),
};
return (
<div>
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={tokens} rowKey="name" size="middle" bordered pagination={{pageSize: 100}}
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={tokens} rowKey="name" size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Tokens")}&nbsp;&nbsp;&nbsp;&nbsp;

View File

@ -27,39 +27,47 @@ class UserListPage extends React.Component {
classes: props,
users: null,
organizationName: props.match.params.organizationName,
total: 0,
};
}
UNSAFE_componentWillMount() {
this.getUsers();
this.getUsers(1, 10);
}
getUsers() {
getUsers(page, pageSize) {
if (this.state.organizationName === undefined) {
UserBackend.getGlobalUsers()
UserBackend.getGlobalUsers(page, pageSize)
.then((res) => {
this.setState({
users: res,
});
if (res.status === "ok") {
this.setState({
users: res.data,
total: res.data2
});
}
});
} else {
UserBackend.getUsers(this.state.organizationName)
UserBackend.getUsers(this.state.organizationName, page, pageSize)
.then((res) => {
this.setState({
users: res,
});
if (res.status === "ok") {
this.setState({
users: res.data,
total: res.data2
});
}
});
}
}
newUser() {
var randomName = Math.random().toString(36).slice(-6)
return {
owner: "built-in", // this.props.account.username,
name: `user_${this.state.users.length}`,
name: `user_${randomName}`,
createdTime: moment().format(),
type: "normal-user",
password: "123",
displayName: `New User - ${this.state.users.length}`,
displayName: `New User - ${randomName}`,
avatar: "https://casbin.org/img/casbin.svg",
email: "user@example.com",
phone: "12345678",
@ -81,6 +89,7 @@ class UserListPage extends React.Component {
Setting.showMessage("success", `User added successfully`);
this.setState({
users: Setting.prependRow(this.state.users, newUser),
total: this.state.total + 1
});
}
)
@ -95,6 +104,7 @@ class UserListPage extends React.Component {
Setting.showMessage("success", `User deleted successfully`);
this.setState({
users: Setting.deleteRow(this.state.users, i),
total: this.state.total - 1
});
}
)
@ -287,9 +297,18 @@ class UserListPage extends React.Component {
},
];
const paginationProps = {
total: this.state.total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.total),
onChange: (page, pageSize) => this.getUsers(page, pageSize),
onShowSizeChange: (current, size) => this.getUsers(current, size),
};
return (
<div>
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={users} rowKey="name" size="middle" bordered pagination={{pageSize: 100}}
<Table scroll={{x: 'max-content'}} columns={columns} dataSource={users} rowKey="name" size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Users")}&nbsp;&nbsp;&nbsp;&nbsp;

View File

@ -14,8 +14,8 @@
import * as Setting from "../Setting";
export function getApplications(owner) {
return fetch(`${Setting.ServerUrl}/api/get-applications?owner=${owner}`, {
export function getApplications(owner, page, pageSize) {
return fetch(`${Setting.ServerUrl}/api/get-applications?owner=${owner}&p=${page}&pageSize=${pageSize}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());

View File

@ -14,8 +14,8 @@
import * as Setting from "../Setting";
export function getOrganizations(owner) {
return fetch(`${Setting.ServerUrl}/api/get-organizations?owner=${owner}`, {
export function getOrganizations(owner, page, pageSize) {
return fetch(`${Setting.ServerUrl}/api/get-organizations?owner=${owner}&p=${page}&pageSize=${pageSize}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());

View File

@ -14,8 +14,8 @@
import * as Setting from "../Setting";
export function getProviders(owner) {
return fetch(`${Setting.ServerUrl}/api/get-providers?owner=${owner}`, {
export function getProviders(owner, page, pageSize) {
return fetch(`${Setting.ServerUrl}/api/get-providers?owner=${owner}&p=${page}&pageSize=${pageSize}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());

View File

@ -14,8 +14,8 @@
import * as Setting from "../Setting";
export function getRecords() {
return fetch(`${Setting.ServerUrl}/api/get-records`, {
export function getRecords(page, pageSize) {
return fetch(`${Setting.ServerUrl}/api/get-records?pageSize=${pageSize}&p=${page}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());

View File

@ -14,8 +14,8 @@
import * as Setting from "../Setting";
export function getResources(owner, user) {
return fetch(`${Setting.ServerUrl}/api/get-resources?owner=${owner}&user=${user}`, {
export function getResources(owner, user, page, pageSize) {
return fetch(`${Setting.ServerUrl}/api/get-resources?owner=${owner}&user=${user}&p=${page}&pageSize=${pageSize}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());

View File

@ -14,8 +14,8 @@
import * as Setting from "../Setting";
export function getTokens(owner) {
return fetch(`${Setting.ServerUrl}/api/get-tokens?owner=${owner}`, {
export function getTokens(owner, page, pageSize) {
return fetch(`${Setting.ServerUrl}/api/get-tokens?owner=${owner}&p=${page}&pageSize=${pageSize}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());

View File

@ -15,15 +15,15 @@
import * as Setting from "../Setting";
import i18next from "i18next";
export function getGlobalUsers() {
return fetch(`${Setting.ServerUrl}/api/get-global-users`, {
export function getGlobalUsers(page, pageSize) {
return fetch(`${Setting.ServerUrl}/api/get-global-users?p=${page}&pageSize=${pageSize}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());
}
export function getUsers(owner) {
return fetch(`${Setting.ServerUrl}/api/get-users?owner=${owner}`, {
export function getUsers(owner, page, pageSize) {
return fetch(`${Setting.ServerUrl}/api/get-users?owner=${owner}&p=${page}&pageSize=${pageSize}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());