bullet_train-super_scaffolding 1.0.28 → 1.0.31

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f442627a03e1aea9a33fd4d046a378d0177649eaffc3c1fef2d77cf6dc738b5b
4
- data.tar.gz: 67a9b22aa08ffe3f99ccd1ff88d1568b2d2d3ff247e53a3e96c96eb80b1a09a0
3
+ metadata.gz: 94c38c4ead4e806119a38b9404d5018ca8337ca652ea7afc7c96dc095f3488cf
4
+ data.tar.gz: 52c02c34adb2e6239409ba77f13be030fdd3740c5e29878972001b3b4ecf5a1a
5
5
  SHA512:
6
- metadata.gz: ef3e5a25df02bce626e7762b482d019852d3c61ba79096c34d8dbd5bfa63e5e939c8aed3755153d0b926086617b11804868609ac5195cda9d5438c988093707f
7
- data.tar.gz: b618a50a54582ca322650947f3b00b0d9fabc1c0383c17c8c6d265c5ee7eba3a7cab200b963935429c63c2e7c49c9fe78badce0233eb1c50aa76b92f313b1d2d
6
+ metadata.gz: 969c7bd956727e3dbe93dbccb870709b3e9454801497a741f97ac9b7912e97d7ca7c1ebefd67335f4eca1b94f392c2fd9967da1b183597b0194df8247994de7b
7
+ data.tar.gz: ef790aee490efc3408d36da33b789dd78dadc4acb09d3578bb940275b7ad507a679008b3514391b302523773f1e9049087acfdcc58270971e12a82b60dd8796a
@@ -0,0 +1,10 @@
1
+ module SuperScaffoldingHelper
2
+ unless defined?(BulletTrain::ActionModels)
3
+ def action_model_select_controller
4
+ # TODO I don't know why if I just call `yield` I get duplicate content on the page.
5
+ tag.div do
6
+ yield
7
+ end
8
+ end
9
+ end
10
+ end
@@ -7,69 +7,82 @@
7
7
  <% tangible_things = tangible_things.order(:id) unless has_order?(tangible_things) %>
8
8
  <% pagy, tangible_things = pagy(tangible_things, page_param: :tangible_things_page) %>
9
9
 
10
- <%= render 'account/shared/box', pagy: pagy do |p| %>
11
- <% p.content_for :title, t(".contexts.#{context.class.name.underscore}.header") %>
12
- <% p.content_for :description do %>
13
- <%= t(".contexts.#{context.class.name.underscore}.description#{"_empty" unless tangible_things.any?}") %>
14
- <% end %>
10
+ <%= action_model_select_controller do %>
11
+ <%= updates_for context, collection do %>
12
+ <%= render 'account/shared/box', pagy: pagy do |p| %>
13
+ <% p.content_for :title, t(".contexts.#{context.class.name.underscore}.header") %>
14
+ <% p.content_for :description do %>
15
+ <%= t(".contexts.#{context.class.name.underscore}.description#{"_empty" unless tangible_things.any?}") %>
16
+ <% end %>
15
17
 
16
- <% p.content_for :table do %>
17
- <% if tangible_things.any? %>
18
- <table class="table">
19
- <thead>
20
- <tr>
21
- <%# 🚅 skip this section when scaffolding. %>
22
- <th><%= t('.fields.text_field_value.heading') %></th>
23
- <th><%= t('.fields.boolean_button_value.heading') %></th>
24
- <th><%= t('.fields.button_value.heading') %></th>
25
- <th><%= t('.fields.multiple_button_values.heading') %></th>
26
- <%# 🚅 stop any skipping we're doing now. %>
27
- <%# 🚅 super scaffolding will insert new field headers above this line. %>
28
- <th><%= t('.fields.created_at.heading') %></th>
29
- <th class="text-right"></th>
30
- </tr>
31
- </thead>
32
- <tbody>
33
- <% tangible_things.each do |tangible_thing| %>
34
- <% with_attribute_settings object: tangible_thing do %>
35
- <tr data-id="<%= tangible_thing.id %>">
18
+ <% p.content_for :table do %>
19
+ <% if tangible_things.any? %>
20
+ <table class="table">
21
+ <thead>
22
+ <tr>
23
+ <%= render "shared/tables/select_all" %>
36
24
  <%# 🚅 skip this section when scaffolding. %>
37
- <td><%= render 'shared/attributes/text', attribute: :text_field_value, url: [:account, tangible_thing] %></td>
38
- <td><%= render 'shared/attributes/boolean', attribute: :boolean_button_value %></td>
39
- <td><%= render 'shared/attributes/option', attribute: :button_value %></td>
40
- <td><%= render 'shared/attributes/options', attribute: :multiple_button_values %></td>
25
+ <th><%= t('.fields.text_field_value.heading') %></th>
26
+ <th><%= t('.fields.boolean_button_value.heading') %></th>
27
+ <th><%= t('.fields.button_value.heading') %></th>
28
+ <th><%= t('.fields.multiple_button_values.heading') %></th>
41
29
  <%# 🚅 stop any skipping we're doing now. %>
42
- <%# 🚅 super scaffolding will insert new fields above this line. %>
43
- <td><%= render 'shared/attributes/date_and_time', attribute: :created_at %></td>
44
- <td class="buttons">
45
- <% unless hide_actions %>
46
- <% if can? :edit, tangible_thing %>
47
- <%= link_to t('.buttons.shorthand.edit'), [:edit, :account, tangible_thing], class: 'button-secondary button-smaller' %>
48
- <% end %>
49
- <% if can? :destroy, tangible_thing %>
50
- <%= button_to t('.buttons.shorthand.destroy'), [:account, tangible_thing], method: :delete, data: { confirm: t('.buttons.confirmations.destroy', model_locales(tangible_thing)) }, class: 'button-secondary button-smaller' %>
51
- <% end %>
52
- <% end %>
53
- </td>
30
+ <%# 🚅 super scaffolding will insert new field headers above this line. %>
31
+ <th><%= t('.fields.created_at.heading') %></th>
32
+ <th class="text-right"></th>
54
33
  </tr>
34
+ </thead>
35
+ <tbody>
36
+ <% tangible_things.each do |tangible_thing| %>
37
+ <% with_attribute_settings object: tangible_thing do %>
38
+ <tr data-id="<%= tangible_thing.id %>">
39
+ <%= render "shared/tables/checkbox", object: tangible_thing %>
40
+ <%# 🚅 skip this section when scaffolding. %>
41
+ <td><%= render 'shared/attributes/text', attribute: :text_field_value, url: [:account, tangible_thing] %></td>
42
+ <td><%= render 'shared/attributes/boolean', attribute: :boolean_button_value %></td>
43
+ <td><%= render 'shared/attributes/option', attribute: :button_value %></td>
44
+ <td><%= render 'shared/attributes/options', attribute: :multiple_button_values %></td>
45
+ <%# 🚅 stop any skipping we're doing now. %>
46
+ <%# 🚅 super scaffolding will insert new fields above this line. %>
47
+ <td><%= render 'shared/attributes/date_and_time', attribute: :created_at %></td>
48
+ <td class="buttons">
49
+ <% unless hide_actions %>
50
+ <% if can? :edit, tangible_thing %>
51
+ <%= link_to t('.buttons.shorthand.edit'), [:edit, :account, tangible_thing], class: 'button-secondary button-smaller' %>
52
+ <% end %>
53
+ <% if can? :destroy, tangible_thing %>
54
+ <%= button_to t('.buttons.shorthand.destroy'), [:account, tangible_thing], method: :delete, data: { confirm: t('.buttons.confirmations.destroy', model_locales(tangible_thing)) }, class: 'button-secondary button-smaller' %>
55
+ <% end %>
56
+ <%# 🚅 super scaffolding will insert new action model buttons above this line. %>
57
+ <% end %>
58
+ </td>
59
+ </tr>
60
+ <% end %>
61
+ <% end %>
62
+ </tbody>
63
+ </table>
64
+ <% end %>
65
+ <% end %>
66
+
67
+ <% p.content_for :actions do %>
68
+ <% unless hide_actions %>
69
+ <% if context == absolutely_abstract_creative_concept %>
70
+ <% if can? :create, Scaffolding::CompletelyConcrete::TangibleThing.new(absolutely_abstract_creative_concept: absolutely_abstract_creative_concept) %>
71
+ <%= link_to t('.buttons.new'), [:new, :account, absolutely_abstract_creative_concept, :completely_concrete_tangible_thing], class: "#{first_button_primary(:completely_concrete_tangible_thing)} new" %>
55
72
  <% end %>
56
73
  <% end %>
57
- </tbody>
58
- </table>
59
- <% end %>
60
- <% end %>
61
74
 
62
- <% p.content_for :actions do %>
63
- <% unless hide_actions %>
64
- <% if context == absolutely_abstract_creative_concept %>
65
- <% if can? :create, Scaffolding::CompletelyConcrete::TangibleThing.new(absolutely_abstract_creative_concept: absolutely_abstract_creative_concept) %>
66
- <%= link_to t('.buttons.new'), [:new, :account, absolutely_abstract_creative_concept, :completely_concrete_tangible_thing], class: "#{first_button_primary(:completely_concrete_tangible_thing)} new" %>
75
+ <% unless hide_back %>
76
+ <%# 🚅 super scaffolding will insert new bulk action model buttons above this line. %>
77
+ <%= render "shared/bulk_action_select" %>
78
+ <%= link_to t('global.buttons.back'), [:account, context], class: "#{first_button_primary(:completely_concrete_tangible_thing)} back" %>
79
+ <% end %>
67
80
  <% end %>
68
81
  <% end %>
69
82
 
70
- <% unless hide_back %>
71
- <%= link_to t('global.buttons.back'), [:account, context], class: "#{first_button_primary(:completely_concrete_tangible_thing)} back" %>
83
+ <% p.content_for :raw_footer do %>
84
+ <%# 🚅 super scaffolding will insert new action model index views above this line. %>
72
85
  <% end %>
73
86
  <% end %>
74
87
  <% end %>
75
- <% end %>
88
+ <% end %>
@@ -1,42 +1,49 @@
1
1
  <%= render 'account/shared/page' do |p| %>
2
2
  <% p.content_for :title, t('.section') %>
3
3
  <% p.content_for :body do %>
4
- <%= render 'account/shared/box', divider: true do |p| %>
5
- <% p.content_for :title, t('.header') %>
6
- <% p.content_for :description do %>
7
- <%= t('.description') %>
8
- <%= t('.manage_description') if can? :manage, @tangible_thing %>
9
- <% end %>
4
+ <%= updates_for @tangible_thing do %>
5
+ <%= render 'account/shared/box', divider: true do |p| %>
6
+ <% p.content_for :title, t('.header') %>
7
+ <% p.content_for :description do %>
8
+ <%= t('.description') %>
9
+ <%= t('.manage_description') if can? :manage, @tangible_thing %>
10
+ <% end %>
10
11
 
11
- <% p.content_for :body do %>
12
- <% with_attribute_settings object: @tangible_thing, strategy: :label do %>
13
- <%# 🚅 skip this section when scaffolding. %>
14
- <%= render 'shared/attributes/text', attribute: :text_field_value %>
15
- <%= render 'shared/attributes/boolean', attribute: :boolean_button_value %>
16
- <%= render 'shared/attributes/option', attribute: :button_value %>
17
- <%= render 'shared/attributes/options', attribute: :multiple_button_values %>
18
- <%= render 'shared/attributes/code', attribute: :color_picker_value %>
19
- <%= render 'shared/attributes/text', attribute: :cloudinary_image_value %>
20
- <%= render 'shared/attributes/date', attribute: :date_field_value %>
21
- <%= render 'shared/attributes/date_and_time', attribute: :date_and_time_field_value %>
22
- <%= render 'shared/attributes/email', attribute: :email_field_value %>
23
- <%= render 'shared/attributes/text', attribute: :password_field_value %>
24
- <%= render 'shared/attributes/phone_number', attribute: :phone_field_value %>
25
- <%= render 'shared/attributes/option', attribute: :option_value %>
26
- <%= render 'shared/attributes/options', attribute: :multiple_option_values %>
27
- <%= render 'shared/attributes/option', attribute: :super_select_value %>
28
- <%= render 'shared/attributes/options', attribute: :multiple_super_select_values %>
29
- <%= render 'shared/attributes/block', attribute: :text_area_value %>
30
- <%= render 'shared/attributes/html', attribute: :action_text_value %>
31
- <%# 🚅 stop any skipping we're doing now. %>
32
- <%# 🚅 super scaffolding will insert new fields above this line. %>
12
+ <% p.content_for :body do %>
13
+ <% with_attribute_settings object: @tangible_thing, strategy: :label do %>
14
+ <%# 🚅 skip this section when scaffolding. %>
15
+ <%= render 'shared/attributes/text', attribute: :text_field_value %>
16
+ <%= render 'shared/attributes/boolean', attribute: :boolean_button_value %>
17
+ <%= render 'shared/attributes/option', attribute: :button_value %>
18
+ <%= render 'shared/attributes/options', attribute: :multiple_button_values %>
19
+ <%= render 'shared/attributes/code', attribute: :color_picker_value %>
20
+ <%= render 'shared/attributes/text', attribute: :cloudinary_image_value %>
21
+ <%= render 'shared/attributes/date', attribute: :date_field_value %>
22
+ <%= render 'shared/attributes/date_and_time', attribute: :date_and_time_field_value %>
23
+ <%= render 'shared/attributes/email', attribute: :email_field_value %>
24
+ <%= render 'shared/attributes/text', attribute: :password_field_value %>
25
+ <%= render 'shared/attributes/phone_number', attribute: :phone_field_value %>
26
+ <%= render 'shared/attributes/option', attribute: :option_value %>
27
+ <%= render 'shared/attributes/options', attribute: :multiple_option_values %>
28
+ <%= render 'shared/attributes/option', attribute: :super_select_value %>
29
+ <%= render 'shared/attributes/options', attribute: :multiple_super_select_values %>
30
+ <%= render 'shared/attributes/block', attribute: :text_area_value %>
31
+ <%= render 'shared/attributes/html', attribute: :action_text_value %>
32
+ <%# 🚅 stop any skipping we're doing now. %>
33
+ <%# 🚅 super scaffolding will insert new fields above this line. %>
34
+ <% end %>
33
35
  <% end %>
34
- <% end %>
35
36
 
36
- <% p.content_for :actions do %>
37
- <%= link_to t('.buttons.edit'), [:edit, :account, @tangible_thing], class: first_button_primary if can? :edit, @tangible_thing %>
38
- <%= button_to t('.buttons.destroy'), [:account, @tangible_thing], method: :delete, class: first_button_primary, data: { confirm: t('.buttons.confirmations.destroy', model_locales(@tangible_thing)) } if can? :destroy, @tangible_thing %>
39
- <%= link_to t('global.buttons.back'), [:account, @absolutely_abstract_creative_concept, :completely_concrete_tangible_things], class: first_button_primary %>
37
+ <% p.content_for :actions do %>
38
+ <%= link_to t('.buttons.edit'), [:edit, :account, @tangible_thing], class: first_button_primary if can? :edit, @tangible_thing %>
39
+ <%# 🚅 super scaffolding will insert new action model buttons above this line. %>
40
+ <%= button_to t('.buttons.destroy'), [:account, @tangible_thing], method: :delete, class: first_button_primary, data: { confirm: t('.buttons.confirmations.destroy', model_locales(@tangible_thing)) } if can? :destroy, @tangible_thing %>
41
+ <%= link_to t('global.buttons.back'), [:account, @absolutely_abstract_creative_concept, :completely_concrete_tangible_things], class: first_button_primary %>
42
+ <% end %>
43
+
44
+ <% p.content_for :raw_footer do %>
45
+ <%# 🚅 super scaffolding will insert new action model index views above this line. %>
46
+ <% end %>
40
47
  <% end %>
41
48
  <% end %>
42
49
 
File without changes
File without changes
File without changes
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module SuperScaffolding
3
- VERSION = "1.0.28"
3
+ VERSION = "1.0.31"
4
4
  end
5
5
  end
@@ -137,4 +137,8 @@ class Scaffolding::BlockManipulator
137
137
  end
138
138
  current_line
139
139
  end
140
+
141
+ def block_indentation_size(line_number)
142
+ lines[line_number].scan(/^\s+/).first.size
143
+ end
140
144
  end
@@ -1,5 +1,5 @@
1
1
  class Scaffolding::RoutesFileManipulator
2
- attr_accessor :child, :parent, :lines, :transformer_options
2
+ attr_accessor :child, :parent, :lines, :transformer_options, :block_manipulator
3
3
 
4
4
  def initialize(filename, child, parent, transformer_options = {})
5
5
  self.child = child
@@ -7,6 +7,7 @@ class Scaffolding::RoutesFileManipulator
7
7
  @filename = filename
8
8
  self.lines = File.readlines(@filename)
9
9
  self.transformer_options = transformer_options
10
+ self.block_manipulator = Scaffolding::BlockManipulator.new(@filename)
10
11
  end
11
12
 
12
13
  def child_parts
@@ -141,7 +142,12 @@ class Scaffolding::RoutesFileManipulator
141
142
  current_namespace = nil
142
143
  while namespaces.any?
143
144
  current_namespace = namespaces.shift
144
- namespace_lines = find_namespaces(created_namespaces + [current_namespace], within)
145
+ namespace_lines = if within.nil?
146
+ find_namespaces(created_namespaces + [current_namespace], within)
147
+ else
148
+ scope_namespace_to_parent(current_namespace, within)
149
+ end
150
+
145
151
  unless namespace_lines[current_namespace]
146
152
  lines_to_add = ["namespace :#{current_namespace} do", "end"]
147
153
  if created_namespaces.any?
@@ -156,6 +162,35 @@ class Scaffolding::RoutesFileManipulator
156
162
  namespace_lines ? namespace_lines[current_namespace] : nil
157
163
  end
158
164
 
165
+ # Since it's possible for multiple namespaces to exist on different levels,
166
+ # We scope the namespace we're trying to scaffold to its proper parent before processing it.
167
+ #
168
+ # i.e:
169
+ # Parent: Insight => Child: Personality::CharacterTrait
170
+ # Parent: Team => Child: Personality::Disposition
171
+ # In this case, the :personality namespace under :insights should be
172
+ # ignored when Super Scaffolding Personality::Dispositon.
173
+ #
174
+ # resources do :insights do
175
+ # namespace :personality do
176
+ # resources :character_traits
177
+ # end
178
+ # end
179
+ #
180
+ # namespace :personality do
181
+ # resources :dispositions
182
+ # end
183
+ #
184
+ # In this case, Personality::CharacterTrait is under Team just like Personality::Disposition,
185
+ # but Personality::CharacterTrait's DIRECT parent is Insight so we shouldn't scaffold its routes there.
186
+ def scope_namespace_to_parent(namespace, within)
187
+ namespace_block_start = namespace_blocks_directly_under_parent(within).map do |namespace_block|
188
+ namespace_line_number = namespace_block.begin
189
+ namespace_line_number if lines[namespace_line_number].match?(/ +namespace :#{namespace}/)
190
+ end.compact
191
+ namespace_block_start.present? ? {namespace => namespace_block_start} : {}
192
+ end
193
+
159
194
  def find(needle, within = nil)
160
195
  lines_within(within).each_with_index do |line, line_number|
161
196
  return (within + (within ? 1 : 0) + line_number) if line.match?(needle)
@@ -220,6 +255,8 @@ class Scaffolding::RoutesFileManipulator
220
255
  result
221
256
  end
222
257
 
258
+ # Finds namespace blocks no matter how many levels deep they are nested in resource blocks, etc.
259
+ # However, will not find namespace blocks inside namespace blocks.
223
260
  def top_level_namespace_block_lines(within)
224
261
  local_namespace_blocks = []
225
262
  lines_within(within).each do |line|
@@ -253,6 +290,24 @@ class Scaffolding::RoutesFileManipulator
253
290
  local_namespace_blocks
254
291
  end
255
292
 
293
+ # Whereas top_level_namespace_block_lines grabs all namespace blocks that
294
+ # appear first no matter how many resource blocks they're nested in,
295
+ # this method grabs namespace blocks that are only indented one level deep.
296
+ def namespace_blocks_directly_under_parent(within)
297
+ blocks = []
298
+ if lines[within].match?(/do$/)
299
+ parent_indentation_size = block_manipulator.block_indentation_size(within)
300
+ within_block_end = find_block_end(within)
301
+ within.upto(within_block_end) do |line_number|
302
+ if lines[line_number].match?(/^#{" " * (parent_indentation_size + 2)}namespace/)
303
+ namespace_block_lines = line_number..find_block_end(line_number)
304
+ blocks << namespace_block_lines
305
+ end
306
+ end
307
+ end
308
+ blocks
309
+ end
310
+
256
311
  def find_or_create_resource_block(parts, options = {})
257
312
  find_or_create_resource(parts, options)
258
313
  find_or_convert_resource_block(parts.last, options)
@@ -300,7 +355,6 @@ class Scaffolding::RoutesFileManipulator
300
355
  child_namespaces, child_resource, parent_namespaces, parent_resource = divergent_parts
301
356
 
302
357
  within = find_or_create_namespaces(base_namespaces)
303
- within = find_or_create_namespaces(common_namespaces, within) if common_namespaces.any?
304
358
 
305
359
  # e.g. Project and Projects::Deliverable
306
360
  if parent_namespaces.empty? && child_namespaces.one? && parent_resource == child_namespaces.first
@@ -326,33 +380,31 @@ class Scaffolding::RoutesFileManipulator
326
380
  # resources :deliverables, except: collection_actions
327
381
  # end
328
382
 
383
+ # We want to see if there are any namespaces one level above the parent itself,
384
+ # because namespaces with the same name as the resource can exist on the same level.
385
+ parent_block_start = find_block_parent(parent_within)
386
+ namespace_line_within = find_or_create_namespaces(child_namespaces, parent_block_start)
387
+ find_or_create_resource([child_resource], options: "except: collection_actions", within: namespace_line_within)
329
388
  unless find_namespaces(child_namespaces, within)[child_namespaces.last]
330
- insert_after(["", "namespace :#{child_namespaces.last} do", "end"], find_block_end(scope_within))
331
- unless find_namespaces(child_namespaces, within)[child_namespaces.last]
332
- raise "tried to insert `namespace :#{child_namespaces.last}` but it seems we failed"
333
- end
389
+ raise "tried to insert `namespace :#{child_namespaces.last}` but it seems we failed"
334
390
  end
335
391
 
336
- find_or_create_resource(child_namespaces + [child_resource], options: "except: collection_actions", within: within)
337
-
338
392
  # e.g. Projects::Deliverable and Objective Under It, Abstract::Concept and Concrete::Thing
339
393
  elsif parent_namespaces.any?
340
394
 
341
395
  # namespace :projects do
342
396
  # resources :deliverables
343
397
  # end
344
- #
398
+ top_parent_namespace = find_namespaces(parent_namespaces, within)[parent_namespaces.first]
399
+ find_or_create_resource(child_namespaces + [child_resource], within: top_parent_namespace)
400
+
345
401
  # resources :projects_deliverables, path: 'projects/deliverables' do
346
402
  # resources :objectives
347
403
  # end
348
-
349
- find_resource(parent_namespaces + [parent_resource], within: within)
350
- top_parent_namespace = find_namespaces(parent_namespaces, within)[parent_namespaces.first]
351
404
  block_parent_within = find_block_parent(top_parent_namespace)
352
405
  parent_namespaces_and_resource = (parent_namespaces + [parent_resource]).join("_")
353
406
  parent_within = find_or_create_resource_block([parent_namespaces_and_resource], options: "path: '#{parent_namespaces_and_resource.tr("_", "/")}'", within: block_parent_within)
354
407
  find_or_create_resource(child_namespaces + [child_resource], within: parent_within)
355
-
356
408
  else
357
409
 
358
410
  begin
@@ -37,6 +37,12 @@ def check_required_options_for_attributes(scaffolding_type, attributes, child, p
37
37
  name = parts.shift
38
38
  type = parts.join(":")
39
39
 
40
+ unless Scaffolding.valid_attribute_type?(type)
41
+ raise "You have entered an invalid attribute type: #{type}. General data types are used when creating new models, but Bullet Train " +
42
+ "uses field partials when Super Scaffolding, i.e. - `name:text_field` as opposed to `name:string`. " +
43
+ "Please refer to the Field Partial documentation to view which attribute types are available."
44
+ end
45
+
40
46
  # extract any options they passed in with the field.
41
47
  type, attribute_options = type.scan(/^(.*){(.*)}/).first || type
42
48
 
@@ -655,8 +655,14 @@ class Scaffolding::Transformer
655
655
  "email"
656
656
  when "color_picker"
657
657
  "code"
658
- else
658
+ when "text_field"
659
+ "text"
660
+ when "text_area"
661
+ "text"
662
+ when "file_field"
659
663
  "text"
664
+ else
665
+ raise "Invalid attribute type: #{type}."
660
666
  end
661
667
 
662
668
  cell_attributes = if boolean_buttons
@@ -1030,10 +1036,14 @@ class Scaffolding::Transformer
1030
1036
  scaffold_add_line_to_file("./app/views/account/scaffolding/completely_concrete/tangible_things/_tangible_thing.json.jbuilder", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true, suppress_could_not_find: true)
1031
1037
  scaffold_add_line_to_file("./app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true)
1032
1038
 
1033
- assertion = if type == "date_field"
1039
+ assertion = case type
1040
+ when "date_field"
1034
1041
  "assert_equal Date.parse(tangible_thing_data['#{name}']), tangible_thing.#{name}"
1035
- elsif type == "date_and_time_field"
1042
+ when "date_and_time_field"
1036
1043
  "assert_equal DateTime.parse(tangible_thing_data['#{name}']), tangible_thing.#{name}"
1044
+ when "file_field"
1045
+ # TODO: If we want to use Cloudinary to handle our files, we should make sure we're getting a URL.
1046
+ "assert_equal tangible_thing_data['#{name}']['record']['id'], tangible_thing.#{name}.record.id"
1037
1047
  else
1038
1048
  "assert_equal tangible_thing_data['#{name}'], tangible_thing.#{name}"
1039
1049
  end
@@ -1276,10 +1286,20 @@ class Scaffolding::Transformer
1276
1286
  else
1277
1287
  transform_string("association :absolutely_abstract_creative_concept, factory: :scaffolding_absolutely_abstract_creative_concept")
1278
1288
  end
1289
+
1279
1290
  scaffold_replace_line_in_file("./test/factories/scaffolding/completely_concrete/tangible_things.rb", content, "absolutely_abstract_creative_concept { nil }")
1280
1291
 
1281
1292
  add_has_many_association
1282
1293
 
1294
+ # Adds file attachment to factory
1295
+ attributes.each do |attribute|
1296
+ attribute_name, partial_type = attribute.split(":")
1297
+ if partial_type == "file_field"
1298
+ content = "#{attribute_name} { Rack::Test::UploadedFile.new(\"test/support/foo.txt\") }"
1299
+ scaffold_replace_line_in_file("./test/factories/scaffolding/completely_concrete/tangible_things.rb", content, "#{attribute_name} { nil }")
1300
+ end
1301
+ end
1302
+
1283
1303
  if class_names_transformer.belongs_to_needs_class_definition?
1284
1304
  scaffold_replace_line_in_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", transform_string("belongs_to :absolutely_abstract_creative_concept, class_name: \"Scaffolding::AbsolutelyAbstract::CreativeConcept\"\n"), transform_string("belongs_to :absolutely_abstract_creative_concept\n"))
1285
1305
  end
data/lib/scaffolding.rb CHANGED
@@ -1,2 +1,21 @@
1
1
  module Scaffolding
2
+ def self.valid_attribute_type?(type)
3
+ [
4
+ "boolean",
5
+ "button",
6
+ "cloudinary_image",
7
+ "color_picker",
8
+ "date_and_time_field",
9
+ "date_field",
10
+ "email_field",
11
+ "file_field",
12
+ "options",
13
+ "password_field",
14
+ "phone_field",
15
+ "super_select",
16
+ "text_area",
17
+ "text_field",
18
+ "trix_editor"
19
+ ].include?(type.gsub(/{.*}/, "")) # Pop off curly brackets such as `super_select{class_name=Membership}`
20
+ end
2
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train-super_scaffolding
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.28
4
+ version: 1.0.31
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-22 00:00:00.000000000 Z
11
+ date: 2022-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard
@@ -89,6 +89,7 @@ files:
89
89
  - app/controllers/api/v1/scaffolding/completely_concrete.rb
90
90
  - app/controllers/api/v1/scaffolding/completely_concrete/tangible_things_endpoint.rb
91
91
  - app/controllers/concerns/scaffolding/absolutely_abstract/creative_concepts/controller_support.rb
92
+ - app/helpers/super_scaffolding_helper.rb
92
93
  - app/models/scaffolding.rb
93
94
  - app/models/scaffolding/absolutely_abstract.rb
94
95
  - app/models/scaffolding/absolutely_abstract/creative_concept.rb
@@ -133,6 +134,9 @@ files:
133
134
  - app/views/account/scaffolding/completely_concrete/tangible_things/new.html.erb
134
135
  - app/views/account/scaffolding/completely_concrete/tangible_things/show.html.erb
135
136
  - app/views/account/scaffolding/completely_concrete/tangible_things/show.json.jbuilder
137
+ - app/views/shared/_bulk_action_select.html.erb
138
+ - app/views/shared/tables/_checkbox.html.erb
139
+ - app/views/shared/tables/_select_all.html.erb
136
140
  - config/locales/en/scaffolding/absolutely_abstract/creative_concepts.en.yml
137
141
  - config/locales/en/scaffolding/absolutely_abstract/creative_concepts/collaborators.en.yml
138
142
  - config/locales/en/scaffolding/completely_concrete/tangible_things.en.yml