sferik-merb-admin 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +55 -0
- data/Rakefile +69 -0
- data/app/controllers/application.rb +17 -0
- data/app/controllers/forms.rb +85 -0
- data/app/helpers/application_helper.rb +66 -0
- data/app/helpers/forms_helper.rb +112 -0
- data/app/views/forms/_big_decimal.html.erb +8 -0
- data/app/views/forms/_date.html.erb +8 -0
- data/app/views/forms/_date_time.html.erb +8 -0
- data/app/views/forms/_float.html.erb +8 -0
- data/app/views/forms/_integer.html.erb +12 -0
- data/app/views/forms/_string.html.erb +16 -0
- data/app/views/forms/_time.html.erb +8 -0
- data/app/views/forms/_true_class.html.erb +5 -0
- data/app/views/forms/delete.html.erb +12 -0
- data/app/views/forms/edit.html.erb +23 -0
- data/app/views/forms/index.html.erb +22 -0
- data/app/views/forms/list.html.erb +64 -0
- data/app/views/forms/new.html.erb +19 -0
- data/app/views/layout/_message.html.erb +10 -0
- data/app/views/layout/dashboard.html.erb +37 -0
- data/app/views/layout/form.html.erb +51 -0
- data/app/views/layout/list.html.erb +45 -0
- data/lib/merb-admin/merbtasks.rb +103 -0
- data/lib/merb-admin/slicetasks.rb +20 -0
- data/lib/merb-admin/spectasks.rb +53 -0
- data/lib/merb-admin.rb +101 -0
- data/public/images/arrow-down.gif +0 -0
- data/public/images/arrow-up.gif +0 -0
- data/public/images/changelist-bg.gif +0 -0
- data/public/images/changelist-bg_rtl.gif +0 -0
- data/public/images/chooser-bg.gif +0 -0
- data/public/images/chooser_stacked-bg.gif +0 -0
- data/public/images/default-bg-reverse.gif +0 -0
- data/public/images/default-bg.gif +0 -0
- data/public/images/deleted-overlay.gif +0 -0
- data/public/images/icon-no.gif +0 -0
- data/public/images/icon-unknown.gif +0 -0
- data/public/images/icon-yes.gif +0 -0
- data/public/images/icon_addlink.gif +0 -0
- data/public/images/icon_alert.gif +0 -0
- data/public/images/icon_calendar.gif +0 -0
- data/public/images/icon_changelink.gif +0 -0
- data/public/images/icon_clock.gif +0 -0
- data/public/images/icon_deletelink.gif +0 -0
- data/public/images/icon_error.gif +0 -0
- data/public/images/icon_searchbox.png +0 -0
- data/public/images/icon_success.gif +0 -0
- data/public/images/inline-delete-8bit.png +0 -0
- data/public/images/inline-delete.png +0 -0
- data/public/images/inline-restore-8bit.png +0 -0
- data/public/images/inline-restore.png +0 -0
- data/public/images/inline-splitter-bg.gif +0 -0
- data/public/images/nav-bg-grabber.gif +0 -0
- data/public/images/nav-bg-reverse.gif +0 -0
- data/public/images/nav-bg.gif +0 -0
- data/public/images/selector-add.gif +0 -0
- data/public/images/selector-addall.gif +0 -0
- data/public/images/selector-remove.gif +0 -0
- data/public/images/selector-removeall.gif +0 -0
- data/public/images/selector-search.gif +0 -0
- data/public/images/selector_stacked-add.gif +0 -0
- data/public/images/selector_stacked-remove.gif +0 -0
- data/public/images/tool-left.gif +0 -0
- data/public/images/tool-left_over.gif +0 -0
- data/public/images/tool-right.gif +0 -0
- data/public/images/tool-right_over.gif +0 -0
- data/public/images/tooltag-add.gif +0 -0
- data/public/images/tooltag-add_over.gif +0 -0
- data/public/images/tooltag-arrowright.gif +0 -0
- data/public/images/tooltag-arrowright_over.gif +0 -0
- data/public/javascripts/CollapsedFieldsets.js +85 -0
- data/public/javascripts/DateTimeShortcuts.js +255 -0
- data/public/javascripts/RelatedObjectLookups.js +96 -0
- data/public/javascripts/SelectBox.js +111 -0
- data/public/javascripts/SelectFilter2.js +113 -0
- data/public/javascripts/actions.js +39 -0
- data/public/javascripts/calendar.js +143 -0
- data/public/javascripts/core.js +176 -0
- data/public/javascripts/dateparse.js +233 -0
- data/public/javascripts/getElementsBySelector.js +167 -0
- data/public/javascripts/i18n.js +33 -0
- data/public/javascripts/master.js +0 -0
- data/public/javascripts/ordering.js +137 -0
- data/public/javascripts/timeparse.js +94 -0
- data/public/javascripts/urlify.js +140 -0
- data/public/stylesheets/base.css +746 -0
- data/public/stylesheets/changelists.css +269 -0
- data/public/stylesheets/dashboard.css +24 -0
- data/public/stylesheets/forms.css +327 -0
- data/public/stylesheets/global.css +142 -0
- data/public/stylesheets/ie.css +51 -0
- data/public/stylesheets/layout.css +29 -0
- data/public/stylesheets/login.css +54 -0
- data/public/stylesheets/master.css +2 -0
- data/public/stylesheets/null.css +1 -0
- data/public/stylesheets/patch-iewin.css +8 -0
- data/public/stylesheets/rtl.css +206 -0
- data/public/stylesheets/widgets.css +506 -0
- data/spec/controller/forms_spec.rb +41 -0
- data/spec/merb-admin_spec.rb +5 -0
- data/spec/spec_helper.rb +58 -0
- metadata +213 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
<%
|
2
|
+
slice_name = "MerbAdmin" + (MerbAdmin[:app_name].blank? ? "" : " for #{MerbAdmin[:app_name]}")
|
3
|
+
page_name = "Site administration"
|
4
|
+
%>
|
5
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
|
7
|
+
<head>
|
8
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
9
|
+
<meta name="robots" content="NONE,NOARCHIVE" />
|
10
|
+
<title><%= page_name %> | <%= slice_name %></title>
|
11
|
+
<link href="<%= public_path_for :stylesheet, 'base.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" />
|
12
|
+
<link href="<%= public_path_for :stylesheet, 'dashboard.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" />
|
13
|
+
<!--[if lte IE 7]><link href="<%= public_path_for :stylesheet, 'ie.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" /><![endif]-->
|
14
|
+
</head>
|
15
|
+
<body class="admin-slice dashboard">
|
16
|
+
<div id="container">
|
17
|
+
<div id="header">
|
18
|
+
<div id="branding">
|
19
|
+
<h1 id="site-name">
|
20
|
+
<%= slice_name %>
|
21
|
+
</h1>
|
22
|
+
</div>
|
23
|
+
<div id="user-tools">
|
24
|
+
Welcome, <strong><%= %></strong>. <a href="<%= %>">Log out</a>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
<%= partial 'layout/message' -%>
|
28
|
+
<div id="content" class="colMS">
|
29
|
+
<h1>
|
30
|
+
<%= page_name %>
|
31
|
+
</h1>
|
32
|
+
<%= catch_content :for_layout -%>
|
33
|
+
</div>
|
34
|
+
<div id="footer"></div>
|
35
|
+
</div>
|
36
|
+
</body>
|
37
|
+
</html>
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<%
|
2
|
+
slice_name = "MerbAdmin" + (MerbAdmin[:app_name].blank? ? "" : " for #{MerbAdmin[:app_name]}")
|
3
|
+
page_name = action_name.capitalize + " " + @model_name.snake_case.gsub('_', ' ')
|
4
|
+
%>
|
5
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
|
7
|
+
<head>
|
8
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
9
|
+
<meta name="robots" content="NONE,NOARCHIVE" />
|
10
|
+
<title><%= page_name %> | <%= slice_name %></title>
|
11
|
+
<link href="<%= public_path_for :stylesheet, 'base.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" />
|
12
|
+
<link href="<%= public_path_for :stylesheet, 'forms.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" />
|
13
|
+
<!--[if lte IE 7]><link href="<%= public_path_for :stylesheet, 'ie.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" /><![endif]-->
|
14
|
+
<script src="<%= public_path_for :javascript, 'i18n.js' %>" type="text/javascript" charset="utf-8"></script>
|
15
|
+
<script src="<%= public_path_for :javascript, 'core.js' %>" type="text/javascript" charset="utf-8"></script>
|
16
|
+
<script src="<%= public_path_for :javascript, 'RelatedObjectLookups.js' %>" type="text/javascript" charset="utf-8"></script>
|
17
|
+
<script src="<%= public_path_for :javascript, 'getElementsBySelector.js' %>" type="text/javascript" charset="utf-8"></script>
|
18
|
+
<script src="<%= public_path_for :javascript, 'actions.js' %>" type="text/javascript" charset="utf-8"></script>
|
19
|
+
<script src="<%= public_path_for :javascript, 'SelectBox.js' %>" type="text/javascript" charset="utf-8"></script>
|
20
|
+
<script src="<%= public_path_for :javascript, 'SelectFilter2.js' %>" type="text/javascript" charset="utf-8"></script>
|
21
|
+
<script src="<%= public_path_for :javascript, 'calendar.js' %>" type="text/javascript" charset="utf-8"></script>
|
22
|
+
<script src="<%= public_path_for :javascript, 'DateTimeShortcuts.js' %>" type="text/javascript" charset="utf-8"></script>
|
23
|
+
</head>
|
24
|
+
<body class="admin-slice change-form">
|
25
|
+
<div id="container">
|
26
|
+
<div id="header">
|
27
|
+
<div id="branding">
|
28
|
+
<h1 id="site-name">
|
29
|
+
<%= slice_name %>
|
30
|
+
</h1>
|
31
|
+
</div>
|
32
|
+
<div id="user-tools">
|
33
|
+
Welcome, <strong><%= %></strong>. <a href="<%= %>">Log out</a>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
<div class="breadcrumbs">
|
37
|
+
<a href="<%= url(:admin_dashboard) %>">Home</a> ›
|
38
|
+
<a href="<%= url(:admin_list, :model_name => @model_name.snake_case) %>"><%=h @model_name.pluralize %></a> ›
|
39
|
+
<%= page_name %>
|
40
|
+
</div>
|
41
|
+
<%= partial 'layout/message' -%>
|
42
|
+
<div id="content" class="colM">
|
43
|
+
<h1>
|
44
|
+
<%= page_name %>
|
45
|
+
</h1>
|
46
|
+
<%= catch_content :for_layout -%>
|
47
|
+
</div>
|
48
|
+
<div id="footer"></div>
|
49
|
+
</div>
|
50
|
+
</body>
|
51
|
+
</html>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<%
|
2
|
+
slice_name = "MerbAdmin" + (MerbAdmin[:app_name].blank? ? "" : " for #{MerbAdmin[:app_name]}")
|
3
|
+
page_name = "Select " + @model_name.snake_case.gsub('_', ' ') + " to edit"
|
4
|
+
%>
|
5
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
|
7
|
+
<head>
|
8
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
9
|
+
<meta name="robots" content="NONE,NOARCHIVE" />
|
10
|
+
<title><%= page_name %> | <%= slice_name %></title>
|
11
|
+
<link href="<%= public_path_for :stylesheet, 'base.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" />
|
12
|
+
<link href="<%= public_path_for :stylesheet, 'changelists.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" />
|
13
|
+
<!--[if lte IE 7]><link href="<%= public_path_for :stylesheet, 'ie.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all" /><![endif]-->
|
14
|
+
<script src="<%= public_path_for :javascript, 'core.js' %>" type="text/javascript" charset="utf-8"></script>
|
15
|
+
<script src="<%= public_path_for :javascript, 'RelatedObjectLookups.js' %>" type="text/javascript" charset="utf-8"></script>
|
16
|
+
<script src="<%= public_path_for :javascript, 'getElementsBySelector.js' %>" type="text/javascript" charset="utf-8"></script>
|
17
|
+
<script src="<%= public_path_for :javascript, 'actions.js' %>" type="text/javascript" charset="utf-8"></script>
|
18
|
+
</head>
|
19
|
+
<body class="admin-slice change-list">
|
20
|
+
<div id="container">
|
21
|
+
<div id="header">
|
22
|
+
<div id="branding">
|
23
|
+
<h1 id="site-name">
|
24
|
+
<%= slice_name %>
|
25
|
+
</h1>
|
26
|
+
</div>
|
27
|
+
<div id="user-tools">
|
28
|
+
Welcome, <strong><%= %></strong>. <a href="<%= %>">Log out</a>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<div class="breadcrumbs">
|
32
|
+
<a href="<%= url(:admin_dashboard) %>">Home</a> ›
|
33
|
+
<%=h @model_name.pluralize %>
|
34
|
+
</div>
|
35
|
+
<%= partial 'layout/message' -%>
|
36
|
+
<div id="content" class="flex">
|
37
|
+
<h1>
|
38
|
+
<%= page_name %>
|
39
|
+
</h1>
|
40
|
+
<%= catch_content :for_layout -%>
|
41
|
+
</div>
|
42
|
+
<div id="footer"></div>
|
43
|
+
</div>
|
44
|
+
</body>
|
45
|
+
</html>
|
@@ -0,0 +1,103 @@
|
|
1
|
+
namespace :slices do
|
2
|
+
namespace :"merb-admin" do
|
3
|
+
|
4
|
+
desc "Install MerbAdmin"
|
5
|
+
task :install => [:preflight, :setup_directories, :copy_assets, :migrate]
|
6
|
+
|
7
|
+
desc "Test for any dependencies"
|
8
|
+
task :preflight do # see slicetasks.rb
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Setup directories"
|
12
|
+
task :setup_directories do
|
13
|
+
puts "Creating directories for host application"
|
14
|
+
MerbAdmin.mirrored_components.each do |type|
|
15
|
+
if File.directory?(MerbAdmin.dir_for(type))
|
16
|
+
if !File.directory?(dst_path = MerbAdmin.app_dir_for(type))
|
17
|
+
relative_path = dst_path.relative_path_from(Merb.root)
|
18
|
+
puts "- creating directory :#{type} #{File.basename(Merb.root) / relative_path}"
|
19
|
+
mkdir_p(dst_path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# desc "Copy stub files to host application"
|
26
|
+
# task :stubs do
|
27
|
+
# puts "Copying stubs for MerbAdmin - resolves any collisions"
|
28
|
+
# copied, preserved = MerbAdmin.mirror_stubs!
|
29
|
+
# puts "- no files to copy" if copied.empty? && preserved.empty?
|
30
|
+
# copied.each { |f| puts "- copied #{f}" }
|
31
|
+
# preserved.each { |f| puts "! preserved override as #{f}" }
|
32
|
+
# end
|
33
|
+
|
34
|
+
# desc "Copy stub files and views to host application"
|
35
|
+
# task :patch => [ "stubs", "freeze:views" ]
|
36
|
+
|
37
|
+
desc "Copy public assets to host application"
|
38
|
+
task :copy_assets do
|
39
|
+
puts "Copying assets for MerbAdmin - resolves any collisions"
|
40
|
+
copied, preserved = MerbAdmin.mirror_public!
|
41
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
42
|
+
copied.each { |f| puts "- copied #{f}" }
|
43
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Migrate the database"
|
47
|
+
task :migrate do # see slicetasks.rb
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Freeze MerbAdmin into your app (only merb-admin/app)"
|
51
|
+
task :freeze => [ "freeze:app" ]
|
52
|
+
|
53
|
+
namespace :freeze do
|
54
|
+
|
55
|
+
# desc "Freezes MerbAdmin by installing the gem into application/gems"
|
56
|
+
# task :gem do
|
57
|
+
# ENV["GEM"] ||= "merb-admin"
|
58
|
+
# Rake::Task['slices:install_as_gem'].invoke
|
59
|
+
# end
|
60
|
+
|
61
|
+
desc "Freezes MerbAdmin by copying all files from merb-admin/app to your application"
|
62
|
+
task :app do
|
63
|
+
puts "Copying all merb-admin/app files to your application - resolves any collisions"
|
64
|
+
copied, preserved = MerbAdmin.mirror_app!
|
65
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
66
|
+
copied.each { |f| puts "- copied #{f}" }
|
67
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Freeze all views into your application for easy modification"
|
71
|
+
task :views do
|
72
|
+
puts "Copying all view templates to your application - resolves any collisions"
|
73
|
+
copied, preserved = MerbAdmin.mirror_files_for :view
|
74
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
75
|
+
copied.each { |f| puts "- copied #{f}" }
|
76
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Freeze all models into your application for easy modification"
|
80
|
+
task :models do
|
81
|
+
puts "Copying all models to your application - resolves any collisions"
|
82
|
+
copied, preserved = MerbAdmin.mirror_files_for :model
|
83
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
84
|
+
copied.each { |f| puts "- copied #{f}" }
|
85
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
86
|
+
end
|
87
|
+
|
88
|
+
desc "Freezes MerbAdmin as a gem and copies over merb-admin/app"
|
89
|
+
task :app_with_gem => [:gem, :app]
|
90
|
+
|
91
|
+
desc "Freezes MerbAdmin by unpacking all files into your application"
|
92
|
+
task :unpack do
|
93
|
+
puts "Unpacking MerbAdmin files to your application - resolves any collisions"
|
94
|
+
copied, preserved = MerbAdmin.unpack_slice!
|
95
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
96
|
+
copied.each { |f| puts "- copied #{f}" }
|
97
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
namespace :slices do
|
2
|
+
namespace :"merb-admin" do
|
3
|
+
|
4
|
+
# add your own merb-admin tasks here
|
5
|
+
|
6
|
+
# # Uncomment the following lines and edit the pre defined tasks
|
7
|
+
#
|
8
|
+
# # implement this to test for structural/code dependencies
|
9
|
+
# # like certain directories or availability of other files
|
10
|
+
# desc "Test for any dependencies"
|
11
|
+
# task :preflight do
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # implement this to perform any database related setup steps
|
15
|
+
# desc "Migrate the database"
|
16
|
+
# task :migrate do
|
17
|
+
# end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
namespace :slices do
|
2
|
+
namespace :"merb-admin" do
|
3
|
+
|
4
|
+
desc "Run slice specs within the host application context"
|
5
|
+
task :spec => [ "spec:explain", "spec:default" ]
|
6
|
+
|
7
|
+
namespace :spec do
|
8
|
+
|
9
|
+
slice_root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
10
|
+
|
11
|
+
task :explain do
|
12
|
+
puts "\nNote: By running MerbAdmin specs inside the application context any\n" +
|
13
|
+
"overrides could break existing specs. This isn't always a problem,\n" +
|
14
|
+
"especially in the case of views. Use these spec tasks to check how\n" +
|
15
|
+
"well your application conforms to the original slice implementation."
|
16
|
+
end
|
17
|
+
|
18
|
+
Spec::Rake::SpecTask.new('default') do |t|
|
19
|
+
t.spec_opts = ["--format", "specdoc", "--colour"]
|
20
|
+
t.spec_files = Dir["#{slice_root}/spec/**/*_spec.rb"].sort
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Run all model specs, run a spec for a specific Model with MODEL=MyModel"
|
24
|
+
Spec::Rake::SpecTask.new('model') do |t|
|
25
|
+
t.spec_opts = ["--format", "specdoc", "--colour"]
|
26
|
+
if(ENV['MODEL'])
|
27
|
+
t.spec_files = Dir["#{slice_root}/spec/models/**/#{ENV['MODEL']}_spec.rb"].sort
|
28
|
+
else
|
29
|
+
t.spec_files = Dir["#{slice_root}/spec/models/**/*_spec.rb"].sort
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Run all request specs, run a spec for a specific request with REQUEST=MyRequest"
|
34
|
+
Spec::Rake::SpecTask.new('request') do |t|
|
35
|
+
t.spec_opts = ["--format", "specdoc", "--colour"]
|
36
|
+
if(ENV['REQUEST'])
|
37
|
+
t.spec_files = Dir["#{slice_root}/spec/requests/**/#{ENV['REQUEST']}_spec.rb"].sort
|
38
|
+
else
|
39
|
+
t.spec_files = Dir["#{slice_root}/spec/requests/**/*_spec.rb"].sort
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Run all specs and output the result in html"
|
44
|
+
Spec::Rake::SpecTask.new('html') do |t|
|
45
|
+
t.spec_opts = ["--format", "html"]
|
46
|
+
t.libs = ['lib', 'server/lib' ]
|
47
|
+
t.spec_files = Dir["#{slice_root}/spec/**/*_spec.rb"].sort
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/lib/merb-admin.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
if defined?(Merb::Plugins)
|
2
|
+
|
3
|
+
$:.unshift File.dirname(__FILE__)
|
4
|
+
|
5
|
+
dependency 'merb-slices', :immediate => true
|
6
|
+
Merb::Plugins.add_rakefiles "merb-admin/merbtasks", "merb-admin/slicetasks", "merb-admin/spectasks"
|
7
|
+
|
8
|
+
# Register the Slice for the current host application
|
9
|
+
Merb::Slices::register(__FILE__)
|
10
|
+
|
11
|
+
# Slice configuration - set this in a before_app_loads callback.
|
12
|
+
# By default a Slice uses its own layout, so you can swicht to
|
13
|
+
# the main application layout or no layout at all if needed.
|
14
|
+
#
|
15
|
+
# Configuration options:
|
16
|
+
# :layout - the layout to use; defaults to :merb-admin
|
17
|
+
# :mirror - which path component types to use on copy operations; defaults to all
|
18
|
+
Merb::Slices::config[:merb_admin][:layout] ||= :merb_admin
|
19
|
+
|
20
|
+
# All Slice code is expected to be namespaced inside a module
|
21
|
+
module MerbAdmin
|
22
|
+
|
23
|
+
# Slice metadata
|
24
|
+
self.description = "MerbAdmin is a merb slice that uses your DataMapper models to provide an easy-to-use, Django-style interface for content managers."
|
25
|
+
self.version = "0.1.7"
|
26
|
+
self.author = "Erik Michaels-Ober"
|
27
|
+
|
28
|
+
# Stub classes loaded hook - runs before LoadClasses BootLoader
|
29
|
+
# right after a slice's classes have been loaded internally.
|
30
|
+
def self.loaded
|
31
|
+
require "dm-is-paginated"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Initialization hook - runs before AfterAppLoads BootLoader
|
35
|
+
def self.init
|
36
|
+
end
|
37
|
+
|
38
|
+
# Activation hook - runs after AfterAppLoads BootLoader
|
39
|
+
def self.activate
|
40
|
+
end
|
41
|
+
|
42
|
+
# Deactivation hook - triggered by Merb::Slices.deactivate(MerbAdmin)
|
43
|
+
def self.deactivate
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.setup_router(scope)
|
47
|
+
|
48
|
+
scope.match("/admin(/index)", :method => :get).
|
49
|
+
to(:controller => "forms", :action => "index").
|
50
|
+
name(:admin_dashboard)
|
51
|
+
|
52
|
+
scope.match("/admin/:model_name(/index)", :method => :get).
|
53
|
+
to(:controller => "forms", :action => "list").
|
54
|
+
name(:admin_list)
|
55
|
+
|
56
|
+
scope.match("/admin/:model_name/new", :method => :get).
|
57
|
+
to(:controller => "forms", :action => "new").
|
58
|
+
name(:admin_new)
|
59
|
+
|
60
|
+
scope.match("/admin/:model_name/:id/edit", :method => :get).
|
61
|
+
to(:controller => "forms", :action => "edit").
|
62
|
+
name(:admin_edit)
|
63
|
+
|
64
|
+
scope.match("/admin/:model_name", :method => :post).
|
65
|
+
to(:controller => "forms", :action => "create").
|
66
|
+
name(:admin_create)
|
67
|
+
|
68
|
+
scope.match("/admin/:model_name/:id", :method => :put).
|
69
|
+
to(:controller => "forms", :action => "update").
|
70
|
+
name(:admin_update)
|
71
|
+
|
72
|
+
scope.match("/admin/:model_name/:id/delete", :method => :get).
|
73
|
+
to(:controller => "forms", :action => "delete").
|
74
|
+
name(:admin_delete)
|
75
|
+
|
76
|
+
scope.match("/admin/:model_name/:id(.:format)", :method => :delete).
|
77
|
+
to(:controller => "forms", :action => "destroy").
|
78
|
+
name(:admin_destroy)
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# Setup the slice layout for MerbAdmin
|
85
|
+
#
|
86
|
+
# Use MerbAdmin.push_path and MerbAdmin.push_app_path
|
87
|
+
# to set paths to merb-admin-level and app-level paths. Example:
|
88
|
+
#
|
89
|
+
# MerbAdmin.push_path(:application, MerbAdmin.root)
|
90
|
+
# MerbAdmin.push_app_path(:application, Merb.root / 'slices' / 'merb-admin')
|
91
|
+
# ...
|
92
|
+
#
|
93
|
+
# Any component path that hasn't been set will default to MerbAdmin.root
|
94
|
+
#
|
95
|
+
# Or just call setup_default_structure! to setup a basic Merb MVC structure.
|
96
|
+
MerbAdmin.setup_default_structure!
|
97
|
+
|
98
|
+
# Add dependencies for other MerbAdmin classes below. Example:
|
99
|
+
# dependency "merb-admin/other"
|
100
|
+
|
101
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,85 @@
|
|
1
|
+
// Finds all fieldsets with class="collapse", collapses them, and gives each
|
2
|
+
// one a "Show" link that uncollapses it. The "Show" link becomes a "Hide"
|
3
|
+
// link when the fieldset is visible.
|
4
|
+
|
5
|
+
function findForm(node) {
|
6
|
+
// returns the node of the form containing the given node
|
7
|
+
if (node.tagName.toLowerCase() != 'form') {
|
8
|
+
return findForm(node.parentNode);
|
9
|
+
}
|
10
|
+
return node;
|
11
|
+
}
|
12
|
+
|
13
|
+
var CollapsedFieldsets = {
|
14
|
+
collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with.
|
15
|
+
collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden.
|
16
|
+
collapsed_class: 'collapsed',
|
17
|
+
init: function() {
|
18
|
+
var fieldsets = document.getElementsByTagName('fieldset');
|
19
|
+
var collapsed_seen = false;
|
20
|
+
for (var i = 0, fs; fs = fieldsets[i]; i++) {
|
21
|
+
// Collapse this fieldset if it has the correct class, and if it
|
22
|
+
// doesn't have any errors. (Collapsing shouldn't apply in the case
|
23
|
+
// of error messages.)
|
24
|
+
if (fs.className.match(CollapsedFieldsets.collapse_re) && !CollapsedFieldsets.fieldset_has_errors(fs)) {
|
25
|
+
collapsed_seen = true;
|
26
|
+
// Give it an additional class, used by CSS to hide it.
|
27
|
+
fs.className += ' ' + CollapsedFieldsets.collapsed_class;
|
28
|
+
// (<a id="fieldsetcollapser3" class="collapse-toggle" href="#">Show</a>)
|
29
|
+
var collapse_link = document.createElement('a');
|
30
|
+
collapse_link.className = 'collapse-toggle';
|
31
|
+
collapse_link.id = 'fieldsetcollapser' + i;
|
32
|
+
collapse_link.onclick = new Function('CollapsedFieldsets.show('+i+'); return false;');
|
33
|
+
collapse_link.href = '#';
|
34
|
+
collapse_link.innerHTML = gettext('Show');
|
35
|
+
var h2 = fs.getElementsByTagName('h2')[0];
|
36
|
+
h2.appendChild(document.createTextNode(' ('));
|
37
|
+
h2.appendChild(collapse_link);
|
38
|
+
h2.appendChild(document.createTextNode(')'));
|
39
|
+
}
|
40
|
+
}
|
41
|
+
if (collapsed_seen) {
|
42
|
+
// Expand all collapsed fieldsets when form is submitted.
|
43
|
+
addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); });
|
44
|
+
}
|
45
|
+
},
|
46
|
+
fieldset_has_errors: function(fs) {
|
47
|
+
// Returns true if any fields in the fieldset have validation errors.
|
48
|
+
var divs = fs.getElementsByTagName('div');
|
49
|
+
for (var i=0; i<divs.length; i++) {
|
50
|
+
if (divs[i].className.match(/\berrors\b/)) {
|
51
|
+
return true;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
return false;
|
55
|
+
},
|
56
|
+
show: function(fieldset_index) {
|
57
|
+
var fs = document.getElementsByTagName('fieldset')[fieldset_index];
|
58
|
+
// Remove the class name that causes the "display: none".
|
59
|
+
fs.className = fs.className.replace(CollapsedFieldsets.collapsed_re, '');
|
60
|
+
// Toggle the "Show" link to a "Hide" link
|
61
|
+
var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
|
62
|
+
collapse_link.onclick = new Function('CollapsedFieldsets.hide('+fieldset_index+'); return false;');
|
63
|
+
collapse_link.innerHTML = gettext('Hide');
|
64
|
+
},
|
65
|
+
hide: function(fieldset_index) {
|
66
|
+
var fs = document.getElementsByTagName('fieldset')[fieldset_index];
|
67
|
+
// Add the class name that causes the "display: none".
|
68
|
+
fs.className += ' ' + CollapsedFieldsets.collapsed_class;
|
69
|
+
// Toggle the "Hide" link to a "Show" link
|
70
|
+
var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
|
71
|
+
collapse_link.onclick = new Function('CollapsedFieldsets.show('+fieldset_index+'); return false;');
|
72
|
+
collapse_link.innerHTML = gettext('Show');
|
73
|
+
},
|
74
|
+
|
75
|
+
uncollapse_all: function() {
|
76
|
+
var fieldsets = document.getElementsByTagName('fieldset');
|
77
|
+
for (var i=0; i<fieldsets.length; i++) {
|
78
|
+
if (fieldsets[i].className.match(CollapsedFieldsets.collapsed_re)) {
|
79
|
+
CollapsedFieldsets.show(i);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
addEvent(window, 'load', CollapsedFieldsets.init);
|