Add pagination to the lists page

This commit is contained in:
Kailash Nadh 2019-05-14 16:41:05 +05:30
parent b467c9bc3f
commit d9585a7365
4 changed files with 80 additions and 15 deletions

View File

@ -184,9 +184,28 @@ class CreateFormDef extends React.PureComponent {
const CreateForm = Form.create()(CreateFormDef) const CreateForm = Form.create()(CreateFormDef)
class Lists extends React.PureComponent { class Lists extends React.PureComponent {
defaultPerPage = 20
state = { state = {
formType: null, formType: null,
record: {} record: {},
queryParams: {}
}
// Pagination config.
paginationOptions = {
hideOnSinglePage: false,
showSizeChanger: true,
showQuickJumper: true,
defaultPageSize: this.defaultPerPage,
pageSizeOptions: ["20", "50", "70", "100"],
position: "both",
showTotal: (total, range) => `${range[0]} to ${range[1]} of ${total}`,
onChange: (page, perPage) => {
this.fetchRecords({ page: page, per_page: perPage })
},
onShowSizeChange: (page, perPage) => {
this.fetchRecords({ page: page, per_page: perPage })
}
} }
constructor(props) { constructor(props) {
@ -295,8 +314,28 @@ class Lists extends React.PureComponent {
this.fetchRecords() this.fetchRecords()
} }
fetchRecords = () => { fetchRecords = params => {
this.props.modelRequest(cs.ModelLists, cs.Routes.GetLists, cs.MethodGet) let qParams = {
page: this.state.queryParams.page,
per_page: this.state.queryParams.per_page
}
if (params) {
qParams = { ...qParams, ...params }
}
this.props
.modelRequest(cs.ModelLists, cs.Routes.GetLists, cs.MethodGet, qParams)
.then(() => {
this.setState({
queryParams: {
...this.state.queryParams,
total: this.props.data[cs.ModelLists].total,
perPage: this.props.data[cs.ModelLists].per_page,
page: this.props.data[cs.ModelLists].page,
query: this.props.data[cs.ModelLists].query
}
})
})
} }
deleteRecord = record => { deleteRecord = record => {
@ -340,7 +379,7 @@ class Lists extends React.PureComponent {
<section className="content"> <section className="content">
<Row> <Row>
<Col span={22}> <Col span={22}>
<h1>Lists ({this.props.data[cs.ModelLists].length}) </h1> <h1>Lists ({this.props.data[cs.ModelLists].total}) </h1>
</Col> </Col>
<Col span={2}> <Col span={2}>
<Button <Button
@ -358,9 +397,17 @@ class Lists extends React.PureComponent {
className="lists" className="lists"
columns={this.columns} columns={this.columns}
rowKey={record => record.uuid} rowKey={record => record.uuid}
dataSource={this.props.data[cs.ModelLists]} dataSource={(() => {
if (
!this.props.data[cs.ModelLists] ||
!this.props.data[cs.ModelLists].hasOwnProperty("results")
) {
return []
}
return this.props.data[cs.ModelLists].results
})()}
loading={this.props.reqStates[cs.ModelLists] !== cs.StateDone} loading={this.props.reqStates[cs.ModelLists] !== cs.StateDone}
pagination={false} pagination={{ ...this.paginationOptions, ...this.state.queryParams }}
/> />
<CreateForm <CreateForm

View File

@ -13,12 +13,21 @@ import (
"github.com/labstack/echo" "github.com/labstack/echo"
) )
type listsWrap struct {
Results []models.List `json:"results"`
Total int `json:"total"`
PerPage int `json:"per_page"`
Page int `json:"page"`
}
// handleGetLists handles retrieval of lists. // handleGetLists handles retrieval of lists.
func handleGetLists(c echo.Context) error { func handleGetLists(c echo.Context) error {
var ( var (
app = c.Get("app").(*App) app = c.Get("app").(*App)
out []models.List out listsWrap
pg = getPagination(c.QueryParams())
listID, _ = strconv.Atoi(c.Param("id")) listID, _ = strconv.Atoi(c.Param("id"))
single = false single = false
) )
@ -28,27 +37,32 @@ func handleGetLists(c echo.Context) error {
single = true single = true
} }
err := app.Queries.GetLists.Select(&out, listID) err := app.Queries.GetLists.Select(&out.Results, listID, pg.Offset, pg.Limit)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching lists: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching lists: %s", pqErrMsg(err)))
} else if single && len(out) == 0 { } else if single && len(out.Results) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, "List not found.") return echo.NewHTTPError(http.StatusBadRequest, "List not found.")
} else if len(out) == 0 { } else if len(out.Results) == 0 {
return c.JSON(http.StatusOK, okResp{[]struct{}{}}) return c.JSON(http.StatusOK, okResp{[]struct{}{}})
} }
// Replace null tags. // Replace null tags.
for i, v := range out { for i, v := range out.Results {
if v.Tags == nil { if v.Tags == nil {
out[i].Tags = make(pq.StringArray, 0) out.Results[i].Tags = make(pq.StringArray, 0)
} }
} }
if single { if single {
return c.JSON(http.StatusOK, okResp{out[0]}) return c.JSON(http.StatusOK, okResp{out.Results[0]})
} }
// Meta.
out.Total = out.Results[0].Total
out.Page = pg.Page
out.PerPage = pg.PerPage
return c.JSON(http.StatusOK, okResp{out}) return c.JSON(http.StatusOK, okResp{out})
} }

View File

@ -121,6 +121,10 @@ type List struct {
// This is only relevant when querying the lists of a subscriber. // This is only relevant when querying the lists of a subscriber.
SubscriptionStatus string `db:"subscription_status" json:"subscription_status,omitempty"` SubscriptionStatus string `db:"subscription_status" json:"subscription_status,omitempty"`
// Pseudofield for getting the total number of subscribers
// in searches and queries.
Total int `db:"total" json:"-"`
} }
// Campaign represents an e-mail campaign. // Campaign represents an e-mail campaign.

View File

@ -226,11 +226,11 @@ UPDATE subscriber_lists SET status='unsubscribed', updated_at=NOW()
-- lists -- lists
-- name: get-lists -- name: get-lists
SELECT lists.*, COUNT(subscriber_lists.subscriber_id) AS subscriber_count SELECT COUNT(*) OVER () AS total, lists.*, COUNT(subscriber_lists.subscriber_id) AS subscriber_count
FROM lists LEFT JOIN subscriber_lists FROM lists LEFT JOIN subscriber_lists
ON (subscriber_lists.list_id = lists.id AND subscriber_lists.status != 'unsubscribed') ON (subscriber_lists.list_id = lists.id AND subscriber_lists.status != 'unsubscribed')
WHERE ($1 = 0 OR id = $1) WHERE ($1 = 0 OR id = $1)
GROUP BY lists.id ORDER BY lists.created_at; GROUP BY lists.id ORDER BY lists.created_at OFFSET $2 LIMIT $3;
-- name: create-list -- name: create-list
INSERT INTO lists (uuid, name, type, tags) VALUES($1, $2, $3, $4) RETURNING id; INSERT INTO lists (uuid, name, type, tags) VALUES($1, $2, $3, $4) RETURNING id;