Преглед на файлове

Fix import and campaign page and integrate new paginated lists API

Kailash Nadh преди 6 години
родител
ревизия
8701cb445a
променени са 8 файла, в които са добавени 67 реда и са изтрити 31 реда
  1. 3 1
      frontend/my/src/App.js
  2. 13 8
      frontend/my/src/Campaign.js
  3. 8 2
      frontend/my/src/Import.js
  4. 11 4
      handlers.go
  5. 1 0
      main.go
  6. 5 4
      queries.go
  7. 4 1
      queries.sql
  8. 22 11
      subimporter/importer.go

+ 3 - 1
frontend/my/src/App.js

@@ -79,7 +79,9 @@ class App extends React.PureComponent {
 
       // If it's a GET call, set the response as the data state.
       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
     } catch (e) {

+ 13 - 8
frontend/my/src/Campaign.js

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

+ 8 - 2
frontend/my/src/Import.js

@@ -33,7 +33,9 @@ class TheFormDef extends React.PureComponent {
 
   componentDidMount() {
     // 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.
@@ -413,7 +415,11 @@ class Import extends React.PureComponent {
         <TheForm
           {...this.props}
           fetchimportState={this.fetchimportState}
-          lists={this.props.data[cs.ModelLists]}
+          lists={
+            this.props.data[cs.ModelLists].hasOwnProperty("results")
+              ? this.props.data[cs.ModelLists].results
+              : []
+          }
         />
 
         <hr />

+ 11 - 4
handlers.go

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

+ 1 - 0
main.go

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

+ 5 - 4
queries.go

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

+ 4 - 1
queries.sql

@@ -230,7 +230,7 @@ SELECT COUNT(*) OVER () AS total, lists.*, COUNT(subscriber_lists.subscriber_id)
     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 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
 INSERT INTO lists (uuid, name, type, tags) VALUES($1, $2, $3, $4) RETURNING id;
@@ -243,6 +243,9 @@ UPDATE lists SET
     updated_at=NOW()
 WHERE id = $1;
 
+-- name: update-lists-date
+UPDATE lists SET updated_at=NOW() WHERE id = ANY($1);
+
 -- name: delete-lists
 DELETE FROM lists WHERE id = ALL($1);
 

+ 22 - 11
subimporter/importer.go

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