mirror of
https://github.com/knadh/listmonk.git
synced 2024-09-20 07:16:33 +08:00
Add tag/type/optin filter options to lists and campaigns APIs. Closes #1631.
This commit is contained in:
parent
c468e7ae71
commit
01acd386f6
|
@ -57,13 +57,14 @@ func handleGetCampaigns(c echo.Context) error {
|
|||
pg = app.paginator.NewFromURL(c.Request().URL.Query())
|
||||
|
||||
status = c.QueryParams()["status"]
|
||||
tags = c.QueryParams()["tag"]
|
||||
query = strings.TrimSpace(c.FormValue("query"))
|
||||
orderBy = c.FormValue("order_by")
|
||||
order = c.FormValue("order")
|
||||
noBody, _ = strconv.ParseBool(c.QueryParam("no_body"))
|
||||
)
|
||||
|
||||
res, total, err := app.core.QueryCampaigns(query, status, orderBy, order, pg.Offset, pg.Limit)
|
||||
res, total, err := app.core.QueryCampaigns(query, status, tags, orderBy, order, pg.Offset, pg.Limit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -16,7 +16,10 @@ func handleGetLists(c echo.Context) error {
|
|||
pg = app.paginator.NewFromURL(c.Request().URL.Query())
|
||||
|
||||
query = strings.TrimSpace(c.FormValue("query"))
|
||||
tags = c.QueryParams()["tag"]
|
||||
orderBy = c.FormValue("order_by")
|
||||
typ = c.FormValue("type")
|
||||
optin = c.FormValue("optin")
|
||||
order = c.FormValue("order")
|
||||
minimal, _ = strconv.ParseBool(c.FormValue("minimal"))
|
||||
listID, _ = strconv.Atoi(c.Param("id"))
|
||||
|
@ -58,7 +61,7 @@ func handleGetLists(c echo.Context) error {
|
|||
}
|
||||
|
||||
// Full list query.
|
||||
res, total, err := app.core.QueryLists(query, orderBy, order, pg.Offset, pg.Limit)
|
||||
res, total, err := app.core.QueryLists(query, typ, optin, tags, orderBy, order, pg.Offset, pg.Limit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -26,13 +26,15 @@ Retrieve all campaigns.
|
|||
|
||||
##### Parameters
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|:---------|:-------|:---------|:---------------------------------------------------------------------|
|
||||
| order | string | | Sorting order: ASC for ascending, DESC for descending. |
|
||||
| order_by | string | | Result sorting field. Options: name, status, created_at, updated_at. |
|
||||
| query | string | | SQL query expression to filter subscribers. |
|
||||
| page | number | | Page number for paginated results. |
|
||||
| per_page | number | | Results per page. Set as 'all' for all results. |
|
||||
| Name | Type | Required | Description |
|
||||
|:---------|:---------|:---------|:---------------------------------------------------------------------|
|
||||
| order | string | | Sorting order: ASC for ascending, DESC for descending. |
|
||||
| order_by | string | | Result sorting field. Options: name, status, created_at, updated_at. |
|
||||
| query | string | | SQL query expression to filter campaigns. |
|
||||
| status | []string | | Status to filter campaigns. Repeat in the query for multiple values. |
|
||||
| tags | []string | | Tags to filter campaigns. Repeat in the query for multiple values. |
|
||||
| page | number | | Page number for paginated results. |
|
||||
| per_page | number | | Results per page. Set as 'all' for all results. |
|
||||
|
||||
##### Example Response
|
||||
|
||||
|
|
|
@ -16,13 +16,15 @@ Retrieve lists.
|
|||
|
||||
##### Parameters
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|:---------|:----------|:---------|:-----------------------------------------------------------|
|
||||
| query | string | | string for list name search. |
|
||||
| order_by | string | | Sort field. Options: name, status, created_at, updated_at. |
|
||||
| order | string | | Sorting order. Options: ASC, DESC. |
|
||||
| page | number | | Page number for pagination. |
|
||||
| per_page | number | | Results per page. Set to 'all' to return all results. |
|
||||
| Name | Type | Required | Description |
|
||||
|:---------|:---------|:---------|:-----------------------------------------------------------------|
|
||||
| query | string | | string for list name search. |
|
||||
| status | []string | | Status to filter lists. Repeat in the query for multiple values. |
|
||||
| tags | []string | | Tags to filter lists. Repeat in the query for multiple values. |
|
||||
| order_by | string | | Sort field. Options: name, status, created_at, updated_at. |
|
||||
| order | string | | Sorting order. Options: ASC, DESC. |
|
||||
| page | number | | Page number for pagination. |
|
||||
| per_page | number | | Results per page. Set to 'all' to return all results. |
|
||||
|
||||
##### Example Request
|
||||
|
||||
|
|
|
@ -23,16 +23,20 @@ const (
|
|||
|
||||
// QueryCampaigns retrieves paginated campaigns optionally filtering them by the given arbitrary
|
||||
// query expression. It also returns the total number of records in the DB.
|
||||
func (c *Core) QueryCampaigns(searchStr string, statuses []string, orderBy, order string, offset, limit int) (models.Campaigns, int, error) {
|
||||
func (c *Core) QueryCampaigns(searchStr string, statuses, tags []string, orderBy, order string, offset, limit int) (models.Campaigns, int, error) {
|
||||
queryStr, stmt := makeSearchQuery(searchStr, orderBy, order, c.q.QueryCampaigns, campQuerySortFields)
|
||||
|
||||
if statuses == nil {
|
||||
statuses = []string{}
|
||||
}
|
||||
|
||||
if tags == nil {
|
||||
tags = []string{}
|
||||
}
|
||||
|
||||
// Unsafe to ignore scanning fields not present in models.Campaigns.
|
||||
var out models.Campaigns
|
||||
if err := c.db.Select(&out, stmt, 0, pq.Array(statuses), queryStr, offset, limit); err != nil {
|
||||
if err := c.db.Select(&out, stmt, 0, pq.StringArray(statuses), pq.StringArray(tags), queryStr, offset, limit); err != nil {
|
||||
c.log.Printf("error fetching campaigns: %v", err)
|
||||
return nil, 0, echo.NewHTTPError(http.StatusInternalServerError,
|
||||
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
|
||||
|
|
|
@ -36,12 +36,16 @@ func (c *Core) GetLists(typ string) ([]models.List, error) {
|
|||
|
||||
// QueryLists gets multiple lists based on multiple query params. Along with the paginated and sliced
|
||||
// results, the total number of lists in the DB is returned.
|
||||
func (c *Core) QueryLists(searchStr, orderBy, order string, offset, limit int) ([]models.List, int, error) {
|
||||
func (c *Core) QueryLists(searchStr, typ, optin string, tags []string, orderBy, order string, offset, limit int) ([]models.List, int, error) {
|
||||
out := []models.List{}
|
||||
|
||||
queryStr, stmt := makeSearchQuery(searchStr, orderBy, order, c.q.QueryLists, listQuerySortFields)
|
||||
|
||||
if err := c.db.Select(&out, stmt, 0, "", queryStr, offset, limit); err != nil {
|
||||
if tags == nil {
|
||||
tags = []string{}
|
||||
}
|
||||
|
||||
if err := c.db.Select(&out, stmt, 0, "", queryStr, typ, optin, pq.StringArray(tags), offset, limit); err != nil {
|
||||
c.log.Printf("error fetching lists: %v", err)
|
||||
return nil, 0, echo.NewHTTPError(http.StatusInternalServerError,
|
||||
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.lists}", "error", pqErrMsg(err)))
|
||||
|
@ -76,7 +80,7 @@ func (c *Core) GetList(id int, uuid string) (models.List, error) {
|
|||
|
||||
var res []models.List
|
||||
queryStr, stmt := makeSearchQuery("", "", "", c.q.QueryLists, nil)
|
||||
if err := c.db.Select(&res, stmt, id, uu, queryStr, 0, 1); err != nil {
|
||||
if err := c.db.Select(&res, stmt, id, uu, queryStr, "", "", pq.StringArray{}, 0, 1); err != nil {
|
||||
c.log.Printf("error fetching lists: %v", err)
|
||||
return models.List{}, echo.NewHTTPError(http.StatusInternalServerError,
|
||||
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.lists}", "error", pqErrMsg(err)))
|
||||
|
|
27
queries.sql
27
queries.sql
|
@ -408,15 +408,17 @@ SELECT * FROM lists WHERE (CASE WHEN $1 = '' THEN 1=1 ELSE type=$1::list_type EN
|
|||
|
||||
-- name: query-lists
|
||||
WITH ls AS (
|
||||
SELECT COUNT(*) OVER () AS total, lists.* FROM lists
|
||||
WHERE
|
||||
CASE
|
||||
WHEN $1 > 0 THEN id = $1
|
||||
WHEN $2 != '' THEN uuid = $2::UUID
|
||||
WHEN $3 != '' THEN to_tsvector(name) @@ to_tsquery ($3)
|
||||
ELSE true
|
||||
END
|
||||
OFFSET $4 LIMIT (CASE WHEN $5 < 1 THEN NULL ELSE $5 END)
|
||||
SELECT COUNT(*) OVER () AS total, lists.* FROM lists WHERE
|
||||
CASE
|
||||
WHEN $1 > 0 THEN id = $1
|
||||
WHEN $2 != '' THEN uuid = $2::UUID
|
||||
WHEN $3 != '' THEN to_tsvector(name) @@ to_tsquery ($3)
|
||||
ELSE TRUE
|
||||
END
|
||||
AND ($4 = '' OR type = $4::list_type)
|
||||
AND ($5 = '' OR optin = $5::list_optin)
|
||||
AND (CARDINALITY($6::VARCHAR(100)[]) = 0 OR $6 <@ tags)
|
||||
OFFSET $7 LIMIT (CASE WHEN $8 < 1 THEN NULL ELSE $8 END)
|
||||
),
|
||||
counts AS (
|
||||
SELECT list_id, JSON_OBJECT_AGG(status, num) AS subscriber_statuses, SUM(num) AS subscriber_count
|
||||
|
@ -525,9 +527,10 @@ SELECT c.id, c.uuid, c.name, c.subject, c.from_email,
|
|||
) AS lists
|
||||
FROM campaigns c
|
||||
WHERE ($1 = 0 OR id = $1)
|
||||
AND status=ANY(CASE WHEN CARDINALITY($2::campaign_status[]) != 0 THEN $2::campaign_status[] ELSE ARRAY[status] END)
|
||||
AND ($3 = '' OR TO_TSVECTOR(CONCAT(name, ' ', subject)) @@ TO_TSQUERY($3))
|
||||
ORDER BY %order% OFFSET $4 LIMIT (CASE WHEN $5 < 1 THEN NULL ELSE $5 END);
|
||||
AND (CARDINALITY($2::campaign_status[]) = 0 OR status = ANY($2))
|
||||
AND (CARDINALITY($3::VARCHAR(100)[]) = 0 OR $3 <@ tags)
|
||||
AND ($4 = '' OR TO_TSVECTOR(CONCAT(name, ' ', subject)) @@ TO_TSQUERY($4))
|
||||
ORDER BY %order% OFFSET $5 LIMIT (CASE WHEN $6 < 1 THEN NULL ELSE $6 END);
|
||||
|
||||
-- name: get-campaign
|
||||
SELECT campaigns.*,
|
||||
|
|
Loading…
Reference in a new issue