active_scaffold 3.2.20 → 3.3.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/CHANGELOG +19 -13
  2. data/README +66 -0
  3. data/app/assets/javascripts/jquery/active_scaffold.js +156 -113
  4. data/app/assets/javascripts/jquery/active_scaffold_chosen.js +11 -0
  5. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +0 -1
  6. data/app/assets/javascripts/jquery/jquery.editinplace.js +132 -128
  7. data/app/assets/javascripts/prototype/active_scaffold.js +68 -25
  8. data/{frontends/default/views/_horizontal_subform_footer.html.erb → app/assets/javascripts/prototype/active_scaffold_chosen.js} +0 -0
  9. data/app/assets/stylesheets/active_scaffold_colors.css.scss +8 -1
  10. data/app/assets/stylesheets/active_scaffold_layout.css +14 -8
  11. data/{frontends/default/views → app/views/active_scaffold_overrides}/_add_existing_form.html.erb +0 -0
  12. data/{frontends/default/views → app/views/active_scaffold_overrides}/_base_form.html.erb +0 -0
  13. data/{frontends/default/views → app/views/active_scaffold_overrides}/_create_form.html.erb +0 -0
  14. data/{frontends/default/views → app/views/active_scaffold_overrides}/_create_form_on_list.html.erb +0 -0
  15. data/{frontends/default/views → app/views/active_scaffold_overrides}/_field_search.html.erb +0 -0
  16. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form.html.erb +0 -0
  17. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_association.html.erb +8 -3
  18. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_association_footer.html.erb +5 -4
  19. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +85 -0
  20. data/app/views/active_scaffold_overrides/_form_attribute.html.erb +23 -0
  21. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_hidden_attribute.html.erb +0 -0
  22. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_messages.html.erb +0 -0
  23. data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +12 -0
  24. data/app/views/active_scaffold_overrides/_horizontal_subform_footer.html.erb +0 -0
  25. data/{frontends/default/views → app/views/active_scaffold_overrides}/_horizontal_subform_header.html.erb +3 -2
  26. data/{frontends/default/views → app/views/active_scaffold_overrides}/_human_conditions.html.erb +0 -0
  27. data/app/views/active_scaffold_overrides/_list.html.erb +35 -0
  28. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_calculations.html.erb +0 -0
  29. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_column_headings.html.erb +0 -0
  30. data/app/views/active_scaffold_overrides/_list_header.html.erb +8 -0
  31. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_inline_adapter.html.erb +0 -0
  32. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_messages.html.erb +4 -4
  33. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_pagination.html.erb +0 -0
  34. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_pagination_links.html.erb +0 -0
  35. data/app/views/active_scaffold_overrides/_list_record.html.erb +30 -0
  36. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_with_header.html.erb +0 -0
  37. data/{frontends/default/views → app/views/active_scaffold_overrides}/_messages.html.erb +0 -0
  38. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +1 -0
  39. data/{frontends/default/views → app/views/active_scaffold_overrides}/_render_field.js.erb +9 -1
  40. data/{frontends/default/views → app/views/active_scaffold_overrides}/_row.html.erb +0 -0
  41. data/{frontends/default/views → app/views/active_scaffold_overrides}/_search.html.erb +0 -0
  42. data/{frontends/default/views → app/views/active_scaffold_overrides}/_search_attribute.html.erb +0 -0
  43. data/{frontends/default/views → app/views/active_scaffold_overrides}/_show.html.erb +0 -0
  44. data/{frontends/default/views → app/views/active_scaffold_overrides}/_show_columns.html.erb +0 -0
  45. data/app/views/active_scaffold_overrides/_update_actions.html.erb +9 -0
  46. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_calculations.js.erb +0 -0
  47. data/app/views/active_scaffold_overrides/_update_column.js.erb +16 -0
  48. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_form.html.erb +0 -0
  49. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_messages.js.erb +0 -0
  50. data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +8 -0
  51. data/{frontends/default/views → app/views/active_scaffold_overrides}/action_confirmation.html.erb +0 -0
  52. data/{frontends/default/views → app/views/active_scaffold_overrides}/add_existing.js.erb +0 -0
  53. data/{frontends/default/views → app/views/active_scaffold_overrides}/add_existing_form.html.erb +0 -0
  54. data/{frontends/default/views → app/views/active_scaffold_overrides}/create.html.erb +0 -0
  55. data/{frontends/default/views → app/views/active_scaffold_overrides}/delete.html.erb +0 -0
  56. data/{frontends/default/views → app/views/active_scaffold_overrides}/destroy.js.erb +0 -0
  57. data/{frontends/default/views → app/views/active_scaffold_overrides}/edit_associated.js.erb +1 -1
  58. data/{frontends/default/views → app/views/active_scaffold_overrides}/field_search.html.erb +0 -0
  59. data/{frontends/default/views → app/views/active_scaffold_overrides}/form_messages.js.erb +0 -0
  60. data/{frontends/default/views → app/views/active_scaffold_overrides}/list.html.erb +0 -0
  61. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_action_update.js.erb +3 -3
  62. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_create.js.erb +1 -1
  63. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_mark.js.erb +0 -0
  64. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_update.js.erb +4 -4
  65. data/{frontends/default/views → app/views/active_scaffold_overrides}/render_field.js.erb +0 -0
  66. data/{frontends/default/views → app/views/active_scaffold_overrides}/row.js.erb +1 -1
  67. data/{frontends/default/views → app/views/active_scaffold_overrides}/search.html.erb +0 -0
  68. data/{frontends/default/views → app/views/active_scaffold_overrides}/show.html.erb +0 -0
  69. data/{frontends/default/views → app/views/active_scaffold_overrides}/update.html.erb +1 -1
  70. data/app/views/active_scaffold_overrides/update_column.js.erb +26 -0
  71. data/{frontends/default/views → app/views/active_scaffold_overrides}/update_row.js.erb +0 -0
  72. data/config/locales/de.yml +1 -0
  73. data/config/locales/en.yml +1 -0
  74. data/config/locales/es.yml +1 -0
  75. data/config/locales/fr.yml +1 -0
  76. data/config/locales/hu.yml +1 -0
  77. data/config/locales/ja.yml +1 -0
  78. data/config/locales/ru.yml +1 -0
  79. data/lib/active_scaffold.rb +14 -26
  80. data/lib/active_scaffold/actions/core.rb +14 -11
  81. data/lib/active_scaffold/actions/create.rb +3 -3
  82. data/lib/active_scaffold/actions/delete.rb +3 -0
  83. data/lib/active_scaffold/actions/list.rb +9 -6
  84. data/lib/active_scaffold/actions/mark.rb +1 -1
  85. data/lib/active_scaffold/actions/nested.rb +8 -6
  86. data/lib/active_scaffold/actions/show.rb +6 -1
  87. data/lib/active_scaffold/actions/update.rb +39 -19
  88. data/lib/active_scaffold/active_record_permissions.rb +29 -12
  89. data/lib/active_scaffold/attribute_params.rb +14 -7
  90. data/lib/active_scaffold/bridges/calendar_date_select.rb +1 -1
  91. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +1 -2
  92. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
  93. data/lib/active_scaffold/bridges/chosen.rb +14 -0
  94. data/lib/active_scaffold/bridges/chosen/helpers.rb +48 -0
  95. data/lib/active_scaffold/bridges/date_picker/helper.rb +7 -6
  96. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +1 -1
  97. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +1 -1
  98. data/lib/active_scaffold/bridges/file_column.rb +1 -1
  99. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
  100. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +2 -2
  101. data/lib/active_scaffold/bridges/file_column/list_ui.rb +4 -4
  102. data/lib/active_scaffold/bridges/paperclip.rb +1 -1
  103. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +1 -1
  104. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  105. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +1 -1
  106. data/lib/active_scaffold/bridges/shared/date_bridge.rb +1 -1
  107. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +1 -1
  108. data/lib/active_scaffold/config/core.rb +9 -2
  109. data/lib/active_scaffold/config/list.rb +9 -13
  110. data/lib/active_scaffold/config/nested.rb +11 -2
  111. data/lib/active_scaffold/data_structures/action_columns.rb +19 -5
  112. data/lib/active_scaffold/data_structures/action_link.rb +9 -2
  113. data/lib/active_scaffold/data_structures/action_links.rb +5 -36
  114. data/lib/active_scaffold/data_structures/column.rb +21 -21
  115. data/lib/active_scaffold/data_structures/nested_info.rb +31 -44
  116. data/lib/active_scaffold/extensions/action_controller_rescueing.rb +1 -0
  117. data/lib/active_scaffold/extensions/action_view_rendering.rb +30 -36
  118. data/lib/active_scaffold/extensions/reverse_associations.rb +10 -6
  119. data/lib/active_scaffold/extensions/routing_mapper.rb +6 -5
  120. data/lib/active_scaffold/extensions/unsaved_associated.rb +1 -1
  121. data/lib/active_scaffold/finder.rb +18 -10
  122. data/lib/active_scaffold/helpers/association_helpers.rb +21 -2
  123. data/lib/active_scaffold/helpers/controller_helpers.rb +14 -16
  124. data/lib/active_scaffold/helpers/form_column_helpers.rb +161 -21
  125. data/lib/active_scaffold/helpers/id_helpers.rb +7 -7
  126. data/lib/active_scaffold/helpers/list_column_helpers.rb +42 -92
  127. data/lib/active_scaffold/helpers/search_column_helpers.rb +10 -3
  128. data/lib/active_scaffold/helpers/show_column_helpers.rb +4 -9
  129. data/lib/active_scaffold/helpers/view_helpers.rb +278 -78
  130. data/lib/active_scaffold/version.rb +2 -2
  131. data/lib/generators/active_scaffold_controller/templates/controller.rb +1 -1
  132. data/test/bridges/paperclip_test.rb +2 -2
  133. data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +1882 -1276
  134. metadata +79 -80
  135. data/README.md +0 -67
  136. data/frontends/default/views/_action_group.html.erb +0 -24
  137. data/frontends/default/views/_form_attribute.html.erb +0 -23
  138. data/frontends/default/views/_horizontal_subform.html.erb +0 -22
  139. data/frontends/default/views/_horizontal_subform_record.html.erb +0 -43
  140. data/frontends/default/views/_list.html.erb +0 -18
  141. data/frontends/default/views/_list_actions.html.erb +0 -15
  142. data/frontends/default/views/_list_header.html.erb +0 -10
  143. data/frontends/default/views/_list_record.html.erb +0 -13
  144. data/frontends/default/views/_list_record_columns.html.erb +0 -8
  145. data/frontends/default/views/_refresh_list.js.erb +0 -1
  146. data/frontends/default/views/_update_actions.html.erb +0 -9
  147. data/frontends/default/views/_vertical_subform.html.erb +0 -12
  148. data/frontends/default/views/_vertical_subform_record.html.erb +0 -43
  149. data/frontends/default/views/refresh_list.js.erb +0 -2
  150. data/frontends/default/views/update_column.js.erb +0 -15
  151. data/lib/active_scaffold/extensions/active_record_offset.rb +0 -12
  152. data/lib/active_scaffold/extensions/nil_id_in_url_params.rb +0 -7
@@ -12,7 +12,7 @@ module ActiveScaffold::Bridges
12
12
  /%m/ => 'mm',
13
13
  /%y/ => 'y',
14
14
  /%Y/ => 'yy',
15
- /%H/ => 'hh', # options ampm => false
15
+ /%H/ => 'HH', # options ampm => false
16
16
  /%I/ => 'hh', # options ampm => true
17
17
  /%M/ => 'mm',
18
18
  /%p/ => 'tt',
@@ -101,6 +101,7 @@ module ActiveScaffold::Bridges
101
101
  nil
102
102
  end
103
103
  js_format = rails_format.dup
104
+ js_format.gsub! /([ ]|^)([^% ]\S*)/, " '\\2'"
104
105
  DATE_FORMAT_CONVERSION.each do |key, value|
105
106
  js_format.gsub!(key, value)
106
107
  end
@@ -110,13 +111,13 @@ module ActiveScaffold::Bridges
110
111
  def self.split_datetime_format(datetime_format)
111
112
  date_format = datetime_format
112
113
  time_format = nil
113
- time_start_indicators = %w{hh mm tt ss}
114
+ time_start_indicators = %w{HH hh mm tt ss}
114
115
  unless datetime_format.nil?
115
116
  start_indicator = time_start_indicators.detect {|indicator| datetime_format.include?(indicator)}
116
117
  unless start_indicator.nil?
117
118
  pos_time_format = datetime_format.index(start_indicator)
118
- date_format = datetime_format.to(pos_time_format - 1)
119
- time_format = datetime_format.from(pos_time_format)
119
+ date_format = datetime_format.to(pos_time_format - 1).strip
120
+ time_format = datetime_format.from(pos_time_format).strip
120
121
  end
121
122
  end
122
123
  return date_format, time_format
@@ -158,7 +159,7 @@ module ActiveScaffold::Bridges
158
159
  options = active_scaffold_input_text_options(options.merge(column.options))
159
160
  options[:class] << " #{column.search_ui.to_s}"
160
161
  options[:style] = (options[:show].nil? || options[:show]) ? nil : "display: none"
161
- format = options.delete(:format) || column.search_ui == :date_picker ? :default : :picker
162
+ format = options.delete(:format) || (column.search_ui == :date_picker ? :default : :picker)
162
163
  datepicker_format_options(column, format, options)
163
164
  text_field_tag("#{options[:name]}[#{name}]", value ? l(value, :format => format) : nil, options.merge(:id => "#{options[:id]}_#{name}", :name => "#{options[:name]}[#{name}]"))
164
165
  end
@@ -169,7 +170,7 @@ module ActiveScaffold::Bridges
169
170
  options = active_scaffold_input_text_options(options.merge(column.options))
170
171
  options[:class] << " #{column.form_ui.to_s}"
171
172
  value = controller.class.condition_value_for_datetime(@record.send(column.name), column.form_ui == :date_picker ? :to_date : :to_time)
172
- format = options.delete(:format) || column.form_ui == :date_picker ? :default : :picker
173
+ format = options.delete(:format) || (column.form_ui == :date_picker ? :default : :picker)
173
174
  datepicker_format_options(column, format, options)
174
175
  options[:value] = (value ? l(value, :format => format) : nil)
175
176
  text_field(:record, column.name, options)
@@ -12,7 +12,7 @@ module ActiveScaffold
12
12
  js_remove_file_code = "$(this).previous().value='true'; $(this).up().hide().next().show(); return false;";
13
13
  end
14
14
 
15
- content = active_scaffold_column_dragonfly(column, @record)
15
+ content = active_scaffold_column_dragonfly(@record, column)
16
16
  content_tag(:div,
17
17
  content + " | " +
18
18
  hidden_field(:record, "remove_#{column.name}", :value => "false") +
@@ -1,7 +1,7 @@
1
1
  module ActiveScaffold
2
2
  module Helpers
3
3
  module ListColumnHelpers
4
- def active_scaffold_column_dragonfly(column, record)
4
+ def active_scaffold_column_dragonfly(record, column)
5
5
  attachment = record.send("#{column.name}")
6
6
  return nil unless attachment.present?
7
7
  content = if attachment.image?
@@ -1,6 +1,6 @@
1
1
  class ActiveScaffold::Bridges::FileColumn < ActiveScaffold::DataStructures::Bridge
2
2
  def self.install
3
- if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_file_column".send(::ActiveScaffold::METHOD_CONVERSION))
3
+ if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_file_column")
4
4
  raise RuntimeError, "We've detected that you have active_scaffold_file_column_bridge installed. This plugin has been moved to core. Please remove active_scaffold_file_column_bridge to prevent any conflicts"
5
5
  end
6
6
  require File.join(File.dirname(__FILE__), "file_column/as_file_column_bridge")
@@ -24,7 +24,7 @@ module ActiveScaffold::Config
24
24
  }
25
25
  end
26
26
 
27
- alias_method_chain :initialize, :file_column unless self.instance_methods.include?("initialize_without_file_column".send(::ActiveScaffold::METHOD_CONVERSION))
27
+ alias_method_chain :initialize, :file_column unless self.instance_methods.include?("initialize_without_file_column")
28
28
 
29
29
  def configure_file_column_field(field)
30
30
  # set list_ui first because it gets its default value from form_ui
@@ -4,12 +4,12 @@ module ActiveScaffold
4
4
  module FileColumnHelpers
5
5
  class << self
6
6
  def file_column_fields(klass)
7
- klass.instance_methods.select{|m| m.to_s =~ /_just_uploaded\?$/}.collect{|m| m[0..-16].to_sym }
7
+ klass.instance_methods.grep(/_just_uploaded\?$/).collect{|m| m[0..-16].to_sym }
8
8
  end
9
9
 
10
10
  def generate_delete_helpers(klass)
11
11
  file_column_fields(klass).each { |field|
12
- klass.send :class_eval, <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("#{field}_with_delete=".send(::ActiveScaffold::METHOD_CONVERSION))
12
+ klass.send :class_eval, <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("#{field}_with_delete=")
13
13
  attr_reader :delete_#{field}
14
14
 
15
15
  def delete_#{field}=(value)
@@ -2,18 +2,18 @@ module ActiveScaffold
2
2
  module Helpers
3
3
  # Helpers that assist with the rendering of a List Column
4
4
  module ListColumnHelpers
5
- def active_scaffold_column_download_link_with_filename(column, record)
5
+ def active_scaffold_column_download_link_with_filename(record, column)
6
6
  return nil if record.send(column.name).nil?
7
- active_scaffold_column_download_link(column, record, File.basename(record.send(column.name)))
7
+ active_scaffold_column_download_link(record, column, File.basename(record.send(column.name)))
8
8
  end
9
9
 
10
- def active_scaffold_column_download_link(column, record, label = nil)
10
+ def active_scaffold_column_download_link(record, column, label = nil)
11
11
  return nil if record.send(column.name).nil?
12
12
  label||=as_(:download)
13
13
  link_to( label, url_for_file_column(record, column.name.to_s), :popup => true)
14
14
  end
15
15
 
16
- def active_scaffold_column_thumbnail(column, record)
16
+ def active_scaffold_column_thumbnail(record, column)
17
17
  return nil if record.send(column.name).nil?
18
18
  link_to(
19
19
  image_tag(url_for_file_column(record, column.name.to_s, "thumb"), :border => 0),
@@ -1,6 +1,6 @@
1
1
  class ActiveScaffold::Bridges::Paperclip < ActiveScaffold::DataStructures::Bridge
2
2
  def self.install
3
- if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_paperclip".send(::ActiveScaffold::METHOD_CONVERSION))
3
+ if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_paperclip")
4
4
  raise RuntimeError, "We've detected that you have active_scaffold_paperclip_bridge installed. This plugin has been moved to core. Please remove active_scaffold_paperclip_bridge to prevent any conflicts"
5
5
  end
6
6
  require File.join(File.dirname(__FILE__), "paperclip/form_ui")
@@ -12,7 +12,7 @@ module ActiveScaffold
12
12
  js_remove_file_code = "$(this).previous().value='true'; $(this).up().hide().next().show(); return false;";
13
13
  end
14
14
 
15
- content = active_scaffold_column_paperclip(column, @record)
15
+ content = active_scaffold_column_paperclip(@record, column)
16
16
  content_tag(:div,
17
17
  content + " | " +
18
18
  hidden_field(:record, "delete_#{column.name}", :value => "false") +
@@ -1,7 +1,7 @@
1
1
  module ActiveScaffold
2
2
  module Helpers
3
3
  module ListColumnHelpers
4
- def active_scaffold_column_paperclip(column, record)
4
+ def active_scaffold_column_paperclip(record, column)
5
5
  paperclip = record.send("#{column.name}")
6
6
  return nil unless paperclip.file?
7
7
  content = if paperclip.styles.include?(ActiveScaffold::Bridges::Paperclip::PaperclipBridgeHelpers.thumbnail_style)
@@ -6,7 +6,7 @@ module ActiveScaffold
6
6
  self.thumbnail_style = :thumbnail
7
7
 
8
8
  def self.generate_delete_helper(klass, field)
9
- klass.class_eval <<-EOF, __FILE__, __LINE__ + 1 unless klass.instance_methods.include?("delete_#{field}=".send(::ActiveScaffold::METHOD_CONVERSION))
9
+ klass.class_eval <<-EOF, __FILE__, __LINE__ + 1 unless klass.instance_methods.include?("delete_#{field}=")
10
10
  attr_reader :delete_#{field}
11
11
 
12
12
  def delete_#{field}=(value)
@@ -114,7 +114,7 @@ module ActiveScaffold
114
114
  unless operator.nil?
115
115
  ["%{search_sql} #{value[:opt]} ?", from_value.to_s(:db)] unless from_value.nil?
116
116
  else
117
- ["%{search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)] unless from_value.nil? || to_value.nil?
117
+ ["%{search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)] unless from_value.nil? && to_value.nil?
118
118
  end
119
119
  end
120
120
  end
@@ -16,7 +16,7 @@ class ActiveScaffold::Bridges::TinyMce
16
16
  options[:class] = "#{options[:class]} mceEditor #{column.options[:class]}".strip
17
17
 
18
18
  settings = { :theme => 'simple' }.merge(column.options[:tinymce] || {})
19
- settings = settings.to_json
19
+ settings = settings.to_s.gsub(/:(.+?)\=\>/, '\1:')
20
20
  settings = "tinyMCE.settings = #{settings};"
21
21
 
22
22
  html = []
@@ -25,6 +25,10 @@ module ActiveScaffold::Config
25
25
  cattr_accessor :theme
26
26
  @@theme = :default
27
27
 
28
+ # enable caching of action link urls
29
+ cattr_accessor :cache_action_link_urls
30
+ @@cache_action_link_urls = true
31
+
28
32
  # lets you disable the DHTML history
29
33
  def self.dhtml_history=(val)
30
34
  @@dhtml_history = val
@@ -91,6 +95,9 @@ module ActiveScaffold::Config
91
95
  # lets you override the global ActiveScaffold theme for a specific controller
92
96
  attr_accessor :theme
93
97
 
98
+ # enable caching of action link urls
99
+ attr_accessor :cache_action_link_urls
100
+
94
101
  # lets you specify whether add a create link for each sti child for a specific controller
95
102
  attr_accessor :sti_create_links
96
103
  def add_sti_create_links?
@@ -139,6 +146,7 @@ module ActiveScaffold::Config
139
146
  # inherit the global frontend
140
147
  @frontend = self.class.frontend
141
148
  @theme = self.class.theme
149
+ @cache_action_link_urls = self.class.cache_action_link_urls
142
150
  @sti_create_links = self.class.sti_create_links
143
151
 
144
152
  # inherit from the global set of action links
@@ -154,8 +162,7 @@ module ActiveScaffold::Config
154
162
  # then, register the column objects
155
163
  self.actions.each do |action_name|
156
164
  action = self.send(action_name)
157
- next unless action.respond_to? :columns
158
- action.columns.set_columns(self.columns)
165
+ action.columns.set_columns(self.columns) if action.respond_to?(:columns)
159
166
  end
160
167
  end
161
168
 
@@ -23,6 +23,7 @@ module ActiveScaffold::Config
23
23
  @wrap_tag = self.class.wrap_tag
24
24
  @always_show_search = self.class.always_show_search
25
25
  @always_show_create = self.class.always_show_create
26
+ @messages_above_header = self.class.messages_above_header
26
27
  end
27
28
 
28
29
  # global level configuration
@@ -39,17 +40,14 @@ module ActiveScaffold::Config
39
40
  cattr_accessor :page_links_outer_window
40
41
  @@page_links_outer_window = 0
41
42
 
42
- class << self
43
- def page_links_window=(value)
44
- ActiveSupport::Deprecation.warn("Use page_links_inner_window", caller(1))
45
- self.page_links_inner_window = value
46
- end
47
- end
48
-
49
43
  # what string to use when a field is empty
50
44
  cattr_accessor :empty_field_text
51
45
  @@empty_field_text = '-'
52
46
 
47
+ # display messages above table header
48
+ cattr_accessor :messages_above_header
49
+ @@messages_above_header = false
50
+
53
51
  # what string to use to join records from plural associations
54
52
  cattr_accessor :association_join_text
55
53
  @@association_join_text = ', '
@@ -67,7 +65,7 @@ module ActiveScaffold::Config
67
65
 
68
66
  # the ActionLink to reset search
69
67
  cattr_reader :reset_link
70
- @@reset_link = ActiveScaffold::DataStructures::ActionLink.new('index', :label => :click_to_reset, :type => :collection, :position => false)
68
+ @@reset_link = ActiveScaffold::DataStructures::ActionLink.new('index', :label => :click_to_reset, :type => :collection, :position => false, :parameters => {:search => ''})
71
69
 
72
70
  # wrap normal cells (not inplace editable columns or with link) with a tag
73
71
  # it allows for more css styling
@@ -102,11 +100,6 @@ module ActiveScaffold::Config
102
100
  # how many page links around current page to show
103
101
  attr_accessor :page_links_outer_window
104
102
 
105
- def page_links_window=(value)
106
- ActiveSupport::Deprecation.warn("Use page_links_inner_window", caller(1))
107
- self.page_links_inner_window = value
108
- end
109
-
110
103
  # What kind of pagination to use:
111
104
  # * true: The usual pagination
112
105
  # * :infinite: Treat the source as having an infinite number of pages (i.e. don't count the records; useful for large tables where counting is slow and we don't really care anyway)
@@ -116,6 +109,9 @@ module ActiveScaffold::Config
116
109
  # what string to use when a field is empty
117
110
  attr_accessor :empty_field_text
118
111
 
112
+ # display messages above table header
113
+ attr_accessor :messages_above_header
114
+
119
115
  # what string to use to join records from plural associations
120
116
  attr_accessor :association_join_text
121
117
 
@@ -6,25 +6,34 @@ module ActiveScaffold::Config
6
6
  super
7
7
  @label = :add_existing_model
8
8
  @shallow_delete = self.class.shallow_delete
9
+ @ignore_order_from_association = self.class.ignore_order_from_association
9
10
  end
10
11
 
11
12
  # global level configuration
12
13
  # --------------------------
13
14
  cattr_accessor :shallow_delete
14
15
  @@shallow_delete = true
16
+
17
+ cattr_accessor :ignore_order_from_association
15
18
 
16
19
  # instance-level configuration
17
20
  # ----------------------------
18
21
  attr_accessor :shallow_delete
22
+
23
+ attr_accessor :ignore_order_from_association
19
24
 
20
25
  # Add a nested ActionLink
21
26
  def add_link(attribute, options = {})
22
27
  column = @core.columns[attribute.to_sym]
23
28
  unless column.nil? || column.association.nil?
24
- options.reverse_merge! :security_method => :nested_authorized?, :label => column.association.klass.model_name.human({:count => column.singular_association? ? 1 : 2, :default => column.association.klass.name.pluralize})
29
+ label = if column.polymorphic_association?
30
+ column.label
31
+ else
32
+ column.association.klass.model_name.human({:count => column.singular_association? ? 1 : 2, :default => column.association.klass.name.pluralize})
33
+ end
34
+ options.reverse_merge! :security_method => :nested_authorized?, :label => label
25
35
  action_group = options.delete(:action_group) || self.action_group
26
36
  action_link = @core.link_for_association(column, options)
27
- action_link.action ||= :index
28
37
  @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
29
38
  else
30
39
  # TODO: raise exception
@@ -16,6 +16,16 @@ module ActiveScaffold::DataStructures
16
16
  @label.to_s.underscore
17
17
  end
18
18
 
19
+ # this is so that array.delete and array.include?, etc., will work by column name
20
+ def ==(other) #:nodoc:
21
+ # another ActionColumns
22
+ if other.class == self.class
23
+ self.label == other.label
24
+ else
25
+ @label.to_s == other.to_s
26
+ end
27
+ end
28
+
19
29
  # Whether this column set is collapsed by default in contexts where collapsing is supported
20
30
  attr_accessor :collapsed
21
31
 
@@ -39,7 +49,7 @@ module ActiveScaffold::DataStructures
39
49
 
40
50
  def names
41
51
  if @columns
42
- self.collect(&:name)
52
+ self.collect_visible(:flatten => true) { |c| c.name }
43
53
  else
44
54
  names_without_auth_check
45
55
  end
@@ -66,8 +76,12 @@ module ActiveScaffold::DataStructures
66
76
  item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
67
77
  next if self.skip_column?(item, options)
68
78
  end
69
- if item.is_a? ActiveScaffold::DataStructures::ActionColumns and options.has_key?(:flatten) and options[:flatten]
70
- item.each(options, &proc)
79
+ if item.is_a? ActiveScaffold::DataStructures::ActionColumns
80
+ if options[:flatten]
81
+ item.each(options, &proc)
82
+ elsif !options[:skip_groups]
83
+ yield item
84
+ end
71
85
  else
72
86
  yield item
73
87
  end
@@ -84,9 +98,9 @@ module ActiveScaffold::DataStructures
84
98
  next if self.skip_column?(item, options)
85
99
  end
86
100
  if item.is_a? ActiveScaffold::DataStructures::ActionColumns and options.has_key?(:flatten) and options[:flatten]
87
- columns = columns + item.collect(options, &proc)
101
+ columns += item.collect_visible(options, &proc)
88
102
  else
89
- columns << item
103
+ columns << (block_given? ? yield(item) : item)
90
104
  end
91
105
  end
92
106
  columns
@@ -172,13 +172,20 @@ module ActiveScaffold::DataStructures
172
172
  # nested action_links are referencing a column
173
173
  attr_accessor :column
174
174
 
175
+ # don't close the panel when another action link is open
176
+ attr_writer :keep_open
177
+ def keep_open?
178
+ @keep_open
179
+ end
180
+
175
181
  # indicates that this a nested_link
176
182
  def nested_link?
177
183
  @column || (parameters && parameters[:named_scope])
178
184
  end
179
185
 
180
- # Internal use: generated eid for this action_link
181
- attr_accessor :eid
186
+ def name_to_cache_link_url
187
+ @name_to_cache_link_url ||= :"#{controller || 'self'}_#{action}#{'_' if parameters.present?}#{parameters.map{|k,v| "#{k}_#{v}"}.join('_')}_link_url"
188
+ end
182
189
 
183
190
 
184
191
  end
@@ -88,8 +88,9 @@ module ActiveScaffold::DataStructures
88
88
 
89
89
  # iterates over the links, possibly by type
90
90
  def each(options = {}, &block)
91
- @set.each {|item|
92
- if item.is_a?(ActiveScaffold::DataStructures::ActionLinks)
91
+ method = options[:reverse] ? :reverse_each : :each
92
+ @set.send(method) do |item|
93
+ if item.is_a?(ActiveScaffold::DataStructures::ActionLinks) && !options[:groups]
93
94
  item.each(options, &block)
94
95
  else
95
96
  if options[:include_set]
@@ -98,7 +99,7 @@ module ActiveScaffold::DataStructures
98
99
  yield item
99
100
  end
100
101
  end
101
- }
102
+ end
102
103
  end
103
104
 
104
105
  def collect_by_type(type = nil)
@@ -107,34 +108,6 @@ module ActiveScaffold::DataStructures
107
108
  links
108
109
  end
109
110
 
110
- def traverse(controller, options = {}, &block)
111
- traverse_method = options.delete(:reverse).nil? ? :each : :reverse_each
112
- options[:level] ||= -1
113
- options[:level] += 1
114
- first_action = true
115
- @set.send(traverse_method) do |link|
116
- if link.is_a?(ActiveScaffold::DataStructures::ActionLinks)
117
- unless link.empty?
118
- yield(link, nil, {:node => :start_traversing, :first_action => first_action, :level => options[:level]})
119
- link.traverse(controller,options, &block)
120
- yield(link, nil, {:node => :finished_traversing, :first_action => first_action, :level => options[:level]})
121
- first_action = false
122
- end
123
- elsif controller.nil? || !skip_action_link(controller, link, *(Array(options[:for])))
124
- security_method = link.security_method_set? || controller.respond_to?(link.security_method)
125
- authorized = if security_method
126
- controller.send(link.security_method, *(Array(options[:for])))
127
- else
128
- options[:for].nil? ? true : options[:for].authorized_for?(:crud_type => link.crud_type, :action => link.action)
129
- end
130
- next unless authorized || link.type == :member
131
- yield(self, link, {:authorized => authorized, :first_action => first_action, :level => options[:level]})
132
- first_action = false
133
- end
134
- end
135
- options[:level] -= 1
136
- end
137
-
138
111
  def collect
139
112
  @set
140
113
  end
@@ -178,14 +151,10 @@ module ActiveScaffold::DataStructures
178
151
 
179
152
  protected
180
153
 
181
- def skip_action_link(controller, link, *args)
182
- !link.ignore_method.nil? && controller.respond_to?(link.ignore_method) && controller.send(link.ignore_method, *args)
183
- end
184
-
185
154
  # called during clone or dup. makes the clone/dup deeper.
186
155
  def initialize_copy(from)
187
156
  @set = []
188
157
  from.instance_variable_get('@set').each { |link| @set << link.clone }
189
158
  end
190
159
  end
191
- end
160
+ end