diff --git a/db/migrate/001_users.rb b/db/migrate/001_users.rb index b95303d..ece84c4 100644 --- a/db/migrate/001_users.rb +++ b/db/migrate/001_users.rb @@ -16,6 +16,9 @@ def self.up t.datetime :last_login_at t.string :current_login_ip t.string :last_login_ip + + # Custom columns + t.boolean :admin, :default => false end end diff --git a/lib/a_b_front_end/controller/spec.rb b/lib/a_b_front_end/controller/spec.rb new file mode 100644 index 0000000..d2f0c57 --- /dev/null +++ b/lib/a_b_front_end/controller/spec.rb @@ -0,0 +1,10 @@ +Application.class_eval do + + get '/spec' do + if current_user && current_user.admin? + haml :spec + else + nil + end + end +end \ No newline at end of file diff --git a/lib/a_b_front_end/model/user.rb b/lib/a_b_front_end/model/user.rb index c130182..4f69af9 100644 --- a/lib/a_b_front_end/model/user.rb +++ b/lib/a_b_front_end/model/user.rb @@ -2,6 +2,8 @@ class User < ActiveRecord::Base acts_as_authentic + attr_protected :admin + validates_confirmation_of :password, :on => :create validates_format_of :email, :with => /^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i validates_presence_of :email diff --git a/lib/a_b_front_end/view/dashboard.haml b/lib/a_b_front_end/view/dashboard.haml index 91f5ec7..23d542b 100644 --- a/lib/a_b_front_end/view/dashboard.haml +++ b/lib/a_b_front_end/view/dashboard.haml @@ -1,5 +1,5 @@ - @css = %w(dashboard) -- @js = %w(templ dashboard) +- @js = %w(tmpl dashboard) /.success This is a test! .dashboard .span-12.filter#sites @@ -46,22 +46,33 @@ %textarea.hide#test_template %table %tr - %th <%= test.name %> + %th.first <%= test.name %> %th Visits %th Conversions %th Suggested Visits %th Confidence %th Status <% $.each(test.variants, function(i, variant) { %> - <% $.each(variant.for_dashboard, function(e, item) { %> - <% if (e == env) { %> - %tr - %td <%= item.name %> - %td <%= item.visits_with_commas %> - %td <%= item.pretty_conversion_rate %> - %td <%= item.suggested_visits_with_commas %> + %tr{ :class => '<% if (i % 2 == 0) { %>odd<% } %>'} + %td <%= variant.name %> + <% + var found = false; + $.each(variant.for_dashboard, function(e, item) { + if (e == env) { + found = true; %> + %td <%= item.visits %> + %td <%= item.conversion_rate %> + %td <%= item.suggested_visits %> %td <%= item.confidence %> %td ? - <% } %> - <% }); %> + <% + } + }); + if (!found) { %> + %td - + %td - + %td - + %td - + %td - + <% } %> <% }); %> \ No newline at end of file diff --git a/public/css/dashboard.css b/public/css/dashboard.css index 3255eb1..f75015b 100644 --- a/public/css/dashboard.css +++ b/public/css/dashboard.css @@ -11,25 +11,32 @@ .dashboard #tests table { border-width: 2px; - border-spacing: 5px; + border-spacing: 0px; border-style: solid; border-color: rgb(207, 207, 207); border-collapse: separate; background-color: rgb(239, 239, 239); + margin-top: 15px; +} + +.dashboard #tests table th.first { + color: #000; } .dashboard #tests table th { border-width: 1px; - padding: 5px; + padding: 10px; border-style: none; border-color: gray; background-color: rgb(239, 239, 239); + color: #8F8F8F; } -.dashboard #tests table.sample td { - border-width: 1px; - padding: 5px; +.dashboard #tests table tr.odd { + background-color: #fff; +} + +.dashboard #tests table td { + padding: 10px; border-style: none; - border-color: gray; - background-color: rgb(239, 239, 239); } \ No newline at end of file diff --git a/public/js/dashboard.js b/public/js/dashboard.js index 6f1fd2e..f42822d 100644 --- a/public/js/dashboard.js +++ b/public/js/dashboard.js @@ -138,18 +138,30 @@ window.Dashboard = function(sites) { $('.remove', filter).removeClass('hide'); target.removeClass('hide'); - if (target_id != 'tests' && target_id && site[target_id]) { - target.children('.selectable').remove(); - $.each(site[target_id], function(i, item) { - target.append(createSelectable(item.name)); - }); - addLastClassToSelectables(); + if (target_id != 'tests') { + if (target_id && site[target_id]) { + target.children('.selectable').remove(); + + $.each(site[target_id], function(i, item) { + target.append(createSelectable(item.name)); + }); + + addLastClassToSelectables(); + } } else { + var category = byName(site.categories, $('#categories .selected').text()); + var env = $('#envs .selected').text(); + $('.dialog', target).remove(); + + $.each(category.tests, function(i, test) { + $('#tests').append( + $('#test_template').tmpl({ test: test, env: env }) + ); + }); } - } else { + } else $('.remove', filter).addClass('hide'); - } }); $('.remove').live('click', function() { diff --git a/public/js/tmpl.js b/public/js/tmpl.js index 0bd0e34..488f11e 100644 --- a/public/js/tmpl.js +++ b/public/js/tmpl.js @@ -35,8 +35,8 @@ new function() { // Convert the template into pure JavaScript str .replace(/[\r\t\n]/g, " ") + .replace(/'/g, "\\'") .split("<%").join("\t") - .replace(/((^|%>)[^\t]*)'/g, "$1\r") .replace(/\t=(.*?)%>/g, "',$1,'") .split("\t").join("');") .split("%>").join("p.push('")