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.
- data/README.markdown +2 -4
- data/Rakefile +1 -6
- data/app/controllers/main.rb +6 -7
- data/app/helpers/main_helper.rb +17 -18
- data/app/views/layout/_message.html.erb +10 -10
- data/app/views/layout/dashboard.html.erb +0 -3
- data/app/views/layout/form.html.erb +0 -3
- data/app/views/layout/list.html.erb +0 -3
- data/app/views/main/_belongs_to.html.erb +14 -10
- data/app/views/main/_big_decimal.html.erb +8 -2
- data/app/views/main/_boolean.html.erb +5 -1
- data/app/views/main/_date.html.erb +8 -3
- data/app/views/main/_date_time.html.erb +8 -3
- data/app/views/main/_float.html.erb +8 -2
- data/app/views/main/_has_many.html.erb +9 -3
- data/app/views/main/_has_one.html.erb +15 -11
- data/app/views/main/_integer.html.erb +12 -4
- data/app/views/main/_properties.html.erb +6 -5
- data/app/views/main/_string.html.erb +8 -2
- data/app/views/main/_text.html.erb +7 -2
- data/app/views/main/_time.html.erb +8 -3
- data/app/views/main/edit.html.erb +0 -5
- data/app/views/main/index.html.erb +0 -8
- data/app/views/main/list.html.erb +43 -29
- data/lib/datamapper_support.rb +16 -0
- data/lib/merb-admin.rb +1 -1
- data/spec/fixtures/division_fixture.rb +0 -13
- data/spec/fixtures/draft_fixture.rb +0 -19
- data/spec/fixtures/league_fixture.rb +0 -12
- data/spec/fixtures/player_fixture.rb +0 -23
- data/spec/fixtures/team_fixture.rb +0 -15
- data/spec/models/division.rb +12 -0
- data/spec/models/draft.rb +18 -0
- data/spec/models/league.rb +11 -0
- data/spec/models/player.rb +22 -0
- data/spec/models/team.rb +15 -0
- data/spec/requests/main_spec.rb +2 -2
- data/spec/spec_helper.rb +4 -1
- 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.
|
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.
|
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
|
data/app/controllers/main.rb
CHANGED
@@ -18,20 +18,18 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
18
18
|
merge_query(options)
|
19
19
|
merge_sort(options)
|
20
20
|
|
21
|
-
if
|
21
|
+
if params[:all]
|
22
22
|
options = {
|
23
|
-
:limit =>
|
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.
|
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
|
-
|
161
|
-
|
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)
|
data/app/helpers/main_helper.rb
CHANGED
@@ -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
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
url = options.delete :url
|
44
|
+
options[:left_cut_label] ||= '…'
|
45
|
+
options[:right_cut_label] ||= '…'
|
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
|
-
|
4
|
-
</p>
|
5
|
-
<% end %>
|
6
|
-
<% if message && message[:notice] %>
|
7
|
-
<ul class="messagelist">
|
8
|
-
|
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">
|
@@ -1,22 +1,26 @@
|
|
1
1
|
<%
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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><%=
|
10
|
-
<div class="<%= @object.errors[
|
11
|
-
<% if @object.errors[
|
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[
|
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(
|
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(
|
8
|
+
<%= text_field(name, :maxlength => length, :label => label) %>
|
3
9
|
<p class="help">
|
4
|
-
<%=
|
10
|
+
<%= required ? "Required." : "Optional." %>
|
5
11
|
</p>
|
6
12
|
</div>
|
@@ -1,7 +1,12 @@
|
|
1
|
-
<%
|
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(
|
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
|
-
<%=
|
10
|
+
<%= required ? "Required." : "Optional." %>
|
6
11
|
</p>
|
7
12
|
</div>
|
@@ -1,7 +1,12 @@
|
|
1
|
-
<%
|
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(
|
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
|
-
<%=
|
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(
|
8
|
+
<%= text_field(name, :maxlength => length, :label => label) %>
|
3
9
|
<p class="help">
|
4
|
-
<%=
|
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><%=
|
8
|
+
<h2><%= label %></h2>
|
3
9
|
<div class="form-row">
|
4
10
|
<div>
|
5
|
-
<%= select(:name => "associations[#{
|
6
|
-
<script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("<%=
|
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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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><%=
|
11
|
-
<div class="<%= @object.errors[
|
12
|
-
<% if @object.errors[
|
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[
|
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[#{
|
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
|
3
|
-
|
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
|
-
|
12
|
+
<% length = property[:length] %>
|
13
|
+
<%= text_field(name, :maxlength => length, :label => label) %>
|
6
14
|
<p class="help">
|
7
|
-
<%=
|
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
|
-
<%
|
5
|
-
<% next if
|
6
|
-
|
7
|
-
|
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[
|
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(
|
8
|
+
<%= text_field(name, :size => [50, length].min, :maxlength => length, :label => label) %>
|
3
9
|
<p class="help">
|
4
|
-
<%=
|
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(
|
7
|
+
<%= text_area(name, :cols => 80, :label => label) %>
|
3
8
|
<p class="help">
|
4
|
-
<%=
|
9
|
+
<%= required ? "Required." : "Optional." %>
|
5
10
|
</p>
|
6
11
|
</div>
|
@@ -1,7 +1,12 @@
|
|
1
|
-
<%
|
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(
|
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
|
-
<%=
|
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) -%>
|
@@ -1,4 +1,10 @@
|
|
1
|
-
<%
|
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
|
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
|
19
|
-
<%
|
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
|
-
<%
|
31
|
-
|
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="<%=
|
34
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (
|
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="<%=
|
37
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (
|
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="<%=
|
40
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (
|
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
|
44
|
-
<h3>By <%=
|
53
|
+
<% elsif type == :integer && flag_map %>
|
54
|
+
<h3>By <%= pretty_name %></h3>
|
45
55
|
<ul>
|
46
|
-
<li class="<%=
|
47
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (
|
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
|
-
<%
|
50
|
-
<li class="<%=
|
51
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (
|
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
|
-
|
63
|
-
|
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
|
88
|
+
<% case type %>
|
75
89
|
<% when :boolean %>
|
76
|
-
<% if object.send(
|
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(
|
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(
|
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(
|
102
|
+
<% value = object.send(name) %>
|
89
103
|
<%= value.respond_to?(:strftime) ? value.strftime("%I:%M%p") : nil %>
|
90
104
|
<% when :string %>
|
91
|
-
<%= object.send(
|
105
|
+
<%= object.send(name).to_s.truncate(50) %>
|
92
106
|
<% when :text %>
|
93
|
-
<%= object.send(
|
107
|
+
<%= object.send(name).to_s.truncate(50) %>
|
94
108
|
<% else %>
|
95
|
-
<%= object.send(
|
109
|
+
<%= object.send(name) %>
|
96
110
|
<% end %>
|
97
111
|
</a>
|
98
112
|
</td>
|
data/lib/datamapper_support.rb
CHANGED
@@ -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.
|
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,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
|
data/spec/models/team.rb
ADDED
@@ -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
|
data/spec/requests/main_spec.rb
CHANGED
@@ -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
|
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
|
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
|
-
|
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
|
+
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-
|
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.
|
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.
|