@@ -74,7 +74,7 @@
-
+
@@ -96,7 +96,7 @@
-
+
@@ -215,6 +215,8 @@ export default Vue.extend({
queryParams: {
page: 1,
query: '',
+ orderBy: 'created_at',
+ order: 'desc',
},
pollID: null,
campaignStatsData: {},
@@ -264,6 +266,12 @@ export default Vue.extend({
this.getCampaigns();
},
+ onSort(field, direction) {
+ this.queryParams.orderBy = field;
+ this.queryParams.order = direction;
+ this.getCampaigns();
+ },
+
// Campaign actions.
previewCampaign(c) {
this.previewItem = c;
@@ -277,6 +285,8 @@ export default Vue.extend({
this.$api.getCampaigns({
page: this.queryParams.page,
query: this.queryParams.query,
+ order_by: this.queryParams.orderBy,
+ order: this.queryParams.order,
});
},
diff --git a/frontend/src/views/Lists.vue b/frontend/src/views/Lists.vue
index 32ae364..f9e9639 100644
--- a/frontend/src/views/Lists.vue
+++ b/frontend/src/views/Lists.vue
@@ -17,6 +17,7 @@
hoverable default-sort="createdAt"
paginated backend-pagination pagination-position="both" @page-change="onPageChange"
:current-page="queryParams.page" :per-page="lists.perPage" :total="lists.total"
+ backend-sorting @sort="onSort"
>
-
+
{{ props.row.subscriberCount }}
-
+
{{ $utils.niceDate(props.row.createdAt) }}
-
+
{{ $utils.niceDate(props.row.updatedAt) }}
@@ -115,7 +116,11 @@ export default Vue.extend({
curItem: null,
isEditing: false,
isFormVisible: false,
- queryParams: { page: 1 },
+ queryParams: {
+ page: 1,
+ orderBy: 'created_at',
+ order: 'asc',
+ },
};
},
@@ -125,6 +130,13 @@ export default Vue.extend({
this.getLists();
},
+ onSort(field, direction) {
+ this.queryParams.orderBy = field;
+ this.queryParams.order = direction;
+ this.getLists();
+ },
+
+
// Show the edit list form.
showEditForm(list) {
this.curItem = list;
@@ -144,7 +156,11 @@ export default Vue.extend({
},
getLists() {
- this.$api.getLists({ page: this.queryParams.page });
+ this.$api.getLists({
+ page: this.queryParams.page,
+ order_by: this.queryParams.orderBy,
+ order: this.queryParams.order,
+ });
},
deleteList(list) {
diff --git a/frontend/src/views/Subscribers.vue b/frontend/src/views/Subscribers.vue
index 2fb515d..abeca80 100644
--- a/frontend/src/views/Subscribers.vue
+++ b/frontend/src/views/Subscribers.vue
@@ -94,17 +94,16 @@
:checked-rows.sync="bulk.checked"
paginated backend-pagination pagination-position="both" @page-change="onPageChange"
:current-page="queryParams.page" :per-page="subscribers.perPage" :total="subscribers.total"
- hoverable
- checkable>
+ hoverable checkable backend-sorting @sort="onSort">
-
+
{{ props.row.status }}
-
+
{{ props.row.email }}
@@ -119,7 +118,7 @@
-
+
{{ props.row.name }}
@@ -130,11 +129,11 @@
{{ listCount(props.row.lists) }}
-
+
{{ $utils.niceDate(props.row.createdAt) }}
-
+
{{ $utils.niceDate(props.row.updatedAt) }}
@@ -217,6 +216,8 @@ export default Vue.extend({
// ID of the list the current subscriber view is filtered by.
listID: null,
page: 1,
+ orderBy: 'updated_at',
+ order: 'desc',
},
};
},
@@ -279,15 +280,17 @@ export default Vue.extend({
this.isBulkListFormVisible = true;
},
- sortSubscribers(field, order, event) {
- console.log(field, order, event);
- },
-
onPageChange(p) {
this.queryParams.page = p;
this.querySubscribers();
},
+ onSort(field, direction) {
+ this.queryParams.orderBy = field;
+ this.queryParams.order = direction;
+ this.querySubscribers();
+ },
+
// Prepares an SQL expression for simple name search inputs and saves it
// in this.queryExp.
onSimpleQueryInput(v) {
@@ -308,6 +311,8 @@ export default Vue.extend({
list_id: this.queryParams.listID,
query: this.queryParams.queryExp,
page: this.queryParams.page,
+ order_by: this.queryParams.orderBy,
+ order: this.queryParams.order,
}).then(() => {
this.bulk.checked = [];
});
diff --git a/queries.sql b/queries.sql
index 5c8859a..a602430 100644
--- a/queries.sql
+++ b/queries.sql
@@ -1,3 +1,4 @@
+
-- subscribers
-- name: get-subscriber
-- Get a single subscriber by id or UUID.
@@ -297,7 +298,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 (CASE WHEN $3 = 0 THEN NULL ELSE $3 END);
+ GROUP BY lists.id ORDER BY %s %s OFFSET $2 LIMIT (CASE WHEN $3 = 0 THEN NULL ELSE $3 END);
-- name: get-lists-by-optin
-- Can have a list of IDs or a list of UUIDs.
@@ -370,18 +371,23 @@ INSERT INTO campaign_lists (campaign_id, list_id, list_name)
-- there's a COUNT() OVER() that still returns the total result count
-- for pagination in the frontend, albeit being a field that'll repeat
-- with every resultant row.
-SELECT COUNT(*) OVER () AS total, campaigns.*, (
- SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(l)), '[]') FROM (
- SELECT COALESCE(campaign_lists.list_id, 0) AS id,
- campaign_lists.list_name AS name
- FROM campaign_lists WHERE campaign_lists.campaign_id = campaigns.id
+SELECT campaigns.id, campaigns.uuid, campaigns.name, campaigns.subject, campaigns.from_email,
+ campaigns.messenger, campaigns.started_at, campaigns.to_send, campaigns.sent, campaigns.type,
+ campaigns.body, campaigns.send_at, campaigns.status, campaigns.content_type, campaigns.tags,
+ campaigns.template_id, campaigns.created_at, campaigns.updated_at,
+ COUNT(*) OVER () AS total,
+ (
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(l)), '[]') FROM (
+ SELECT COALESCE(campaign_lists.list_id, 0) AS id,
+ campaign_lists.list_name AS name
+ FROM campaign_lists WHERE campaign_lists.campaign_id = campaigns.id
) l
) AS lists
FROM campaigns
WHERE ($1 = 0 OR id = $1)
AND status=ANY(CASE WHEN ARRAY_LENGTH($2::campaign_status[], 1) != 0 THEN $2::campaign_status[] ELSE ARRAY[status] END)
AND ($3 = '' OR CONCAT(name, subject) ILIKE $3)
-ORDER BY campaigns.updated_at DESC OFFSET $4 LIMIT $5;
+ORDER BY %s %s OFFSET $4 LIMIT $5;
-- name: get-campaign
SELECT campaigns.*,