sferik-merb-admin 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +55 -0
  3. data/Rakefile +69 -0
  4. data/app/controllers/application.rb +17 -0
  5. data/app/controllers/forms.rb +85 -0
  6. data/app/helpers/application_helper.rb +66 -0
  7. data/app/helpers/forms_helper.rb +112 -0
  8. data/app/views/forms/_big_decimal.html.erb +8 -0
  9. data/app/views/forms/_date.html.erb +8 -0
  10. data/app/views/forms/_date_time.html.erb +8 -0
  11. data/app/views/forms/_float.html.erb +8 -0
  12. data/app/views/forms/_integer.html.erb +12 -0
  13. data/app/views/forms/_string.html.erb +16 -0
  14. data/app/views/forms/_time.html.erb +8 -0
  15. data/app/views/forms/_true_class.html.erb +5 -0
  16. data/app/views/forms/delete.html.erb +12 -0
  17. data/app/views/forms/edit.html.erb +23 -0
  18. data/app/views/forms/index.html.erb +22 -0
  19. data/app/views/forms/list.html.erb +64 -0
  20. data/app/views/forms/new.html.erb +19 -0
  21. data/app/views/layout/_message.html.erb +10 -0
  22. data/app/views/layout/dashboard.html.erb +37 -0
  23. data/app/views/layout/form.html.erb +51 -0
  24. data/app/views/layout/list.html.erb +45 -0
  25. data/lib/merb-admin/merbtasks.rb +103 -0
  26. data/lib/merb-admin/slicetasks.rb +20 -0
  27. data/lib/merb-admin/spectasks.rb +53 -0
  28. data/lib/merb-admin.rb +101 -0
  29. data/public/images/arrow-down.gif +0 -0
  30. data/public/images/arrow-up.gif +0 -0
  31. data/public/images/changelist-bg.gif +0 -0
  32. data/public/images/changelist-bg_rtl.gif +0 -0
  33. data/public/images/chooser-bg.gif +0 -0
  34. data/public/images/chooser_stacked-bg.gif +0 -0
  35. data/public/images/default-bg-reverse.gif +0 -0
  36. data/public/images/default-bg.gif +0 -0
  37. data/public/images/deleted-overlay.gif +0 -0
  38. data/public/images/icon-no.gif +0 -0
  39. data/public/images/icon-unknown.gif +0 -0
  40. data/public/images/icon-yes.gif +0 -0
  41. data/public/images/icon_addlink.gif +0 -0
  42. data/public/images/icon_alert.gif +0 -0
  43. data/public/images/icon_calendar.gif +0 -0
  44. data/public/images/icon_changelink.gif +0 -0
  45. data/public/images/icon_clock.gif +0 -0
  46. data/public/images/icon_deletelink.gif +0 -0
  47. data/public/images/icon_error.gif +0 -0
  48. data/public/images/icon_searchbox.png +0 -0
  49. data/public/images/icon_success.gif +0 -0
  50. data/public/images/inline-delete-8bit.png +0 -0
  51. data/public/images/inline-delete.png +0 -0
  52. data/public/images/inline-restore-8bit.png +0 -0
  53. data/public/images/inline-restore.png +0 -0
  54. data/public/images/inline-splitter-bg.gif +0 -0
  55. data/public/images/nav-bg-grabber.gif +0 -0
  56. data/public/images/nav-bg-reverse.gif +0 -0
  57. data/public/images/nav-bg.gif +0 -0
  58. data/public/images/selector-add.gif +0 -0
  59. data/public/images/selector-addall.gif +0 -0
  60. data/public/images/selector-remove.gif +0 -0
  61. data/public/images/selector-removeall.gif +0 -0
  62. data/public/images/selector-search.gif +0 -0
  63. data/public/images/selector_stacked-add.gif +0 -0
  64. data/public/images/selector_stacked-remove.gif +0 -0
  65. data/public/images/tool-left.gif +0 -0
  66. data/public/images/tool-left_over.gif +0 -0
  67. data/public/images/tool-right.gif +0 -0
  68. data/public/images/tool-right_over.gif +0 -0
  69. data/public/images/tooltag-add.gif +0 -0
  70. data/public/images/tooltag-add_over.gif +0 -0
  71. data/public/images/tooltag-arrowright.gif +0 -0
  72. data/public/images/tooltag-arrowright_over.gif +0 -0
  73. data/public/javascripts/CollapsedFieldsets.js +85 -0
  74. data/public/javascripts/DateTimeShortcuts.js +255 -0
  75. data/public/javascripts/RelatedObjectLookups.js +96 -0
  76. data/public/javascripts/SelectBox.js +111 -0
  77. data/public/javascripts/SelectFilter2.js +113 -0
  78. data/public/javascripts/actions.js +39 -0
  79. data/public/javascripts/calendar.js +143 -0
  80. data/public/javascripts/core.js +176 -0
  81. data/public/javascripts/dateparse.js +233 -0
  82. data/public/javascripts/getElementsBySelector.js +167 -0
  83. data/public/javascripts/i18n.js +33 -0
  84. data/public/javascripts/master.js +0 -0
  85. data/public/javascripts/ordering.js +137 -0
  86. data/public/javascripts/timeparse.js +94 -0
  87. data/public/javascripts/urlify.js +140 -0
  88. data/public/stylesheets/base.css +746 -0
  89. data/public/stylesheets/changelists.css +269 -0
  90. data/public/stylesheets/dashboard.css +24 -0
  91. data/public/stylesheets/forms.css +327 -0
  92. data/public/stylesheets/global.css +142 -0
  93. data/public/stylesheets/ie.css +51 -0
  94. data/public/stylesheets/layout.css +29 -0
  95. data/public/stylesheets/login.css +54 -0
  96. data/public/stylesheets/master.css +2 -0
  97. data/public/stylesheets/null.css +1 -0
  98. data/public/stylesheets/patch-iewin.css +8 -0
  99. data/public/stylesheets/rtl.css +206 -0
  100. data/public/stylesheets/widgets.css +506 -0
  101. data/spec/controller/forms_spec.rb +41 -0
  102. data/spec/merb-admin_spec.rb +5 -0
  103. data/spec/spec_helper.rb +58 -0
  104. metadata +213 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Erik Michaels-Ober
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,55 @@
1
+ # MerbAdmin
2
+
3
+ **MerbAdmin is a merb slice that provides an easy-to-use interface for managing your data.**
4
+
5
+ It currently offers the features listed [here](http://sferik.tadalist.com/lists/1352791/public).
6
+
7
+ ## Get it
8
+
9
+ At the command prompt, type:
10
+
11
+ git clone git://github.com/sferik/merb-admin.git
12
+ cd merb-admin
13
+ sudo rake install
14
+
15
+ ## Install it
16
+
17
+ In your app, add the following dependency to `config/dependencies.rb`:
18
+
19
+ dependency "merb-admin", "0.1.7"
20
+
21
+ Add the following route to `config/router.rb`:
22
+
23
+ slice(:MerbAdmin, :name_prefix => nil, :path_prefix => "", :default_routes => false)
24
+
25
+ Then, run the following rake task:
26
+
27
+ rake slices:merb-admin:install
28
+
29
+ ## Configure it (optional)
30
+
31
+ You can configuring the merb-admin slice in a before_app_loads block:
32
+
33
+ Merb::BootLoader.before_app_loads do
34
+ Merb::Slices::config[:merb_admin][:app_name] = "My App"
35
+ end
36
+
37
+ ## Run it
38
+
39
+ Start the server:
40
+
41
+ merb
42
+
43
+ You should now be able to administer your site at [http://localhost:4000/admin](http://localhost:4000/admin).
44
+
45
+ Please report any problems you encounter to <sferik@gmail.com> or [@sferik](http://twitter.com/home/?status=@sferik%20) on Twitter.
46
+
47
+ ## WARNING
48
+
49
+ MerbAdmin does not implement any authorization scheme. Make sure to apply authorization logic before deploying to production!
50
+
51
+ ## Acknowledgements
52
+
53
+ Many thanks to [Wilson Miner](http://www.wilsonminer.com) for contributing the stylesheets and javascripts from [Django](http://www.djangoproject.com).
54
+
55
+ Also, thanks to [beer](http://www.anchorbrewing.com).
data/Rakefile ADDED
@@ -0,0 +1,69 @@
1
+ require "rubygems"
2
+ require "rake/gempackagetask"
3
+
4
+ require "merb-core"
5
+ require "merb-core/tasks/merb"
6
+
7
+ dependency "dm-core"
8
+ dependency "merb_datamapper"
9
+
10
+ GEM_NAME = "merb-admin"
11
+ AUTHOR = "Erik Michaels-Ober"
12
+ EMAIL = "sferik@gmail.com"
13
+ HOMEPAGE = "http://twitter.com/sferik"
14
+ SUMMARY = "MerbAdmin is a merb slice that provides an easy-to-use interface for managing your data."
15
+ GEM_VERSION = "0.1.7"
16
+
17
+ spec = Gem::Specification.new do |s|
18
+ s.rubyforge_project = "merb"
19
+ s.name = GEM_NAME
20
+ s.version = GEM_VERSION
21
+ s.platform = Gem::Platform::RUBY
22
+ s.has_rdoc = false
23
+ s.extra_rdoc_files = ["README.markdown", "LICENSE"]
24
+ s.summary = SUMMARY
25
+ s.description = s.summary
26
+ s.author = AUTHOR
27
+ s.email = EMAIL
28
+ s.homepage = HOMEPAGE
29
+ s.add_dependency("merb-slices", Merb::VERSION)
30
+ s.add_dependency("merb_datamapper", Merb::VERSION)
31
+ s.add_dependency("dm-core", ">= 0.9.11")
32
+ s.add_dependency("dm-is-paginated", ">= 0.0.1")
33
+ s.require_path = "lib"
34
+ s.files = %w(LICENSE README.markdown Rakefile) + Dir.glob("{lib,spec,app,public,stubs}/**/*")
35
+ s.post_install_message = <<-POST_INSTALL_MESSAGE
36
+ #{"*" * 80}
37
+
38
+ WARNING: MerbAdmin does not implement any authorization scheme.
39
+ Make sure to apply authorization logic before deploying to production!
40
+
41
+ #{"*" * 80}
42
+ POST_INSTALL_MESSAGE
43
+ end
44
+
45
+ Rake::GemPackageTask.new(spec) do |pkg|
46
+ pkg.gem_spec = spec
47
+ end
48
+
49
+ desc "Install the gem"
50
+ task :install do
51
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
52
+ end
53
+
54
+ desc "Uninstall the gem"
55
+ task :uninstall do
56
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
57
+ end
58
+
59
+ desc "Create a gemspec file"
60
+ task :gemspec do
61
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
62
+ file.puts spec.to_ruby
63
+ end
64
+ end
65
+
66
+ require "spec/rake/spectask"
67
+ require "merb-core/test/tasks/spectasks"
68
+ desc "Default: run spec examples"
69
+ task :default => "spec"
@@ -0,0 +1,17 @@
1
+ class MerbAdmin::Application < Merb::Controller
2
+
3
+ controller_for_slice
4
+
5
+ before :set_model, :exclude => "index"
6
+
7
+ def set_model
8
+ @model_name = params[:model_name].to_s.camel_case.singularize
9
+ begin
10
+ @model = eval(@model_name)
11
+ rescue StandardError
12
+ raise NotFound
13
+ end
14
+ @properties = @model.properties.to_a
15
+ end
16
+
17
+ end
@@ -0,0 +1,85 @@
1
+ class MerbAdmin::Forms < MerbAdmin::Application
2
+ layout :form
3
+
4
+ def index
5
+ @models = DataMapper::Resource.descendants.to_a.sort{|a, b| a.to_s <=> b.to_s}
6
+ # remove DataMapperSessionStore because it's included by default
7
+ @models -= [Merb::DataMapperSessionStore] if Merb.const_defined?(:DataMapperSessionStore)
8
+ render(:layout => "dashboard")
9
+ end
10
+
11
+ def list
12
+ if params[:all]
13
+ @instances = @model.all(:limit => 200).reverse
14
+ else
15
+ # monkey patch pagination
16
+ @model.class_eval("is_paginated") unless @model.respond_to?(:paginated)
17
+ @current_page = (params[:page] || 1).to_i
18
+ @page_count, @instances = @model.paginated(:page => @current_page, :per_page => 100)
19
+ end
20
+ render(:layout => "list")
21
+ end
22
+
23
+ def new
24
+ @instance = @model.new
25
+ render(:layout => "form")
26
+ end
27
+
28
+ def edit(id)
29
+ @instance = @model.get(id)
30
+ raise NotFound unless @instance
31
+ render(:layout => "form")
32
+ end
33
+
34
+ def create
35
+ instance = eval("params[:#{@model_name.snake_case}]")
36
+ @instance = @model.new(instance)
37
+ if @instance.save
38
+ if params[:_continue]
39
+ redirect slice_url(:admin_edit, :model_name => @model_name.snake_case, :id => @instance.id), :message => {:notice => "#{@model_name} was successfully created"}
40
+ elsif params[:_add_another]
41
+ redirect slice_url(:admin_new, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully created"}
42
+ else
43
+ redirect slice_url(:admin_list, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully created"}
44
+ end
45
+ else
46
+ message[:error] = "#{@model_name} failed to be created"
47
+ render(:new, :layout => "form")
48
+ end
49
+ end
50
+
51
+ def update(id)
52
+ instance = eval("params[:#{@model_name.snake_case}]")
53
+ @instance = @model.get(id)
54
+ raise NotFound unless @instance
55
+ if @instance.update_attributes(instance)
56
+ if params[:_continue]
57
+ redirect slice_url(:admin_edit, :model_name => @model_name.snake_case, :id => @instance.id), :message => {:notice => "#{@model_name} was successfully updated"}
58
+ elsif params[:_add_another]
59
+ redirect slice_url(:admin_new, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully updated"}
60
+ else
61
+ redirect slice_url(:admin_list, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully updated"}
62
+ end
63
+ else
64
+ message[:error] = "#{@model_name} failed to be updated"
65
+ render(:edit, :layout => "form")
66
+ end
67
+ end
68
+
69
+ def delete(id)
70
+ @instance = @model.get(id)
71
+ raise NotFound unless @instance
72
+ render(:layout => "form")
73
+ end
74
+
75
+ def destroy(id)
76
+ @instance = @model.get(id)
77
+ raise NotFound unless @instance
78
+ if @instance.destroy
79
+ redirect slice_url(:admin_list, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully destroyed"}
80
+ else
81
+ raise InternalServerError
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,66 @@
1
+ module Merb
2
+ module MerbAdmin
3
+ module ApplicationHelper
4
+
5
+ # @param *segments<Array[#to_s]> Path segments to append.
6
+ #
7
+ # @return <String>
8
+ # A path relative to the public directory, with added segments.
9
+ def image_path(*segments)
10
+ public_path_for(:image, *segments)
11
+ end
12
+
13
+ # @param *segments<Array[#to_s]> Path segments to append.
14
+ #
15
+ # @return <String>
16
+ # A path relative to the public directory, with added segments.
17
+ def javascript_path(*segments)
18
+ public_path_for(:javascript, *segments)
19
+ end
20
+
21
+ # @param *segments<Array[#to_s]> Path segments to append.
22
+ #
23
+ # @return <String>
24
+ # A path relative to the public directory, with added segments.
25
+ def stylesheet_path(*segments)
26
+ public_path_for(:stylesheet, *segments)
27
+ end
28
+
29
+ # Construct a path relative to the public directory
30
+ #
31
+ # @param <Symbol> The type of component.
32
+ # @param *segments<Array[#to_s]> Path segments to append.
33
+ #
34
+ # @return <String>
35
+ # A path relative to the public directory, with added segments.
36
+ def public_path_for(type, *segments)
37
+ ::MerbAdmin.public_path_for(type, *segments)
38
+ end
39
+
40
+ # Construct an app-level path.
41
+ #
42
+ # @param <Symbol> The type of component.
43
+ # @param *segments<Array[#to_s]> Path segments to append.
44
+ #
45
+ # @return <String>
46
+ # A path within the host application, with added segments.
47
+ def app_path_for(type, *segments)
48
+ ::MerbAdmin.app_path_for(type, *segments)
49
+ end
50
+
51
+ # Construct a slice-level path.
52
+ #
53
+ # @param <Symbol> The type of component.
54
+ # @param *segments<Array[#to_s]> Path segments to append.
55
+ #
56
+ # @return <String>
57
+ # A path within the slice source (Gem), with added segments.
58
+ def slice_path_for(type, *segments)
59
+ ::MerbAdmin.slice_path_for(type, *segments)
60
+ end
61
+
62
+
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,112 @@
1
+ require 'builder'
2
+ module Merb
3
+ module MerbAdmin
4
+ module FormsHelper
5
+ # Given a page count and the current page, we generate a set of pagination
6
+ # links.
7
+ #
8
+ # * We use an inner and outer window into a list of links. For a set of
9
+ # 20 pages with the current page being 10:
10
+ # outer_window:
11
+ # 1 2 ..... 19 20
12
+ # inner_window
13
+ # 5 6 7 8 9 10 11 12 13 14
14
+ #
15
+ # This is totally adjustable, or can be turned off by giving the
16
+ # :inner_window setting a value of nil.
17
+ #
18
+ # * Options
19
+ # :left_cut_label => <em>text_for_cut</em>::
20
+ # Used when the page numbers need to be cut off to prevent the set of
21
+ # pagination links from being too long.
22
+ # Defaults to '&hellip;'
23
+ # :right_cut_label => <em>text_for_cut</em>::
24
+ # Same as :left_cut_label but for the right side of numbers.
25
+ # Defaults to '&hellip;'
26
+ # :outer_window => <em>number_of_pages</em>::
27
+ # Sets the number of pages to include in the outer 'window'
28
+ # Defaults to 2
29
+ # :inner_window => <em>number_of_pages</em>::
30
+ # Sets the number of pags to include in the inner 'window'
31
+ # Defaults to 7
32
+ # :page_param => <em>name_of_page_paramiter</em>
33
+ # Sets the name of the paramiter the paginator uses to return what
34
+ # page is being requested.
35
+ # Defaults to 'page'
36
+ # :url => <em>url_for_links</em>
37
+ # Provides the base url to use in the page navigation links.
38
+ # Defaults to ''
39
+ def paginate(current_page, page_count, options = {})
40
+ options.reverse_merge!({
41
+ :left_cut_label => '&hellip;',
42
+ :right_cut_label => '&hellip;',
43
+ :outer_window => 2,
44
+ :inner_window => 7,
45
+ :page_param => 'page',
46
+ :url => ''
47
+ })
48
+ url = options.delete :url
49
+ url << (url.include?('?') ? '&' : '?') << options[:page_param]
50
+
51
+ pages = {
52
+ :all => (1..page_count).to_a,
53
+ :left => [],
54
+ :center => [],
55
+ :right => []
56
+ }
57
+
58
+ # Only worry about using our 'windows' if the page count is less then
59
+ # our windows combined.
60
+ if options[:inner_window].nil? || ((options[:outer_window] * 2) + options[:inner_window] + 2) >= page_count
61
+ pages[:center] = pages[:all]
62
+ else
63
+ pages[:left] = pages[:all][0, options[:outer_window]]
64
+ pages[:right] = pages[:all][page_count - options[:outer_window], options[:outer_window]]
65
+ pages[:center] = case current_page
66
+ # allow the inner 'window' to shift to right when close to the left edge
67
+ # Ex: 1 2 [3] 4 5 6 7 8 9 ... 20
68
+ when -infinity .. (options[:inner_window] / 2) + 3
69
+ pages[:all][options[:outer_window], options[:inner_window]] +
70
+ [options[:right_cut_label]]
71
+ # allow the inner 'window' to shift left when close to the right edge
72
+ # Ex: 1 2 ... 12 13 14 15 16 [17] 18 19 20
73
+ when (page_count - (options[:inner_window] / 2.0).ceil) - 1 .. infinity
74
+ [options[:left_cut_label]] +
75
+ pages[:all][page_count - options[:inner_window] - options[:outer_window], options[:inner_window]]
76
+ # Display the unshifed window
77
+ # ex: 1 2 ... 5 6 7 [8] 9 10 11 ... 19 20
78
+ else
79
+ [options[:left_cut_label]] +
80
+ pages[:all][current_page - (options[:inner_window] / 2) - 1, options[:inner_window]] +
81
+ [options[:right_cut_label]]
82
+ end
83
+ end
84
+
85
+ b = []
86
+
87
+ [pages[:left], pages[:center], pages[:right]].each do |p|
88
+ p.each do |page_number|
89
+ case page_number
90
+ when String
91
+ b << page_number
92
+ when current_page
93
+ b << Builder::XmlMarkup.new.span(page_number, :class => "this-page")
94
+ when page_count
95
+ b << Builder::XmlMarkup.new.a(page_number, :class => "end", :href => "#{url}=#{page_number}")
96
+ else
97
+ b << Builder::XmlMarkup.new.a(page_number, :href => "#{url}=#{page_number}")
98
+ end
99
+ end
100
+ end
101
+
102
+ b.join(" ")
103
+ end
104
+
105
+ private
106
+
107
+ def infinity
108
+ 1.0 / 0
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,8 @@
1
+ <div class="form-row page">
2
+ <div>
3
+ <%= text_field(property.name, :maxlength => property.length, :label => property.field.capitalize.gsub('_', ' ')) %>
4
+ <p class="help">
5
+ <%= !property.nullable? || property.serial? ? "Required." : "Optional." %>
6
+ </p>
7
+ </div>
8
+ </div>
@@ -0,0 +1,8 @@
1
+ <div class="form-row page">
2
+ <div>
3
+ <%= text_field(property.name, :class => "vDateField", :label => property.field.capitalize.gsub('_', ' '), :value => eval("@instance.#{property.field}").strftime("%Y-%m-%d")) %>
4
+ <p class="help">
5
+ <%= !property.nullable? ? "Required." : "Optional." %>
6
+ </p>
7
+ </div>
8
+ </div>
@@ -0,0 +1,8 @@
1
+ <div class="form-row page">
2
+ <div>
3
+ <%= text_field(property.name, :class => "vDateField", :label => property.field.capitalize.gsub('_', ' '), :value => eval("@instance.#{property.field}").strftime("%Y-%m-%d %H:%M:%S")) %>
4
+ <p class="help">
5
+ <%= !property.nullable? ? "Required." : "Optional." %>
6
+ </p>
7
+ </div>
8
+ </div>
@@ -0,0 +1,8 @@
1
+ <div class="form-row page">
2
+ <div>
3
+ <%= text_field(property.name, :maxlength => property.length, :label => property.field.capitalize.gsub('_', ' ')) %>
4
+ <p class="help">
5
+ <%= !property.nullable? || property.serial? ? "Required." : "Optional." %>
6
+ </p>
7
+ </div>
8
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="form-row page">
2
+ <div>
3
+ <% if property.type.respond_to?(:flag_map) #Enum or Flag type %>
4
+ <%= select(property.name, :collection => property.type.flag_map.map{|x| [x[1], x[1].to_s.capitalize.gsub('_', ' ')]}.sort{|a, b| a[1] <=> b[1]}, :label => property.field.capitalize.gsub('_', ' ')) %>
5
+ <% else %>
6
+ <%= text_field(property.name, :maxlength => property.length, :label => property.field.capitalize.gsub('_', ' ')) %>
7
+ <% end %>
8
+ <p class="help">
9
+ <%= !property.nullable? || property.serial? ? "Required." : "Optional." %>
10
+ </p>
11
+ </div>
12
+ </div>
@@ -0,0 +1,16 @@
1
+ <div class="form-row page">
2
+ <div>
3
+ <% case property.type.to_s %>
4
+ <% when "DataMapper::Types::Text" %>
5
+ <%= text_area(property.name, :cols => 80, :label => property.field.capitalize.gsub('_', ' ')) %>
6
+ <p class="help">
7
+ <%= property.nullable? ? "Required." : "Optional." %>
8
+ </p>
9
+ <% else %>
10
+ <%= text_field(property.name, :size => [50, property.length].min, :maxlength => property.length, :label => property.field.capitalize.gsub('_', ' ')) %>
11
+ <p class="help">
12
+ <%= !property.nullable? ? "Required." : "Optional." %> <%= property.length %> <%= property.length == 1 ? "character." : "characters or fewer." %>
13
+ </p>
14
+ <% end %>
15
+ </div>
16
+ </div>
@@ -0,0 +1,8 @@
1
+ <div class="form-row page">
2
+ <div>
3
+ <%= text_field(property.name, :class => "vTimeField", :label => property.field.capitalize.gsub('_', ' '), :value => eval("@instance.#{property.field}").strftime("%H:%M:%S")) %>
4
+ <p class="help">
5
+ <%= !property.nullable? ? "Required." : "Optional." %>
6
+ </p>
7
+ </div>
8
+ </div>
@@ -0,0 +1,5 @@
1
+ <div class="form-row page">
2
+ <div>
3
+ <%= check_box(property.name, :label => property.field.capitalize.gsub('_', ' ')) %>
4
+ </div>
5
+ </div>
@@ -0,0 +1,12 @@
1
+ <p>Are you sure you want to delete the <%= @model_name.snake_case.gsub('_', ' ') %>? All of the following related items will be deleted:</p>
2
+ <ul>
3
+ <li>
4
+ <a href="<%= slice_url(:admin_edit, :model_name => @model_name.snake_case, :id => @instance.id) %>"><%= @model_name %></a>
5
+ </li>
6
+ </ul>
7
+ <%= form_for(@instance, :action => slice_url(:admin_destroy, :model_name => @model_name.snake_case, :id => @instance.id), :method => :delete) do %>
8
+ <div>
9
+ <%= submit "Yes, I'm sure" %>
10
+ </div>
11
+ <% end =%>
12
+
@@ -0,0 +1,23 @@
1
+ <div id="content-main">
2
+ <ul class="object-tools">
3
+ <li><a href="<%= "/#{@model_name.snake_case}/#{@instance.id}" %>" target="_blank" class="viewsitelink">View on site</a></li>
4
+ </ul>
5
+ <%= form_for(@instance, :action => slice_url(:admin_update, :model_name => @model_name.snake_case, :id => @instance.id)) do %>
6
+ <div>
7
+ <fieldset class="module aligned">
8
+ <h2><%= @model_name %> info</h2>
9
+ <% @properties.each do |property| %>
10
+ <% next if [:id, :created_at, :created_on, :updated_at, :updated_on].include?(property.name) %>
11
+ <%= partial property.primitive.to_s.snake_case, :property => property -%>
12
+ <% end %>
13
+ </fieldset>
14
+ <div class="submit-row" >
15
+ <%= submit "Save", :class => "default", :name => "_save" %>
16
+ <p class="deletelink-box"><a href="<%= slice_url(:admin_delete, :model_name => @model_name.snake_case, :id => @instance.id) %>" class="deletelink">Delete</a></p>
17
+ <%= submit "Save and add another", :name => "_add_another" %>
18
+ <%= submit "Save and continue editing", :name => "_continue" %>
19
+ </div>
20
+ </div>
21
+ <% end =%>
22
+
23
+ </div>
@@ -0,0 +1,22 @@
1
+ <div id="content-main">
2
+ <div class="module">
3
+ <table summary="Models available in the application.">
4
+ <caption><a href="<%= slice_url(:admin_dashboard) %>" class="section">Models</a></caption>
5
+ <% @models.map{|m| m.to_s}.each do |model_name| %>
6
+ <tr>
7
+ <th scope="row"><a href="<%= slice_url(:admin_list, :model_name => model_name.snake_case) %>"><%=h model_name.pluralize %></a></th>
8
+ <td><a href="<%= slice_url(:admin_new, :model_name => model_name.snake_case) %>" class="addlink">Add</a></td>
9
+ <td><a href="<%= slice_url(:admin_list, :model_name => model_name.snake_case) %>" class="changelink">Edit</a></td>
10
+ </tr>
11
+ <% end %>
12
+ </table>
13
+ </div>
14
+ </div>
15
+ <div id="content-related">
16
+ <div class="module" id="recent-actions-module">
17
+ <h2>Recent Actions</h2>
18
+ <h3>My Actions</h3>
19
+ <p>None available</p>
20
+ </div>
21
+ </div>
22
+ <br class="clear" />
@@ -0,0 +1,64 @@
1
+ <div id="content-main">
2
+ <ul class="object-tools">
3
+ <li>
4
+ <a href="<%= slice_url(:admin_new, :model_name => @model_name.snake_case) %>" class="addlink">Add <%=h @model_name.snake_case.gsub('_', ' ') %></a>
5
+ </li>
6
+ </ul>
7
+ <div class="module filtered" id="changelist">
8
+ <table cellspacing="0">
9
+ <thead>
10
+ <tr>
11
+ <% @properties.each do |property| %>
12
+ <th>
13
+ <%= property.field.capitalize.gsub('_', ' ') %>
14
+ </th>
15
+ <% end %>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <% @instances.each_with_index do |instance, index| %>
20
+ <tr class="row<%= index % 2 == 0 ? '1' : '2' %>">
21
+ <% @properties.each do |property| %>
22
+ <td>
23
+ <a href="<%= slice_url(:admin_edit, :model_name => @model_name.snake_case, :id => eval("instance.id")) %>">
24
+ <% case property.primitive.to_s %>
25
+ <% when "TrueClass" %>
26
+ <% if eval("instance.#{property.field}") == true %>
27
+ <img alt="True" src="<%= image_path("icon-yes.gif") %>"/>
28
+ <% else %>
29
+ <img alt="False" src="<%= image_path("icon-no.gif") %>"/>
30
+ <% end %>
31
+ <% when "DateTime" %>
32
+ <%= eval("instance.#{property.field}").strftime("%b. %d, %Y, %I:%M%p") %>
33
+ <% when "Date" %>
34
+ <%= eval("instance.#{property.field}").strftime("%b. %d, %Y") %>
35
+ <% when "Time" %>
36
+ <%= eval("instance.#{property.field}").strftime("%I:%M%p") %>
37
+ <% when "Integer" %>
38
+ <% if property.type.respond_to?(:flag_map) #Enum or Flag type %>
39
+ <%= eval("instance.#{property.field}").to_s.capitalize.gsub('_', ' ') %>
40
+ <% else %>
41
+ <%= eval("instance.#{property.field}") %>
42
+ <% end %>
43
+ <% when "BigDecimal" %>
44
+ <%= eval("instance.#{property.field}") %>
45
+ <% when "Float" %>
46
+ <%= eval("instance.#{property.field}") %>
47
+ <% when "String" %>
48
+ <%= eval("instance.#{property.field}").to_s.truncate(50) %>
49
+ <% end %>
50
+ </a>
51
+ </td>
52
+ <% end %>
53
+ </tr>
54
+ <% end %>
55
+ </tbody>
56
+ </table>
57
+ <p class="paginator">
58
+ <%= paginate(@current_page, @page_count, :url => slice_url(:admin_list, :model_name => @model_name.snake_case)) if @page_count.to_i > 1 %>
59
+ <%= @model.count %> <%= @model.count == 1 ? @model_name.snake_case.gsub('_', ' ') : @model_name.snake_case.gsub('_', ' ').pluralize %>
60
+ <%= "<a href=\"#{slice_url(:admin_list, :model_name => @model_name.snake_case, :all => true)}\" class=\"showall\">Show all</a>" if @page_count.to_i == 2 %>
61
+ </p>
62
+ </div>
63
+ </div>
64
+ <br class="clear" />
@@ -0,0 +1,19 @@
1
+ <div id="content-main">
2
+ <%= form_for(@instance, :action => slice_url(:admin_create, :model_name => @model_name.snake_case)) do %>
3
+ <div>
4
+ <fieldset class="module aligned">
5
+ <h2><%= @model_name %> info</h2>
6
+ <% @properties.each do |property| %>
7
+ <% next if [:id, :created_at, :created_on, :updated_at, :updated_on].include?(property.name) %>
8
+ <%= partial property.primitive.to_s.snake_case, :property => property -%>
9
+ <% end %>
10
+ </fieldset>
11
+ <div class="submit-row" >
12
+ <%= submit "Save", :class => "default", :name => "_save" %>
13
+ <%= submit "Save and add another", :name => "_add_another" %>
14
+ <%= submit "Save and continue editing", :name => "_continue" %>
15
+ </div>
16
+ </div>
17
+ <% end =%>
18
+
19
+ </div>