Fix import and campaign page and integrate new paginated lists API

This commit is contained in:
Kailash Nadh 2019-05-14 22:06:14 +05:30
parent 3cf075e3a9
commit 8701cb445a
8 changed files with 67 additions and 31 deletions

View File

@ -79,7 +79,9 @@ class App extends React.PureComponent {
// If it's a GET call, set the response as the data state. // If it's a GET call, set the response as the data state.
if (method === cs.MethodGet) { if (method === cs.MethodGet) {
this.setState({ data: { ...this.state.data, [model]: res.data.data } }) this.setState({
data: { ...this.state.data, [model]: res.data.data }
})
} }
return res return res
} catch (e) { } catch (e) {

View File

@ -440,17 +440,20 @@ class TheFormDef extends React.PureComponent {
initialValue: initialValue:
subLists.length > 0 subLists.length > 0
? subLists ? subLists
: this.props.data[cs.ModelLists].length === 1 : this.props.data[cs.ModelLists].hasOwnProperty(
? [this.props.data[cs.ModelLists][0].id] "results"
) && this.props.data[cs.ModelLists].results.length === 1
? [this.props.data[cs.ModelLists].results[0].id]
: undefined, : undefined,
rules: [{ required: true }] rules: [{ required: true }]
})( })(
<Select disabled={this.props.formDisabled} mode="multiple"> <Select disabled={this.props.formDisabled} mode="multiple">
{[...this.props.data[cs.ModelLists]].map((v, i) => ( {this.props.data[cs.ModelLists].hasOwnProperty("results") &&
<Select.Option value={v["id"]} key={v["id"]}> [...this.props.data[cs.ModelLists].results].map((v, i) => (
{v["name"]} <Select.Option value={v["id"]} key={v["id"]}>
</Select.Option> {v["name"]}
))} </Select.Option>
))}
</Select> </Select>
)} )}
</Form.Item> </Form.Item>
@ -585,7 +588,9 @@ class Campaign extends React.PureComponent {
componentDidMount = () => { componentDidMount = () => {
// Fetch lists. // Fetch lists.
this.props.modelRequest(cs.ModelLists, cs.Routes.GetLists, cs.MethodGet) this.props.modelRequest(cs.ModelLists, cs.Routes.GetLists, cs.MethodGet, {
per_page: "all"
})
// Fetch templates. // Fetch templates.
this.props.modelRequest( this.props.modelRequest(

View File

@ -33,7 +33,9 @@ class TheFormDef extends React.PureComponent {
componentDidMount() { componentDidMount() {
// Fetch lists. // Fetch lists.
this.props.modelRequest(cs.ModelLists, cs.Routes.GetLists, cs.MethodGet) this.props.modelRequest(cs.ModelLists, cs.Routes.GetLists, cs.MethodGet, {
per_page: "all"
})
} }
// Handle create / edit form submission. // Handle create / edit form submission.
@ -413,7 +415,11 @@ class Import extends React.PureComponent {
<TheForm <TheForm
{...this.props} {...this.props}
fetchimportState={this.fetchimportState} fetchimportState={this.fetchimportState}
lists={this.props.data[cs.ModelLists]} lists={
this.props.data[cs.ModelLists].hasOwnProperty("results")
? this.props.data[cs.ModelLists].results
: []
}
/> />
<hr /> <hr />

View File

@ -171,12 +171,19 @@ func makeAttribsBlob(keys []string, vals []string) ([]byte, bool) {
// getPagination takes form values and extracts pagination values from it. // getPagination takes form values and extracts pagination values from it.
func getPagination(q url.Values) pagination { func getPagination(q url.Values) pagination {
var ( var (
perPage, _ = strconv.Atoi(q.Get("per_page")) page, _ = strconv.Atoi(q.Get("page"))
page, _ = strconv.Atoi(q.Get("page")) perPage = defaultPerPage
) )
if perPage < 1 || perPage > maxPerPage { pp := q.Get("per_page")
perPage = defaultPerPage if pp == "all" {
// No limit.
perPage = 0
} else {
ppi, _ := strconv.Atoi(pp)
if ppi < 1 || ppi > maxPerPage {
perPage = defaultPerPage
}
} }
if page < 1 { if page < 1 {

View File

@ -204,6 +204,7 @@ func main() {
} }
app.Importer = subimporter.New(q.UpsertSubscriber.Stmt, app.Importer = subimporter.New(q.UpsertSubscriber.Stmt,
q.UpsertBlacklistSubscriber.Stmt, q.UpsertBlacklistSubscriber.Stmt,
q.UpdateListsDate.Stmt,
db.DB, db.DB,
importNotifCB) importNotifCB)

View File

@ -36,10 +36,11 @@ type Queries struct {
DeleteSubscriptionsByQuery string `query:"delete-subscriptions-by-query"` DeleteSubscriptionsByQuery string `query:"delete-subscriptions-by-query"`
UnsubscribeSubscribersFromListsByQuery string `query:"unsubscribe-subscribers-from-lists-by-query"` UnsubscribeSubscribersFromListsByQuery string `query:"unsubscribe-subscribers-from-lists-by-query"`
CreateList *sqlx.Stmt `query:"create-list"` CreateList *sqlx.Stmt `query:"create-list"`
GetLists *sqlx.Stmt `query:"get-lists"` GetLists *sqlx.Stmt `query:"get-lists"`
UpdateList *sqlx.Stmt `query:"update-list"` UpdateList *sqlx.Stmt `query:"update-list"`
DeleteLists *sqlx.Stmt `query:"delete-lists"` UpdateListsDate *sqlx.Stmt `query:"update-lists-date"`
DeleteLists *sqlx.Stmt `query:"delete-lists"`
CreateCampaign *sqlx.Stmt `query:"create-campaign"` CreateCampaign *sqlx.Stmt `query:"create-campaign"`
QueryCampaigns *sqlx.Stmt `query:"query-campaigns"` QueryCampaigns *sqlx.Stmt `query:"query-campaigns"`

View File

@ -230,7 +230,7 @@ SELECT COUNT(*) OVER () AS total, lists.*, COUNT(subscriber_lists.subscriber_id)
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 OFFSET $2 LIMIT $3; GROUP BY lists.id ORDER BY lists.created_at OFFSET $2 LIMIT (CASE WHEN $3 = 0 THEN NULL ELSE $3 END);
-- 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;
@ -243,6 +243,9 @@ UPDATE lists SET
updated_at=NOW() updated_at=NOW()
WHERE id = $1; WHERE id = $1;
-- name: update-lists-date
UPDATE lists SET updated_at=NOW() WHERE id = ANY($1);
-- name: delete-lists -- name: delete-lists
DELETE FROM lists WHERE id = ALL($1); DELETE FROM lists WHERE id = ALL($1);

View File

@ -47,10 +47,11 @@ const (
// Importer represents the bulk CSV subscriber import system. // Importer represents the bulk CSV subscriber import system.
type Importer struct { type Importer struct {
upsert *sql.Stmt upsert *sql.Stmt
blacklist *sql.Stmt blacklist *sql.Stmt
db *sql.DB updateListDate *sql.Stmt
notifCB models.AdminNotifCallback db *sql.DB
notifCB models.AdminNotifCallback
stop chan bool stop chan bool
status Status status Status
@ -93,14 +94,16 @@ var (
) )
// New returns a new instance of Importer. // New returns a new instance of Importer.
func New(upsert *sql.Stmt, blacklist *sql.Stmt, db *sql.DB, notifCB models.AdminNotifCallback) *Importer { func New(upsert *sql.Stmt, blacklist *sql.Stmt, updateListDate *sql.Stmt,
db *sql.DB, notifCB models.AdminNotifCallback) *Importer {
im := Importer{ im := Importer{
upsert: upsert, upsert: upsert,
blacklist: blacklist, blacklist: blacklist,
stop: make(chan bool, 1), updateListDate: updateListDate,
db: db, stop: make(chan bool, 1),
notifCB: notifCB, db: db,
status: Status{Status: StatusNone, logBuf: bytes.NewBuffer(nil)}, notifCB: notifCB,
status: Status{Status: StatusNone, logBuf: bytes.NewBuffer(nil)},
} }
return &im return &im
@ -276,6 +279,10 @@ func (s *Session) Start() {
s.log.Printf("imported finished") s.log.Printf("imported finished")
s.im.sendNotif(StatusFinished) s.im.sendNotif(StatusFinished)
if _, err := s.im.updateListDate.Exec(listIDs); err != nil {
s.log.Printf("error updating lists date: %v", err)
}
return return
} }
@ -292,6 +299,10 @@ func (s *Session) Start() {
s.im.setStatus(StatusFinished) s.im.setStatus(StatusFinished)
s.log.Printf("imported finished") s.log.Printf("imported finished")
s.im.sendNotif(StatusFinished) s.im.sendNotif(StatusFinished)
if _, err := s.im.updateListDate.Exec(listIDs); err != nil {
s.log.Printf("error updating lists date: %v", err)
}
} }
// Stop stops an active import session. // Stop stops an active import session.