hot-glue 0.6.15 → 0.6.16

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e3993f35ba9d926cec0a205bb06708be83c2d72012eaafebce6cb384da07a92
4
- data.tar.gz: 509b98c64699c6561435d63da9b0ae6afe2924d6c1624dbcedf1a3288a5dfc0d
3
+ metadata.gz: '09ebf223206d1bf224f02aaafe2796774bfa6b3d61c6892c1b0144ec2a8dd0f3'
4
+ data.tar.gz: 1fd04b5e1909ebcf2ecc9eeb5c4e212f7a6878d49c0fe918305e43e441cd73d3
5
5
  SHA512:
6
- metadata.gz: b3d097f4f7130718597c9024173980e2d7b59826d4bb355ce34c22f70f0fec01e6265784007bdc296f41e0cd232d96d7a1ed2e0b055a6f7dbb1eef644fac5da7
7
- data.tar.gz: 83905ccb51e15676d2dff4253f656ef29a330272ed0549ebbbb74a7272ee9aa42b04491ba4ef88c2bf9fb84ec047991da89fa027e519cf048f3197bd7687ccd1
6
+ metadata.gz: c01e39699fe999a7024850b9d738d5e205b4e5abe8c39d3619d10efa74fbed2384ac6cadfa4010d52c0a9fdea3878ae599aa23002cd439d323701f4b8524c3eb
7
+ data.tar.gz: 79c20e1f78772f79e396cecfc81990a70b3a0d17988962baebd6c2ea0b10eabedea59ebd8624f34d0ad7ce864d59bf7ad7be2afb8c712ef01f605ab06e272fce
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hot-glue (0.6.14)
4
+ hot-glue (0.6.15)
5
5
  ffaker (~> 2.16)
6
6
  kaminari (~> 1.2)
7
7
  rails (> 5.1)
data/README.md CHANGED
@@ -790,6 +790,23 @@ end
790
790
  Because Hot Glue detects the `*_able?` methods at build time, if you add them to your policy, you will have to rebuild your scaffold.
791
791
 
792
792
 
793
+ ### `--pundit-policy-override`
794
+ if you use the flag `--pundit-policy-override` your controller operations will bypass the invisible (pundit provided) access control and use the pundit policy you specify.
795
+
796
+ example
797
+
798
+ `rails generate hot_glue:scaffold Invoice --gd --pundit-policy-override='UniqueInvoicePolicy'`
799
+
800
+ You will implement a Pundit policy for `UniqueInvoicePolicy` and it should implement actions with question mark `?` endings corresponding to the same actions you are building, `new?`, `create?`, `edit?`, `update?`, and `destroy?`
801
+
802
+ If provided, the output code looks something like (in this example, showing the `edit?` method)
803
+
804
+ ```
805
+ skip_authorization
806
+ raise Pundit::NotAuthorizedError if ! UniqueInvoicePolicy.edit?
807
+ ```
808
+
809
+
793
810
  ### `--show-only=`
794
811
  (separate field names by COMMA)
795
812
 
@@ -1751,6 +1768,39 @@ These automatic pickups for partials are detected at build time. This means that
1751
1768
 
1752
1769
  # VERSION HISTORY
1753
1770
 
1771
+ #### 2025-03-31 v0.6.16
1772
+
1773
+ • Bootstrap Tab Panes For Downnested Portals
1774
+ Downnested portals are now built with bootstrap tab panes (always) and are no longer stacked on top of one another.
1775
+
1776
+ It looks like this:
1777
+ https://getbootstrap.com/docs/5.0/components/navs-tabs/#javascript-behavior
1778
+
1779
+ • inline_list_labels can be set in hot_glue.yml
1780
+ • typeaheads nested inside of routes are fixed
1781
+ • switches back to current_timezone implementation, displaying times relative to the user's set timezone
1782
+ • load all code now sets query parameters
1783
+
1784
+ • Pundit Policy Override
1785
+ if you use the flag `--pundit-policy-override` your controller operations will bypass the invisible (pundit provided) access control and use the pundit policy you specify.
1786
+
1787
+ example
1788
+
1789
+ `rails generate hot_glue:scaffold Invoice --gd --pundit-policy-override='UniqueInvoicePolicy'`
1790
+
1791
+ Implement `UniqueInvoicePolicy` using actions with question mark `?` endings corresponding to the same actions you are building, `new?`, `create?`, `edit?`, `update?`, and `destroy?`
1792
+
1793
+
1794
+ • Bootstrap column builder has been changed.
1795
+ The bootstrap column bulder previously defaulted all real columns to col-sm-2 (or whichever bootstrap column with you set)
1796
+
1797
+ The builder has been refactored to allow for a per-column width generated automatically by the builder. If there are unused bootstrap columns, the builder will add width to the first columns in your layout, making them wider.
1798
+
1799
+
1800
+
1801
+
1802
+
1803
+
1754
1804
  #### 2025-03-17 - v0.6.15
1755
1805
 
1756
1806
  • now store on your current_user model (this is automatically passed into the method modify_date_inputs_on_params). HG will set user-inputted values correctly to daylight savings time during April-Nov months only (#195)
@@ -12,8 +12,6 @@ require_relative "fields/uuid_field"
12
12
  require_relative "fields/attachment_field"
13
13
  require_relative "fields/related_set_field"
14
14
 
15
-
16
-
17
15
  class FieldFactory
18
16
  attr_accessor :field, :class_name
19
17
  def initialize(type: , name: , generator: )
@@ -51,6 +49,9 @@ class FieldFactory
51
49
  end
52
50
  @class_name = class_name
53
51
 
52
+ if field_class.nil?
53
+ raise "Field type could be identified #{name} "
54
+ end
54
55
 
55
56
  @field = field_class.new(name: name,
56
57
  layout_strategy: generator.layout_strategy,
@@ -32,6 +32,7 @@ class EnumField < Field
32
32
 
33
33
  def form_field_output
34
34
  enum_type = eval("#{class_name}.columns.select{|x| x.name == '#{name}'}[0].sql_type")
35
+
35
36
  if eval("defined? #{class_name}.#{enum_type}_labels") == "method"
36
37
  enum_definer = "#{class_name}.#{enum_type}_labels"
37
38
  else
@@ -40,7 +40,8 @@ module HotGlue
40
40
  layout_object = {
41
41
  columns: {
42
42
  size_each: smart_layout ? bootstrap_column_width : (specified_grouping_mode ? nil : 1),
43
- container: [] # array of arrays
43
+ container: [] , # array of arrays,
44
+ bootstrap_column_width: []
44
45
  },
45
46
  portals: {
46
47
 
@@ -99,7 +100,7 @@ module HotGlue
99
100
  }
100
101
  layout_object[:columns][:container] = (0..available_columns-1).collect { |x| [columns[x]] }
101
102
  layout_object[:columns][:container].reject!{|x| x == [nil]}
102
- layout_object[:columns][:size_each] = bootstrap_column_width
103
+ # layout_object[:columns][:size_each] = bootstrap_column_width
103
104
  end
104
105
  elsif ! specified_grouping_mode
105
106
  # not smart and no specified grouping
@@ -117,22 +118,33 @@ module HotGlue
117
118
  # input control
118
119
 
119
120
  user_layout_columns = @include_setting.split(":")
120
- size_each = (bootstrap_columns / user_layout_columns.count).floor # this is the bootstrap size
121
121
 
122
- layout_object[:columns][:size_each] = size_each
122
+ extra_columns = available_columns - user_layout_columns.size
123
+ # size_each = (bootstrap_columns / user_layout_columns.count).floor # this is the bootstrap size
124
+ #
125
+ # layout_object[:columns][:size_each] = size_each
123
126
 
124
- if user_layout_columns.size > available_columns
125
- raise "Your include statement #{@include_setting } has #{user_layout_columns.size} columns, but I can only construct up to #{available_columns}"
126
- end
127
+ # if user_layout_columns.size > available_columns
128
+ # raise "Your include statement #{@include_setting } has #{user_layout_columns.size} columns, but I can only construct up to #{available_columns}"
129
+ # end
127
130
  user_layout_columns.each_with_index do |column,i|
128
131
  layout_object[:columns][:container][i] = column.split(",").collect(&:to_sym)
132
+
133
+ default_col_width = 1
134
+ if extra_columns > 0
135
+ default_col_width += 1
136
+ extra_columns -= 1
137
+ end
138
+ layout_object[:columns][:bootstrap_column_width][i] = default_col_width
129
139
  end
130
140
 
131
141
  if user_layout_columns.size < layout_object[:columns][:container].size
132
142
  layout_object[:columns][:container].reject!{|x| x == []}
133
143
  end
144
+
134
145
  end
135
146
 
147
+
136
148
  puts "*** constructed smart layout columns #{layout_object.inspect}"
137
149
  layout_object
138
150
  end
@@ -17,20 +17,20 @@ class LayoutStrategy::Bootstrap < LayoutStrategy::Base
17
17
  end
18
18
 
19
19
 
20
- def column_classes_for_form_fields
21
- "col-md-#{builder.layout_object[:columns][:size_each]}"
20
+ def column_classes_for_form_fields(size = nil)
21
+ "col-md-#{size || builder.layout_object[:columns][:size_each]}"
22
22
  end
23
23
 
24
- def column_classes_for_column_headings
25
- column_classes_for_line_fields
24
+ def column_classes_for_column_headings(size = nil)
25
+ column_classes_for_line_fields(size)
26
26
  end
27
27
 
28
28
  def container_name
29
29
  "container"
30
30
  end
31
31
 
32
- def column_classes_for_line_fields
33
- "col-sm-#{builder.layout_object[:columns][:size_each]}"
32
+ def column_classes_for_line_fields(size = nil)
33
+ "col-sm-#{size || builder.layout_object[:columns][:size_each]}"
34
34
  end
35
35
 
36
36
  def column_width
@@ -39,18 +39,18 @@ class LayoutStrategy::HotGlue < LayoutStrategy::Base
39
39
  "scaffold-row"
40
40
  end
41
41
 
42
- def column_classes_for_form_fields
42
+ def column_classes_for_form_fields(size = nil)
43
43
  "scaffold-cell"
44
44
  end
45
45
 
46
46
  def row_heading_classes
47
47
  "scaffold-heading-row"
48
48
  end
49
- def column_classes_for_line_fields
49
+ def column_classes_for_line_fields(size = nil)
50
50
  "scaffold-cell"
51
51
  end
52
52
 
53
- def column_classes_for_column_headings
53
+ def column_classes_for_column_headings(size = nil)
54
54
  "scaffold-cell"
55
55
  end
56
56
 
@@ -6,9 +6,9 @@ class LayoutStrategy::Tailwind < LayoutStrategy::Base
6
6
  def button_style ; ""; end
7
7
  def column_headings_col_style; "" ; end
8
8
  def column_width; ""; end
9
- def column_classes_for_line_fields; ""; end
10
- def column_classes_for_form_fields; ""; end
11
- def column_classes_for_column_headings; ""; end
9
+ def column_classes_for_line_fields(size = nil); ""; end
10
+ def column_classes_for_form_fields(size = nil); ""; end
11
+ def column_classes_for_column_headings(size = nil); ""; end
12
12
  def col_width; 100; end
13
13
  def container_name; ""; end
14
14
  def downnest_style ; ""; end
@@ -76,13 +76,14 @@ module HotGlue
76
76
  }.join("\n")
77
77
  end
78
78
 
79
- def list_column_headings(col_identifier: ,
80
- column_width:, singular: )
79
+ def list_column_headings(column_width:, singular: )
81
80
  col_style = @layout_strategy.column_headings_col_style
82
81
 
83
82
  columns = layout_object[:columns][:container]
84
- result = columns.map{ |column|
85
- "<div class='#{col_identifier} hg-heading-row heading--#{singular}--#{column.join("-")}' " + col_style + ">" +
83
+ result = columns.map.with_index{ |column,i|
84
+
85
+ size = layout_object[:columns][:bootstrap_column_width][i]
86
+ "<div class='#{layout_strategy.column_classes_for_column_headings(size)} hg-heading-row heading--#{singular}--#{column.join("-")}' " + col_style + ">" +
86
87
  column.map(&:to_s).map{|col_name| "#{col_name.humanize}"}.join("<br />") + "</div>"
87
88
  }.join("\n")
88
89
  return result
@@ -95,7 +96,6 @@ module HotGlue
95
96
 
96
97
  def search_input_area
97
98
  columns = layout_object[:columns][:container]
98
- column_classes = layout_strategy.column_classes_for_form_fields
99
99
 
100
100
  res =+ "<\%= form_with url: #{form_path}, method: :get, html: {'data-turbo-action': 'advance', 'data-controller': 'search-form'} do |f| %>"
101
101
  res << "<div class=\"#{@layout_strategy.row_classes} search--#{@plural}\">"
@@ -116,12 +116,13 @@ module HotGlue
116
116
  end
117
117
  }.compact.join("\n")
118
118
 
119
- " <div class='#{column_classes} search-cell--#{singular}--#{column.join("-")}' >" +
119
+ size = layout_object[:columns][:bootstrap_column_width][columns.index(column)]
120
+ " <div class='#{layout_strategy.column_classes_for_form_fields(size)} search-cell--#{singular}--#{column.join("-")}' >" +
120
121
  cols_result + "</div>"
121
122
 
122
123
  }.join("\n")
123
124
  res << "</div>"
124
- res << "<div class='#{column_classes}'>"
125
+ res << "<div class='#{layout_strategy.column_classes_for_form_fields(nil)}'>"
125
126
  if @search_clear_button
126
127
  res << "<\%= f.button \"Clear\", name: nil, 'data-search-form-target': 'clearButton', class: 'btn btn-sm btn-secondary' %>"
127
128
  end
@@ -132,11 +133,12 @@ module HotGlue
132
133
 
133
134
 
134
135
  def all_form_fields(layout_strategy:)
135
- column_classes = layout_strategy.column_classes_for_form_fields
136
136
  columns = layout_object[:columns][:container]
137
137
 
138
138
  result = columns.map{ |column|
139
- " <div class='#{column_classes} cell--#{singular}--#{column.join("-")}' >" +
139
+ size = layout_object[:columns][:bootstrap_column_width][columns.index(column)]
140
+
141
+ " <div class='#{layout_strategy.column_classes_for_form_fields(size)} cell--#{singular}--#{column.join("-")}' >" +
140
142
  column.map { |col|
141
143
 
142
144
  field_error_name = columns_map[col].field_error_name
@@ -192,10 +194,8 @@ module HotGlue
192
194
  ################################################################
193
195
 
194
196
  def all_line_fields(layout_strategy:,
195
- perc_width:,
196
- col_identifier: nil)
197
+ perc_width:)
197
198
 
198
- @col_identifier = layout_strategy.column_classes_for_line_fields
199
199
 
200
200
  inline_list_labels = @inline_list_labels || 'omit'
201
201
  columns = layout_object[:columns][:container]
@@ -205,9 +205,11 @@ module HotGlue
205
205
 
206
206
  style_with_flex_basis = layout_strategy.style_with_flex_basis(perc_width)
207
207
 
208
- result = columns.map{ |column|
208
+ result = columns.map.with_index{ |column,i|
209
209
 
210
- "<div class='hg-col #{col_identifier} #{singular}--#{column.join("-")}'#{style_with_flex_basis}> " +
210
+ size = layout_object[:columns][:bootstrap_column_width][i]
211
+
212
+ "<div class='hg-col #{layout_strategy.column_classes_for_line_fields(size)} #{singular}--#{column.join("-")}'#{style_with_flex_basis}> " +
211
213
  column.map { |col|
212
214
  if eval("#{singular_class}.columns_hash['#{col}']").nil? && !attachments.keys.include?(col) && !related_sets.include?(col)
213
215
  raise "Can't find column '#{col}' on #{singular_class}, are you sure that is the column name?"
@@ -219,6 +221,8 @@ module HotGlue
219
221
  "#{inline_list_labels == 'before' ? label + "<br/>" : ''}#{field_output}#{inline_list_labels == 'after' ? "<br/>" + label : ''}"
220
222
  }.join( "<br />") + "</div>"
221
223
  }.join("\n")
224
+ return result
225
+
222
226
  end
223
227
  end
224
228
  end
@@ -91,6 +91,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
91
91
  class_option :modify, default: {}
92
92
  class_option :display_as, default: {}
93
93
  class_option :pundit, default: nil
94
+ class_option :pundit_policy_override, default: nil
94
95
  class_option :related_sets, default: ''
95
96
  class_option :code_before_create, default: nil
96
97
  class_option :code_after_create, default: nil
@@ -357,6 +358,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
357
358
 
358
359
 
359
360
  @pundit = options['pundit']
361
+ @pundit_policy_override = options['pundit_policy_override']
360
362
 
361
363
  @no_nav_menu = options['no_nav_menu']
362
364
 
@@ -978,7 +980,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
978
980
 
979
981
  def list_column_headings
980
982
  @template_builder.list_column_headings(
981
- col_identifier: @layout_strategy.column_classes_for_column_headings,
982
983
  column_width: @layout_strategy.column_width,
983
984
  singular: @singular
984
985
  )
@@ -1442,7 +1443,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
1442
1443
 
1443
1444
  def all_line_fields
1444
1445
  @template_builder.all_line_fields(
1445
- col_identifier: @layout_strategy.column_classes_for_line_fields,
1446
1446
  perc_width: @layout_strategy.each_col, # undefined method `each_col'
1447
1447
  layout_strategy: @layout_strategy
1448
1448
  )
@@ -78,11 +78,12 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
78
78
  end
79
79
 
80
80
  def index
81
- load_all_<%= plural %>
82
- <% if @search_fields %>
81
+ load_all_<%= plural %><% if @search_fields %>
83
82
  <%= @search_fields.collect{|field_name| @columns_map[field_name.to_sym].code_to_reset_match_if_search_is_blank}.compact.join(" \n") %><% end %>
84
- load_all_<%= plural %><% if @pundit %><% if @pundit %>
85
- authorize @<%= plural_name %><% end %>
83
+ <% if @pundit %><% if @pundit && !@pundit_policy_override %>
84
+ authorize @<%= plural_name %><% elsif @pundit && @pundit_policy_override %>
85
+ skip_authorization
86
+ raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.index?<% end %>
86
87
  rescue Pundit::NotAuthorizedError
87
88
  flash[:alert] = 'You are not authorized to perform this action.'
88
89
  render 'layouts/error'<% end %>
@@ -92,7 +93,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
92
93
  @<%= singular_name %> = <%= class_name %>.new<% if eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>(<%= @object_owner_sym %>: <%= @object_owner_eval %>)<% end %><% elsif @object_owner_optional && any_nested? %>
93
94
  @<%= singular_name %> = <%= class_name %>.new({}.merge(<%= @nested_set.last[:singular] %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}))<% else %>
94
95
  @<%= singular_name %> = <%= class_name %>.new(<% if any_nested? %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)<% end %>
95
- <% if @pundit %>authorize @<%= singular_name %><% end %><% if @pundit %>
96
+ <% if @pundit && !@pundit_policy_override %>
97
+ authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
98
+ skip_authorization
99
+ raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.new?<% end %><% if @pundit %>
96
100
  @action = 'new'
97
101
  rescue Pundit::NotAuthorizedError
98
102
  flash[:alert] = 'You are not authorized to perform this action.'
@@ -112,7 +116,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
112
116
  <%= creation_syntax %>
113
117
  <% if @pundit %><% @related_sets.each do |key, related_set| %>
114
118
  check_<%= related_set[:association_ids_method].to_s %>_permissions(modified_params, :create)<% end %><% end %>
115
- <% if @pundit %>authorize @<%= singular %><% end %>
119
+ <% if @pundit && !@pundit_policy_override %>
120
+ authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
121
+ skip_authorization
122
+ raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.create?<% end %>
116
123
  <%= @code_before_create ? "\n " + @code_before_create.gsub(";", "\n") : "" %>
117
124
  if @<%= singular_name %>.save<%= @code_after_create ? ("\n " + @code_after_create.gsub(";", "\n")) : ""%>
118
125
  flash[:notice] = "Successfully created #{@<%= singular %>.<%= display_class %>}"
@@ -148,8 +155,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
148
155
 
149
156
  <% end %>
150
157
  <% unless @no_edit %>
151
- def show<% if @pundit %>
152
- authorize @<%= singular %><% end %>
158
+ def show<% if @pundit && !@pundit_policy_override %>
159
+ authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
160
+ skip_authorization
161
+ raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.show?<% end %>
153
162
  redirect_to <%= HotGlue.optionalized_ternary(namespace: @namespace,
154
163
  target: @singular,
155
164
  top_level: false,
@@ -160,8 +169,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
160
169
  put_form: true).gsub("(#{singular}", "(@#{singular}") %>
161
170
  end
162
171
 
163
- def edit<% if @pundit %>
164
- authorize @<%= singular_name %><% end %>
172
+ def edit<% if @pundit && !@pundit_policy_override %>
173
+ authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
174
+ skip_authorization
175
+ raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.edit?<% end %>
165
176
  @action = 'edit'
166
177
  render :edit<% if @pundit %>
167
178
  rescue Pundit::NotAuthorizedError
@@ -187,15 +198,19 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
187
198
 
188
199
  <% if @hawk_keys.any? %> modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %>
189
200
  <%= controller_attachment_orig_filename_pickup_syntax %>
190
- <% if @pundit %>
191
- if @<%= singular_name %>.attributes = modified_params
201
+ <% if @pundit && !@pundit_policy_override %>
192
202
  authorize @<%= singular_name %>
193
203
  <%= @code_before_update ? "\n " + @code_before_update.gsub(";", "\n") : "" %>
194
- @<%= singular_name %>.save
195
- <% else %>
196
- <%= @code_before_update ? "\n " + @code_before_update.gsub(";", "\n") : "" %>
204
+
197
205
  if @<%= singular_name %>.update(modified_params)
198
- <% end %>
206
+
207
+ <% elsif @pundit && @pundit_policy_override %>
208
+ skip_authorization
209
+ raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.update?
210
+ if @<%= singular_name %>.update(modified_params)
211
+ <% else %>
212
+ <%= @code_before_update ? "\n " + @code_before_update.gsub(";", "\n") : "" %>
213
+ if @<%= singular_name %>.update(modified_params)<% end %>
199
214
  <%= post_action_parental_updates.compact.join("\n ") %>
200
215
  <%= @code_after_update ? "\n " + @code_after_update.gsub(";", "\n") : "" %>
201
216
  <% if @display_list_after_update %> load_all_<%= plural %><% end %>
@@ -216,11 +231,14 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
216
231
  end
217
232
 
218
233
  <% end %><% if destroy_action %> def destroy
219
- <% if @pundit %>authorize @<%= singular_name %><% end %>
234
+ <% if @pundit && !@pundit_policy_override %>
235
+ authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
236
+ skip_authorization
237
+ raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.destroy?<% end %>
220
238
  begin
221
239
  @<%=singular_name%>.destroy
222
240
  flash[:notice] = '<%= singular_name.titlecase %> successfully deleted'
223
- rescue StandardError => e
241
+ rescue ActiveRecordError => e
224
242
  flash[:alert] = '<%= singular_name.titlecase %> could not be deleted'
225
243
  end
226
244
  <%= post_action_parental_updates.join("\n ") %>
@@ -8,30 +8,40 @@
8
8
  <% if @big_edit %>
9
9
  </div>
10
10
  </div>
11
+ </div>
12
+
11
13
 
12
14
 
13
15
  <% if @downnest_children.any? && @big_edit %>
14
- <hr />
15
- <% each_downnest_width = @downnest_children.count == 1 ? 33 : (53/@downnest_children.count).floor %>
16
- <% @downnest_object.each do |downnest, size| %>
17
- <div class="row">
18
- <div class="col-md-<%= @big_edit ? 12 : 6 %>">
16
+ <div class="container" data-controller="bootstrap-tabbed-nav">
17
+ <ul class="nav nav-tabs" id="<%= singular + "_downnest_portals" %>" role="tablist">
18
+ <% @downnest_object.each_with_index do |data,index| %>
19
+ <% downnest = data[0] %>
20
+ <li class="nav-item" role="presentation">
21
+ <button class="nav-link <%= "active" if index==0 %>" id="<%= downnest %>-tab" data-bs-toggle="tab" data-bs-target="#<%= downnest %>-portal" type="button" role="tab" aria-controls="home" aria-selected="true">
22
+ <%= downnest.titlecase.pluralize %>
23
+ </button>
24
+ </li>
25
+ <% end %>
26
+ </ul>
27
+
28
+ <div class="tab-content" id="myTabContent">
29
+ <% @downnest_object.each_with_index do |data, index| %>
30
+ <% downnest = data[0] %>
31
+ <div class="tab-pane fade <%= "show active" if index==0 %>" id="<%= downnest %>-portal" role="tabpanel" aria-labelledby="<%= downnest %>-tab">
19
32
  <% downnest_object = eval("#{singular_class}.reflect_on_association(:#{downnest})") %>
20
33
  <% if downnest_object.nil?; raise "no relationship for downnested portal `#{downnest}` found on `#{singular_class}`; please check relationship for has_many :#{downnest}"; end; %>
21
34
  <% downnest_class = downnest_object.class_name %>
22
35
  <% downnest_object_name = eval("#{downnest_class}.table_name") %>
23
36
  <% downnest_style = @layout_strategy.downnest_style %>
24
- <% if @downnest_shows_headings %>
25
- <h3>
26
- <%= downnest_class.titlecase.pluralize %>
27
- </h3>
28
- <% end %>
29
- <\%= render partial: "<%= namespace_with_trailing_dash %><%= downnest_object_name %>/list", locals: {<%= @singular %>: @<%= @singular %>, <%= downnest_object_name %>: @<%= @singular %>.<%= downnest %><% if @nested_set.any? %>, <%= @nested_set.collect{|x| "#{x[:singular]}: @#{x[:singular]}"}.join(", ") %>, nested_for: "<%= @nested_set.collect{|x| "#{x[:singular]}-" + "\#{" + "@#{x[:singular]}.id}"}.join("__") %>__<%= singular %>-#{@<%= @singular %>.id}" <% end %> } \%>
30
37
 
31
- </div>
38
+ <\%= render partial: "<%= namespace_with_trailing_dash %><%= downnest_object_name %>/list", locals: {<%= @singular %>: @<%= @singular %>, <%= downnest_object_name %>: @<%= @singular %>.<%= downnest %><% if @nested_set.any? %>, <%= @nested_set.collect{|x| "#{x[:singular]}: @#{x[:singular]}"}.join(", ") %>, nested_for: "<%= @nested_set.collect{|x| "#{x[:singular]}-" + "\#{" + "@#{x[:singular]}.id}"}.join("__") %>__<%= singular %>-#{@<%= @singular %>.id}" <% end %> } \%>
32
39
  </div>
33
40
  <% end %>
34
- <% end %>
41
+ </div>
42
+
35
43
  </div>
36
44
  <% end %>
37
45
 
46
+
47
+ <% end %>
@@ -1,5 +1,5 @@
1
1
  module HotGlue
2
2
  class Version
3
- CURRENT = '0.6.15'
3
+ CURRENT = '0.6.16'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hot-glue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.15
4
+ version: 0.6.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Fleetwood-Boldt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-17 00:00:00.000000000 Z
11
+ date: 2025-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails