Skip to content
Browse files

Added new dashboard which uses data from petition_reports. Once finis…

…hed, this will replace the current dashboard (which will be removed).
  • Loading branch information...
1 parent 2357126 commit a21b01af4564c2a3d8aa0f21ac8fe1d0974f9231 @rafaelpetry rafaelpetry committed Jan 2, 2013
View
7 app/controllers/admin/petitions_controller.rb
@@ -8,4 +8,11 @@ def index
format.json { render json: PetitionsDatatable.new(view_context, PetitionStatisticsBuilder.new) }
end
end
+
+ def new_dashboard
+ respond_to do |format|
+ format.html {}
+ format.json { render json: PetitionsDatatable.new(view_context, PetitionReportRepository.new) }
+ end
+ end
end
View
13 app/datatables/petitions_datatable.rb
@@ -43,7 +43,7 @@ def dpct(numerator, denominator, percentify=true)
def data
petitions.map do |petition|
[
- link_to(petition.p.title, petition.p),
+ link_to(petition.petition_title, petition.p),
h(petition.email_count),
dpct(petition.opened_emails_count, petition.email_count),
dpct(petition.clicked_emails_count, petition.email_count),
@@ -52,7 +52,7 @@ def data
dpct(petition.hit_count, petition.email_count, false),
dpct(petition.new_member_count, petition.email_count),
dpct(petition.unsubscribe_count, petition.email_count),
- h(format_date_time(petition.p.created_at)),
+ h(format_date_time(petition.petition_created_at)),
]
end
end
@@ -78,9 +78,14 @@ def sort_column
columns[params[:iSortCol_0].to_i]
end
+ # Eliminate this method once previous dashboard is removed
def analytics_since
- since = params[:since]
- since.nil? ? nil : since.to_date
+ begin
+ since = params[:since]
+ since.nil? ? nil : since.to_date
+ rescue
+ params[:since]
+ end
end
def page
View
28 app/models/petition_report_presenter.rb
@@ -0,0 +1,28 @@
+class PetitionReportPresenter
+ delegate :petition_id, :petition_title, :petition_created_at, :to => :@report
+
+ def initialize(petition_report, time_span)
+ @report = petition_report
+ @time_span = time_span
+ end
+
+ def method_missing(method)
+ @report.send(:"#{method}_#{@time_span}") || 0.0
+ end
+
+ # TODO: change datatable so sorting properties match database columns, eliminating the need for these crazy methods
+ def p; Petition.new end
+
+ def email_count; @report.send(:"sent_emails_count_#{@time_span}") || 0 end
+ def signature_count; @report.send(:"signatures_count_#{@time_span}") || 0 end
+ def email_signature_count; @report.send(:"signed_from_emails_count_#{@time_span}") || 0 end
+ def new_member_count; @report.send(:"new_members_count_#{@time_span}") || 0 end
+ def unsubscribe_count; @report.send(:"unsubscribes_count_#{@time_span}") || 0 end
+ def likes_count; @report.send(:"like_count_#{@time_span}") || 0 end
+
+ def open_rate; @report.send(:"opened_emails_rate_#{@time_span}") || 0.0 end
+ def clicked_rate; @report.send(:"clicked_emails_rate_#{@time_span}") || 0.0 end
+ def sign_rate; @report.send(:"signatures_rate_#{@time_span}") || 0.0 end
+ def new_rate; @report.send(:"new_members_count_#{@time_span}") || 0.0 end
+ def unsub_rate; @report.send(:"unsubscribes_rate_#{@time_span}") || 0.0 end
+end
View
26 app/models/petition_report_repository.rb
@@ -0,0 +1,26 @@
+class PetitionReportRepository
+
+ # TODO: change datatable so sorting properties match database columns, eliminating the need for mapping
+ PROPERTIES_MAP = {
+ 'petition_title' => 'petition_title',
+ 'petition_created_at' => 'petition_created_at',
+ 'email_count' => 'sent_emails_count',
+ 'open_rate' => 'opened_emails_rate',
+ 'clicked_rate' => 'clicked_emails_rate',
+ 'sign_rate' => 'signed_from_emails_rate',
+ 'like_rate' => 'like_rate',
+ 'hit_rate' => 'hit_rate',
+ 'new_rate' => 'new_members_rate',
+ 'unsub_rate' => 'unsubscribes_rate'
+ }
+
+ def all_since_and_ordered(time_span, property, direction)
+ direction = direction == :asc ? 'ASC NULLS FIRST' : 'DESC NULLS LAST'
+ property = PROPERTIES_MAP[property] || 'year'
+ column = property =~ /(count|rate)/ ? "#{property}_#{time_span}" : property
+
+ PetitionReport.order("#{column} #{direction}").map do |report|
+ PetitionReportPresenter.new(report, time_span)
+ end
+ end
+end
View
25 app/views/admin/petitions/new_dashboard.html.haml
@@ -0,0 +1,25 @@
+.page_content
+ %h1 Petitions dashboard
+
+ %p
+ - labels = 'day', 'week', 'month', 'year'
+ - options = Hash[labels.zip(labels)]
+ - params[:since] ||= 'year'
+ Activity since last #{link_to_self_with_param :since, options, " | "}
+
+ <button style="float: right" class="btn btn-success" onClick="$('table').dataTable().fnDraw()">Reload</button>
+
+ %table#petitions.bordered-table.table-striped.dataTable{"data-source" => new_dashboard_admin_petitions_url(format: "json", since: params[:since])}
+ %thead
+ %tr
+ %th Title
+ %th Sent
+ %th Open
+ %th Click
+ %th Sign
+ %th Like
+ %th <acronym title="Hits Per Sent email">HPS</acronym>
+ %th <acronym title="New members Per Sent email">NPS</acronym>
+ %th Unsub
+ %th Created
+ %tbody
View
4 config/routes.rb
@@ -32,7 +32,9 @@
get 'contact', to: 'user_feedbacks#new', as: 'contact'
namespace(:admin) do
- resources :petitions
+ resources :petitions do
+ collection { get 'new_dashboard' }
+ end
resources :users
resource :stats do
View
11 spec/controllers/admin/petitions_controller_spec.rb
@@ -1,13 +1,16 @@
module Admin
-
describe PetitionsController do
before :each do
AnalyticsGateway.stub(:get_report_results).and_return({})
stub_bandit controller
end
describe "GET index" do
- let(:action){ get :index }
- it_behaves_like "an admin only resource page"
- end
+ let(:action) { get :index }
+ it_behaves_like "an admin only resource page"
+ end
+ describe "GET new_dashboard" do
+ let(:action) { get :new_dashboard }
+ it_behaves_like "an admin only resource page"
+ end
end
end
View
5 spec/factories/petition_reports.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :petition_report do
+ petition_title { Faker::Lorem.sentence }
+ end
+end
View
8 spec/models/petition_report_presenter_spec.rb
@@ -0,0 +1,8 @@
+describe PetitionReportPresenter do
+ let(:report) { build(:petition_report, :petition_title => 'My Petition', :sent_emails_count_week => 5) }
+
+ subject { PetitionReportPresenter.new(report, 'week') }
+
+ its(:petition_title) { should eq 'My Petition' }
+ its(:sent_emails_count) { should eq 5 }
+end
View
32 spec/models/petition_report_repository_spec.rb
@@ -0,0 +1,32 @@
+describe PetitionReportRepository do
+ let(:repository) { PetitionReportRepository.new }
+
+ before do
+ @petition_with_more_likes = create(:petition_report, :petition_id => 1, :petition_title => 'More Likes', :like_rate_month => 0.5)
+ @petition_with_less_likes = create(:petition_report, :petition_id => 2, :petition_title => 'Less Likes', :like_rate_month => 0.3)
+ end
+
+ context "when property has time span" do
+ it "retrieves petitions sorted by property" do
+ petitions = repository.all_since_and_ordered('month', 'like_rate', :asc)
+ petitions.map(&:petition_id).should eq [@petition_with_less_likes.petition_id, @petition_with_more_likes.petition_id]
+ end
+
+ it "retrieves petitions sorted by property descending" do
+ petitions = repository.all_since_and_ordered('month', 'like_rate', :desc)
+ petitions.map(&:petition_id).should eq [@petition_with_more_likes.petition_id, @petition_with_less_likes.petition_id]
+ end
+ end
+
+ context "when property does not have time span" do
+ it "retrieves petitions sorted by property" do
+ petitions = repository.all_since_and_ordered('month', 'petition_title', :asc)
+ petitions.map(&:petition_id).should eq [@petition_with_less_likes.petition_id, @petition_with_more_likes.petition_id]
+ end
+
+ it "retrieves petitions sorted by property descending" do
+ petitions = repository.all_since_and_ordered('month', 'petition_title', :desc)
+ petitions.map(&:petition_id).should eq [@petition_with_more_likes.petition_id, @petition_with_less_likes.petition_id]
+ end
+ end
+end

0 comments on commit a21b01a

Please sign in to comment.
Something went wrong with that request. Please try again.