puffer 0.0.23 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.rspec +1 -0
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +55 -53
  4. data/VERSION +1 -1
  5. data/app/assets/javascripts/puffer/application.js +6 -3
  6. data/app/assets/javascripts/puffer/paginator.js +223 -0
  7. data/app/assets/javascripts/puffer/puffer.js +12 -0
  8. data/app/assets/javascripts/puffer/rails.js +1 -0
  9. data/app/assets/javascripts/puffer/{right-autocompleter.js → right-autocompleter-src.js} +45 -41
  10. data/app/assets/javascripts/puffer/{right-calendar.js → right-calendar-src.js} +53 -50
  11. data/app/assets/javascripts/puffer/right-dialog-src.js +768 -0
  12. data/app/assets/javascripts/puffer/right-slider-src.js +507 -0
  13. data/app/assets/javascripts/puffer/{right.js → right-src.js} +1000 -230
  14. data/app/assets/stylesheets/puffer/application.css +2 -0
  15. data/app/assets/stylesheets/puffer/paginator.css +33 -0
  16. data/app/assets/stylesheets/puffer/right.css +4 -0
  17. data/app/components/base/form.html.erb +15 -0
  18. data/app/components/base_component.rb +15 -0
  19. data/app/components/boolean/form.html.erb +3 -0
  20. data/app/components/boolean/index.html.erb +3 -0
  21. data/app/components/boolean_component.rb +13 -0
  22. data/app/components/date_time/form.html.erb +5 -0
  23. data/app/components/date_time_component.rb +12 -0
  24. data/app/components/file/form.html.erb +5 -0
  25. data/app/components/file_component.rb +3 -0
  26. data/app/components/hidden/form.html.erb +1 -0
  27. data/app/components/hidden_component.rb +3 -0
  28. data/app/components/password/form.html.erb +5 -0
  29. data/app/components/password_component.rb +7 -0
  30. data/app/components/references_many/form.html.erb +1 -0
  31. data/app/components/references_many_component.rb +7 -0
  32. data/app/components/references_one/choose.html.erb +9 -0
  33. data/app/components/references_one/form.html.erb +28 -0
  34. data/app/components/references_one_component.rb +12 -0
  35. data/app/components/select/form.html.erb +5 -0
  36. data/app/components/select_component.rb +15 -0
  37. data/app/components/string/form.html.erb +5 -0
  38. data/app/components/string_component.rb +3 -0
  39. data/app/components/text/form.html.erb +5 -0
  40. data/app/components/text_component.rb +3 -0
  41. data/app/controllers/puffer/base.rb +4 -0
  42. data/app/views/puffer/base/_form.html.erb +0 -1
  43. data/app/views/puffer/base/_table.html.erb +25 -0
  44. data/app/views/puffer/base/index.html.erb +14 -28
  45. data/app/views/puffer/tree_base/_record.html.erb +1 -1
  46. data/lib/generators/puffer/component/USAGE +12 -0
  47. data/lib/generators/puffer/component/component_generator.rb +19 -0
  48. data/lib/generators/puffer/component/templates/component.rb +15 -0
  49. data/lib/generators/puffer/component/templates/component_spec.rb +19 -0
  50. data/lib/puffer/component.rb +141 -0
  51. data/lib/puffer/controller/dsl.rb +25 -12
  52. data/lib/puffer/engine.rb +5 -0
  53. data/lib/puffer/extensions/controller.rb +11 -9
  54. data/lib/puffer/extensions/form.rb +2 -1
  55. data/lib/puffer/extensions/mapper.rb +2 -0
  56. data/lib/puffer/field.rb +30 -19
  57. data/lib/puffer/field_set.rb +17 -2
  58. data/lib/puffer.rb +25 -8
  59. data/puffer.gemspec +59 -28
  60. data/spec/app/components/base_component_spec.rb +19 -0
  61. data/spec/app/components/boolean_component_spec.rb +36 -0
  62. data/spec/app/components/date_time_component_spec.rb +26 -0
  63. data/spec/app/components/file_component_spec.rb +25 -0
  64. data/spec/app/components/hidden_component_spec.rb +24 -0
  65. data/spec/app/components/password_component_spec.rb +37 -0
  66. data/spec/app/components/references_many_component_spec.rb +19 -0
  67. data/spec/app/components/references_one_component_spec.rb +19 -0
  68. data/spec/app/components/select_component_spec.rb +30 -0
  69. data/spec/app/components/string_component_spec.rb +25 -0
  70. data/spec/app/components/text_component_spec.rb +25 -0
  71. data/spec/dummy/app/controllers/admin/categories_controller.rb +3 -3
  72. data/spec/dummy/app/controllers/admin/posts_controller.rb +3 -0
  73. data/spec/dummy/app/controllers/{puffer → admin}/sessions_controller.rb +1 -1
  74. data/spec/dummy/app/controllers/admin/users_controller.rb +2 -2
  75. data/spec/dummy/app/models/post.rb +4 -0
  76. data/spec/dummy/db/migrate/20100930132656_create_posts.rb +2 -0
  77. data/spec/dummy/db/migrate/20100930132726_create_categories.rb +1 -0
  78. data/spec/dummy/db/schema.rb +3 -0
  79. data/spec/dummy/db/seeds.rb +6 -1
  80. data/spec/fabricators/categories_fabricator.rb +1 -0
  81. data/spec/fabricators/posts_fabricator.rb +1 -0
  82. data/spec/lib/component_spec.rb +7 -0
  83. data/spec/lib/fields_spec.rb +0 -4
  84. metadata +85 -56
  85. data/app/views/puffer/base/associated/_many.html.erb +0 -56
  86. data/app/views/puffer/base/associated/many.rjs +0 -1
  87. data/app/views/puffer/base/associated/one.js.erb +0 -13
  88. data/app/views/puffer/base/association/_many.html.erb +0 -7
  89. data/lib/puffer/controller/generated.rb +0 -65
  90. data/lib/puffer/customs.rb +0 -64
  91. data/lib/puffer/inputs/association.rb +0 -38
  92. data/lib/puffer/inputs/base.rb +0 -51
  93. data/lib/puffer/inputs/boolean.rb +0 -19
  94. data/lib/puffer/inputs/collection_association.rb +0 -11
  95. data/lib/puffer/inputs/date_time.rb +0 -16
  96. data/lib/puffer/inputs/file.rb +0 -11
  97. data/lib/puffer/inputs/hidden.rb +0 -15
  98. data/lib/puffer/inputs/password.rb +0 -11
  99. data/lib/puffer/inputs/select.rb +0 -19
  100. data/lib/puffer/inputs/text.rb +0 -11
@@ -1,56 +0,0 @@
1
- <% ids = "$$('#associated_#{field} input[type=hidden]').collect(function(element){return $F(element)})" %>
2
- <div class="header">
3
- <div class="popup_close"><%= link_to t(:close), '#', :terbium_popup_close => true %></div>
4
- <ul class="navigation">
5
- <li<%= ' class="selected"' if params[:action] == "associated_#{field}" %>>
6
- <%= link_to t(:existing), '#', :ajax => resource_path(record, "associated_#{field}"), :ids => ids %>
7
- </li>
8
- <li<%= ' class="selected"' if params[:action] == "associated_#{field}_choosing" %>>
9
- <%= link_to t(:choosing), '#', :ajax => resource_path(record, "associated_#{field}_choosing"), :ids => ids %>
10
- </li>
11
- <li class="notab">
12
- <% form_tag '#', :class => 'associated_search', :ajax => current_path, :ids => ids do %>
13
- <%= text_field_tag :query, resource_session[:query] %>
14
- <%= submit_tag 'Search' %>
15
- <% if resource_session[:query].present? %>
16
- <%= link_to 'clear', '#', :ajax => current_path(:query => ''), :ids => ids %>
17
- <% end %>
18
- <% end %>
19
- </li>
20
- </ul>
21
- </div>
22
-
23
- <div class="pagination">
24
- <%= paginate associated, :renderer => AssociatedLinkRenderer, :ids => ids %>
25
- </div>
26
-
27
- <div class="popup_content">
28
- <table class="list_table">
29
- <thead>
30
- <tr>
31
- <% field.association_fields.each do |f| -%>
32
- <th><%= f.label %></th>
33
- <% end -%>
34
- <th class="actions">Actions</th>
35
- </tr>
36
- </thead>
37
- <tbody>
38
- <% associated.each do |association| -%>
39
- <tr id="<%= dom_id association %>">
40
- <% field.association_fields.each do |f| -%>
41
- <td><%= render_field association, f %></td>
42
- <% end -%>
43
- <td class="actions">
44
- <%= link_to t(:show), resource_path(association), :target => '_blank' if (resource_path(association) rescue nil) %>
45
- <% if params[:action] == "associated_#{field}" %>
46
- <%= link_to_function t(:remove), "$('associated_#{field}_#{association.id}').remove(); $('#{dom_id association}').remove()" %>
47
- <% else %>
48
- <%= link_to_function t(:add), "$('associated_#{field}').insert({bottom: \"#{escape_javascript hidden_field_tag("#{model_name}[#{field.to_s.singularize}_ids][]", association.id, :id => "associated_#{field}_#{association.id}")}\"}); $('#{dom_id association}').remove()" %>
49
- <%= link_to_function t(:add), "$('associated_#{field}').replace(\"#{escape_javascript render(:partial => "terbium/association/many", :object => @choosen + [association], :locals => {:field => field})}\"); Event.addBehavior.reload()" %>
50
- <% end %>
51
- </td>
52
- </tr>
53
- <% end -%>
54
- </tbody>
55
- </table>
56
- </div>
@@ -1 +0,0 @@
1
- page.replace_html 'terbium_popup', :partial => 'terbium/associated/many', :locals => {:field => @field, :associated => @records}
@@ -1,13 +0,0 @@
1
- <ul>
2
- <% primary_key = @field.reflection.primary_key_column.name.to_sym %>
3
- <% records.each do |record| %>
4
- <li data-id="<%= record[primary_key] %>">
5
- <div class="title"><strong><%= record[primary_key] %></strong> — <%= record.to_title %></div>
6
- <div class="description">
7
- <% @field.association_columns.searchable.each do |column| %>
8
- <div><strong><%= column.human %>:</strong> <%= render_field column, record %></div>
9
- <% end %>
10
- </div>
11
- </li>
12
- <% end %>
13
- </ul>
@@ -1,7 +0,0 @@
1
- <div id="associated_<%= field %>">
2
- <%= link_to "#{t(:choose_associated)} (#{many.size})", '#', :terbium_popup => resource_path(record, "associated_#{field}"), :ids => "$$('#associated_#{field} input[type=hidden]').collect(function(element){return $F(element)})" %>
3
- <%= hidden_field_tag "#{model_name}[#{field.to_s.singularize}_ids][]" %>
4
- <% many.each do |association| %>
5
- <%= hidden_field_tag "#{model_name}[#{field.to_s.singularize}_ids][]", association.id, :id => "associated_#{field}_#{association.id}" %>
6
- <% end %>
7
- </div>
@@ -1,65 +0,0 @@
1
- module Puffer
2
- module Controller
3
- module Generated
4
-
5
- def self.included base
6
- base.class_eval do
7
- extend ClassMethods
8
- end
9
- end
10
-
11
- module ClassMethods
12
-
13
- def generate_association_actions field
14
- field.collection? ? generate_collection_association_actions(field) : generate_single_association_actions(field)
15
- end
16
-
17
- def generate_single_association_actions field
18
- define_method "associated_#{field}_choosing" do
19
- @field = field
20
- @record = resource.member if params[:id]
21
- @records = field.reflection.klass.includes(field.association_columns.includes).where(field.association_columns.searches(params[:search])).limit(100).all
22
- render :action => 'associated/one'
23
- end
24
-
25
- collection do
26
- get "associated_#{field}_choosing", :display => false
27
- end
28
- end
29
-
30
- def generate_collection_association_actions field
31
- define_method "associated_#{field}" do
32
- @record = resource.member
33
- @records = field.association.klass.scoped(:conditions => {:id => params[:ids]}).scoped(:conditions => search_query(field.association_fields)).paginate(:page => params[:page], :include => includes(field.association_fields))
34
- @field = field
35
- render :action => 'associated/many'
36
- end
37
-
38
- define_method "associated_#{field}_choosing" do
39
- @record = resource.member
40
- @records = field.association.klass.scoped(:conditions => search_query(field.association_fields)).paginate(:page => params[:page], :include => includes(field.association_fields))
41
- @choosen = field.association.klass.scoped(:conditions => {:id => params[:ids]}).scoped(:conditions => search_query(field.association_fields)).paginate(:page => params[:page], :include => includes(field.association_fields))
42
- @field = field
43
- render :action => 'associated/many'
44
- end
45
-
46
- collection do
47
- get "associated_#{field}", :display => false
48
- get "associated_#{field}_choosing", :display => false
49
- end
50
- end
51
-
52
- def generate_change_actions field
53
- define_method "toggle_#{field}" do
54
- @record = model.find params[:id]
55
- @field = field
56
- @record.toggle! field.name.to_sym
57
- render :action => 'toggle'
58
- end
59
- end
60
-
61
- end
62
-
63
- end
64
- end
65
- end
@@ -1,64 +0,0 @@
1
- module Puffer
2
- module Customs
3
-
4
- # Custom field types
5
-
6
- mattr_accessor :types
7
- self.types = []
8
-
9
- def self.map_type &block
10
- types.unshift block if block_given?
11
- end
12
-
13
- def self.type_for field
14
- swallow_nil{ types.detect { |offer| offer.call(field) }.call(field) }
15
- end
16
-
17
- map_type { |field| :select if field.options.key?(:select) }
18
- map_type { |field| :password if field.name =~ /password/ }
19
- map_type { |field| swallow_nil{ field.reflection.macro } }
20
-
21
-
22
- # Custom inputs
23
-
24
- mattr_accessor :inputs
25
- self.inputs = {}
26
-
27
- def self.map_input *args
28
- to = args.extract_options![:to]
29
- args.each { |type| inputs[type] = to }
30
- end
31
-
32
- def self.input_for field
33
- inputs[field.type] || ("Puffer::Inputs::#{field.type.to_s.camelize}".constantize rescue Puffer::Inputs::Base)
34
- end
35
-
36
- map_input :belongs_to, :has_one, :to => Puffer::Inputs::Association
37
- map_input :has_many, :has_and_belongs_to_many, :to => Puffer::Inputs::CollectionAssociation
38
- map_input :date, :time, :datetime, :timestamp, :to => Puffer::Inputs::DateTime
39
-
40
-
41
- # Customs renderers
42
-
43
- mattr_accessor :renderers
44
- self.renderers = {}
45
-
46
- def self.map_renderer *args
47
- to = args.extract_options![:to]
48
- args.each { |type| renderers[type] = to }
49
- end
50
-
51
-
52
- # Customs filters
53
-
54
- mattr_accessor :filters
55
- self.filters = {}
56
-
57
- def self.map_filter *args
58
- to = args.extract_options![:to]
59
- args.each { |type| filters[type] = to }
60
- end
61
-
62
- end
63
- end
64
-
@@ -1,38 +0,0 @@
1
- # coding: utf-8
2
- module Puffer
3
- module Inputs
4
- class Association < Puffer::Inputs::Base
5
-
6
- def input
7
- <<-INPUT
8
- <div class="association">
9
- #{text_field_tag field, value, field.input_options.merge(
10
- :autocomplete => :off,
11
- :disabled => (true if builder.object.send(field.name)),
12
- 'data-autocompleter' => "{url: '#{resource.collection_path(:action => "associated_#{field}_choosing")}', onDone: association_done}"
13
- )}
14
- <div class="association_clear">×</div>
15
- #{builder.hidden_field field.reflection.foreign_key}
16
- </div>
17
- INPUT
18
- end
19
-
20
- def value
21
- value = [
22
- swallow_nil{builder.object.send(field.name)[field.reflection.primary_key_column.name.to_sym]},
23
- swallow_nil{builder.object.send(field.name).to_title}
24
- ].compact.join(' - ')
25
- end
26
-
27
- def label
28
- label_tag field
29
- end
30
-
31
- def error
32
- builder.object.errors[field.reflection.foreign_key.to_sym].first ||
33
- builder.object.errors[field.name.to_sym].first.presence
34
- end
35
-
36
- end
37
- end
38
- end
@@ -1,51 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class Base
4
-
5
- attr_accessor :builder, :template, :field
6
-
7
- def self.render *args
8
- new(*args).render
9
- end
10
-
11
- def initialize builder, field
12
- @builder = builder
13
- @field = field
14
- @template = builder.instance_variable_get :@template
15
- end
16
-
17
- def render
18
- html.html_safe
19
- end
20
-
21
- def html
22
- <<-INPUT
23
- <div class="label">
24
- #{label}
25
- <div class="field_error">
26
- #{error}
27
- </div>
28
- </div>
29
- #{input}
30
- INPUT
31
- end
32
-
33
- def label
34
- builder.label field
35
- end
36
-
37
- def input
38
- builder.text_field field, field.input_options
39
- end
40
-
41
- def error
42
- builder.object.errors[field.name.to_sym].first
43
- end
44
-
45
- def method_missing method, *args, &block
46
- template.send method, *args, &block if template.respond_to? method
47
- end
48
-
49
- end
50
- end
51
- end
@@ -1,19 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class Boolean < Puffer::Inputs::Base
4
-
5
- def html
6
- <<-INPUT
7
- #{input}
8
- #{label}
9
- #{error}
10
- INPUT
11
- end
12
-
13
- def input
14
- builder.check_box field, field.input_options
15
- end
16
-
17
- end
18
- end
19
- end
@@ -1,11 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class CollectionAssociation < Puffer::Inputs::Base
4
-
5
- def input
6
- field.type
7
- end
8
-
9
- end
10
- end
11
- end
@@ -1,16 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class DateTime < Puffer::Inputs::Base
4
-
5
- def input
6
- format = case field.type
7
- when :date then '%Y-%m-%d'
8
- when :time then '%H:%M:%S'
9
- when :datetime, :timestamp then '%Y-%m-%d %H:%M:%S'
10
- end
11
- builder.text_field field, field.input_options.merge("data-calendar" => "{showButtons: true, listYears: true, format: '#{format}'}", :autocomplete => :off)
12
- end
13
-
14
- end
15
- end
16
- end
@@ -1,11 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class File < Puffer::Inputs::Base
4
-
5
- def input
6
- builder.file_field field, field.input_options
7
- end
8
-
9
- end
10
- end
11
- end
@@ -1,15 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class Hidden < Puffer::Inputs::Base
4
-
5
- def input
6
- builder.hidden_field field, field.input_options
7
- end
8
-
9
- def html
10
- input
11
- end
12
-
13
- end
14
- end
15
- end
@@ -1,11 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class Password < Puffer::Inputs::Base
4
-
5
- def input
6
- builder.password_field field, field.input_options
7
- end
8
-
9
- end
10
- end
11
- end
@@ -1,19 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class Select < Puffer::Inputs::Base
4
-
5
- def input
6
- options = case field.options[:select]
7
- when Symbol then
8
- send field.options[:select]
9
- when Proc then
10
- field.options[:select].bind(temptate).call
11
- else
12
- field.options[:select]
13
- end
14
- builder.select field, options, {:include_blank => field.options[:include_blank]}, field.input_options
15
- end
16
-
17
- end
18
- end
19
- end
@@ -1,11 +0,0 @@
1
- module Puffer
2
- module Inputs
3
- class Text < Puffer::Inputs::Base
4
-
5
- def input
6
- builder.text_area field, field.input_options
7
- end
8
-
9
- end
10
- end
11
- end