Skip to content

Commit

Permalink
Initial implementation of admin console and site settings
Browse files Browse the repository at this point in the history
  • Loading branch information
gabceb committed Feb 21, 2013
1 parent fe1124f commit ebb5f3f
Show file tree
Hide file tree
Showing 23 changed files with 399 additions and 91 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ gem 'aws-sdk'
gem 'paperclip'
gem 'remotipart'
gem 'jquery-rails'
gem 'enumerize'

# Making the world a better, more stable place
gem 'airbrake'
Expand All @@ -42,6 +43,7 @@ group :development do
gem 'awesome_print'
gem 'better_errors'
gem 'binding_of_caller'
gem 'debugger'
end

group :test do
Expand Down
12 changes: 12 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,17 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.4.0)
columnize (0.3.6)
cookiejar (0.3.0)
daemons (1.1.9)
database_cleaner (0.9.1)
debugger (1.2.3)
columnize (>= 0.3.1)
debugger-linecache (~> 1.1.1)
debugger-ruby_core_source (~> 1.1.5)
debugger-linecache (1.1.2)
debugger-ruby_core_source (>= 1.1.1)
debugger-ruby_core_source (1.1.6)
devise (1.5.3)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3)
Expand All @@ -98,6 +106,8 @@ GEM
http_parser.rb (>= 0.5.3)
em-socksify (0.2.1)
eventmachine (>= 1.0.0.beta.4)
enumerize (0.5.1)
activesupport (>= 3.2)
erubis (2.7.0)
eventmachine (1.0.0)
execjs (1.4.0)
Expand Down Expand Up @@ -271,9 +281,11 @@ DEPENDENCIES
cloudfuji
coffee-rails
database_cleaner
debugger
devise
devise_cloudfuji_authenticatable
eco
enumerize
execjs
factory_girl_rails
faker
Expand Down
2 changes: 2 additions & 0 deletions app/assets/javascripts/admin/admin.js.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$(document).ready ->

1 change: 1 addition & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
//= require lib/backbone
//= require backbone/kandan
//= require_tree .
//= stub admin/admin
//= require lib/jquery.atwho
//= require lib/jquery.caret
16 changes: 0 additions & 16 deletions app/assets/javascripts/backbone/kandan.js.coffee.erb
Original file line number Diff line number Diff line change
Expand Up @@ -123,29 +123,13 @@ window.Kandan =
Kandan.Plugins.Mentions.initUsersMentions(Kandan.Helpers.ActiveUsers.all())
return

setCurrentUser: ()->
template = JST['current_user']
currentUser = Kandan.Helpers.Users.currentUser()
displayName = "#{currentUser.first_name} #{currentUser.last_name}" if currentUser.first_name?
displayName ||= currentUser.email
$(".header .user").html template({
gravatarHash: currentUser.gravatar_hash,
name: displayName
})

registerUtilityEvents: ()->
window.setInterval(=>
for el in $(".posted_at")
$(el).text (new Date($(el).data("timestamp"))).toRelativeTime(@options.nowThreshold)
, @options.timestampRefreshInterval)

$(".user_menu_link").click (e)->
e.preventDefault()
$(".user_menu").toggle()
false

init: ->
@setCurrentUser()
channels = new Kandan.Collections.Channels()
channels.fetch({
success: (channelsCollection)=>
Expand Down
5 changes: 5 additions & 0 deletions app/assets/javascripts/layout.js.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$(document).ready ->
$(".user_menu_link").click (e)->
e.preventDefault()
$(".user_menu").toggle()
false
27 changes: 27 additions & 0 deletions app/controllers/admin/admin_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Admin
class AdminController < BaseController

def index
@settings = Setting.my_settings
@all_users = User.find(:all, :conditions => ["id != ?", current_user.id])

# Note that this reject! will remove users from all_users in order to show users in 2 different tables
@waiting_for_approval_users = @all_users.reject!{|user| user.status.waiting_approval? } || []
end

def update

max_rooms = params[:setting][:max_rooms].to_i
public_site = params[:setting][:public_site] == "1"

Setting.set_values(:max_rooms => max_rooms, :public_site => public_site)

redirect_to :admin_root
end

def update_users

end

end
end
12 changes: 12 additions & 0 deletions app/controllers/admin/base_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Admin
class BaseController < ApplicationController
before_filter :authenticate_admin!

private

def authenticate_admin!
redirect_to root_url unless current_user.try(:is_admin?)
end

end
end
9 changes: 9 additions & 0 deletions app/helpers/admin/admin_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Admin::AdminHelper
def user_status user
"<div class='#{user.status}'>#{user.status}</div>".html_safe
end

def user_action user

end
end
63 changes: 63 additions & 0 deletions app/models/setting.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
class Setting < ActiveRecord::Base
attr_accessible :values
serialize :values, Hash

before_create :set_default_values
before_create :ensure_only_one_settings
before_destroy :ensure_only_one_settings

before_save :validate_max_rooms, :validate_public_site

def max_rooms
self.values[:max_rooms]
end

def public_site?
self.values[:public_site]
end

alias_method :public_site, :public_site?

def set_default_values
self.values.merge!(self.class.default_values)
end

def ensure_only_one_settings
return false if Setting.count >= 1
end

# Making sure the max_rooms is an integer and is never less than the current number of rooms
def validate_max_rooms
self.values[:max_rooms].is_a?(Integer) && self.values[:max_rooms] >= Channel.count unless self.new_record?
end

# Making sure the public site is a boolean
def validate_public_site
!!self.values[:public_site] == self.values[:public_site] unless self.new_record?
end

def self.default_values
return {:max_rooms => 99, :public_site => false }
end

# Helper methods to be used while we don't need to deal with multi-tenancy
def self.my_settings
self.first_or_create
end

def self.get_value(k)
setting = self.my_settings
setting.values[k]
end

def self.set_values(values)
setting = self.my_settings

values.each do |k,v|
setting.values[k.to_sym] = v
end

setting.save!
end

end
33 changes: 33 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
class User < ActiveRecord::Base
extend Enumerize

# Being pesimistic here and making the default waiting for approval for security reasons
enumerize :status, in: [:active, :suspended, :waiting_approval], :default => :waiting_approval

has_many :activities
before_save :ensure_authentication_token
before_save :ensure_gravatar_hash
before_save :mark_status_depending_on_app_settings

after_create :ensure_at_least_one_admin
after_destroy :ensure_at_least_one_admin

validates :username, :presence => true, :uniqueness => true
validates :first_name, :presence => true
validates :last_name, :presence => true


# Kandan.devise_modules is defined in config/initializers/kandan.rb
Expand All @@ -13,17 +23,40 @@ class User < ActiveRecord::Base
# Setup accessible (or protected) attributes for your model
attr_accessible :id, :username, :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :locale, :gravatar_hash

def full_name
"#{self.first_name.to_s} #{self.last_name.to_s}".titlecase
end

def full_name_or_username
self.full_name.blank? ? self.username : self.full_name
end

def cloudfuji_extra_attributes(extra_attributes)
self.first_name = extra_attributes["first_name"].to_s
self.last_name = extra_attributes["last_name"].to_s
self.email = extra_attributes["email"]
self.locale = extra_attributes["locale"]
end

# Callback to mark the user status depending on the settings of the app
def mark_status_depending_on_app_settings
# If the site is public we will make the user active. Otherwise we will make the user as waiting_approval
self.status = Setting.my_settings.public_site? ? :active : :waiting_approval
end

def ensure_gravatar_hash
self.gravatar_hash = Digest::MD5.hexdigest self.email
end

# We never want an app without an admin so let's ensure there is at least one user
def ensure_at_least_one_admin
if User.count == 1
u = User.first
u.is_admin = true
u.save!
end
end

def active_for_authentication?
super && active?
end
Expand Down
99 changes: 99 additions & 0 deletions app/views/admin/admin/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<% content_for :javascript_includes do %>
<%= javascript_include_tag "admin/admin" %>
<% end %>

<div class="admin-main-area">
<%= form_for @settings, :url => admin_update_path do |f| %>
<%= f.label :max_rooms, 'Max number of rooms' %>:
<%= f.text_field :max_rooms %><br />
<%= f.label :public_site, 'Is this a public site?' %>:
<%= f.check_box :public_site %><br />
<%= f.submit %>
<% end %>

<div class="waiting-for-approval-users">
<% if @waiting_for_approval_users.any? %>
<table cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<th class="">Username</th>
<th class="">First Name</th>
<th class="">Last Name</th>
<th class="">Email</th>
<th class="">Status</th>
<th class="">Action</th>
</tr>
</thead>
<tbody>
<% @all_users.each do |user| %>
<tr class="<%= cycle('odd', 'even')%>" data-user-id="<%= user.id%>">
<td>
<%= user.username %>
</td>
<td>
<%= user.first_name %>
</td>
<td>
<%= user.last_name %>
</td>
<td>
<%= user.email %>
</td>
<td>
<%= user_status(user) %>
</td>
<td>

</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div>There are no users. Invite others to join Kandan!</div>
<% end %>
</div>

<div class="approved-users">
<% if @all_users.any? %>
<table cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<th class="">Username</th>
<th class="">First Name</th>
<th class="">Last Name</th>
<th class="">Email</th>
<th class="">Status</th>
<th class="">Action</th>
</tr>
</thead>
<tbody>
<% @all_users.each do |user| %>
<tr class="<%= cycle('odd', 'even')%>" data-user-id="<%= user.id%>">
<td>
<%= user.username %>
</td>
<td>
<%= user.first_name %>
</td>
<td>
<%= user.last_name %>
</td>
<td>
<%= user.email %>
</td>
<td>
<%= user_status(user) %>
</td>
<td>

</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div>There are no users. Invite others to join Kandan!</div>
<% end %>
</div>
</div>
6 changes: 6 additions & 0 deletions app/views/devise/registrations/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>

<p><%= f.label :first_name %><br />
<%= f.text_field :first_name %></p>

<p><%= f.label :last_name %><br />
<%= f.text_field :last_name %></p>

<p><%= f.label :email %><br />
<%= f.email_field :email %></p>

Expand Down
Loading

0 comments on commit ebb5f3f

Please sign in to comment.