Skip to content

Commit

Permalink
Add subscription status filter to subscriber list query and admin UI.
Browse files Browse the repository at this point in the history
  • Loading branch information
knadh committed Dec 23, 2023
1 parent 8f12c03 commit 51af75c
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 17 deletions.
11 changes: 6 additions & 5 deletions cmd/subscribers.go
Expand Up @@ -87,10 +87,11 @@ func handleQuerySubscribers(c echo.Context) error {
pg = app.paginator.NewFromURL(c.Request().URL.Query())

// The "WHERE ?" bit.
query = sanitizeSQLExp(c.FormValue("query"))
orderBy = c.FormValue("order_by")
order = c.FormValue("order")
out models.PageResults
query = sanitizeSQLExp(c.FormValue("query"))
subStatus = c.FormValue("subscription_status")
orderBy = c.FormValue("order_by")
order = c.FormValue("order")
out models.PageResults
)

// Limit the subscribers to specific lists?
Expand All @@ -99,7 +100,7 @@ func handleQuerySubscribers(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidID"))
}

res, total, err := app.core.QuerySubscribers(query, listIDs, order, orderBy, pg.Offset, pg.Limit)
res, total, err := app.core.QuerySubscribers(query, listIDs, subStatus, order, orderBy, pg.Offset, pg.Limit)
if err != nil {
return err
}
Expand Down
16 changes: 9 additions & 7 deletions docs/docs/content/apis/subscribers.md
Expand Up @@ -24,13 +24,15 @@ Retrieve all subscribers.

##### Query parameters

| Name | Type | Required | Description |
|:---------|:-------|:---------|:---------------------------------------------------------------------|
| query | string | | Subscriber search term by name. |
| order_by | string | | Result sorting field. Options: name, status, created_at, updated_at. |
| order | string | | Sorting order: ASC for ascending, DESC for descending. |
| page | number | | Page number for paginated results. |
| per_page | number | | Results per page. Set as 'all' for all results. |
| Name | Type | Required | Description |
|:--------------------|:-------|:---------|:----------------------------------------------------------------------|
| query | string | | Subscriber search by SQL expression. |
| list_id | int[] | | ID of lists to filter by. Repeat in the query for multiple values. |
| subscription_status | string | | Subscription status to filter by if there are one or more `list_id`s. |
| order_by | string | | Result sorting field. Options: name, status, created_at, updated_at. |
| order | string | | Sorting order: ASC for ascending, DESC for descending. |
| page | number | | Page number for paginated results. |
| per_page | number | | Results per page. Set as 'all' for all results. |

##### Example Request

Expand Down
5 changes: 4 additions & 1 deletion frontend/src/views/Lists.vue
Expand Up @@ -99,7 +99,10 @@
<div class="fields stats">
<p v-for="(count, status) in filterStatuses(props.row)" :key="status">
<label>{{ $tc(`subscribers.status.${status}`, count) }}</label>
<span :class="status">{{ $utils.formatNumber(count) }}</span>
<router-link :to="`/subscribers/lists/${props.row.id}?subscription_status=${status}`"
:class="status">
{{ $utils.formatNumber(count) }}
</router-link>
</p>
</div>
</b-table-column>
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/views/Subscribers.vue
Expand Up @@ -251,6 +251,7 @@ export default Vue.extend({
page: 1,
orderBy: 'id',
order: 'desc',
subStatus: null,
},
};
},
Expand Down Expand Up @@ -357,6 +358,7 @@ export default Vue.extend({
list_id: this.queryParams.listID,
query: this.queryParams.queryExp,
page: this.queryParams.page,
subscription_status: this.queryParams.subStatus,
order_by: this.queryParams.orderBy,
order: this.queryParams.order,
}).then(() => {
Expand Down Expand Up @@ -515,6 +517,10 @@ export default Vue.extend({
// Get subscribers on load.
this.querySubscribers();
}
if (this.$route.query.subscription_status) {
this.queryParams.subStatus = this.$route.query.subscription_status;
}
},
});
</script>
6 changes: 3 additions & 3 deletions internal/core/subscribers.go
Expand Up @@ -66,7 +66,7 @@ func (c *Core) GetSubscribersByEmail(emails []string) (models.Subscribers, error
}

// QuerySubscribers queries and returns paginated subscrribers based on the given params including the total count.
func (c *Core) QuerySubscribers(query string, listIDs []int, order, orderBy string, offset, limit int) (models.Subscribers, int, error) {
func (c *Core) QuerySubscribers(query string, listIDs []int, subStatus string, order, orderBy string, offset, limit int) (models.Subscribers, int, error) {
// There's an arbitrary query condition.
cond := ""
if query != "" {
Expand Down Expand Up @@ -98,7 +98,7 @@ func (c *Core) QuerySubscribers(query string, listIDs []int, order, orderBy stri

// Execute the readonly query and get the count of results.
total := 0
if err := tx.Get(&total, stmt, pq.Array(listIDs)); err != nil {
if err := tx.Get(&total, stmt, pq.Array(listIDs), subStatus); err != nil {
return nil, 0, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
}
Expand All @@ -112,7 +112,7 @@ func (c *Core) QuerySubscribers(query string, listIDs []int, order, orderBy stri
var out models.Subscribers
stmt = strings.ReplaceAll(c.q.QuerySubscribers, "%query%", cond)
stmt = strings.ReplaceAll(stmt, "%order%", orderBy+" "+order)
if err := tx.Select(&out, stmt, pq.Array(listIDs), offset, limit); err != nil {
if err := tx.Select(&out, stmt, pq.Array(listIDs), subStatus, offset, limit); err != nil {
return nil, 0, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
}
Expand Down
4 changes: 3 additions & 1 deletion queries.sql
Expand Up @@ -306,10 +306,11 @@ SELECT subscribers.* FROM subscribers
-- Optional list filtering.
(CASE WHEN CARDINALITY($1::INT[]) > 0 THEN true ELSE false END)
AND subscriber_lists.subscriber_id = subscribers.id
AND ($2 = '' OR subscriber_lists.status = $2::subscription_status)
)
WHERE (CARDINALITY($1) = 0 OR subscriber_lists.list_id = ANY($1::INT[]))
%query%
ORDER BY %order% OFFSET $2 LIMIT (CASE WHEN $3 < 1 THEN NULL ELSE $3 END);
ORDER BY %order% OFFSET $3 LIMIT (CASE WHEN $4 < 1 THEN NULL ELSE $4 END);

-- name: query-subscribers-count
-- Replica of query-subscribers for obtaining the results count.
Expand All @@ -319,6 +320,7 @@ SELECT COUNT(*) AS total FROM subscribers
-- Optional list filtering.
(CASE WHEN CARDINALITY($1::INT[]) > 0 THEN true ELSE false END)
AND subscriber_lists.subscriber_id = subscribers.id
AND ($2 = '' OR subscriber_lists.status = $2::subscription_status)
)
WHERE (CARDINALITY($1) = 0 OR subscriber_lists.list_id = ANY($1::INT[])) %s;

Expand Down

0 comments on commit 51af75c

Please sign in to comment.