sferik-merb-admin 0.3.4 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/README.markdown +2 -4
  2. data/Rakefile +1 -6
  3. data/app/controllers/main.rb +6 -7
  4. data/app/helpers/main_helper.rb +17 -18
  5. data/app/views/layout/_message.html.erb +10 -10
  6. data/app/views/layout/dashboard.html.erb +0 -3
  7. data/app/views/layout/form.html.erb +0 -3
  8. data/app/views/layout/list.html.erb +0 -3
  9. data/app/views/main/_belongs_to.html.erb +14 -10
  10. data/app/views/main/_big_decimal.html.erb +8 -2
  11. data/app/views/main/_boolean.html.erb +5 -1
  12. data/app/views/main/_date.html.erb +8 -3
  13. data/app/views/main/_date_time.html.erb +8 -3
  14. data/app/views/main/_float.html.erb +8 -2
  15. data/app/views/main/_has_many.html.erb +9 -3
  16. data/app/views/main/_has_one.html.erb +15 -11
  17. data/app/views/main/_integer.html.erb +12 -4
  18. data/app/views/main/_properties.html.erb +6 -5
  19. data/app/views/main/_string.html.erb +8 -2
  20. data/app/views/main/_text.html.erb +7 -2
  21. data/app/views/main/_time.html.erb +8 -3
  22. data/app/views/main/edit.html.erb +0 -5
  23. data/app/views/main/index.html.erb +0 -8
  24. data/app/views/main/list.html.erb +43 -29
  25. data/lib/datamapper_support.rb +16 -0
  26. data/lib/merb-admin.rb +1 -1
  27. data/spec/fixtures/division_fixture.rb +0 -13
  28. data/spec/fixtures/draft_fixture.rb +0 -19
  29. data/spec/fixtures/league_fixture.rb +0 -12
  30. data/spec/fixtures/player_fixture.rb +0 -23
  31. data/spec/fixtures/team_fixture.rb +0 -15
  32. data/spec/models/division.rb +12 -0
  33. data/spec/models/draft.rb +18 -0
  34. data/spec/models/league.rb +11 -0
  35. data/spec/models/player.rb +22 -0
  36. data/spec/models/team.rb +15 -0
  37. data/spec/requests/main_spec.rb +2 -2
  38. data/spec/spec_helper.rb +4 -1
  39. metadata +10 -23
data/README.markdown CHANGED
@@ -14,8 +14,7 @@ At the command prompt, type:
14
14
 
15
15
  In your app, add the following dependency to `config/dependencies.rb`:
16
16
 
17
- dependency "sferik-merb-admin", "0.3.4", :require_as => "merb-admin"
18
- dependency "dm-is-paginated", "0.0.1" # if you want pagination support
17
+ dependency "sferik-merb-admin", "0.3.6", :require_as => "merb-admin"
19
18
 
20
19
  Add the following route to `config/router.rb`:
21
20
 
@@ -31,7 +30,6 @@ You can configuring the merb-admin slice in a before_app_loads block:
31
30
 
32
31
  Merb::BootLoader.before_app_loads do
33
32
  Merb::Slices::config[:merb_admin][:app_name] = "My App"
34
- Merb::Slices::config[:merb_admin][:paginate] = true
35
33
  Merb::Slices::config[:merb_admin][:per_page] = 100
36
34
  end
37
35
 
@@ -54,8 +52,8 @@ MerbAdmin does not implement any authorization scheme. Make sure to apply author
54
52
  Many thanks to:
55
53
 
56
54
  * [Wilson Miner](http://www.wilsonminer.com) for contributing the stylesheets and javascripts from [Django](http://www.djangoproject.com)
57
- * [Lori Holden](http://loriholden.com/) for providing pagination via [dm-is-paginated](http://github.com/lholden/dm-is-paginated)
58
55
  * [Aaron Wheeler](http://fightinjoe.com/) for contributing libraries from [Merb AutoScaffold](http://github.com/fightinjoe/merb-autoscaffold)
56
+ * [Lori Holden](http://loriholden.com/) for contributing the [merb-pagination](http://github.com/lholden/merb-pagination) helper
59
57
  * [why the lucky stiff](http://whytheluckystiff.net/) for [metaid](http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html)
60
58
 
61
59
  Also, thanks to [beer](http://www.anchorbrewing.com).
data/Rakefile CHANGED
@@ -4,15 +4,12 @@ require "rake/gempackagetask"
4
4
  require "merb-core"
5
5
  require "merb-core/tasks/merb"
6
6
 
7
- dependency "dm-core"
8
- dependency "merb_datamapper"
9
-
10
7
  GEM_NAME = "merb-admin"
11
8
  AUTHOR = "Erik Michaels-Ober"
12
9
  EMAIL = "sferik@gmail.com"
13
10
  HOMEPAGE = "http://twitter.com/sferik"
14
11
  SUMMARY = "MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data."
15
- GEM_VERSION = "0.3.4"
12
+ GEM_VERSION = "0.3.6"
16
13
 
17
14
  spec = Gem::Specification.new do |s|
18
15
  s.rubyforge_project = "merb"
@@ -27,8 +24,6 @@ spec = Gem::Specification.new do |s|
27
24
  s.email = EMAIL
28
25
  s.homepage = HOMEPAGE
29
26
  s.add_dependency("merb-slices", ">= 1.0.12")
30
- s.add_dependency("merb_datamapper", ">= 1.0.12")
31
- s.add_dependency("dm-core", ">= 0.9.11")
32
27
  s.require_path = "lib"
33
28
  s.files = %w(LICENSE README.markdown Rakefile) + Dir.glob("{lib,spec,app,public,stubs}/**/*")
34
29
  s.post_install_message = <<-POST_INSTALL_MESSAGE
@@ -18,20 +18,18 @@ class MerbAdmin::Main < MerbAdmin::Application
18
18
  merge_query(options)
19
19
  merge_sort(options)
20
20
 
21
- if !MerbAdmin[:paginate] || params[:all]
21
+ if params[:all]
22
22
  options = {
23
- :limit => 200,
23
+ :limit => MerbAdmin[:per_page] * 2,
24
24
  }.merge(options)
25
25
  @objects = @abstract_model.find_all(options).reverse
26
26
  else
27
- # monkey patch pagination
28
- @abstract_model.model.class_eval('is_paginated') unless @abstract_model.model.respond_to?(:paginated)
29
27
  @current_page = (params[:page] || 1).to_i
30
28
  options = {
31
29
  :page => @current_page,
32
30
  :per_page => MerbAdmin[:per_page],
33
31
  }.merge(options)
34
- @page_count, @objects = @abstract_model.model.paginated(options)
32
+ @page_count, @objects = @abstract_model.paginated(options)
35
33
  options.delete(:page)
36
34
  options.delete(:per_page)
37
35
  options.delete(:offset)
@@ -157,8 +155,9 @@ class MerbAdmin::Main < MerbAdmin::Application
157
155
  end
158
156
 
159
157
  def merge_sort(options)
160
- return unless params[:sort]
161
- options.merge!(:order => [params[:sort].to_sym.send(params[:sort_reverse] ? :desc : :asc)])
158
+ sort = params[:sort] || "id"
159
+ order = params[:sort_reverse] == "true" ? :desc : :asc
160
+ options.merge!(:order => [sort.to_sym.send(order)])
162
161
  end
163
162
 
164
163
  def update_has_one_association(association, id)
@@ -8,15 +8,15 @@ module Merb
8
8
 
9
9
  # Given a page count and the current page, we generate a set of pagination
10
10
  # links.
11
- #
12
- # * We use an inner and outer window into a list of links. For a set of
11
+ #
12
+ # * We use an inner and outer window into a list of links. For a set of
13
13
  # 20 pages with the current page being 10:
14
14
  # outer_window:
15
15
  # 1 2 ..... 19 20
16
16
  # inner_window
17
17
  # 5 6 7 8 9 10 11 12 13 14
18
18
  #
19
- # This is totally adjustable, or can be turned off by giving the
19
+ # This is totally adjustable, or can be turned off by giving the
20
20
  # :inner_window setting a value of nil.
21
21
  #
22
22
  # * Options
@@ -41,25 +41,24 @@ module Merb
41
41
  # Provides the base url to use in the page navigation links.
42
42
  # Defaults to ''
43
43
  def paginate(current_page, page_count, options = {})
44
- options.reverse_merge!({
45
- :left_cut_label => '&hellip;',
46
- :right_cut_label => '&hellip;',
47
- :outer_window => 2,
48
- :inner_window => 7,
49
- :page_param => 'page',
50
- :url => ''
51
- })
52
- url = options.delete :url
44
+ options[:left_cut_label] ||= '&hellip;'
45
+ options[:right_cut_label] ||= '&hellip;'
46
+ options[:outer_window] ||= 2
47
+ options[:inner_window] ||= 7
48
+ options[:page_param] ||= 'page'
49
+ options[:url] ||= ''
50
+
51
+ url = options.delete(:url)
53
52
  url << (url.include?('?') ? '&' : '?') << options[:page_param]
54
53
 
55
- pages = {
56
- :all => (1..page_count).to_a,
57
- :left => [],
58
- :center => [],
59
- :right => []
54
+ pages = {
55
+ :all => (1..page_count).to_a,
56
+ :left => [],
57
+ :center => [],
58
+ :right => []
60
59
  }
61
60
 
62
- # Only worry about using our 'windows' if the page count is less then
61
+ # Only worry about using our 'windows' if the page count is less then
63
62
  # our windows combined.
64
63
  if options[:inner_window].nil? || ((options[:outer_window] * 2) + options[:inner_window] + 2) >= page_count
65
64
  pages[:center] = pages[:all]
@@ -1,10 +1,10 @@
1
- <% if message && message[:error] %>
2
- <p class="errornote">
3
- <%=h message[:error] %>
4
- </p>
5
- <% end %>
6
- <% if message && message[:notice] %>
7
- <ul class="messagelist">
8
- <li><%=h message[:notice] %></li>
9
- </ul>
10
- <% end %>
1
+ <% if message && message[:error] %>
2
+ <p class="errornote">
3
+ <%=h message[:error] %>
4
+ </p>
5
+ <% end %>
6
+ <% if message && message[:notice] %>
7
+ <ul class="messagelist">
8
+ <li><%=h message[:notice] %></li>
9
+ </ul>
10
+ <% end %>
@@ -20,9 +20,6 @@
20
20
  <%= slice_name %>
21
21
  </h1>
22
22
  </div>
23
- <div id="user-tools">
24
- <!-- Welcome, <strong></strong>. <a href="">Log out</a> -->
25
- </div>
26
23
  </div>
27
24
  <%= partial('layout/message', :message => message) unless message.blank? -%>
28
25
  <div id="content" class="colMS">
@@ -29,9 +29,6 @@
29
29
  <%= slice_name %>
30
30
  </h1>
31
31
  </div>
32
- <div id="user-tools">
33
- <!-- Welcome, <strong></strong>. <a href="">Log out</a> -->
34
- </div>
35
32
  </div>
36
33
  <div class="breadcrumbs">
37
34
  <%= link_to("Home", url(:admin_dashboard)) %> &rsaquo;
@@ -24,9 +24,6 @@
24
24
  <%= slice_name %>
25
25
  </h1>
26
26
  </div>
27
- <div id="user-tools">
28
- <!-- Welcome, <strong></strong>. <a href="">Log out</a> -->
29
- </div>
30
27
  </div>
31
28
  <div class="breadcrumbs">
32
29
  <%= link_to("Home", url(:admin_dashboard)) %> &rsaquo;
@@ -1,22 +1,26 @@
1
1
  <%
2
- required = false
3
- @properties.each do |property|
4
- next unless property[:name] == association[:child_key].first
5
- required = true unless property[:nullable?]
6
- end
2
+ child_key = association[:child_key].first
3
+ collection = MerbAdmin::AbstractModel.new(association[:parent_model]).find_all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}
4
+ selected = @object.send(child_key)
5
+ label = association[:pretty_name].capitalize
6
+ required = false
7
+ @properties.each do |property|
8
+ next unless property[:name] == child_key
9
+ required = true unless property[:nullable?]
10
+ end
7
11
  %>
8
12
  <fieldset class="module aligned">
9
- <h2><%= association[:pretty_name].capitalize %></h2>
10
- <div class="<%= @object.errors[association[:child_key].first] ? "form-row errors" : "form-row"%>">
11
- <% if @object.errors[association[:child_key].first] %>
13
+ <h2><%= label %></h2>
14
+ <div class="<%= @object.errors[child_key] ? "form-row errors" : "form-row"%>">
15
+ <% if @object.errors[child_key] %>
12
16
  <ul class="errorlist">
13
- <% @object.errors[association[:child_key].first].each do |error| %>
17
+ <% @object.errors[child_key].each do |error| %>
14
18
  <li><%= error %></li>
15
19
  <% end %>
16
20
  </ul>
17
21
  <% end %>
18
22
  <div>
19
- <%= select(association[:child_key].first, :collection => MerbAdmin::AbstractModel.new(association[:parent_model]).find_all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}, :include_blank => true, :selected => @object.send(association[:child_key].first).to_s, :label => association[:pretty_name].capitalize) %>
23
+ <%= select(child_key, :collection => collection, :include_blank => true, :selected => selected.to_s, :label => label) %>
20
24
  <p class="help">
21
25
  <%= required ? "Required." : "Optional." %>
22
26
  </p>
@@ -1,6 +1,12 @@
1
+ <%
2
+ name = property[:name]
3
+ length = property[:length]
4
+ label = property[:pretty_name].capitalize
5
+ required = !property[:nullable?] || property[:serial?]
6
+ %>
1
7
  <div>
2
- <%= text_field(property[:name], :maxlength => property[:length], :label => property[:pretty_name].capitalize) %>
8
+ <%= text_field(name, :maxlength => length, :label => label) %>
3
9
  <p class="help">
4
- <%= !property[:nullable?] || property[:serial?] ? "Required." : "Optional." %>
10
+ <%= required ? "Required." : "Optional." %>
5
11
  </p>
6
12
  </div>
@@ -1,3 +1,7 @@
1
+ <%
2
+ name = property[:name]
3
+ label = property[:pretty_name].capitalize
4
+ %>
1
5
  <div>
2
- <%= check_box(property[:name], :label => property[:pretty_name].capitalize) %>
6
+ <%= check_box(name, :label => label) %>
3
7
  </div>
@@ -1,7 +1,12 @@
1
- <% value = @object.send(property[:name]) %>
1
+ <%
2
+ name = property[:name]
3
+ value = @object.send(name)
4
+ label = property[:pretty_name].capitalize
5
+ required = !property[:nullable?]
6
+ %>
2
7
  <div>
3
- <%= text_field(property[:name], :class => "vDateField", :label => property[:pretty_name].capitalize, :value => value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d") : nil) %>
8
+ <%= text_field(name, :class => "vDateField", :value => value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d") : nil, :label => label) %>
4
9
  <p class="help">
5
- <%= !property[:nullable?] ? "Required." : "Optional." %>
10
+ <%= required ? "Required." : "Optional." %>
6
11
  </p>
7
12
  </div>
@@ -1,7 +1,12 @@
1
- <% value = @object.send(property[:name]) %>
1
+ <%
2
+ name = property[:name]
3
+ value = @object.send(name)
4
+ label = property[:pretty_name].capitalize
5
+ required = !property[:nullable?]
6
+ %>
2
7
  <div>
3
- <%= text_field(property[:name], :class => "vDateField", :label => property[:pretty_name].capitalize, :value => value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d %H:%M:%S") : nil) %>
8
+ <%= text_field(name, :class => "vDateField", :value => value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d %H:%M:%S") : nil, :label => label) %>
4
9
  <p class="help">
5
- <%= !property[:nullable?] ? "Required." : "Optional." %>
10
+ <%= required ? "Required." : "Optional." %>
6
11
  </p>
7
12
  </div>
@@ -1,6 +1,12 @@
1
+ <%
2
+ name = property[:name]
3
+ length = property[:length]
4
+ label = property[:pretty_name].capitalize
5
+ required = !property[:nullable?] || property[:serial?]
6
+ %>
1
7
  <div>
2
- <%= text_field(property[:name], :maxlength => property[:length], :label => property[:pretty_name].capitalize) %>
8
+ <%= text_field(name, :maxlength => length, :label => label) %>
3
9
  <p class="help">
4
- <%= !property[:nullable?] || property[:serial?] ? "Required." : "Optional." %>
10
+ <%= required ? "Required." : "Optional." %>
5
11
  </p>
6
12
  </div>
@@ -1,9 +1,15 @@
1
+ <%
2
+ name = association[:name]
3
+ collection = MerbAdmin::AbstractModel.new(association[:child_model]).find_all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}
4
+ selected = @object.send(name)
5
+ label = association[:pretty_name].capitalize
6
+ %>
1
7
  <fieldset class="module aligned">
2
- <h2><%= association[:pretty_name].capitalize %></h2>
8
+ <h2><%= label %></h2>
3
9
  <div class="form-row">
4
10
  <div>
5
- <%= select(:name => "associations[#{association[:name]}][]", :id => association[:name], :collection => MerbAdmin::AbstractModel.new(association[:child_model]).find_all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}, :selected => @object.send(association[:name]).map{|o| o.id.to_s}, :label => association[:pretty_name].capitalize, :multiple => true) %>
6
- <script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("<%= association[:name] %>", "<%= association[:name] %>", 0, "<%= image_path %>"); });</script>
11
+ <%= select(:name => "associations[#{name}][]", :id => name, :collection => collection, :selected => selected.map{|o| o.id.to_s}, :label => label, :multiple => true) %>
12
+ <script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("<%= name %>", "<%= name %>", 0, "<%= image_path %>"); });</script>
7
13
  <p class="help">Hold down "Control", or "Command" on a Mac, to select more than one.</p>
8
14
  </div>
9
15
  </div>
@@ -1,23 +1,27 @@
1
1
  <%
2
- selected = MerbAdmin::AbstractModel.new(association[:child_model]).find_all(association[:child_key].first => @object.id).first
3
- required = false
4
- @properties.each do |property|
5
- next unless property[:name] == association[:child_key].first
6
- required = true unless property[:nullable?]
7
- end
2
+ child_key = association[:child_key].first
3
+ name = association[:name]
4
+ collection = MerbAdmin::AbstractModel.new(association[:child_model]).find_all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}
5
+ selected = MerbAdmin::AbstractModel.new(association[:child_model]).find_all(child_key => @object.id).first
6
+ label = association[:pretty_name].capitalize
7
+ required = false
8
+ @properties.each do |property|
9
+ next unless property[:name] == child_key
10
+ required = true unless property[:nullable?]
11
+ end
8
12
  %>
9
13
  <fieldset class="module aligned">
10
- <h2><%= association[:pretty_name].capitalize %></h2>
11
- <div class="<%= @object.errors[association[:child_key].first] ? "form-row errors" : "form-row"%>">
12
- <% if @object.errors[association[:child_key].first] %>
14
+ <h2><%= label %></h2>
15
+ <div class="<%= @object.errors[child_key] ? "form-row errors" : "form-row" %>">
16
+ <% if @object.errors[child_key] %>
13
17
  <ul class="errorlist">
14
- <% @object.errors[association[:child_key].first].each do |error| %>
18
+ <% @object.errors[child_key].each do |error| %>
15
19
  <li><%= error %></li>
16
20
  <% end %>
17
21
  </ul>
18
22
  <% end %>
19
23
  <div>
20
- <%= select(:name => "associations[#{association[:name]}][]", :id => association[:name], :collection => MerbAdmin::AbstractModel.new(association[:child_model]).find_all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}, :include_blank => true, :selected => selected ? selected.id.to_s : nil, :label => association[:pretty_name].capitalize) %>
24
+ <%= select(:name => "associations[#{name}][]", :id => name, :collection => collection, :include_blank => true, :selected => selected ? selected.id.to_s : nil, :label => label) %>
21
25
  <p class="help">
22
26
  <%= required ? "Required." : "Optional." %>
23
27
  </p>
@@ -1,10 +1,18 @@
1
+ <%
2
+ flag_map = property[:flag_map]
3
+ name = property[:name]
4
+ label = property[:pretty_name].capitalize
5
+ required = !property[:nullable?] || property[:serial?]
6
+ %>
1
7
  <div>
2
- <% if property[:flag_map] # Enum or Flag type %>
3
- <%= select(property[:name], :collection => property[:flag_map].map{|x| [x[1], x[1].to_s.capitalize.gsub('_', ' ')]}.sort{|a, b| a[1] <=> b[1]}, :label => property[:pretty_name].capitalize) %>
8
+ <% if flag_map # Enum or Flag type %>
9
+ <% collection = flag_map.map{|x| [x[1], x[1].to_s.capitalize.gsub('_', ' ')]}.sort{|a, b| a[1] <=> b[1]} %>
10
+ <%= select(name, :collection => collection, :label => label) %>
4
11
  <% else %>
5
- <%= text_field(property[:name], :maxlength => property[:length], :label => property[:pretty_name].capitalize) %>
12
+ <% length = property[:length] %>
13
+ <%= text_field(name, :maxlength => length, :label => label) %>
6
14
  <p class="help">
7
- <%= !property[:nullable?] || property[:serial?] ? "Required." : "Optional." %>
15
+ <%= required ? "Required." : "Optional." %>
8
16
  </p>
9
17
  <% end %>
10
18
  </div>
@@ -1,12 +1,13 @@
1
1
  <fieldset class="module aligned">
2
2
  <% belongs_to_keys = @abstract_model.belongs_to_associations.map{|b| b[:child_key].first} %>
3
3
  <% properties.each do |property| %>
4
- <% next if [:id, :created_at, :created_on, :deleted_at, :updated_at, :updated_on, :deleted_on].include?(property[:name]) %>
5
- <% next if belongs_to_keys.include?(property[:name]) %>
6
- <div class="<%= @object.errors[property[:name]] ? "form-row errors" : "form-row" %>">
7
- <% if @object.errors[property[:name]] %>
4
+ <% name = property[:name] %>
5
+ <% next if [:id, :created_at, :created_on, :deleted_at, :updated_at, :updated_on, :deleted_on].include?(name) %>
6
+ <% next if belongs_to_keys.include?(name) %>
7
+ <div class="<%= @object.errors[name] ? "form-row errors" : "form-row" %>">
8
+ <% if @object.errors[name] %>
8
9
  <ul class="errorlist">
9
- <% @object.errors[property[:name]].each do |error| %>
10
+ <% @object.errors[name].each do |error| %>
10
11
  <li><%= error %></li>
11
12
  <% end %>
12
13
  </ul>
@@ -1,6 +1,12 @@
1
+ <%
2
+ name = property[:name]
3
+ length = property[:length]
4
+ label = property[:pretty_name].capitalize
5
+ required = !property[:nullable?]
6
+ %>
1
7
  <div>
2
- <%= text_field(property[:name], :size => [50, property[:length]].min, :maxlength => property[:length], :label => property[:pretty_name].capitalize) %>
8
+ <%= text_field(name, :size => [50, length].min, :maxlength => length, :label => label) %>
3
9
  <p class="help">
4
- <%= !property[:nullable?] ? "Required." : "Optional." %> <%= property[:length] %> <%= property[:length] == 1 ? "character." : "characters or fewer." %>
10
+ <%= required ? "Required." : "Optional." %> <%= length %> <%= length == 1 ? "character." : "characters or fewer." %>
5
11
  </p>
6
12
  </div>
@@ -1,6 +1,11 @@
1
+ <%
2
+ name = property[:name]
3
+ label = property[:pretty_name].capitalize
4
+ required = property[:nullable?]
5
+ %>
1
6
  <div>
2
- <%= text_area(property[:name], :cols => 80, :label => property[:pretty_name].capitalize) %>
7
+ <%= text_area(name, :cols => 80, :label => label) %>
3
8
  <p class="help">
4
- <%= property[:nullable?] ? "Required." : "Optional." %>
9
+ <%= required ? "Required." : "Optional." %>
5
10
  </p>
6
11
  </div>
@@ -1,7 +1,12 @@
1
- <% value = @object.send(property[:name]) %>
1
+ <%
2
+ name = property[:name]
3
+ value = @object.send(name)
4
+ label = property[:pretty_name].capitalize
5
+ required = !property[:nullable?]
6
+ %>
2
7
  <div>
3
- <%= text_field(property[:name], :class => "vTimeField", :label => property[:pretty_name].capitalize, :value => value.respond_to?(:strftime) ? value.strftime("%H:%M:%S") : nil) %>
8
+ <%= text_field(name, :class => "vTimeField", :value => value.respond_to?(:strftime) ? value.strftime("%H:%M:%S") : nil, :label => label) %>
4
9
  <p class="help">
5
- <%= !property[:nullable?] ? "Required." : "Optional." %>
10
+ <%= required ? "Required." : "Optional." %>
6
11
  </p>
7
12
  </div>
@@ -1,9 +1,4 @@
1
1
  <div id="content-main">
2
- <ul class="object-tools">
3
- <li>
4
- <%= link_to("View on site", "/#{@abstract_model.singular_name}/#{@object.id}", :target => "_blank", :class => "viewsitelink") %>
5
- </li>
6
- </ul>
7
2
  <%= form_for(@object, :action => slice_url(:admin_update, :model_name => @abstract_model.singular_name, :id => @object.id)) do %>
8
3
  <div>
9
4
  <%= partial('properties', :properties => @properties) -%>
@@ -20,11 +20,3 @@
20
20
  </table>
21
21
  </div>
22
22
  </div>
23
- <div id="content-related">
24
- <div class="module" id="recent-actions-module">
25
- <h2>Recent Actions</h2>
26
- <h3>My Actions</h3>
27
- <p>None available</p>
28
- </div>
29
- </div>
30
- <br class="clear" />
@@ -1,4 +1,10 @@
1
- <% params = request.params.except(:action, :controller, :model_name) %>
1
+ <%
2
+ params = request.params.except(:action, :controller, :model_name)
3
+ filter = params[:filter]
4
+ query = params[:query]
5
+ sort = params[:sort]
6
+ sort_reverse = params[:sort_reverse]
7
+ %>
2
8
  <div id="content-main">
3
9
  <ul class="object-tools">
4
10
  <li>
@@ -12,11 +18,11 @@
12
18
  <label for="searchbar"><img src="<%= image_path("icon_searchbox.png") %>" alt="Search" /></label>
13
19
  <input type="text" size="40" name="query" value="" id="searchbar" />
14
20
  <input type="submit" value="Search" />
15
- <% if params[:query] || params[:filter] %>
21
+ <% if filter || query %>
16
22
  <span class="small quiet"><%= @record_count %> <%= @record_count == 1 ? "result" : "results" %> (<a href="?"><%= @abstract_model.count %> total</a>)</span>
17
23
  <% end %>
18
- <% if params[:filter] %>
19
- <% params[:filter].each do |name, value| %>
24
+ <% if filter %>
25
+ <% filter.each do |name, value| %>
20
26
  <input type="hidden" name="filter[<%= name %>]" value="<%= value %>"/>
21
27
  <% end %>
22
28
  <% end %>
@@ -27,28 +33,32 @@
27
33
  <div id="changelist-filter">
28
34
  <h2>Filter</h2>
29
35
  <% @properties.each do |property| %>
30
- <% if property[:type] == :boolean %>
31
- <h3>By <%= property[:pretty_name] %></h3>
36
+ <% type = property[:type] %>
37
+ <% name = property[:name] %>
38
+ <% pretty_name = property[:pretty_name] %>
39
+ <% flag_map = property[:flag_map] %>
40
+ <% if type == :boolean %>
41
+ <h3>By <%= pretty_name %></h3>
32
42
  <ul>
33
- <li class="<%= params[:filter].nil? || params[:filter][property[:name]].blank? ? "selected" : nil %>">
34
- <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (params[:filter] || {}).reject{|key, value| key.to_sym == property[:name]})) %>">All</a>
43
+ <li class="<%= filter.nil? || filter[name].blank? ? "selected" : nil %>">
44
+ <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).reject{|key, value| key.to_sym == name})) %>">All</a>
35
45
  </li>
36
- <li class="<%= params[:filter] && params[:filter][property[:name]] == "true" ? "selected" : nil %>">
37
- <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (params[:filter] || {}).merge({property[:name] => "true"}))) %>">Yes</a>
46
+ <li class="<%= filter && filter[name] == "true" ? "selected" : nil %>">
47
+ <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).merge({name => "true"}))) %>">Yes</a>
38
48
  </li>
39
- <li class="<%= params[:filter] && params[:filter][property[:name]] == "false" ? "selected" : nil %>">
40
- <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (params[:filter] || {}).merge({property[:name] => "false"}))) %>">No</a>
49
+ <li class="<%= filter && filter[name] == "false" ? "selected" : nil %>">
50
+ <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).merge({name => "false"}))) %>">No</a>
41
51
  </li>
42
52
  </ul>
43
- <% elsif property[:type] == :integer && property[:flag_map] %>
44
- <h3>By <%= property[:pretty_name] %></h3>
53
+ <% elsif type == :integer && flag_map %>
54
+ <h3>By <%= pretty_name %></h3>
45
55
  <ul>
46
- <li class="<%= params[:filter].nil? || params[:filter][property[:name]].blank? ? "selected" : nil %>">
47
- <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (params[:filter] || {}).reject{|key, value| key.to_sym == property[:name]})) %>">All</a>
56
+ <li class="<%= filter.nil? || filter[name].blank? ? "selected" : nil %>">
57
+ <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).reject{|key, value| key.to_sym == name})) %>">All</a>
48
58
  </li>
49
- <% property[:flag_map].each do |value, name| %>
50
- <li class="<%= params[:filter] && params[:filter][property[:name]] == name.to_s ? "selected" : nil %>">
51
- <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (params[:filter] || {}).merge({property[:name] => name}))) %>"><%= name.to_s.capitalize.gsub('_', ' ')%></a>
59
+ <% flag_map.values.map{|v| v.to_s}.sort.each do |value| %>
60
+ <li class="<%= filter && filter[name] == value ? "selected" : nil %>">
61
+ <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).merge({name => value}))) %>"><%= value.capitalize.gsub('_', ' ')%></a>
52
62
  </li>
53
63
  <% end %>
54
64
  </ul>
@@ -59,8 +69,10 @@
59
69
  <thead>
60
70
  <tr>
61
71
  <% @properties.each do |property| %>
62
- <th class="<%= params[:sort] == property[:name].to_s ? params[:sort_reverse] ? 'sorted descending' : 'sorted ascending' : nil %>">
63
- <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:sort => property[:name]).reject{|key, value| key.to_sym == :sort_reverse}.merge(params[:sort] == property[:name].to_s && params[:sort_reverse] != "true" ? {:sort_reverse => "true"} : {})) %>"><%= property[:pretty_name].capitalize %></a>
72
+ <% name = property[:name] %>
73
+ <% pretty_name = property[:pretty_name] %>
74
+ <th class="<%= sort == name.to_s ? sort_reverse ? 'sorted descending' : 'sorted ascending' : nil %>">
75
+ <a href="?<%= Merb::Parse.params_to_query_string(params.merge(:sort => name).reject{|key, value| key.to_sym == :sort_reverse}.merge(sort == name.to_s && sort_reverse != "true" ? {:sort_reverse => "true"} : {})) %>"><%= pretty_name.capitalize %></a>
64
76
  </th>
65
77
  <% end %>
66
78
  </tr>
@@ -69,30 +81,32 @@
69
81
  <% @objects.each_with_index do |object, index| %>
70
82
  <tr class="row<%= index % 2 == 0 ? '1' : '2' %>">
71
83
  <% @properties.each do |property| %>
84
+ <% type = property[:type] %>
85
+ <% name = property[:name] %>
72
86
  <td>
73
87
  <a href="<%= slice_url(:admin_edit, :model_name => @abstract_model.singular_name, :id => object.id) %>">
74
- <% case property[:type] %>
88
+ <% case type %>
75
89
  <% when :boolean %>
76
- <% if object.send(property[:name]) == true %>
90
+ <% if object.send(name) == true %>
77
91
  <img alt="True" src="<%= image_path("icon-yes.gif") %>"/>
78
92
  <% else %>
79
93
  <img alt="False" src="<%= image_path("icon-no.gif") %>"/>
80
94
  <% end %>
81
95
  <% when :date_time %>
82
- <% value = object.send(property[:name]) %>
96
+ <% value = object.send(name) %>
83
97
  <%= value.respond_to?(:strftime) ? value.strftime("%b. %d, %Y, %I:%M%p") : nil %>
84
98
  <% when :date %>
85
- <% value = object.send(property[:name]) %>
99
+ <% value = object.send(name) %>
86
100
  <%= value.respond_to?(:strftime) ? value.strftime("%b. %d, %Y") : nil %>
87
101
  <% when :time %>
88
- <% value = object.send(property[:name]) %>
102
+ <% value = object.send(name) %>
89
103
  <%= value.respond_to?(:strftime) ? value.strftime("%I:%M%p") : nil %>
90
104
  <% when :string %>
91
- <%= object.send(property[:name]).to_s.truncate(50) %>
105
+ <%= object.send(name).to_s.truncate(50) %>
92
106
  <% when :text %>
93
- <%= object.send(property[:name]).to_s.truncate(50) %>
107
+ <%= object.send(name).to_s.truncate(50) %>
94
108
  <% else %>
95
- <%= object.send(property[:name]) %>
109
+ <%= object.send(name) %>
96
110
  <% end %>
97
111
  </a>
98
112
  </td>
@@ -13,6 +13,22 @@ module MerbAdmin
13
13
  model.get(id).extend(InstanceMethods)
14
14
  end
15
15
 
16
+ def paginated(options = {})
17
+ page = options.delete(:page) || 1
18
+ per_page = options.delete(:per_page) || MerbAdmin[:per_page]
19
+
20
+ options[:order] ||= [:id.desc]
21
+
22
+ page_count = (count(options).to_f / per_page).ceil
23
+
24
+ options.merge!({
25
+ :limit => per_page,
26
+ :offset => (page - 1) * per_page
27
+ })
28
+
29
+ [page_count, find_all(options)]
30
+ end
31
+
16
32
  def new(params = {})
17
33
  model.new(params).extend(InstanceMethods)
18
34
  end
data/lib/merb-admin.rb CHANGED
@@ -23,7 +23,7 @@ if defined?(Merb::Plugins)
23
23
 
24
24
  # Slice metadata
25
25
  self.description = "MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data."
26
- self.version = "0.3.4"
26
+ self.version = "0.3.6"
27
27
  self.author = "Erik Michaels-Ober"
28
28
 
29
29
  # Stub classes loaded hook - runs before LoadClasses BootLoader
@@ -1,16 +1,3 @@
1
- class Division
2
- include DataMapper::Resource
3
-
4
- property :id, Serial
5
- property :created_at, DateTime
6
- property :updated_at, DateTime
7
- property :league_id, Integer, :nullable => false, :index => true
8
- property :name, String, :nullable => false, :index => true
9
-
10
- belongs_to :league
11
- has n, :teams
12
- end
13
-
14
1
  Division.fixture {{
15
2
  :league_id => /\d{1,5}/.gen,
16
3
  :name => /\w{5,10}/.gen.capitalize,
@@ -1,22 +1,3 @@
1
- class Draft
2
- include DataMapper::Resource
3
-
4
- property :id, Serial
5
- property :created_at, DateTime
6
- property :updated_at, DateTime
7
- property :player_id, Integer, :nullable => false, :index => true
8
- property :team_id, Integer, :nullable => false, :index => true
9
- property :date, Date, :nullable => false
10
- property :round, Integer, :nullable => false
11
- property :pick, Integer, :nullable => false
12
- property :overall, Integer, :nullable => false
13
- property :college, String, :length => 100
14
- property :notes, Text
15
-
16
- belongs_to :team
17
- belongs_to :player
18
- end
19
-
20
1
  Draft.fixture {{
21
2
  :player_id => /\d{1,5}/.gen,
22
3
  :team_id => /\d{1,5}/.gen,
@@ -1,15 +1,3 @@
1
- class League
2
- include DataMapper::Resource
3
-
4
- property :id, Serial
5
- property :created_at, DateTime
6
- property :updated_at, DateTime
7
- property :name, String, :nullable => false, :index => true
8
-
9
- has n, :divisions
10
- has n, :teams
11
- end
12
-
13
1
  League.fixture {{
14
2
  :name => "#{/\w{5,10}/.gen.capitalize} League",
15
3
  }}
@@ -1,26 +1,3 @@
1
- class Player
2
- include DataMapper::Resource
3
-
4
- property :id, Serial
5
- property :created_at, DateTime
6
- property :updated_at, DateTime
7
- property :deleted_at, ParanoidDateTime
8
- property :team_id, Integer, :nullable => false, :index => true
9
- property :number, Integer, :nullable => false
10
- property :name, String, :length => 100, :nullable => false
11
- property :position, Enum[:pitcher, :catcher, :first, :second, :third, :shortstop, :left, :center, :right]
12
- property :sex, Enum[:male, :female]
13
- property :batting_average, Float, :default => 0.0, :precision => 4, :scale => 3
14
- property :injured, Boolean, :default => false
15
- property :retired, TrueClass, :default => false
16
- property :born_on, Date
17
- property :wake_at, Time
18
- property :notes, Text
19
-
20
- belongs_to :team
21
- has 1, :draft
22
- end
23
-
24
1
  Player.fixture {{
25
2
  :team_id => /\d{1,5}/.gen,
26
3
  :number => /\d{1,2}/.gen,
@@ -1,18 +1,3 @@
1
- class Team
2
- include DataMapper::Resource
3
-
4
- property :id, Serial
5
- property :created_at, DateTime
6
- property :updated_at, DateTime
7
- property :league_id, Integer, :nullable => false, :index => true
8
- property :division_id, Integer, :nullable => false, :index => true
9
- property :name, String, :nullable => false, :index => true
10
-
11
- belongs_to :league
12
- belongs_to :division
13
- has n, :players
14
- end
15
-
16
1
  Team.fixture {{
17
2
  :league_id => /\d{1,5}/.gen,
18
3
  :division_id => /\d{1,5}/.gen,
@@ -0,0 +1,12 @@
1
+ class Division
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :updated_at, DateTime
7
+ property :league_id, Integer, :nullable => false, :index => true
8
+ property :name, String, :nullable => false, :index => true
9
+
10
+ belongs_to :league
11
+ has n, :teams
12
+ end
@@ -0,0 +1,18 @@
1
+ class Draft
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :updated_at, DateTime
7
+ property :player_id, Integer, :nullable => false, :index => true
8
+ property :team_id, Integer, :nullable => false, :index => true
9
+ property :date, Date, :nullable => false
10
+ property :round, Integer, :nullable => false
11
+ property :pick, Integer, :nullable => false
12
+ property :overall, Integer, :nullable => false
13
+ property :college, String, :length => 100
14
+ property :notes, Text
15
+
16
+ belongs_to :team
17
+ belongs_to :player
18
+ end
@@ -0,0 +1,11 @@
1
+ class League
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :updated_at, DateTime
7
+ property :name, String, :nullable => false, :index => true
8
+
9
+ has n, :divisions
10
+ has n, :teams
11
+ end
@@ -0,0 +1,22 @@
1
+ class Player
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :updated_at, DateTime
7
+ property :deleted_at, ParanoidDateTime
8
+ property :team_id, Integer, :nullable => false, :index => true
9
+ property :number, Integer, :nullable => false
10
+ property :name, String, :length => 100, :nullable => false
11
+ property :position, Enum[:pitcher, :catcher, :first, :second, :third, :shortstop, :left, :center, :right]
12
+ property :sex, Enum[:male, :female]
13
+ property :batting_average, Float, :default => 0.0, :precision => 4, :scale => 3
14
+ property :injured, Boolean, :default => false
15
+ property :retired, TrueClass, :default => false
16
+ property :born_on, Date
17
+ property :wake_at, Time
18
+ property :notes, Text
19
+
20
+ belongs_to :team
21
+ has 1, :draft
22
+ end
@@ -0,0 +1,15 @@
1
+ class Team
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :updated_at, DateTime
7
+ property :league_id, Integer, :nullable => false, :index => true
8
+ property :division_id, Integer, :nullable => false, :index => true
9
+ property :name, String, :nullable => false, :index => true
10
+ property :colors, Flag[:beige, :black, :blue, :bronze, :brown, :cool, :copper, :cream, :gold, :gray, :green, :khaki, :maroon, :midnight, :navy, :orange, :pink, :purple, :red, :silver, :tan, :turquoise, :violet, :white, :yellow]
11
+
12
+ belongs_to :league
13
+ belongs_to :division
14
+ has n, :players
15
+ end
@@ -124,7 +124,7 @@ describe "MerbAdmin" do
124
124
  end
125
125
 
126
126
  it "should be ordered correctly" do
127
- @response.body.should contain(/Sandy Koufax.*Jackie Robinson/m)
127
+ @response.body.should contain(/Jackie Robinson.*Sandy Koufax/m)
128
128
  end
129
129
  end
130
130
 
@@ -140,7 +140,7 @@ describe "MerbAdmin" do
140
140
  end
141
141
 
142
142
  it "should be ordered correctly" do
143
- @response.body.should contain(/Jackie Robinson.*Sandy Koufax/m)
143
+ @response.body.should contain(/Sandy Koufax.*Jackie Robinson/m)
144
144
  end
145
145
  end
146
146
 
data/spec/spec_helper.rb CHANGED
@@ -10,7 +10,10 @@ require 'dm-sweatshop'
10
10
  require 'dm-types'
11
11
  require 'dm-aggregates'
12
12
  require 'dm-validations'
13
- require 'dm-is-paginated'
13
+
14
+ Dir[File.join(File.dirname(__FILE__), 'models', '**', '*.rb').to_s].each do |model_file|
15
+ require model_file
16
+ end
14
17
 
15
18
  Dir[File.join(File.dirname(__FILE__), 'fixtures', '**', '*_fixture.rb').to_s].each do |fixture_file|
16
19
  require fixture_file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sferik-merb-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Michaels-Ober
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-31 00:00:00 -07:00
12
+ date: 2009-09-07 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,26 +22,6 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.0.12
24
24
  version:
25
- - !ruby/object:Gem::Dependency
26
- name: merb_datamapper
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 1.0.12
34
- version:
35
- - !ruby/object:Gem::Dependency
36
- name: dm-core
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: 0.9.11
44
- version:
45
25
  description: MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data.
46
26
  email: sferik@gmail.com
47
27
  executables: []
@@ -72,6 +52,12 @@ files:
72
52
  - spec/fixtures/league_fixture.rb
73
53
  - spec/fixtures/player_fixture.rb
74
54
  - spec/fixtures/team_fixture.rb
55
+ - spec/models
56
+ - spec/models/division.rb
57
+ - spec/models/draft.rb
58
+ - spec/models/league.rb
59
+ - spec/models/player.rb
60
+ - spec/models/team.rb
75
61
  - spec/requests
76
62
  - spec/requests/main_spec.rb
77
63
  - spec/spec_helper.rb
@@ -183,6 +169,7 @@ files:
183
169
  - public/stylesheets/widgets.css
184
170
  has_rdoc: false
185
171
  homepage: http://twitter.com/sferik
172
+ licenses:
186
173
  post_install_message: |
187
174
  ********************************************************************************
188
175
 
@@ -210,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
197
  requirements: []
211
198
 
212
199
  rubyforge_project: merb
213
- rubygems_version: 1.2.0
200
+ rubygems_version: 1.3.5
214
201
  signing_key:
215
202
  specification_version: 3
216
203
  summary: MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data.