Add pagination to the lists page
This commit is contained in:
parent
b467c9bc3f
commit
d9585a7365
4 changed files with 80 additions and 15 deletions
|
@ -184,9 +184,28 @@ class CreateFormDef extends React.PureComponent {
|
|||
const CreateForm = Form.create()(CreateFormDef)
|
||||
|
||||
class Lists extends React.PureComponent {
|
||||
defaultPerPage = 20
|
||||
state = {
|
||||
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) {
|
||||
|
@ -295,8 +314,28 @@ class Lists extends React.PureComponent {
|
|||
this.fetchRecords()
|
||||
}
|
||||
|
||||
fetchRecords = () => {
|
||||
this.props.modelRequest(cs.ModelLists, cs.Routes.GetLists, cs.MethodGet)
|
||||
fetchRecords = params => {
|
||||
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 => {
|
||||
|
@ -340,7 +379,7 @@ class Lists extends React.PureComponent {
|
|||
<section className="content">
|
||||
<Row>
|
||||
<Col span={22}>
|
||||
<h1>Lists ({this.props.data[cs.ModelLists].length}) </h1>
|
||||
<h1>Lists ({this.props.data[cs.ModelLists].total}) </h1>
|
||||
</Col>
|
||||
<Col span={2}>
|
||||
<Button
|
||||
|
@ -358,9 +397,17 @@ class Lists extends React.PureComponent {
|
|||
className="lists"
|
||||
columns={this.columns}
|
||||
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}
|
||||
pagination={false}
|
||||
pagination={{ ...this.paginationOptions, ...this.state.queryParams }}
|
||||
/>
|
||||
|
||||
<CreateForm
|
||||
|
|
28
lists.go
28
lists.go
|
@ -13,12 +13,21 @@ import (
|
|||
"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.
|
||||
func handleGetLists(c echo.Context) error {
|
||||
var (
|
||||
app = c.Get("app").(*App)
|
||||
out []models.List
|
||||
out listsWrap
|
||||
|
||||
pg = getPagination(c.QueryParams())
|
||||
listID, _ = strconv.Atoi(c.Param("id"))
|
||||
single = false
|
||||
)
|
||||
|
@ -28,27 +37,32 @@ func handleGetLists(c echo.Context) error {
|
|||
single = true
|
||||
}
|
||||
|
||||
err := app.Queries.GetLists.Select(&out, listID)
|
||||
err := app.Queries.GetLists.Select(&out.Results, listID, pg.Offset, pg.Limit)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError,
|
||||
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.")
|
||||
} else if len(out) == 0 {
|
||||
} else if len(out.Results) == 0 {
|
||||
return c.JSON(http.StatusOK, okResp{[]struct{}{}})
|
||||
}
|
||||
|
||||
// Replace null tags.
|
||||
for i, v := range out {
|
||||
for i, v := range out.Results {
|
||||
if v.Tags == nil {
|
||||
out[i].Tags = make(pq.StringArray, 0)
|
||||
out.Results[i].Tags = make(pq.StringArray, 0)
|
||||
}
|
||||
}
|
||||
|
||||
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})
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,10 @@ type List struct {
|
|||
|
||||
// This is only relevant when querying the lists of a subscriber.
|
||||
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.
|
||||
|
|
|
@ -226,11 +226,11 @@ UPDATE subscriber_lists SET status='unsubscribed', updated_at=NOW()
|
|||
|
||||
-- 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
|
||||
ON (subscriber_lists.list_id = lists.id AND subscriber_lists.status != 'unsubscribed')
|
||||
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
|
||||
INSERT INTO lists (uuid, name, type, tags) VALUES($1, $2, $3, $4) RETURNING id;
|
||||
|
|
Loading…
Reference in a new issue