diff --git a/app/assets/javascripts/admin/controllers/admin_email_logs_skipped_controller.js b/app/assets/javascripts/admin/controllers/admin_email_logs_skipped_controller.js new file mode 100644 index 000000000..f6e235c4a --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin_email_logs_skipped_controller.js @@ -0,0 +1,20 @@ + /** + This controller supports email logs functionality. + + @class AdminEmailSkippedController + @extends Discourse.Controller + @namespace Discourse + @module Discourse +**/ +Discourse.AdminEmailSkippedController = Discourse.Controller.extend({ + + filterEmailLogs: Discourse.debounce(function() { + var self = this; + this.set("loading", true); + Discourse.EmailLog.findAll(this.get("filter")).then(function(logs) { + self.set("model", false); + self.set("model", logs); + }); + }, 250).observes("filter.user", "filter.address", "filter.type", "filter.reason"), + +}); diff --git a/app/assets/javascripts/admin/controllers/admin_email_sent_controller.js b/app/assets/javascripts/admin/controllers/admin_email_sent_controller.js new file mode 100644 index 000000000..52cc020b8 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin_email_sent_controller.js @@ -0,0 +1,20 @@ + /** + This controller supports email logs functionality. + + @class AdminEmailSentController + @extends Discourse.Controller + @namespace Discourse + @module Discourse +**/ +Discourse.AdminEmailSentController = Discourse.Controller.extend({ + + filterEmailLogs: Discourse.debounce(function() { + var self = this; + this.set("loading", true); + Discourse.EmailLog.findAll(this.get("filter")).then(function(logs) { + self.set("loading", false); + self.set("model", logs); + }); + }, 250).observes("filter.user", "filter.address", "filter.type", "filter.reply_key"), + +}); diff --git a/app/assets/javascripts/admin/models/email_log.js b/app/assets/javascripts/admin/models/email_log.js index b22cc9e29..4819683fa 100644 --- a/app/assets/javascripts/admin/models/email_log.js +++ b/app/assets/javascripts/admin/models/email_log.js @@ -9,25 +9,27 @@ Discourse.EmailLog = Discourse.Model.extend({}); Discourse.EmailLog.reopenClass({ + create: function(attrs) { attrs = attrs || {}; if (attrs.user) { attrs.user = Discourse.AdminUser.create(attrs.user); } + return this._super(attrs); }, findAll: function(filter) { - var result = Em.A(); - Discourse.ajax("/admin/email/" + (filter === 'skipped' ? 'skipped' : 'logs') + ".json", { - data: { filter: filter } - }).then(function(logs) { - _.each(logs,function(log) { - result.pushObject(Discourse.EmailLog.create(log)); + filter = filter || {}; + var status = filter.status || "sent"; + filter = _.omit(filter, "status"); + + return Discourse.ajax("/admin/email/" + status + ".json", { data: filter }).then(function(logs) { + return _.map(logs, function (log) { + return Discourse.EmailLog.create(log); }); }); - return result; } }); diff --git a/app/assets/javascripts/admin/routes/admin_email_index_route.js b/app/assets/javascripts/admin/routes/admin_email_index_route.js index 24d8cf5e2..718afa426 100644 --- a/app/assets/javascripts/admin/routes/admin_email_index_route.js +++ b/app/assets/javascripts/admin/routes/admin_email_index_route.js @@ -8,13 +8,11 @@ **/ Discourse.AdminEmailIndexRoute = Discourse.Route.extend({ - setupController: function(controller) { - Discourse.EmailSettings.find().then(function (model) { - controller.set('model', model); - }); + model: function() { + return Discourse.EmailSettings.find(); }, renderTemplate: function() { - this.render('admin/templates/email_index', {into: 'adminEmail'}); + this.render('admin/templates/email_index', { into: 'adminEmail' }); } }); diff --git a/app/assets/javascripts/admin/routes/admin_email_logs_route.js b/app/assets/javascripts/admin/routes/admin_email_logs_route.js deleted file mode 100644 index af7098d64..000000000 --- a/app/assets/javascripts/admin/routes/admin_email_logs_route.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - Handles routes related to viewing email logs. - - @class AdminEmailLogsRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminEmailLogsRoute = Discourse.Route.extend({ - model: function() { - return Discourse.EmailLog.findAll(); - }, - - renderTemplate: function() { - this.render('admin/templates/email_logs', {into: 'adminEmail'}); - } -}); diff --git a/app/assets/javascripts/admin/routes/admin_email_logs_routes.js b/app/assets/javascripts/admin/routes/admin_email_logs_routes.js new file mode 100644 index 000000000..70c0e72f7 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin_email_logs_routes.js @@ -0,0 +1,27 @@ +/** + Handles routes related to viewing email logs. + + @class AdminEmailSentRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ +Discourse.AdminEmailLogsRoute = Discourse.Route.extend({ + + model: function() { + return Discourse.EmailLog.findAll({ status: this.get("status") }); + }, + + setupController: function(controller) { + // resets the filters + controller.set("filter", { status: this.get("status") }); + }, + + renderTemplate: function() { + this.render("admin/templates/email_" + this.get("status"), { into: "adminEmail" }); + } + +}); + +Discourse.AdminEmailSentRoute = Discourse.AdminEmailLogsRoute.extend({ status: "sent" }); +Discourse.AdminEmailSkippedRoute = Discourse.AdminEmailLogsRoute.extend({ status: "skipped" }); diff --git a/app/assets/javascripts/admin/routes/admin_email_skipped_route.js b/app/assets/javascripts/admin/routes/admin_email_skipped_route.js deleted file mode 100644 index c792deba2..000000000 --- a/app/assets/javascripts/admin/routes/admin_email_skipped_route.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - Handles routes related to viewing email logs of emails that were NOT sent. - - @class AdminEmailSkippedRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminEmailSkippedRoute = Discourse.Route.extend({ - model: function() { - return Discourse.EmailLog.findAll('skipped'); - }, - - renderTemplate: function() { - this.render('admin/templates/email_skipped', {into: 'adminEmail'}); - } -}); diff --git a/app/assets/javascripts/admin/routes/admin_routes.js b/app/assets/javascripts/admin/routes/admin_routes.js index 2864858bf..55d0269d3 100644 --- a/app/assets/javascripts/admin/routes/admin_routes.js +++ b/app/assets/javascripts/admin/routes/admin_routes.js @@ -16,7 +16,7 @@ Discourse.Route.buildRoutes(function() { }); this.resource('adminEmail', { path: '/email'}, function() { - this.route('logs'); + this.route('sent'); this.route('skipped'); this.route('previewDigest', { path: '/preview-digest' }); }); diff --git a/app/assets/javascripts/admin/templates/email.js.handlebars b/app/assets/javascripts/admin/templates/email.js.handlebars index 0fcbc1b61..62d66b996 100644 --- a/app/assets/javascripts/admin/templates/email.js.handlebars +++ b/app/assets/javascripts/admin/templates/email.js.handlebars @@ -2,7 +2,7 @@
diff --git a/app/assets/javascripts/admin/templates/email_logs.js.handlebars b/app/assets/javascripts/admin/templates/email_sent.js.handlebars similarity index 57% rename from app/assets/javascripts/admin/templates/email_logs.js.handlebars rename to app/assets/javascripts/admin/templates/email_sent.js.handlebars index c0130f366..66b8f71a9 100644 --- a/app/assets/javascripts/admin/templates/email_logs.js.handlebars +++ b/app/assets/javascripts/admin/templates/email_sent.js.handlebars @@ -9,7 +9,15 @@ - {{#if model.length}} + + {{i18n admin.email.logs.filters.title}} + {{textField value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}} + {{textField value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}} + {{textField value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}} + {{textField value=filter.reply_key placeholderKey="admin.email.logs.filters.reply_key_placeholder"}} + + + {{#if model}} {{#groupedEach model}} {{unboundDate created_at}} @@ -26,6 +34,8 @@ {{reply_key}} {{/groupedEach}} + {{else}} + {{i18n admin.email.logs.none}} {{/if}} diff --git a/app/assets/javascripts/admin/templates/email_skipped.js.handlebars b/app/assets/javascripts/admin/templates/email_skipped.js.handlebars index 87b3ee9fc..daae2d8a5 100644 --- a/app/assets/javascripts/admin/templates/email_skipped.js.handlebars +++ b/app/assets/javascripts/admin/templates/email_skipped.js.handlebars @@ -9,7 +9,15 @@ - {{#if model.length}} + + {{i18n admin.email.logs.filters.title}} + {{textField value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}} + {{textField value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}} + {{textField value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}} + {{textField value=filter.skipReason placeholderKey="admin.email.logs.filters.skip_reason_placeholder"}} + + + {{#if model}} {{#groupedEach model}} {{unboundDate created_at}} @@ -23,11 +31,11 @@ {{to_address}} {{email_type}} - - {{skipped_reason}} - + {{skipped_reason}} {{/groupedEach}} + {{else}} + {{i18n admin.email.logs.none}} {{/if}} diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index 50310eb33..3002ed9c3 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -12,6 +12,7 @@ td {border-bottom: 1px solid $primary_lighter; border-top: 1px solid $primary_lighter;} tr:hover { background-color: darken($secondary, 2.5%); } tr.selected { background-color: lighten($tertiary, 58%); } + .filters input { margin-bottom: 0px; } } .content-list li a span.count { diff --git a/app/controllers/admin/email_controller.rb b/app/controllers/admin/email_controller.rb index 139f6b815..11d4bf968 100644 --- a/app/controllers/admin/email_controller.rb +++ b/app/controllers/admin/email_controller.rb @@ -3,10 +3,8 @@ require_dependency 'email/renderer' class Admin::EmailController < Admin::AdminController def index - render_json_dump({ - delivery_method: delivery_method, - settings: delivery_settings - }) + data = { delivery_method: delivery_method, settings: delivery_settings } + render_json_dump(data) end def test @@ -15,14 +13,14 @@ class Admin::EmailController < Admin::AdminController render nothing: true end - def logs - @email_logs = EmailLog.sent.limit(50).includes(:user).order('created_at desc').to_a - render_serialized(@email_logs, EmailLogSerializer) + def sent + email_logs = filter_email_logs(EmailLog.sent, params) + render_serialized(email_logs, EmailLogSerializer) end def skipped - @email_logs = EmailLog.skipped.limit(50).includes(:user).order('created_at desc').to_a - render_serialized(@email_logs, EmailLogSerializer) + email_logs = filter_email_logs(EmailLog.skipped, params) + render_serialized(email_logs, EmailLogSerializer) end def preview_digest @@ -33,6 +31,16 @@ class Admin::EmailController < Admin::AdminController private + def filter_email_logs(email_logs, params) + email_logs = email_logs.limit(50).includes(:user).order("email_logs.created_at desc").references(:user) + email_logs = email_logs.where("users.username LIKE ?", "%#{params[:user]}%") if params[:user].present? + email_logs = email_logs.where("email_logs.to_address LIKE ?", "%#{params[:address]}%") if params[:address].present? + email_logs = email_logs.where("email_logs.email_type LIKE ?", "%#{params[:type]}%") if params[:type].present? + email_logs = email_logs.where("email_logs.reply_key LIKE ?", "%#{params[:reply_key]}%") if params[:reply_key].present? + email_logs = email_logs.where("email_logs.skipped_reason LIKE ?", "%#{params[:reason]}%") if params[:reason].present? + email_logs.to_a + end + def delivery_settings action_mailer_settings .reject { |k, v| k == :password } diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index f1ab14876..9cd4c1ceb 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1382,7 +1382,7 @@ en: email: title: "Email" settings: "Settings" - logs: "Logs" + sent: "Sent" skipped: "Skipped" sent_at: "Sent At" time: "Time" @@ -1402,6 +1402,15 @@ en: last_seen_user: "Last Seen User:" reply_key: "Reply Key" skip_reason: "Skip Reason" + logs: + none: "No logs found." + filters: + title: "Filter" + user_placeholder: "username" + address_placeholder: "em@il.com" + type_placeholder: "digest, signup..." + reply_key_placeholder: "" + skip_reason_placeholder: "reason" logs: title: "Logs" diff --git a/config/routes.rb b/config/routes.rb index add242a98..b99673314 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -67,7 +67,7 @@ Discourse::Application.routes.draw do resources :email do collection do post "test" - get "logs" + get "sent" get "skipped" get "preview-digest" => "email#preview_digest" end @@ -120,7 +120,7 @@ Discourse::Application.routes.draw do put "readonly" => "backups#readonly" end end - + get "memory_stats"=> "diagnostics#memory_stats", constraints: AdminConstraint.new end # admin namespace diff --git a/spec/controllers/admin/email_controller_spec.rb b/spec/controllers/admin/email_controller_spec.rb index 38ae61e60..29b824da9 100644 --- a/spec/controllers/admin/email_controller_spec.rb +++ b/spec/controllers/admin/email_controller_spec.rb @@ -27,9 +27,18 @@ describe Admin::EmailController do end end - context '.logs' do + context '.sent' do before do - xhr :get, :logs + xhr :get, :sent + end + + subject { response } + it { should be_success } + end + + context '.skipped' do + before do + xhr :get, :skipped end subject { response }