hot-glue 0.3.9 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,6 +6,8 @@ require_relative './markup_templates/erb'
6
6
  require_relative './markup_templates/haml'
7
7
  require_relative './markup_templates/slim'
8
8
 
9
+ require_relative './layout/builder'
10
+
9
11
  module HotGlue
10
12
  class Error < StandardError
11
13
  end
@@ -52,29 +54,31 @@ module HotGlue
52
54
  class_option :no_delete, type: :boolean, default: false
53
55
  class_option :no_create, type: :boolean, default: false
54
56
  class_option :no_edit, type: :boolean, default: false
57
+ class_option :no_list, type: :boolean, default: false
55
58
  class_option :no_paginate, type: :boolean, default: false
56
59
  class_option :big_edit, type: :boolean, default: false
57
60
  class_option :show_only, type: :string, default: ""
58
- class_option :stimulus_syntax, type: :boolean, default: nil
61
+
62
+ class_option :stimulus_syntax, type: :boolean, default: nil # TODO: rename to ujs_syntax and default to false
63
+
59
64
  class_option :downnest, type: :string, default: nil
60
- class_option :nestable, type: :boolean, default: false
61
65
  class_option :magic_buttons, type: :string, default: nil
62
66
  class_option :display_list_after_update, type: :boolean, default: false
63
-
67
+ class_option :smart_layout, type: :boolean, default: false
64
68
  class_option :markup, type: :string, default: nil # deprecated -- use in app config instead
65
- class_option :layout, type: :string, default: nil # deprecated -- use in app config instead
69
+ class_option :layout, type: :string, default: nil # if used here it will override what is in the config
66
70
 
67
71
 
68
72
  def initialize(*meta_args)
69
73
  super
70
74
 
75
+
71
76
  begin
72
77
  @the_object = eval(class_name)
73
78
  rescue StandardError => e
74
79
  message = "*** Oops: It looks like there is no object for #{class_name}. Please define the object + database table first."
75
80
  puts message
76
- exit
77
- # raise(HotGlue::Error, message)
81
+ raise(HotGlue::Error, message)
78
82
  end
79
83
 
80
84
  if !options['spec_only'].nil? && !options['no_spec'].nil?
@@ -82,10 +86,13 @@ module HotGlue
82
86
  end
83
87
 
84
88
  if !options['exclude'].empty? && !options['include'].empty?
85
- puts "*** Oops: You seem to have specified both --include and --exclude. Please use one or the other. Aborting."
86
- exit
89
+ exit_message = "*** Oops: You seem to have specified both --include and --exclude. Please use one or the other. Aborting."
90
+ puts exit_message
91
+
92
+ raise(HotGlue::Error, exit_message)
87
93
  end
88
94
 
95
+
89
96
  if @stimulus_syntax.nil?
90
97
  if Rails.version.split(".")[0].to_i >= 7
91
98
  @stimulus_syntax = true
@@ -95,13 +102,14 @@ module HotGlue
95
102
  end
96
103
 
97
104
  if !options['markup'].nil?
98
- puts "Using --markup flag in the generator is deprecated; instead, use a file at config/hot_glue.yml with a key markup set to `erb` or `haml`"
99
- exit
105
+ message = "Using --markup flag in the generator is deprecated; instead, use a file at config/hot_glue.yml with a key markup set to `erb` or `haml`"
106
+ raise(HotGlue::Error, message)
107
+
100
108
  end
101
109
 
102
110
  if !options['markup'].nil?
103
- puts "Using --layout flag in the generator is deprecated; instead, use a file at config/hot_glue.yml with a key markup set to `erb` or `haml`"
104
- exit
111
+ message = "Using --layout flag in the generator is deprecated; instead, use a file at config/hot_glue.yml with a key markup set to `erb` or `haml`"
112
+ raise(HotGlue::Error, message)
105
113
  end
106
114
 
107
115
  yaml_from_config = YAML.load(File.read("config/hot_glue.yml"))
@@ -110,8 +118,8 @@ module HotGlue
110
118
  if @markup == "erb"
111
119
  @template_builder = HotGlue::ErbTemplate.new
112
120
  elsif @markup == "slim"
113
- puts "SLIM IS NOT IMPLEMENTED; please see https://github.com/jasonfb/hot-glue/issues/3"
114
- abort
121
+ message = "SLIM IS NOT IMPLEMENTED; please see https://github.com/jasonfb/hot-glue/issues/3"
122
+ raise(HotGlue::Error, message)
115
123
  @template_builder = HotGlue::SlimTemplate.new
116
124
 
117
125
  elsif @markup == "haml"
@@ -119,13 +127,16 @@ module HotGlue
119
127
  end
120
128
 
121
129
 
122
- @layout = yaml_from_config[:layout]
130
+ if !options['layout']
131
+ @layout = yaml_from_config[:layout]
123
132
 
124
- if !['hotglue', 'bootstrap'].include? @layout
125
- raise "Invalid option #{@layout} in Hot glue config (config/hot_glue.yml). You must pass either hotglue (default) or bootstrap to config"
133
+ if !['hotglue', 'bootstrap'].include? @layout
134
+ raise "Invalid option #{@layout} in Hot glue config (config/hot_glue.yml). You must either use --layout= when generating or have a file config/hotglue.yml; specify layout as either 'hotglue' or 'bootstrap'"
135
+ end
136
+ else
137
+ @layout = options['layout']
126
138
  end
127
139
 
128
-
129
140
  args = meta_args[0]
130
141
  @singular = args.first.tableize.singularize # should be in form hello_world
131
142
  @plural = options['plural'] || @singular + "s" # supply to override; leave blank to use default
@@ -143,7 +154,8 @@ module HotGlue
143
154
 
144
155
  if !options['include'].empty?
145
156
  @include_fields = []
146
- @include_fields += options['include'].split(",").collect(&:to_sym)
157
+ # semicolon to denote layout columns; commas separate fields
158
+ @include_fields += options['include'].gsub(":","").split(",").collect(&:to_sym)
147
159
  end
148
160
 
149
161
 
@@ -164,11 +176,12 @@ module HotGlue
164
176
  @big_edit = options['big_edit']
165
177
 
166
178
  @no_edit = options['no_edit'] || false
167
- @display_list_after_update = options['display_list_after_update'] || false
179
+ @no_list = options['no_list'] || false
168
180
 
181
+ @display_list_after_update = options['display_list_after_update'] || false
182
+ @smart_layout = options['smart_layout']
169
183
 
170
184
 
171
- @col_identifier = @layout == "hotglue" ? "scaffold-cell" : "col"
172
185
  @container_name = @layout == "hotglue" ? "scaffold-container" : "container-fluid"
173
186
 
174
187
  @downnest = options['downnest'] || false
@@ -208,7 +221,6 @@ module HotGlue
208
221
  @build_update_action = !@no_edit || !@magic_buttons.empty?
209
222
  # if the magic buttons are present, build the update action anyway
210
223
 
211
- # @nestable = options['nestable'] || false
212
224
 
213
225
  if @auth && ! @self_auth && @nested_args.none?
214
226
  @object_owner_sym = @auth.gsub("current_", "").to_sym
@@ -224,12 +236,22 @@ module HotGlue
224
236
  end
225
237
  end
226
238
 
227
-
228
-
229
239
  @reference_name = HotGlue.derrive_reference_name(singular_class)
230
240
 
231
241
  identify_object_owner
232
242
  setup_fields
243
+
244
+ builder = HotGlue::Layout::Builder.new({
245
+ include_setting: options['include'],
246
+ downnest_children: @downnest_children,
247
+ no_edit: @no_edit,
248
+ no_delete: @no_delete,
249
+ columns: @columns,
250
+ smart_layout: @smart_layout
251
+ })
252
+ @layout_object = builder.construct
253
+
254
+ @menu_file_exists = true if @nested_args.none? && File.exists?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
233
255
  end
234
256
 
235
257
  def identify_object_owner
@@ -248,17 +270,15 @@ module HotGlue
248
270
  if @god
249
271
  exit_message= "*** Oops: Gd mode could not find the association(#{@object_owner_sym}). Something is wrong."
250
272
  else
251
- @auth_check = "current_user"
273
+ @auth_check = eval(@auth_identifier.titleize)
252
274
  @nested_args.each do |arg|
253
-
254
- if !@auth_check.method("#{arg}s")
275
+ if ! @auth_check.reflect_on_association("#{arg}s".to_sym)
255
276
  exit_message = "*** Oops: your nesting chain does not have a association for #{arg}s on #{@auth_check} something is wrong."
256
277
  end
257
278
  end
258
279
  end
259
280
  puts exit_message
260
- exit
261
-
281
+ raise(HotGlue::Error, exit_message)
262
282
  end
263
283
  end
264
284
  end
@@ -299,26 +319,20 @@ module HotGlue
299
319
  begin
300
320
  eval(assoc.class_name)
301
321
  rescue NameError => e
302
- exit_message = "*** Oops: The model #{singular_class} is missing an association for #{assoc_name} or the model doesn't exist. TODO: Please implement a model for #{assoc_name.titlecase}; your model #{singular_class.titlecase} should have_many :#{assoc_name}s. To make a controller that can read all records, specify with --god."
322
+ exit_message = "*** Oops: The model #{singular_class} is missing an association for :#{assoc_name} or the model #{assoc_name.titlecase} doesn't exist. TODO: Please implement a model for #{assoc_name.titlecase}; your model #{singular_class.titlecase} should belong_to :#{assoc_name}. To make a controller that can read all records, specify with --god."
303
323
  puts exit_message
304
- exit
305
- # raise(HotGlue::Error, exit_message)
306
-
324
+ raise(HotGlue::Error, exit_message)
307
325
  end
308
326
 
309
327
 
310
328
  if assoc.nil?
311
329
  exit_message = "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
312
330
  puts exit_message
313
- exit
314
- # raise(HotGlue::Error,exit_message)
331
+ raise(HotGlue::Error,exit_message)
315
332
  end
316
333
 
317
334
  assoc_class = eval(assoc.class_name)
318
-
319
335
  name_list = [:name, :to_label, :full_name, :display_name, :email]
320
-
321
-
322
336
  if name_list.collect{ |field|
323
337
  assoc_class.column_names.include?(field.to_s) || assoc_class.instance_methods.include?(field)
324
338
  }.any?
@@ -332,7 +346,6 @@ module HotGlue
332
346
  end
333
347
  end
334
348
 
335
- #
336
349
  def formats
337
350
  [format]
338
351
  end
@@ -356,7 +369,25 @@ module HotGlue
356
369
  end
357
370
 
358
371
  unless @no_specs
359
- template "system_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/system#{namespace_with_dash}", "#{plural}_behavior_spec.rb")
372
+ dest_file = File.join("#{'spec/dummy/' if Rails.env.test?}spec/system#{namespace_with_dash}", "#{plural}_behavior_spec.rb")
373
+
374
+ if File.exists?(dest_file)
375
+ existing_file = File.open(dest_file)
376
+ existing_content = existing_file.read
377
+ if existing_content =~ /\#HOTGLUE-SAVESTART/
378
+ if existing_content !~ /\#HOTGLUE-END/
379
+ raise "Your file at #{dest_file} contains a #HOTGLUE-SAVESTART marker without #HOTGLUE-END"
380
+ end
381
+ @existing_content = existing_content[(existing_content =~ /\#HOTGLUE-SAVESTART/) .. (existing_content =~ /\#HOTGLUE-END/)-1]
382
+ @existing_content << "#HOTGLUE-END"
383
+
384
+ end
385
+ existing_file.rewind
386
+ else
387
+ @existing_content = " #HOTGLUE-SAVESTART\n #HOTGLUE-END"
388
+ end
389
+
390
+ template "system_spec.rb.erb", dest_file
360
391
  end
361
392
 
362
393
  template "#{@markup}/_errors.#{@markup}", File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", "_errors.#{@markup}")
@@ -365,24 +396,26 @@ module HotGlue
365
396
  def list_column_headings
366
397
  if @nested_args.any?
367
398
  column_width = each_col * @columns.count
368
-
369
- "<div class='#{@col_identifier}' style='flex-basis: #{column_width}%'>"
370
399
  else
371
- @template_builder.list_column_headings(
372
- column_width: each_col,
373
- columns: @columns,
374
- col_identifier: @col_identifier
375
- )
400
+ column_width = 0
376
401
  end
377
402
 
403
+ if !@smart_layout
404
+ col_identifier = @layout == "hotglue" ? "scaffold-cell" : "col-md-1"
405
+ else
406
+ col_identifier = @layout == "hotglue" ? "scaffold-cell" : "col-md-2"
407
+ end
378
408
 
409
+ @template_builder.list_column_headings(
410
+ columns: @layout_object[:columns][:container],
411
+ col_identifier: col_identifier,
412
+ layout: @layout,
413
+ column_width: column_width
414
+ )
379
415
  end
380
416
 
381
417
  def columns_spec_with_sample_data
382
418
  @columns.map { |c|
383
- if eval("#{singular_class}.columns_hash['#{c}']").nil?
384
- byebug
385
- end
386
419
  type = eval("#{singular_class}.columns_hash['#{c}']").type
387
420
  random_data = case type
388
421
  when :integer
@@ -587,21 +620,6 @@ module HotGlue
587
620
  magic_buttons: @magic_buttons
588
621
  )
589
622
  end
590
- # def erb_replace_ampersands!(filename = nil)
591
- #
592
- # return if filename.nil?
593
- # file = File.open(filename, "r")
594
- # contents = file.read
595
- # file.close
596
- #
597
- # file = File.open(filename, "w")
598
- # file.write( contents.gsub('\%', '%'))
599
- # file.close
600
- # end
601
-
602
-
603
-
604
-
605
623
 
606
624
  def copy_view_files
607
625
  return if @specs_only
@@ -653,20 +671,35 @@ module HotGlue
653
671
  end
654
672
 
655
673
  def all_views
656
- res = %w(index edit _form _line _list _show _errors)
674
+ res = %w(index _line _list _show _errors)
657
675
 
658
676
  unless @no_create
659
677
  res += %w(new _new_form _new_button)
660
678
  end
661
679
 
680
+ unless @no_edit
681
+ res << 'edit'
682
+ res << '_form'
683
+ end
684
+
662
685
  res
663
686
  end
664
687
 
665
688
  def turbo_stream_views
666
- res = %w(create edit update)
689
+ res = []
667
690
  unless @no_delete
668
691
  res << 'destroy'
669
692
  end
693
+
694
+ unless @no_create
695
+ res << 'create'
696
+ end
697
+
698
+ unless @no_edit
699
+ res << 'edit'
700
+ res << 'update'
701
+ end
702
+
670
703
  res
671
704
  end
672
705
 
@@ -684,13 +717,19 @@ module HotGlue
684
717
  end
685
718
 
686
719
  def all_form_fields
720
+ # TODO: DRY THIS
721
+ if !@smart_layout
722
+ col_identifier = @layout == "hotglue" ? "scaffold-cell" : "col-md-1"
723
+ else
724
+ col_identifier = @layout == "hotglue" ? "scaffold-cell" : "col-md-2"
725
+ end
687
726
 
688
727
  @template_builder.all_form_fields(
689
- columns: @columns,
728
+ columns: @layout_object[:columns][:container],
690
729
  show_only: @show_only,
691
730
  singular_class: singular_class,
692
731
  singular: singular,
693
- col_identifier: @col_identifier
732
+ col_identifier: col_identifier
694
733
  )
695
734
  end
696
735
 
@@ -699,7 +738,8 @@ module HotGlue
699
738
  end
700
739
 
701
740
  def each_col
702
- (col_width/@columns.count).to_i
741
+ return col_width if @columns.count == 0
742
+ (col_width/(@columns.count)).to_i
703
743
  end
704
744
 
705
745
  def col_width
@@ -721,7 +761,7 @@ module HotGlue
721
761
 
722
762
  @template_builder.all_line_fields(
723
763
  perc_width: column_width,
724
- columns: @columns,
764
+ columns: @layout_object[:columns][:container],
725
765
  show_only: @show_only,
726
766
  singular_class: singular_class,
727
767
  singular: singular,
@@ -796,16 +836,18 @@ module HotGlue
796
836
 
797
837
  def controller_magic_button_update_actions
798
838
  @magic_buttons.collect{ |magic_button|
799
- " begin
800
- if #{singular}_params[:#{magic_button}]
839
+ " if #{singular}_params[:#{magic_button}]
840
+ begin
801
841
  res = @#{singular}.#{magic_button}!
802
842
  res = \"#{magic_button.titleize}ed.\" if res === true
803
843
  flash[:notice] = (flash[:notice] || \"\") << (res ? res + \" \" : \"\")
844
+ rescue ActiveRecord::RecordInvalid => e
845
+ @#{singular}.errors.add(:base, e.message)
846
+ flash[:alert] = (flash[:alert] || \"\") << 'There was ane error #{magic_button}ing your #{@singular}: '
804
847
  end
805
- rescue ActiveRecord::RecordInvalid => e
806
- @#{singular}.errors.add(:base, e.message)
807
- flash[:alert] = (flash[:alert] || \"\") << 'There was ane error #{magic_button}ing your #{@singular}: '
808
- end" }.join("\n") + "\n"
848
+ end"
849
+
850
+ }.join("\n") + "\n"
809
851
  end
810
852
 
811
853
  def controller_update_params_tap_away_magic_buttons
@@ -1,7 +1,7 @@
1
- def login_as(account)
2
- visit '/accounts/sign_in'
1
+ def login_as(user)
2
+ visit '/users/sign_in'
3
3
  within("#new_account") do
4
- fill_in 'Email', with: account.email
4
+ fill_in 'Email', with: user.email
5
5
  fill_in 'Password', with: 'password'
6
6
  end
7
7
  click_button 'Log in'
@@ -1,7 +1,7 @@
1
1
  <div class="row">
2
2
  <%= all_form_fields %>
3
3
 
4
- <div class="<% @layout == "hotglue" ? 'scaffold-cell' : 'col' %>">
4
+ <div class="<%= @layout == "hotglue" ? 'scaffold-cell' : 'col-md-2' %>">
5
5
  <\%= link_to "Cancel", <%= path_helper_plural %>, {class: "btn btn-secondary"} %>
6
6
  <\%= f.submit "Save", class: "btn btn-primary pull-right" %>
7
7
  </div>
@@ -1,32 +1,31 @@
1
1
  <\%= turbo_frame_tag "<%= plural %>-list" <%= nested_for_turbo_id_list_constructor %> do %>
2
2
  <div class="<%= @container_name %> scaffold-list">
3
- <% unless @nested_args.any? %><h4><%= plural.gsub("_", " ").upcase %></h4><% end %>
3
+ <% unless @no_list || @nested_args.any? %><h4><%= plural.gsub("_", " ").upcase %></h4><% end %>
4
4
 
5
- <% unless @no_create %><%= '<%= render partial: "' + ((@namespace+"/" if @namespace) || "") + plural + '/new_button", locals: {' + nested_assignments + '}' + '%\>'.gsub('\\',"") %><% end %>
5
+ <% unless @no_create %><%= '<%= render partial: "' + ((@namespace+"/" if @namespace) || "") + plural + '/new_button", locals: {' + nested_assignments + '}' + '%\>'.gsub('\\',"") %><br /><% end %>
6
6
 
7
-
8
- <div class="row scaffold-row">
7
+ <% unless @no_list %>
8
+ <div class="row scaffold-heading-row">
9
9
  <%= list_column_headings %>
10
10
  <% if @downnest_children.any? %>
11
11
  <% each_downnest_width = @downnest_children.count == 1 ? 40 : (60/@downnest_children.count).floor %>
12
- <% downnest_column_style = @layout == "hotglue" ? 'style="flex-basis: ' + each_downnest_width + '%;' : "" %>
12
+ <% downnest_column_style = @layout == "hotglue" ? 'style="flex-basis: ' + each_downnest_width.to_s + '%;' : "" %>
13
13
 
14
- <% @downnest_children.each do |downnest| %>
15
- <div class="<%= @col_identifer %> scaffold-col-heading<%= ' col-md-3' if @layout=="bootstrap" %>" <%= downnest_column_style %>>
16
- <h4>
14
+ <% @downnest_children.each_with_index do |downnest,i| %>
15
+ <div class=" scaffold-col-heading<%= " col-sm-#{ @layout_object[:portals][downnest][:size] }" if @layout=="bootstrap" %>" <%= downnest_column_style %>>
16
+ <strong>
17
17
  <%= downnest.titleize %>
18
- </h4>
18
+ </strong>
19
19
  </div>
20
20
  <% end %>
21
21
  <% end %>
22
22
 
23
23
  <% button_column_style = @layout == "hotglue" ? 'style="flex-basis: 150px' : "" %>
24
24
 
25
- <div class='<%= @col_identifer %> scaffold-col-heading scaffold-col-heading-buttons<%= ' col-md-2' if @layout=="bootstrap" %>' <%= button_column_style %>>
25
+ <div class=' scaffold-col-heading scaffold-col-heading-buttons<%= ' col-md-2' if @layout=="bootstrap" %>' <%= button_column_style %>>
26
26
 
27
27
  </div>
28
28
  </div>
29
-
30
29
  <\% if <%= plural %>.empty? %>
31
30
  <div>
32
31
  None
@@ -35,8 +34,7 @@
35
34
  <\% <%= plural %>.each do |<%= singular %>| %>
36
35
  <\%= render partial: '<%= line_path_partial %>', locals: {<%= singular %>: <%= singular %><%= nested_assignments_with_leading_comma if @nestable %><%= ", nested_for: nested_for" if @nestable %> } %>
37
36
  <\% end %>
38
-
39
37
  <%= @no_paginate ? "" : paginate %>
40
- </div>
38
+ <% end %>
41
39
  </div>
42
40
  <\% end %>
@@ -3,29 +3,31 @@
3
3
  <% if @downnest_children.any? %>
4
4
  <% each_downnest_width = @downnest_children.count == 1 ? 33 : (53/@downnest_children.count).floor %>
5
5
 
6
- <% @downnest_children.each do |downnest| %>
6
+ <% @downnest_children.each_with_index do |downnest,i| %>
7
7
 
8
- <% downnest_style = @layout == "hotglue" ? 'style="flex-basis: ' + each_downnest_width + '%"' : "" %>
9
- <div class="<%= @col_identifier %><%= ' col-md-3' if @layout == "bootstrap" %> scaffold-downnest" <%= downnest_style %> >
10
- <\%= render partial: "<%= namespace_with_trailing_dash %><%= downnest %>/list", locals: {
8
+ <% downnest_object = eval("#{singular_class}.reflect_on_association(:#{downnest})") %>
9
+ <% downnest_class = downnest_object.class_name %>
10
+ <% downnest_object_name = eval("#{downnest_class}.table_name") %>
11
+ <% downnest_style = @layout == "hotglue" ? 'style="flex-basis: ' + each_downnest_width.to_s + '%"' : "" %>
12
+ <div class="<%= " col-md-#{@layout_object[:portals][downnest][:size]}" if @layout == "bootstrap" %> scaffold-downnest" <%= downnest_style %> >
13
+ <\%= render partial: "<%= namespace_with_trailing_dash %><%= downnest_object_name %>/list", locals: {
11
14
  nested_for: "<% if @nested_args.any? %>#{nested_for + "__" if nested_for}<% end %><%= @singular %>-#{<%= @singular %>.id}",
12
15
  <%= @singular %>: <%= @singular %><%= nest_assignments_operator(false, true) %>,
13
- <%= downnest %>: <%= @singular %>.<%= downnest %>} %>
16
+ <%= downnest_object_name %>: <%= @singular %>.<%= downnest %>} %>
14
17
  </div>
15
18
  <% end %>
16
19
  <% end %>
17
20
 
18
21
  <% button_style = @layout == "hotglue" ? 'style="flex-basis: ' + (100 - (column_width * @columns.count)).floor.to_s + '%;"' : "" %>
19
22
  <div class="<%= @col_identifier %> scaffold-line-buttons <%= ' col-md-2' if @layout == "bootstrap" %>" <%= button_style %>>
23
+ <%= magic_button_output %>
24
+
20
25
  <% if destroy_action %>
21
26
  <\%= form_with url: <%= path_helper_singular %>(<%= path_helper_args %>), html: {style: "display: inline-block;"}, method: :delete do |f| %>
22
27
  <\%= f.submit "Delete".html_safe, data: <%= delete_confirmation_syntax %>, class: "delete-<%= singular %>-button btn btn-primary btn-sm" %>
23
28
  <\% end %>
24
29
  <% end %>
25
30
 
26
-
27
- <%= magic_button_output %>
28
-
29
31
  <% unless @no_edit %>
30
32
  <\%= link_to "Edit <i class='fa fa-1x fa-list-alt'></i>".html_safe, edit_<%= path_helper_singular %>(<%= path_helper_args %>), <% if @big_edit %>'data-turbo' => 'false', <% end %>disable_with: "Loading...", class: "edit-<%= singular %>-button btn btn-primary btn-sm" %>
31
33
  <% end %>
@@ -1,3 +1,5 @@
1
+ <% if @menu_file_exists %><\%= render partial: "<%= namespace_with_trailing_dash %>menu", locals: {active: '<%= plural %>'} %><% end %>
2
+
1
3
  <div class="<%= @container_name %>">
2
4
  <% if @layout == "bootstrap" %><div class="row"> <div class="col-md-12">
3
5
  <% else %>