sferik-merb-admin 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.