active_scaffold 4.2.3 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.rdoc +16 -1
  3. data/README.md +108 -7
  4. data/app/assets/javascripts/{jquery → active_scaffold}/active_scaffold.js +759 -762
  5. data/app/assets/javascripts/{jquery/date_picker_bridge.js.erb → active_scaffold/date_picker_bridge.js} +0 -3
  6. data/app/assets/javascripts/active_scaffold/load.js +102 -0
  7. data/app/assets/javascripts/active_scaffold.js.erb +3 -27
  8. data/app/assets/stylesheets/active_scaffold/_colours.scss +330 -0
  9. data/app/assets/stylesheets/active_scaffold/_images.scss +65 -0
  10. data/app/assets/stylesheets/{active_scaffold_layout.scss → active_scaffold/_layout.scss} +14 -0
  11. data/app/assets/stylesheets/active_scaffold/_variables.scss +194 -0
  12. data/app/assets/stylesheets/active_scaffold/core.scss +15 -0
  13. data/app/assets/stylesheets/active_scaffold.scss.erb +16 -0
  14. data/app/views/active_scaffold_overrides/_field_search_columns.html.erb +8 -0
  15. data/app/views/active_scaffold_overrides/_form.html.erb +8 -0
  16. data/app/views/active_scaffold_overrides/_form_association.html.erb +3 -1
  17. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +4 -2
  18. data/app/views/active_scaffold_overrides/_show_association.html.erb +2 -1
  19. data/app/views/active_scaffold_overrides/_show_association_horizontal.html.erb +2 -2
  20. data/app/views/active_scaffold_overrides/_show_association_vertical.html.erb +1 -1
  21. data/app/views/active_scaffold_overrides/edit_associated.js.erb +10 -8
  22. data/lib/active_scaffold/actions/core.rb +34 -3
  23. data/lib/active_scaffold/assets/css_deps_generator.rb +42 -0
  24. data/lib/active_scaffold/assets/jquery_ui_manifest.rb +77 -0
  25. data/lib/active_scaffold/assets/jquery_ui_theme_generator.rb +102 -0
  26. data/lib/active_scaffold/assets.rb +109 -0
  27. data/lib/active_scaffold/attribute_params.rb +11 -2
  28. data/lib/active_scaffold/bridges/active_storage/form_ui.rb +1 -1
  29. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +1 -1
  30. data/lib/active_scaffold/bridges/chosen.rb +1 -1
  31. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +1 -1
  32. data/lib/active_scaffold/bridges/file_column/form_ui.rb +1 -1
  33. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +1 -1
  34. data/lib/active_scaffold/bridges/record_select/helpers.rb +1 -1
  35. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +1 -0
  36. data/lib/active_scaffold/bridges/tiny_mce.rb +6 -1
  37. data/lib/active_scaffold/bridges.rb +7 -0
  38. data/lib/active_scaffold/config/core.rb +7 -3
  39. data/lib/active_scaffold/constraints.rb +1 -1
  40. data/lib/active_scaffold/data_structures/action_columns.rb +66 -0
  41. data/lib/active_scaffold/data_structures/bridge.rb +2 -0
  42. data/lib/active_scaffold/data_structures/column.rb +3 -0
  43. data/lib/active_scaffold/engine.rb +40 -0
  44. data/lib/active_scaffold/finder.rb +1 -1
  45. data/lib/active_scaffold/helpers/assets_helpers.rb +39 -0
  46. data/lib/active_scaffold/helpers/controller_helpers.rb +1 -1
  47. data/lib/active_scaffold/helpers/form_column_helpers.rb +57 -532
  48. data/lib/active_scaffold/helpers/form_ui_helpers.rb +530 -0
  49. data/lib/active_scaffold/helpers/human_condition_helpers.rb +1 -0
  50. data/lib/active_scaffold/helpers/list_column_helpers.rb +31 -11
  51. data/lib/active_scaffold/helpers/search_column_helpers.rb +5 -12
  52. data/lib/active_scaffold/helpers/show_column_helpers.rb +4 -2
  53. data/lib/active_scaffold/helpers/view_helpers.rb +12 -0
  54. data/lib/active_scaffold/railties/tasks.rake +10 -0
  55. data/lib/active_scaffold/testing/assert_embedded_load.rb +33 -0
  56. data/lib/active_scaffold/version.rb +2 -2
  57. data/lib/active_scaffold.rb +7 -2
  58. data/lib/tasks/active_scaffold/assets.rake +42 -0
  59. data/lib/tasks/bundle.rake +25 -0
  60. data/vendor/assets/stylesheets/{jquery-ui-theme.css.erb → jquery-ui-theme.css} +17 -17
  61. metadata +26 -28
  62. data/app/assets/stylesheets/active_scaffold.scss +0 -424
  63. data/app/assets/stylesheets/active_scaffold_extensions.css.erb +0 -2
  64. data/app/assets/stylesheets/active_scaffold_images.scss +0 -65
  65. data/app/assets/stylesheets/active_scaffold_jquery_ui.css.erb +0 -13
  66. /data/app/assets/javascripts/{jquery → active_scaffold}/active_scaffold_chosen.js +0 -0
  67. /data/app/assets/javascripts/{jquery → active_scaffold}/draggable_lists.js +0 -0
  68. /data/app/assets/javascripts/{jquery → active_scaffold}/jquery.editinplace.js +0 -0
  69. /data/app/assets/javascripts/{jquery → active_scaffold}/tiny_mce_bridge.js +0 -0
@@ -0,0 +1,194 @@
1
+ // ==============================================================
2
+ // ACTIVE SCAFFOLD VARIABLES
3
+ // ==============================================================
4
+ // These are Sass variables for legacy support.
5
+ // CSS variables are defined below and are the recommended way
6
+ // to customize ActiveScaffold going forward.
7
+ // ==============================================================
8
+
9
+ // Base Colors
10
+ $disabled_color: #999 !default;
11
+ $actions_disabled_color: #666 !default;
12
+ $link_color: #06c !default;
13
+ $hover_bg: #ff8 !default;
14
+ $header_color: #555 !default;
15
+
16
+ // Column Headers
17
+ $column_header_bg: $header_color !default;
18
+ $column_header_link_color: #fff !default;
19
+ $column_header_link_hover_bg: #000 !default;
20
+ $column_header_link_hover_color: #ff8 !default;
21
+ $column_header_color: #eee !default;
22
+ $column_header_sorted_bg: #333 !default;
23
+
24
+ // Columns
25
+ $column_bg: #E6F2FF !default;
26
+ $column_even_bg: #fff !default;
27
+ $column_color: #333 !default;
28
+ $column_empty_color: #999 !default;
29
+ $column_border_color: #C5DBF7 !default;
30
+ $column_even_border_color: #ddd !default;
31
+ $column_actions_border_color: #ccc !default;
32
+ $vertical_sub_form_border_color: $column_actions_border_color !default;
33
+
34
+ // Sorted Columns
35
+ $column_sorted_bg: #B9DCFF !default;
36
+ $column_sorted_border_color: #AFD0F5 !default;
37
+ $column_even_sorted_bg: #E6F2FF !default;
38
+ $column_even_sorted_border_color: #AFD0F5 !default;
39
+
40
+ // Calculations
41
+ $calculations_bg: #eee !default;
42
+ $calculations_border_color: #005CB8 !default;
43
+
44
+ // Action Groups
45
+ $action_group_color: #0066CC !default;
46
+ $action_group_hover_bg: #ff8 !default;
47
+ $action_group_border_color: #005CB8 !default;
48
+ $action_group_items_bg: #EEE !default;
49
+ $action_group_items_border_color: #222 !default;
50
+ $action_group_link_color: $column_color !default;
51
+ $active_filter: $link_color !default;
52
+
53
+ // Nested Levels
54
+ $nested_bg: #DAFFCD !default;
55
+ $nested_border_color: #7FCF00 !default;
56
+ $nested_footer_color: #444 !default;
57
+ $nested_column_bg: #ECFFE7 !default;
58
+ $nested_column_even_bg: #fff !default;
59
+ $nested_column_border_color: $column_border_color !default;
60
+
61
+ $second_nested_bg: #FFFFBB !default;
62
+ $second_nested_border_color: #DDDF37 !default;
63
+
64
+ $third_nested_bg: $nested_bg !default;
65
+ $third_nested_border_color: $nested_border_color !default;
66
+
67
+ // Pagination
68
+ $pagination_border_color: #ccc !default;
69
+
70
+ // Messages
71
+ $msg_color: #333 !default;
72
+ $msg_error_bg: #fbb !default;
73
+ $msg_error_border_color: #f66 !default;
74
+ $msg_warning_bg: #ffb !default;
75
+ $msg_warning_border_color: #ff6 !default;
76
+ $msg_info_bg: #bbf !default;
77
+ $msg_info_border_color: #66f !default;
78
+ $msg_filtered_bg: #e8e8e8 !default;
79
+ $msg_filtered_color: #666 !default;
80
+
81
+ // Forms
82
+ $form_title_color: #1F7F00 !default;
83
+ $label_color: $header_color !default;
84
+ $description_color: #999 !default;
85
+ $placeholder_color: #aaa !default;
86
+ $input_border_color: $form_title_color !default;
87
+ $input_error_border_color: #f00 !default;
88
+ $input_focus_bg: #ffc !default;
89
+
90
+ // Draggable Lists
91
+ $draggable_list_bg: #FFFF88 !default;
92
+ $draggable_list_selected_bg: #7FCF00 !default;
93
+ $draggable_list_disabled_bg: $disabled_color !default;
94
+ $checkbox_list_bg: #fff !default;
95
+
96
+ // Subforms
97
+ $subform_color: #999 !default;
98
+ $subform_header_color: $header_color !default;
99
+ $subform_footer_color: $subform_color !default;
100
+
101
+ // ==============================================================
102
+ // CSS VARIABLES (Recommended for customization)
103
+ // ==============================================================
104
+ :root {
105
+ // Base Colors
106
+ --as-disabled-color: #{$disabled_color};
107
+ --as-actions-disabled-color: #{$actions_disabled_color};
108
+ --as-link-color: #{$link_color};
109
+ --as-hover-bg: #{$hover_bg};
110
+ --as-header-color: #{$header_color};
111
+
112
+ // Column Headers
113
+ --as-column-header-bg: #{$column_header_bg};
114
+ --as-column-header-link-color: #{$column_header_link_color};
115
+ --as-column-header-link-hover-bg: #{$column_header_link_hover_bg};
116
+ --as-column-header-link-hover-color: #{$column_header_link_hover_color};
117
+ --as-column-header-color: #{$column_header_color};
118
+ --as-column-header-sorted-bg: #{$column_header_sorted_bg};
119
+
120
+ // Columns
121
+ --as-column-bg: #{$column_bg};
122
+ --as-column-even-bg: #{$column_even_bg};
123
+ --as-column-color: #{$column_color};
124
+ --as-column-empty-color: #{$column_empty_color};
125
+ --as-column-border-color: #{$column_border_color};
126
+ --as-column-even-border-color: #{$column_even_border_color};
127
+ --as-column-actions-border-color: #{$column_actions_border_color};
128
+
129
+ // Sorted Columns
130
+ --as-column-sorted-bg: #{$column_sorted_bg};
131
+ --as-column-sorted-border-color: #{$column_sorted_border_color};
132
+ --as-column-even-sorted-bg: #{$column_even_sorted_bg};
133
+ --as-column-even-sorted-border-color: #{$column_even_sorted_border_color};
134
+
135
+ // Calculations
136
+ --as-calculations-bg: #{$calculations_bg};
137
+ --as-calculations-border-color: #{$calculations_border_color};
138
+
139
+ // Action Groups
140
+ --as-action-group-color: #{$action_group_color};
141
+ --as-action-group-hover-bg: #{$action_group_hover_bg};
142
+ --as-action-group-border-color: #{$action_group_border_color};
143
+ --as-action-group-items-bg: #{$action_group_items_bg};
144
+ --as-action-group-items-border-color: #{$action_group_items_border_color};
145
+ --as-action-group-link-color: #{$action_group_link_color};
146
+ --as-active-filter: #{$active_filter};
147
+
148
+ // Nested Levels
149
+ --as-nested-bg: #{$nested_bg};
150
+ --as-nested-border-color: #{$nested_border_color};
151
+ --as-nested-footer-color: #{$nested_footer_color};
152
+ --as-nested-column-bg: #{$nested_column_bg};
153
+ --as-nested-column-even-bg: #{$nested_column_even_bg};
154
+ --as-nested-column-border-color: #{$nested_column_border_color};
155
+ --as-second-nested-bg: #{$second_nested_bg};
156
+ --as-second-nested-border-color: #{$second_nested_border_color};
157
+ --as-third-nested-bg: #{$third_nested_bg};
158
+ --as-third-nested-border-color: #{$third_nested_border_color};
159
+
160
+ // Pagination
161
+ --as-pagination-border-color: #{$pagination_border_color};
162
+
163
+ // Messages
164
+ --as-msg-color: #{$msg_color};
165
+ --as-msg-error-bg: #{$msg_error_bg};
166
+ --as-msg-error-border-color: #{$msg_error_border_color};
167
+ --as-msg-warning-bg: #{$msg_warning_bg};
168
+ --as-msg-warning-border-color: #{$msg_warning_border_color};
169
+ --as-msg-info-bg: #{$msg_info_bg};
170
+ --as-msg-info-border-color: #{$msg_info_border_color};
171
+ --as-msg-filtered-bg: #{$msg_filtered_bg};
172
+ --as-msg-filtered-color: #{$msg_filtered_color};
173
+
174
+ // Forms
175
+ --as-form-title-color: #{$form_title_color};
176
+ --as-label-color: #{$label_color};
177
+ --as-description-color: #{$description_color};
178
+ --as-placeholder-color: #{$placeholder_color};
179
+ --as-input-border-color: #{$input_border_color};
180
+ --as-input-error-border-color: #{$input_error_border_color};
181
+ --as-input-focus-bg: #{$input_focus_bg};
182
+
183
+ // Draggable Lists
184
+ --as-draggable-list-bg: #{$draggable_list_bg};
185
+ --as-draggable-list-selected-bg: #{$draggable_list_selected_bg};
186
+ --as-draggable-list-disabled-bg: #{$draggable_list_disabled_bg};
187
+ --as-checkbox-list-bg: #{$checkbox_list_bg};
188
+
189
+ // Subforms
190
+ --as-subform-color: #{$subform_color};
191
+ --as-subform-header-color: #{$subform_header_color};
192
+ --as-subform-footer-color: #{$subform_footer_color};
193
+ --as-vertical-sub-form-border-color: #{$vertical_sub_form_border_color};
194
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ ActiveScaffold
3
+ (c) 2007 Richard White <rrwhite@gmail.com>
4
+
5
+ ActiveScaffold is freely distributable under the terms of an MIT-style license.
6
+
7
+ For details, see the ActiveScaffold web site: https://github.com/activescaffold/active_scaffold
8
+ */
9
+
10
+ @forward 'variables';
11
+ @use 'layout';
12
+ @use 'images';
13
+ @use 'colours';
14
+ @use 'active_scaffold/deps';
15
+ .ui-front { z-index: 98; }
@@ -0,0 +1,16 @@
1
+ /*
2
+ ActiveScaffold
3
+ (c) 2007 Richard White <rrwhite@gmail.com>
4
+
5
+ ActiveScaffold is freely distributable under the terms of an MIT-style license.
6
+
7
+ For details, see the ActiveScaffold web site: https://github.com/activescaffold/active_scaffold
8
+ */
9
+
10
+ @use 'active_scaffold/layout';
11
+ @use 'active_scaffold/images';
12
+ @use 'active_scaffold/colours';
13
+
14
+ <%= File.read(File.join(ActiveScaffold.root, 'app/assets/stylesheets/active_scaffold/_variables.scss')) %>
15
+ <% ActiveScaffold::Assets.active_scaffold_stylesheets(:deps).each { |asset| require_asset asset } %>
16
+ .ui-front { z-index: 98; }
@@ -1,3 +1,10 @@
1
+ <% if columns.layout == :multiple -%>
2
+ <div class="form-columns"<%= " id=#{subsection_id}" if local_assigns.key? :subsection_id %><%= ' style="display: none;"'.html_safe if columns.collapsed %>>
3
+ <% columns.each do |group| %>
4
+ <%= render 'field_search_columns', local_assigns.merge(columns: group, subsection_id: nil) %>
5
+ <% end %>
6
+ </div>
7
+ <% else -%>
1
8
  <ol class="form" <%= "id=#{subsection_id}" unless local_assigns[:subsection_id].nil? %> <%= 'style="display: none;"'.html_safe if columns.collapsed %>>
2
9
  <% visibles, hiddens = visibles_and_hiddens(active_scaffold_config.field_search, columns) %>
3
10
  <% visibles.each do |column| -%>
@@ -30,3 +37,4 @@
30
37
  </li>
31
38
  <% end -%>
32
39
  </ol>
40
+ <% end -%>
@@ -1,3 +1,10 @@
1
+ <% if columns.layout == :multiple %>
2
+ <div class="form-columns"<%= " id=#{subsection_id}" if local_assigns.key? :subsection_id %><%= ' style="display: none;"'.html_safe if columns.collapsed %>>
3
+ <% columns.each do |group| %>
4
+ <%= render 'form', local_assigns.merge(columns: group, subsection_id: nil) %>
5
+ <% end %>
6
+ </div>
7
+ <% else %>
1
8
  <%
2
9
  scope ||= nil
3
10
  subsection_id ||= nil
@@ -37,3 +44,4 @@
37
44
  <% end -%>
38
45
  <% end -%>
39
46
  </ol>
47
+ <% end %>
@@ -19,6 +19,8 @@
19
19
  parent_record: parent_record, column: column, associated: associated, scope: scope, subform_div_id: subform_div_id,
20
20
  tabbed_by: tabbed_by, tab_value: tab_value
21
21
  })
22
+ columns = (column.form_ui_options || column.options)[:subform_columns]
23
+ columns = active_scaffold_config_for(column.association.klass).subform.build_action_columns(columns) if columns
22
24
  -%>
23
25
  <h5>
24
26
  <%= column.label -%>
@@ -28,7 +30,7 @@
28
30
  <div id ="<%= subform_div_id %>" <%= 'style="display: none;"'.html_safe if column.collapsed -%>>
29
31
  <%# HACK: to be able to delete all associated records %>
30
32
  <%= hidden_field_tag "#{(opts = active_scaffold_input_options(column, scope, object: parent_record))[:name]}[0]", '', id: "#{opts[:id]}_0" if column.association.collection? %>
31
- <%= render subform_partial_for_column(column), column: column, parent_record: parent_record, associated: associated, show_blank_record: show_blank_record, scope: scope, tab_id: tab_id %>
33
+ <%= render subform_partial_for_column(column), column: column, parent_record: parent_record, columns: columns, associated: associated, show_blank_record: show_blank_record, scope: scope, tab_id: tab_id %>
32
34
  <%= footer -%>
33
35
  </div>
34
36
  <%
@@ -1,15 +1,17 @@
1
1
  <%
2
2
  record_column = column
3
+ ui_options = record_column.form_ui_options || record_column.options
3
4
  readonly = record.readonly? || !record.authorized_for?(crud_type: :update)
4
5
  crud_type = record.new_record? ? :create : (readonly ? :read : :update)
5
6
  show_actions = false
6
7
  locked ||= false
7
8
  config = active_scaffold_config_for(record.class)
8
9
  columns ||= config.subform.columns
10
+ column_names = columns.visible_columns_names
9
11
  scope = column_scope(record_column, scope, record)
10
12
  options = active_scaffold_input_options(config.columns[record.class.primary_key], scope, object: record)
11
13
  tr_id = "association-#{options[:id]}"
12
- layout ||= column.options[:layout] || config.subform.layout
14
+ layout ||= ui_options[:layout] || config.subform.layout
13
15
 
14
16
  if layout == :vertical
15
17
  record_tag ||= :div
@@ -58,7 +60,7 @@
58
60
  col_class << 'hidden' if column_renders_as(column) == :hidden
59
61
  -%>
60
62
  <%= content_tag column_tag, class: col_class.join(' ') do %>
61
- <%= active_scaffold_render_subform_column(column, scope, crud_type, readonly, false, record) %>
63
+ <%= active_scaffold_render_subform_column(column, scope, crud_type, readonly, false, record, form_columns: column_names) %>
62
64
  <% end %>
63
65
  <% end -%>
64
66
  <% if show_actions -%>
@@ -1,3 +1,4 @@
1
+ <% columns = active_scaffold_config_for(column.association.klass).show.build_action_columns(columns) if local_assigns[:columns].is_a?(Array) %>
1
2
  <% associated = column.association.singular? ? [parent_record.send(column.name)].compact : parent_record.send(column.name).to_a -%>
2
3
  <% associated = associated.select { |record| record.send(tabbed_by) == tab_value } if local_assigns[:tabbed_by] %>
3
- <%= render "show_association_#{show_partial}", column: column, parent_record: parent_record, associated: associated if associated.present? %>
4
+ <%= render "show_association_#{show_partial}", columns: columns, column: column, parent_record: parent_record, associated: associated if associated.present? %>
@@ -1,6 +1,6 @@
1
1
  <%
2
2
  columns_hash = {}
3
- heading_columns = show_columns_for(associated.first, column, columns_hash)
3
+ heading_columns = columns || show_columns_for(associated.first, column, columns_hash)
4
4
  %>
5
5
  <table>
6
6
  <thead>
@@ -12,7 +12,7 @@
12
12
  </thead>
13
13
  <tbody>
14
14
  <% associated.each do |record| -%>
15
- <%= render 'show_horizontal_record', record: record, parent_record: parent_record, columns: show_columns_for(associated.first, column, columns_hash) %>
15
+ <%= render 'show_horizontal_record', record: record, parent_record: parent_record, columns: columns || show_columns_for(associated.first, column, columns_hash) %>
16
16
  <% end -%>
17
17
  </tbody>
18
18
  </table>
@@ -1,4 +1,4 @@
1
1
  <% columns_hash = {} -%>
2
2
  <% associated.each do |record| -%>
3
- <%= render 'show_columns', columns: show_columns_for(record, column, columns_hash), record: record %>
3
+ <%= render 'show_columns', columns: columns || show_columns_for(record, column, columns_hash), record: record %>
4
4
  <% end -%>
@@ -1,13 +1,15 @@
1
1
  <%
2
+ columns = (@column.form_ui_options || @column.options)[:subform_columns]
3
+ columns = active_scaffold_config_for(@column.association.klass).subform.build_action_columns(columns) if columns
2
4
  subform_id = sub_form_list_id(association: @column.name, tab_id: @tab_id, id: @parent_record.id || generated_id(@parent_record) || 99_999_999_999)
3
- associated_form = render 'form_association_record', scope: @scope, parent_record: @parent_record, column: @column, record: @record, locked: @record.new_record? && @column.association.singular?
5
+ associated_form = render 'form_association_record', columns: columns, scope: @scope, parent_record: @parent_record,
6
+ column: @column, record: @record, locked: @record.new_record? && @column.association.singular?
4
7
  options = {singular: false}
5
8
  if @column.association.singular?
6
9
  options[:singular] = true
7
- else
8
- unless @record.new_record?
9
- column = active_scaffold_config_for(@record.class).columns[@record.class.primary_key]
10
- options[:id] = active_scaffold_input_options(column, column_scope(@column, @scope, @record))[:id]
11
- end
12
- end %>
13
- ActiveScaffold.create_associated_record_form('<%= subform_id %>','<%=escape_javascript(associated_form)%>', <%= options.to_json.html_safe %>);
10
+ elsif @record.persisted?
11
+ column = active_scaffold_config_for(@record.class).columns[@record.class.primary_key]
12
+ options[:id] = active_scaffold_input_options(column, column_scope(@column, @scope, @record))[:id]
13
+ end
14
+ %>
15
+ ActiveScaffold.create_associated_record_form('<%= subform_id %>', '<%= escape_javascript(associated_form) %>', <%= options.to_json.html_safe %>);
@@ -80,7 +80,10 @@ module ActiveScaffold::Actions
80
80
  @form_action = params.delete(:form_action).to_sym
81
81
  end
82
82
  @form_action ||= params[:id] ? :update : :create
83
- @main_columns = active_scaffold_config.send(@form_action).columns
83
+ parent_column = parent_column(main_form_controller, @scope) if @scope && main_form_controller
84
+ subform_columns = (parent_column.form_ui_options || parent_column.options)&.dig(:subform_columns) if parent_column
85
+ action_cfg = active_scaffold_config.send(@form_action)
86
+ @main_columns = subform_columns ? action_cfg.build_action_columns(subform_columns) : action_cfg.columns
84
87
  end
85
88
 
86
89
  def render_field_for_update_columns
@@ -90,7 +93,7 @@ module ActiveScaffold::Actions
90
93
  @columns += [@column.name] if @column.options[:refresh_link] && @columns.exclude?(@column.name)
91
94
  process_render_field_params
92
95
 
93
- @record = find_from_scope(setup_parent, @scope) if main_form_controller && @scope
96
+ @record = find_from_scope(setup_parent, @scope) if @scope && main_form_controller
94
97
  if @column.send_form_on_update_column
95
98
  @record ||= updated_record_with_form(@main_columns, params[:record] || params[:search], @scope)
96
99
  elsif @record
@@ -180,6 +183,34 @@ module ActiveScaffold::Actions
180
183
  copy_attributes(saved_record, record).tap { |new_record| new_record.id = id }
181
184
  end
182
185
 
186
+ def parent_column(parent_controller, scope)
187
+ attrs = params[:record]
188
+ parts = scope[1..-2].split('][')
189
+ columns = parent_controller.active_scaffold_config.columns
190
+ column = nil
191
+
192
+ while parts.present?
193
+ column = columns[parts.shift]
194
+ return unless column&.association
195
+ break if parts.blank?
196
+
197
+ klass =
198
+ if column.association.polymorphic? && attrs
199
+ record = column.active_record_class.new(column.association.foreign_type => attrs[column.association.foreign_type])
200
+ column.association.klass(record)
201
+ else
202
+ column.association.klass
203
+ end
204
+ return unless klass
205
+
206
+ columns = active_scaffold_config_for(klass).columns
207
+ attrs = attrs&.dig(column.name)
208
+ attrs = attrs&.dig(parts.shift) if column.association.collection?
209
+ end
210
+
211
+ column
212
+ end
213
+
183
214
  def find_from_scope(parent, scope)
184
215
  parts = scope[1..-2].split('][')
185
216
  record = parent
@@ -189,7 +220,7 @@ module ActiveScaffold::Actions
189
220
  return unless record.respond_to?(part)
190
221
 
191
222
  association = record.class.reflect_on_association(part)
192
- id = parts.shift.to_i if association&.collection?
223
+ id = association&.collection? ? parts.shift.to_i : nil
193
224
  record = record.send(part)
194
225
  if id
195
226
  record = record.find { |child| child.id == id }
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveScaffold
4
+ module Assets
5
+ class CssDepsGenerator
6
+ class << self
7
+ def generate!
8
+ generator = new
9
+ generator.generate!
10
+ end
11
+ end
12
+
13
+ def initialize
14
+ @css_path = Rails.root.join('app/assets/stylesheets/active_scaffold/deps.scss')
15
+ end
16
+
17
+ def generate!
18
+ Rails.logger.info 'ActiveScaffold: Generating deps.css...'
19
+ perform_generation
20
+ end
21
+
22
+ private
23
+
24
+ def perform_generation
25
+ content = ActiveScaffold::Assets.active_scaffold_stylesheets(:deps).map do |sheet|
26
+ "@use '#{sheet}';\n"
27
+ end
28
+ content.unshift("/* File autogenerated by ActiveScaffold, don't modify it */\n\n")
29
+
30
+ # Ensure directory exists
31
+ FileUtils.mkdir_p(File.dirname(@css_path))
32
+
33
+ # Write the processed file
34
+ File.write(@css_path, content.join)
35
+
36
+ Rails.logger.info "✅ ActiveScaffold: deps.css generated at #{@css_path}"
37
+ rescue StandardError => e
38
+ Rails.logger.error "ActiveScaffold: Failed to generate deps.css: #{e.message}"
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveScaffold
4
+ module Assets
5
+ module JqueryUiManifest
6
+ # Full list of jQuery UI dependencies based on jquery-ui-rails structure
7
+ CORE_FILES = [
8
+ ('jquery-ui/core' unless Jquery::Ui::Rails::VERSION >= '8.0.0'),
9
+ 'jquery-ui/version',
10
+ 'jquery-ui/keycode',
11
+ 'jquery-ui/scroll-parent',
12
+ 'jquery-ui/unique-id',
13
+ 'jquery-ui/widget',
14
+ 'jquery-ui/widgets/mouse',
15
+ 'jquery-ui/plugin',
16
+ ('jquery-ui/safe-active-element' unless Jquery::Ui::Rails::VERSION >= '8.0.0'),
17
+ ('jquery-ui/safe-blur' unless Jquery::Ui::Rails::VERSION >= '8.0.0'),
18
+ 'jquery-ui/data',
19
+ 'jquery-ui/disable-selection',
20
+ 'jquery-ui/focusable',
21
+ ('jquery-ui/form' unless Jquery::Ui::Rails::VERSION >= '8.0.0'),
22
+ ('jquery-ui/ie' unless Jquery::Ui::Rails::VERSION >= '8.0.0'),
23
+ 'jquery-ui/labels',
24
+ "jquery-ui/jquery-#{Jquery::Ui::Rails::VERSION >= '7.0.0' ? 'patch' : '1-7'}",
25
+ ('jquery-ui/escape-selector' unless Jquery::Ui::Rails::VERSION >= '7.0.0'),
26
+ 'jquery-ui/tabbable'
27
+ ].compact.freeze
28
+
29
+ WIDGET_FILES = {
30
+ sortable: [
31
+ 'jquery-ui/widgets/sortable'
32
+ ],
33
+ draggable: [
34
+ 'jquery-ui/widgets/draggable'
35
+ ],
36
+ droppable: [
37
+ 'jquery-ui/widgets/droppable'
38
+ ],
39
+ datepicker: [
40
+ 'jquery-ui/widgets/datepicker'
41
+ ]
42
+ # dialog: [
43
+ # 'jquery-ui/position',
44
+ # 'jquery-ui/form-reset-mixin',
45
+ # 'jquery-ui/widgets/controlgroup',
46
+ # 'jquery-ui/widgets/checkboxradio',
47
+ # 'jquery-ui/widgets/button',
48
+ # 'jquery-ui/widgets/resizable',
49
+ # 'jquery-ui/widgets/dialog'
50
+ # ]
51
+ }.freeze
52
+
53
+ EFFECT_FILES = {
54
+ core: [
55
+ ('jquery-ui/jquery-var-for-color' if Jquery::Ui::Rails::VERSION >= '7.0.0'),
56
+ ('jquery-ui/vendor/jquery-color/jquery.color' if Jquery::Ui::Rails::VERSION >= '7.0.0'),
57
+ 'jquery-ui/effect'
58
+ ].compact,
59
+ highlight: ['jquery-ui/effects/effect-highlight']
60
+ }.freeze
61
+
62
+ def self.all_dependencies
63
+ (CORE_FILES +
64
+ WIDGET_FILES.values.flatten +
65
+ EFFECT_FILES.values.flatten).uniq
66
+ end
67
+
68
+ def self.widget_dependencies(widgets)
69
+ deps = CORE_FILES.dup
70
+ Array(widgets).each do |widget|
71
+ deps += WIDGET_FILES[widget.to_sym] if WIDGET_FILES[widget.to_sym]
72
+ end
73
+ deps
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveScaffold
4
+ module Assets
5
+ class JqueryUiThemeGenerator
6
+ class << self
7
+ def generate_if_needed
8
+ return unless jquery_ui_installed?
9
+
10
+ generator = new
11
+ generator.generate_if_needed
12
+ end
13
+
14
+ def generate!(force: false)
15
+ return unless jquery_ui_installed?
16
+
17
+ generator = new
18
+ generator.generate!(force: force)
19
+ end
20
+
21
+ def needs_generation?
22
+ return false unless jquery_ui_installed?
23
+
24
+ generator = new
25
+ generator.needs_generation?
26
+ end
27
+
28
+ private
29
+
30
+ def jquery_ui_installed?
31
+ Gem.loaded_specs['jquery-ui-rails'].present?
32
+ end
33
+ end
34
+
35
+ def initialize
36
+ @jquery_ui_spec = Gem.loaded_specs['jquery-ui-rails']
37
+ @source_path = File.join(@jquery_ui_spec.full_gem_path, 'app/assets/stylesheets/jquery-ui/theme.css.erb')
38
+ @theme_path = Rails.root.join('app/assets/stylesheets/active_scaffold/jquery-ui/theme.css')
39
+ end
40
+
41
+ def generate_if_needed
42
+ return unless source_exists?
43
+
44
+ generate! if needs_generation?
45
+ end
46
+
47
+ def generate!(force: false)
48
+ return unless source_exists?
49
+
50
+ if force || needs_generation?
51
+ Rails.logger.info 'ActiveScaffold: Generating jQuery UI theme...'
52
+ perform_generation
53
+ true
54
+ else
55
+ false
56
+ end
57
+ end
58
+
59
+ def needs_generation?
60
+ return true unless File.exist?(@theme_path)
61
+ return true if source_newer_than_generated?
62
+
63
+ false
64
+ end
65
+
66
+ def source_exists?
67
+ File.exist?(@source_path)
68
+ end
69
+
70
+ private
71
+
72
+ def source_newer_than_generated?
73
+ source_mtime = File.mtime(@source_path)
74
+ theme_mtime = File.mtime(@theme_path)
75
+ source_mtime > theme_mtime
76
+ end
77
+
78
+ def perform_generation
79
+ # Read and process the ERB
80
+ theme_content = File.read(@source_path)
81
+
82
+ # Process asset_path calls
83
+ processed = theme_content.gsub(/<%= image_path\(['"]([^'"]+)['"]\) %>/) do
84
+ "'/assets/#{::Regexp.last_match(1)}'"
85
+ end
86
+
87
+ # Remove any other ERB tags
88
+ processed.gsub!(/<%=.*?%>/, '')
89
+
90
+ # Ensure directory exists
91
+ FileUtils.mkdir_p(File.dirname(@theme_path))
92
+
93
+ # Write the processed file
94
+ File.write(@theme_path, processed)
95
+
96
+ Rails.logger.info "✅ ActiveScaffold: jQuery UI theme generated at #{@theme_path}"
97
+ rescue StandardError => e
98
+ Rails.logger.error "ActiveScaffold: Failed to generate jQuery UI theme: #{e.message}"
99
+ end
100
+ end
101
+ end
102
+ end