From b1db47bad1a24b99c742f3417314348b038d8569 Mon Sep 17 00:00:00 2001 From: Yixiang Zhao Date: Sat, 6 Nov 2021 11:32:22 +0800 Subject: [PATCH] feat: add server-side pagination (#312) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: “seriouszyx” --- controllers/application.go | 17 ++++++++-- controllers/organization.go | 16 +++++++-- controllers/provider.go | 16 +++++++-- controllers/record.go | 17 ++++++++-- controllers/resource.go | 15 +++++++-- controllers/token.go | 18 +++++++++-- controllers/user.go | 29 ++++++++++++++--- object/application.go | 19 +++++++++++ object/organization.go | 21 +++++++++++- object/provider.go | 19 +++++++++++ object/record.go | 10 ++++++ object/resource.go | 24 ++++++++++++++ object/token.go | 23 +++++++++++-- object/user.go | 38 ++++++++++++++++++++++ web/src/ApplicationListPage.js | 34 +++++++++++++------ web/src/OrganizationListPage.js | 34 +++++++++++++------ web/src/ProviderListPage.js | 34 +++++++++++++------ web/src/RecordListPage.js | 27 ++++++++++++---- web/src/ResourceListPage.js | 28 ++++++++++++---- web/src/TokenListPage.js | 31 +++++++++++++----- web/src/UserListPage.js | 45 ++++++++++++++++++-------- web/src/backend/ApplicationBackend.js | 4 +-- web/src/backend/OrganizationBackend.js | 4 +-- web/src/backend/ProviderBackend.js | 4 +-- web/src/backend/RecordBackend.js | 4 +-- web/src/backend/ResourceBackend.js | 4 +-- web/src/backend/TokenBackend.js | 4 +-- web/src/backend/UserBackend.js | 8 ++--- 28 files changed, 444 insertions(+), 103 deletions(-) diff --git a/controllers/application.go b/controllers/application.go index c0f41f12..9dad8509 100644 --- a/controllers/application.go +++ b/controllers/application.go @@ -16,7 +16,10 @@ package controllers import ( "encoding/json" + + "github.com/astaxie/beego/utils/pagination" "github.com/casbin/casdoor/object" + "github.com/casbin/casdoor/util" ) // GetApplications @@ -27,9 +30,17 @@ import ( // @router /get-applications [get] func (c *ApiController) GetApplications() { owner := c.Input().Get("owner") - - c.Data["json"] = object.GetApplications(owner) - c.ServeJSON() + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + if limit == "" || page == "" { + c.Data["json"] = object.GetApplications(owner) + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetApplicationCount(owner))) + applications := object.GetPaginationApplications(owner, paginator.Offset(), limit) + c.ResponseOk(applications, paginator.Nums()) + } } // GetApplication diff --git a/controllers/organization.go b/controllers/organization.go index 78c4092d..6970499d 100644 --- a/controllers/organization.go +++ b/controllers/organization.go @@ -17,7 +17,9 @@ package controllers import ( "encoding/json" + "github.com/astaxie/beego/utils/pagination" "github.com/casbin/casdoor/object" + "github.com/casbin/casdoor/util" ) // GetOrganizations ... @@ -28,9 +30,17 @@ import ( // @router /get-organizations [get] func (c *ApiController) GetOrganizations() { owner := c.Input().Get("owner") - - c.Data["json"] = object.GetOrganizations(owner) - c.ServeJSON() + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + if limit == "" || page == "" { + c.Data["json"] = object.GetOrganizations(owner) + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetOrganizationCount(owner))) + organizations := object.GetPaginationOrganizations(owner, paginator.Offset(), limit) + c.ResponseOk(organizations, paginator.Nums()) + } } // GetOrganization ... diff --git a/controllers/provider.go b/controllers/provider.go index fbd3afcb..246a56e1 100644 --- a/controllers/provider.go +++ b/controllers/provider.go @@ -17,7 +17,9 @@ package controllers import ( "encoding/json" + "github.com/astaxie/beego/utils/pagination" "github.com/casbin/casdoor/object" + "github.com/casbin/casdoor/util" ) // GetProviders @@ -28,9 +30,17 @@ import ( // @router /get-providers [get] func (c *ApiController) GetProviders() { owner := c.Input().Get("owner") - - c.Data["json"] = object.GetProviders(owner) - c.ServeJSON() + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + if limit == "" || page == "" { + c.Data["json"] = object.GetProviders(owner) + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetProviderCount(owner))) + providers := object.GetPaginationProviders(owner, paginator.Offset(), limit) + c.ResponseOk(providers, paginator.Nums()) + } } // @Title GetProvider diff --git a/controllers/record.go b/controllers/record.go index e91610b6..ec5b2403 100644 --- a/controllers/record.go +++ b/controllers/record.go @@ -17,17 +17,30 @@ package controllers import ( "encoding/json" + "github.com/astaxie/beego/utils/pagination" "github.com/casbin/casdoor/object" + "github.com/casbin/casdoor/util" ) // GetRecords // @Title GetRecords // @Description get all records +// @Param pageSize query string true "The size of each page" +// @Param p query string true "The number of the page" // @Success 200 {array} object.Records The Response object // @router /get-records [get] func (c *ApiController) GetRecords() { - c.Data["json"] = object.GetRecords() - c.ServeJSON() + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + if limit == "" || page == "" { + c.Data["json"] = object.GetRecords() + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetRecordCount())) + records := object.GetPaginationRecords(paginator.Offset(), limit) + c.ResponseOk(records, paginator.Nums()) + } } // GetRecordsByFilter diff --git a/controllers/resource.go b/controllers/resource.go index 412393cb..2c506968 100644 --- a/controllers/resource.go +++ b/controllers/resource.go @@ -22,6 +22,7 @@ import ( "mime" "path/filepath" + "github.com/astaxie/beego/utils/pagination" "github.com/casbin/casdoor/object" "github.com/casbin/casdoor/util" ) @@ -29,9 +30,17 @@ import ( func (c *ApiController) GetResources() { owner := c.Input().Get("owner") user := c.Input().Get("user") - - c.Data["json"] = object.GetResources(owner, user) - c.ServeJSON() + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + if limit == "" || page == "" { + c.Data["json"] = object.GetResources(owner, user) + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetResourceCount(owner, user))) + resources := object.GetPaginationResources(owner, user, paginator.Offset(), limit) + c.ResponseOk(resources, paginator.Nums()) + } } func (c *ApiController) GetResource() { diff --git a/controllers/token.go b/controllers/token.go index c128fcec..07f62792 100644 --- a/controllers/token.go +++ b/controllers/token.go @@ -17,20 +17,32 @@ package controllers import ( "encoding/json" + "github.com/astaxie/beego/utils/pagination" "github.com/casbin/casdoor/object" + "github.com/casbin/casdoor/util" ) // GetTokens // @Title GetTokens // @Description get tokens // @Param owner query string true "The owner of tokens" +// @Param pageSize query string true "The size of each page" +// @Param p query string true "The number of the page" // @Success 200 {array} object.Token The Response object // @router /get-tokens [get] func (c *ApiController) GetTokens() { owner := c.Input().Get("owner") - - c.Data["json"] = object.GetTokens(owner) - c.ServeJSON() + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + if limit == "" || page == "" { + c.Data["json"] = object.GetTokens(owner) + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetTokenCount(owner))) + tokens := object.GetPaginationTokens(owner, paginator.Offset(), limit) + c.ResponseOk(tokens, paginator.Nums()) + } } // GetToken diff --git a/controllers/user.go b/controllers/user.go index 50fe3baa..1306855b 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -19,8 +19,10 @@ import ( "fmt" "strings" + "github.com/astaxie/beego/utils/pagination" "github.com/casbin/casdoor/object" "github.com/casbin/casdoor/original" + "github.com/casbin/casdoor/util" ) // GetGlobalUsers @@ -29,8 +31,17 @@ import ( // @Success 200 {array} object.User The Response object // @router /get-global-users [get] func (c *ApiController) GetGlobalUsers() { - c.Data["json"] = object.GetMaskedUsers(object.GetGlobalUsers()) - c.ServeJSON() + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + if limit == "" || page == "" { + c.Data["json"] = object.GetMaskedUsers(object.GetGlobalUsers()) + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetGlobalUserCount())) + users := object.GetPaginationGlobalUsers(paginator.Offset(), limit) + c.ResponseOk(users, paginator.Nums()) + } } // GetUsers @@ -41,9 +52,17 @@ func (c *ApiController) GetGlobalUsers() { // @router /get-users [get] func (c *ApiController) GetUsers() { owner := c.Input().Get("owner") - - c.Data["json"] = object.GetMaskedUsers(object.GetUsers(owner)) - c.ServeJSON() + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + if limit == "" || page == "" { + c.Data["json"] = object.GetMaskedUsers(object.GetUsers(owner)) + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetUserCount(owner))) + users := object.GetPaginationUsers(owner, paginator.Offset(), limit) + c.ResponseOk(users, paginator.Nums()) + } } // GetUser diff --git a/object/application.go b/object/application.go index 7e49c2c8..74f1b13e 100644 --- a/object/application.go +++ b/object/application.go @@ -48,6 +48,15 @@ type Application struct { SigninHtml string `xorm:"mediumtext" json:"signinHtml"` } +func GetApplicationCount(owner string) int { + count, err := adapter.Engine.Count(&Application{Owner: owner}) + if err != nil { + panic(err) + } + + return int(count) +} + func GetApplications(owner string) []*Application { applications := []*Application{} err := adapter.Engine.Desc("created_time").Find(&applications, &Application{Owner: owner}) @@ -58,6 +67,16 @@ func GetApplications(owner string) []*Application { return applications } +func GetPaginationApplications(owner string, offset, limit int) []*Application { + applications := []*Application{} + err := adapter.Engine.Desc("created_time").Limit(limit, offset).Find(&applications, &Application{Owner: owner}) + if err != nil { + panic(err) + } + + return applications +} + func getProviderMap(owner string) map[string]*Provider { providers := GetProviders(owner) m := map[string]*Provider{} diff --git a/object/organization.go b/object/organization.go index 13d138b3..c7516ea4 100644 --- a/object/organization.go +++ b/object/organization.go @@ -33,6 +33,15 @@ type Organization struct { DefaultAvatar string `xorm:"varchar(100)" json:"defaultAvatar"` } +func GetOrganizationCount(owner string) int { + count, err := adapter.Engine.Count(&Organization{Owner: owner}) + if err != nil { + panic(err) + } + + return int(count) +} + func GetOrganizations(owner string) []*Organization { organizations := []*Organization{} err := adapter.Engine.Desc("created_time").Find(&organizations, &Organization{Owner: owner}) @@ -43,6 +52,16 @@ func GetOrganizations(owner string) []*Organization { return organizations } +func GetPaginationOrganizations(owner string, offset, limit int) []*Organization { + organizations := []*Organization{} + err := adapter.Engine.Desc("created_time").Limit(limit, offset).Find(&organizations, &Provider{Owner: owner}) + if err != nil { + panic(err) + } + + return organizations +} + func getOrganization(owner string, name string) *Organization { if owner == "" || name == "" { return nil @@ -57,7 +76,7 @@ func getOrganization(owner string, name string) *Organization { if existed { return &organization } - + return nil } diff --git a/object/provider.go b/object/provider.go index 905f14fb..6091eba7 100644 --- a/object/provider.go +++ b/object/provider.go @@ -64,6 +64,15 @@ func getMaskedProvider(provider *Provider) *Provider { return p } +func GetProviderCount(owner string) int { + count, err := adapter.Engine.Count(&Provider{Owner: owner}) + if err != nil { + panic(err) + } + + return int(count) +} + func GetProviders(owner string) []*Provider { providers := []*Provider{} err := adapter.Engine.Desc("created_time").Find(&providers, &Provider{Owner: owner}) @@ -74,6 +83,16 @@ func GetProviders(owner string) []*Provider { return providers } +func GetPaginationProviders(owner string, offset, limit int) []*Provider { + providers := []*Provider{} + err := adapter.Engine.Desc("created_time").Limit(limit, offset).Find(&providers, &Provider{Owner: owner}) + if err != nil { + panic(err) + } + + return providers +} + func getProvider(owner string, name string) *Provider { if owner == "" || name == "" { return nil diff --git a/object/record.go b/object/record.go index 6a07dddb..425beada 100644 --- a/object/record.go +++ b/object/record.go @@ -54,6 +54,16 @@ func GetRecords() []*Records { return records } +func GetPaginationRecords(offset, limit int) []*Records { + records := []*Records{} + err := adapter.Engine.Desc("id").Limit(limit, offset).Find(&records) + if err != nil { + panic(err) + } + + return records +} + func GetRecordsByField(record *Records) []*Records { records := []*Records{} err := adapter.Engine.Find(&records, record) diff --git a/object/resource.go b/object/resource.go index d337512c..541e56ee 100644 --- a/object/resource.go +++ b/object/resource.go @@ -38,6 +38,15 @@ type Resource struct { Url string `xorm:"varchar(1000)" json:"url"` } +func GetResourceCount(owner string, user string) int { + count, err := adapter.Engine.Count(&Resource{Owner: owner, User: user}) + if err != nil { + panic(err) + } + + return int(count) +} + func GetResources(owner string, user string) []*Resource { if owner == "built-in" { owner = "" @@ -53,6 +62,21 @@ func GetResources(owner string, user string) []*Resource { return resources } +func GetPaginationResources(owner, user string, offset, limit int) []*Resource { + if owner == "built-in" { + owner = "" + user = "" + } + + resources := []*Resource{} + err := adapter.Engine.Desc("created_time").Limit(limit, offset).Find(&resources, &Resource{Owner: owner, User: user}) + if err != nil { + panic(err) + } + + return resources +} + func getResource(owner string, name string) *Resource { resource := Resource{Owner: owner, Name: name} existed, err := adapter.Engine.Get(&resource) diff --git a/object/token.go b/object/token.go index c9dc6396..7e12e9cc 100644 --- a/object/token.go +++ b/object/token.go @@ -49,6 +49,15 @@ type TokenWrapper struct { Scope string `json:"scope"` } +func GetTokenCount(owner string) int { + count, err := adapter.Engine.Count(&Token{Owner: owner}) + if err != nil { + panic(err) + } + + return int(count) +} + func GetTokens(owner string) []*Token { tokens := []*Token{} err := adapter.Engine.Desc("created_time").Find(&tokens, &Token{Owner: owner}) @@ -59,6 +68,16 @@ func GetTokens(owner string) []*Token { return tokens } +func GetPaginationTokens(owner string, offset, limit int) []*Token { + tokens := []*Token{} + err := adapter.Engine.Desc("created_time").Limit(limit, offset).Find(&tokens, &Token{Owner: owner}) + if err != nil { + panic(err) + } + + return tokens +} + func getToken(owner string, name string) *Token { if owner == "" || name == "" { return nil @@ -73,7 +92,7 @@ func getToken(owner string, name string) *Token { if existed { return &token } - + return nil } @@ -87,7 +106,7 @@ func getTokenByCode(code string) *Token { if existed { return &token } - + return nil } diff --git a/object/user.go b/object/user.go index 4a8b4a92..5c42bf0b 100644 --- a/object/user.go +++ b/object/user.go @@ -72,6 +72,15 @@ type User struct { Properties map[string]string `json:"properties"` } +func GetGlobalUserCount() int { + count, err := adapter.Engine.Count(&User{}) + if err != nil { + panic(err) + } + + return int(count) +} + func GetGlobalUsers() []*User { users := []*User{} err := adapter.Engine.Desc("created_time").Find(&users) @@ -82,6 +91,25 @@ func GetGlobalUsers() []*User { return users } +func GetPaginationGlobalUsers(offset, limit int) []*User { + users := []*User{} + err := adapter.Engine.Desc("created_time").Limit(limit, offset).Find(&users) + if err != nil { + panic(err) + } + + return users +} + +func GetUserCount(owner string) int { + count, err := adapter.Engine.Count(&User{Owner: owner}) + if err != nil { + panic(err) + } + + return int(count) +} + func GetUsers(owner string) []*User { users := []*User{} err := adapter.Engine.Desc("created_time").Find(&users, &User{Owner: owner}) @@ -92,6 +120,16 @@ func GetUsers(owner string) []*User { return users } +func GetPaginationUsers(owner string, offset, limit int) []*User { + users := []*User{} + err := adapter.Engine.Desc("created_time").Limit(limit, offset).Find(&users, &User{Owner: owner}) + if err != nil { + panic(err) + } + + return users +} + func getUser(owner string, name string) *User { if owner == "" || name == "" { return nil diff --git a/web/src/ApplicationListPage.js b/web/src/ApplicationListPage.js index 317164b2..0b7dd46a 100644 --- a/web/src/ApplicationListPage.js +++ b/web/src/ApplicationListPage.js @@ -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 (
- (
{i18next.t("general:Applications")}     diff --git a/web/src/OrganizationListPage.js b/web/src/OrganizationListPage.js index 0237fa97..a1ee31ae 100644 --- a/web/src/OrganizationListPage.js +++ b/web/src/OrganizationListPage.js @@ -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 (
-
(
{i18next.t("general:Organizations")}     diff --git a/web/src/ProviderListPage.js b/web/src/ProviderListPage.js index 2b2ce459..d3330090 100644 --- a/web/src/ProviderListPage.js +++ b/web/src/ProviderListPage.js @@ -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 (
-
(
{i18next.t("general:Providers")}     diff --git a/web/src/RecordListPage.js b/web/src/RecordListPage.js index de0bc1bd..7e0d3609 100644 --- a/web/src/RecordListPage.js +++ b/web/src/RecordListPage.js @@ -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 (
-
(
{i18next.t("general:Records")}     diff --git a/web/src/ResourceListPage.js b/web/src/ResourceListPage.js index 1e912b96..39505558 100644 --- a/web/src/ResourceListPage.js +++ b/web/src/ResourceListPage.js @@ -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 (
-
(
{i18next.t("general:Resources")}     diff --git a/web/src/TokenListPage.js b/web/src/TokenListPage.js index 5e3e9497..cb8540ff 100644 --- a/web/src/TokenListPage.js +++ b/web/src/TokenListPage.js @@ -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 (
-
(
{i18next.t("general:Tokens")}     diff --git a/web/src/UserListPage.js b/web/src/UserListPage.js index ef269f2a..4cb54950 100644 --- a/web/src/UserListPage.js +++ b/web/src/UserListPage.js @@ -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 (
-
(
{i18next.t("general:Users")}     diff --git a/web/src/backend/ApplicationBackend.js b/web/src/backend/ApplicationBackend.js index 851921fd..fc0dac67 100644 --- a/web/src/backend/ApplicationBackend.js +++ b/web/src/backend/ApplicationBackend.js @@ -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()); diff --git a/web/src/backend/OrganizationBackend.js b/web/src/backend/OrganizationBackend.js index 68e90b41..91ebb635 100644 --- a/web/src/backend/OrganizationBackend.js +++ b/web/src/backend/OrganizationBackend.js @@ -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()); diff --git a/web/src/backend/ProviderBackend.js b/web/src/backend/ProviderBackend.js index 9a055163..86ff6b61 100644 --- a/web/src/backend/ProviderBackend.js +++ b/web/src/backend/ProviderBackend.js @@ -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()); diff --git a/web/src/backend/RecordBackend.js b/web/src/backend/RecordBackend.js index 873eee67..a49e3c71 100644 --- a/web/src/backend/RecordBackend.js +++ b/web/src/backend/RecordBackend.js @@ -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()); diff --git a/web/src/backend/ResourceBackend.js b/web/src/backend/ResourceBackend.js index 79f15ca2..7079d8d2 100644 --- a/web/src/backend/ResourceBackend.js +++ b/web/src/backend/ResourceBackend.js @@ -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()); diff --git a/web/src/backend/TokenBackend.js b/web/src/backend/TokenBackend.js index 1adb93a5..b248f0d6 100644 --- a/web/src/backend/TokenBackend.js +++ b/web/src/backend/TokenBackend.js @@ -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()); diff --git a/web/src/backend/UserBackend.js b/web/src/backend/UserBackend.js index abeb18ea..829d7409 100644 --- a/web/src/backend/UserBackend.js +++ b/web/src/backend/UserBackend.js @@ -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());