hot-glue 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,19 +8,34 @@ module HotGlue
8
8
  :inline_list_labels, :layout_object,
9
9
  :columns, :col_identifier, :singular,
10
10
  :form_placeholder_labels, :hawk_keys, :update_show_only,
11
- :attachments, :show_only, :columns_map, :pundit, :related_sets
12
-
13
-
14
- def initialize(singular:, singular_class: ,
15
- layout_strategy: , magic_buttons: ,
16
- small_buttons: , show_only: ,
17
- ownership_field: , form_labels_position: ,
18
- inline_list_labels: ,
19
- form_placeholder_labels:, hawk_keys: ,
20
- update_show_only:, attachments: , columns_map:, pundit:, related_sets: )
11
+ :attachments, :show_only, :columns_map, :pundit, :related_sets,
12
+ :search, :search_fields, :search_query_fields, :search_position,
13
+ :form_path, :layout_object, :search_clear_button, :search_autosearch
14
+
15
+
16
+ def initialize(singular:, singular_class: ,
17
+ layout_strategy: , magic_buttons: ,
18
+ small_buttons: , show_only: ,
19
+ ownership_field: , form_labels_position: ,
20
+ inline_list_labels: ,
21
+ form_placeholder_labels:, hawk_keys: ,
22
+ update_show_only:, attachments: , columns_map:, pundit:, related_sets:,
23
+ search:, search_fields:, search_query_fields: , search_position:,
24
+ search_clear_button:, search_autosearch:, layout_object:,
25
+ form_path: )
26
+
27
+
28
+ @form_path = form_path
29
+ @search = search
30
+ @search_fields = search_fields
31
+ @search_by_query = search_query_fields
32
+ @search_position = search_position
33
+ @layout_object = layout_object
21
34
 
22
35
  @singular = singular
23
36
  @singular_class = singular_class
37
+ @search_clear_button = search_clear_button
38
+ @search_autosearch = search_autosearch
24
39
 
25
40
  @columns_map = columns_map
26
41
 
@@ -56,8 +71,7 @@ module HotGlue
56
71
  }.join("\n")
57
72
  end
58
73
 
59
- def list_column_headings(layout_object: ,
60
- col_identifier: ,
74
+ def list_column_headings(col_identifier: ,
61
75
  column_width:, singular: )
62
76
  col_style = @layout_strategy.column_headings_col_style
63
77
 
@@ -74,8 +88,41 @@ module HotGlue
74
88
  # THE FORM
75
89
  ################################################################
76
90
 
91
+ def search_input_area
92
+ columns = layout_object[:columns][:container]
93
+ column_classes = layout_strategy.column_classes_for_form_fields
94
+
95
+
96
+ res =+ "<\%= form_with url: #{form_path}, method: :get, html: {'data-turbo-action': 'advance', 'data-controller': 'search-form'} do |f| %>"
97
+ res << "<div class=\"#{@layout_strategy.row_classes} search--#{@plural}\">"
77
98
 
78
- def all_form_fields(layout_strategy:, layout_object: )
99
+ res << columns.map{ |column|
100
+ " <div class='#{column_classes} search-cell--#{singular}--#{column.join("-")}' >" +
101
+
102
+ column.map { |col|
103
+ label_class = columns_map[col].label_class
104
+ label_for = columns_map[col].label_for
105
+ the_label = "\n<label class='#{label_class}' for='search-#{label_for}'>#{col.to_s.humanize}</label>"
106
+ search_field_result = columns_map[col].search_field_output
107
+
108
+ add_spaces_each_line( "\n <span class='' >\n" +
109
+ add_spaces_each_line( (form_labels_position == 'before' ? the_label || "" : "") +
110
+ + " <br />\n" + search_field_result +
111
+ (form_labels_position == 'after' ? the_label : "") , 4) +
112
+ "\n </span>\n <br /></div>", 2)
113
+ }.join("\n")
114
+ }.join("\n")
115
+ res << "<div class='#{column_classes}'>"
116
+ if @search_clear_button
117
+ res << "<\%= f.button \"Clear\", name: nil, 'data-search-form-target': 'clearButton', class: 'btn btn-sm btn-secondary' %>"
118
+ end
119
+ res << "<\%= submit_tag \"Search\", name: nil, class: 'btn btn-sm btn-primary' %>"
120
+ res << "</div><\% end %>"
121
+ res
122
+ end
123
+
124
+
125
+ def all_form_fields(layout_strategy:)
79
126
  column_classes = layout_strategy.column_classes_for_form_fields
80
127
  columns = layout_object[:columns][:container]
81
128
 
@@ -105,7 +152,7 @@ module HotGlue
105
152
  else
106
153
  columns_map[col].form_field_output
107
154
  end
108
- # byebug
155
+
109
156
  @tinymce_stimulus_controller = (columns_map[col].modify_as == {tinymce: 1} ? "data-controller='tiny-mce' " : "")
110
157
 
111
158
  add_spaces_each_line( "\n <span #{@tinymce_stimulus_controller}class='<%= \"alert alert-danger\" if #{singular}.errors.details.keys.include?(:#{field_error_name}) %>' #{'style="display: inherit;"'} >\n" +
@@ -133,7 +180,6 @@ module HotGlue
133
180
  ################################################################
134
181
 
135
182
  def all_line_fields(layout_strategy:,
136
- layout_object: ,
137
183
  perc_width:,
138
184
  col_identifier: nil)
139
185
 
@@ -23,7 +23,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
23
23
  :nest_with, :path, :plural, :sample_file_path, :show_only_data, :singular,
24
24
  :singular_class, :smart_layout, :stacked_downnesting, :update_show_only, :ownership_field,
25
25
  :layout_strategy, :form_placeholder_labels, :form_labels_position, :pundit,
26
- :self_auth, :namespace_value, :related_sets
26
+ :self_auth, :namespace_value, :related_sets, :search_clear_button, :search_autosearch
27
27
  # important: using an attr_accessor called :namespace indirectly causes a conflict with Rails class_name method
28
28
  # so we use namespace_value instead
29
29
 
@@ -48,7 +48,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
48
48
  class_option :no_edit, type: :boolean, default: false
49
49
  class_option :no_list, type: :boolean, default: false
50
50
  class_option :no_controller, type: :boolean, default: false
51
- class_option :no_list, type: :boolean, default: false
52
51
  class_option :no_paginate, type: :boolean, default: false
53
52
  class_option :paginate_per_page_selector, type: :boolean, default: false
54
53
  class_option :big_edit, type: :boolean, default: false
@@ -95,6 +94,24 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
95
94
  class_option :code_before_update, default: nil
96
95
  class_option :code_after_update, default: nil
97
96
 
97
+ class_option :search, default: nil # set or predicate
98
+
99
+ # FOR THE SET SEARCH
100
+ class_option :search_fields, default: nil # comma separated list of all fields to search
101
+
102
+ # for the single-entry search box, they will be removed from the list specified above.
103
+ class_option :search_query_fields, default: '' # comma separated list of fields to search by single-entry search term
104
+ class_option :search_position, default: 'vertical' # choices are vertical or horizontal
105
+
106
+
107
+ class_option :search_clear_button, default: false
108
+ class_option :saerch_autosearch, default: false
109
+
110
+
111
+ # FOR THE PREDICATE SEARCH
112
+ # TDB
113
+
114
+
98
115
  def initialize(*meta_args)
99
116
  super
100
117
 
@@ -295,6 +312,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
295
312
 
296
313
  @no_edit = options['no_edit'] || false
297
314
  @no_list = options['no_list'] || false
315
+
298
316
  @no_controller = options['no_controller'] || false
299
317
  @no_list = options['no_list'] || false
300
318
  @no_list_label = options['no_list_label'] || false
@@ -471,6 +489,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
471
489
  @columns_map[col] = this_column_object.field
472
490
  end
473
491
 
492
+
474
493
  @columns_map.each do |key, field|
475
494
  if field.is_a?(AssociationField)
476
495
  if @modify_as && @modify_as[key] && @modify_as[key][:typeahead]
@@ -490,11 +509,42 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
490
509
  end
491
510
  end
492
511
 
512
+ # search
513
+ @search = options['search']
514
+ if @search == 'set'
515
+ @search_fields = options['search_fields'].split(',') || @columns
516
+ # within the set search we will take out any fields on the query list
517
+ # or the field
518
+ @search_query_fields = options['search_query_fields'].split(',') || []
519
+ @search_position = options['search_position'] || 'vertical'
520
+
521
+ @search_fields = @search_fields - @search_query_fields
522
+
523
+ @search_fields.each do |field|
524
+ if !@columns.include?(field.to_sym)
525
+ raise "You specified a search field for #{field} but that field is not in the list of columns"
526
+ end
527
+ end
528
+
529
+ @search_clear_button = !!options['search_clear_button']
530
+ @search_autosearch = !!options['search_autosearch']
531
+
532
+ elsif @search == 'predicate'
533
+
534
+ end
535
+
536
+ builder = HotGlue::Layout::Builder.new(generator: self,
537
+ include_setting: options['include'],
538
+ buttons_width: buttons_width)
539
+ @layout_object = builder.construct
493
540
 
494
541
 
495
542
  # create the template object
543
+
544
+
496
545
  if @markup == "erb"
497
546
  @template_builder = HotGlue::ErbTemplate.new(
547
+ layout_object: @layout_object,
498
548
  layout_strategy: @layout_strategy,
499
549
  magic_buttons: @magic_buttons,
500
550
  small_buttons: @small_buttons,
@@ -510,7 +560,14 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
510
560
  attachments: @attachments,
511
561
  columns_map: @columns_map,
512
562
  pundit: @pundit,
513
- related_sets: @related_sets
563
+ related_sets: @related_sets,
564
+ search: @search,
565
+ search_fields: @search_fields,
566
+ search_query_fields: @search_query_fields,
567
+ search_position: @search_position,
568
+ search_clear_button: @search_clear_button,
569
+ search_autosearch: @search_autosearch,
570
+ form_path: form_path_new_helper
514
571
  )
515
572
  elsif @markup == "slim"
516
573
  raise(HotGlue::Error, "SLIM IS NOT IMPLEMENTED")
@@ -518,10 +575,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
518
575
  raise(HotGlue::Error, "HAML IS NOT IMPLEMENTED")
519
576
  end
520
577
 
521
- builder = HotGlue::Layout::Builder.new(generator: self,
522
- include_setting: options['include'],
523
- buttons_width: buttons_width)
524
- @layout_object = builder.construct
525
578
 
526
579
  @menu_file_exists = true if @nested_set.none? && File.exist?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
527
580
 
@@ -688,6 +741,9 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
688
741
  @columns = @the_object.columns.map(&:name).map(&:to_sym).reject { |field| !@include_fields.include?(field) }
689
742
  end
690
743
 
744
+
745
+ @columns = @columns -@nested_set.collect { |set| (set[:singular] + "_id").to_sym }
746
+
691
747
  if @attachments.any?
692
748
  puts "Adding attachments-as-columns: #{@attachments}"
693
749
  @attachments.keys.each do |attachment|
@@ -826,7 +882,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
826
882
 
827
883
  def list_column_headings
828
884
  @template_builder.list_column_headings(
829
- layout_object: @layout_object,
830
885
  col_identifier: @layout_strategy.column_classes_for_column_headings,
831
886
  column_width: @layout_strategy.column_width,
832
887
  singular: @singular
@@ -1252,8 +1307,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
1252
1307
  end
1253
1308
 
1254
1309
  def form_fields_html
1255
- @template_builder.all_form_fields(layout_strategy: @layout_strategy,
1256
- layout_object: @layout_object)
1310
+ @template_builder.all_form_fields(layout_strategy: @layout_strategy)
1257
1311
  end
1258
1312
 
1259
1313
  def list_label
@@ -1268,8 +1322,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
1268
1322
  @template_builder.all_line_fields(
1269
1323
  col_identifier: @layout_strategy.column_classes_for_line_fields,
1270
1324
  perc_width: @layout_strategy.each_col, # undefined method `each_col'
1271
- layout_strategy: @layout_strategy,
1272
- layout_object: @layout_object
1325
+ layout_strategy: @layout_strategy
1273
1326
  )
1274
1327
  end
1275
1328
 
@@ -1387,8 +1440,55 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
1387
1440
  end
1388
1441
  end
1389
1442
 
1443
+
1444
+ def load_all_code
1445
+ # the inner method definition of the load_all_* method
1446
+ res = +""
1447
+ if @search_fields
1448
+ res << @search_fields.collect{ |field|
1449
+ if !@columns_map[field.to_sym].load_all_query_statement.empty?
1450
+ @columns_map[field.to_sym].load_all_query_statement
1451
+ end
1452
+ }.compact.join("\n" + spaces(4))
1453
+ res << "\n"
1454
+ end
1455
+
1456
+ if pundit
1457
+ res << "@#{ plural_name } = policy_scope(#{ object_scope }).page(params[:page])#{ n_plus_one_includes }#{ ".per(per)" if @paginate_per_page_selector }"
1458
+ else
1459
+ if !@self_auth
1460
+ res << spaces(4) + "@#{ plural_name } = #{ object_scope.gsub("@",'') }#{ n_plus_one_includes }.page(params[:page])#{ ".per(per)" if @paginate_per_page_selector }"
1461
+ if @search_fields
1462
+ res << @search_fields.collect{ |field|
1463
+ wqs = @columns_map[field.to_sym].where_query_statement
1464
+ if !wqs.empty?
1465
+ "\n" + spaces(4) + "@#{ plural_name } = @#{ plural_name }#{ wqs } if #{field}_query"
1466
+ end
1467
+ }.compact.join
1468
+ end
1469
+ elsif @nested_set[0] && @nested_set[0][:optional]
1470
+ res << "@#{ plural_name } = #{ class_name }.all"
1471
+ else
1472
+ res << "@#{ plural_name } = #{ class_name }.where(id: #{ auth_object.gsub("@",'') }.id)#{ n_plus_one_includes }"
1473
+ if @search_fields
1474
+ res << @search_fields.collect{ |field|
1475
+ @columns_map[field.to_sym].where_query_statement
1476
+ }.join("\n")
1477
+ end
1478
+ res << ".page(params[:page])#{ ".per(per)" if @paginate_per_page_selector }"
1479
+ end
1480
+ end
1481
+ res
1482
+ end
1483
+
1484
+
1390
1485
  private # thor does something fancy like sending the class all of its own methods during some strange run sequence
1391
1486
  # does not like public methods
1487
+
1488
+ def spaces(num)
1489
+ " " * num
1490
+ end
1491
+
1392
1492
  def cc_filename_with_extensions(name, file_format = format)
1393
1493
  [name, file_format].compact.join(".")
1394
1494
  end
@@ -1419,8 +1519,8 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
1419
1519
 
1420
1520
  def turbo_parental_updates
1421
1521
  @nested_set.collect { |data|
1422
- "<%= turbo_stream.replace \"#{@namespace + '__' if @namespace}\#{dom_id(@#{data[:singular]})}\" do %>
1423
- <%= render partial: \"#{@namespace}/#{data[:plural]}/edit\", locals: {#{data[:singular]}: @#{singular}.#{data[:singular]}.reload} %>
1522
+ "<%= turbo_stream.replace \"__#{@namespace if @namespace}\#{dom_id(@#{data[:singular]})}\" do %>
1523
+ <%= render partial: \"#{@namespace}/#{data[:plural]}/line\", locals: {#{data[:singular]}: @#{singular}.#{data[:singular]}.reload} %>
1424
1524
  <% end %>"
1425
1525
  }.join("\n")
1426
1526
  end
@@ -0,0 +1,26 @@
1
+
2
+
3
+ module HotGlue
4
+ class SetSearchInterfaceInstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('templates', __dir__)
6
+
7
+ def filepath_prefix
8
+ # todo: inject the context
9
+ 'spec/dummy/' if $INTERNAL_SPECS
10
+ end
11
+
12
+ def initialize(*args) #:nodoc:
13
+ super
14
+
15
+ ['date_range_picker','time_range_picker','search_form'].each do |file|
16
+ system("./bin/rails generate stimulus #{file.titlecase.gsub(" ", "")}")
17
+ copy_file "javascript/#{file}_controller.js", "#{filepath_prefix}app/javascript/controllers/#{file}.js"
18
+ puts "HOT GLUE --> copying #{file} stimulus controller into app/javascript/controllers/#{file}.js"
19
+
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+
26
+
@@ -70,24 +70,21 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
70
70
  end<% end %>
71
71
  <% if @paginate_per_page_selector %>def per
72
72
  params[:per] || 10
73
+ end<% end %>
74
+ <% unless @no_list %>
75
+ def load_all_<%= plural %>
76
+ <%= load_all_code %>
73
77
  end
74
78
 
75
- <% end %>def load_all_<%= plural %><% if @pundit %>
76
- @<%= plural_name %> = policy_scope(<%= object_scope %>).page(params[:page])<%= n_plus_one_includes %><%= ".per(per)" if @paginate_per_page_selector %>
77
- <% else %> <% if !@self_auth %>
78
- @<%= plural_name %> = <%= object_scope.gsub("@",'') %><%= n_plus_one_includes %>.page(params[:page])<%= ".per(per)" if @paginate_per_page_selector %><%= " if params.include?(:#{ @nested_set.last[:singular]}_id)" if @nested_set.any? && @nested_set[0] && @nested_set[0][:optional] %><% if @nested_set[0] && @nested_set[0][:optional] %>
79
- @<%= plural_name %> = <%= class_name %>.all<% end %><% else %>
80
- @<%= plural_name %> = <%= class_name %>.where(id: <%= auth_object.gsub("@",'') %>.id)<%= n_plus_one_includes %>.page(params[:page])<%= ".per(per)" if @paginate_per_page_selector %><% end %>
81
- <% end %>
82
- end
83
-
84
- def index
79
+ def index <% if @search == "set" %>
80
+ @q = params[:q] || <%= {"0" => @search_fields.collect{|foo| {"#{foo}_match".to_sym => "", "#{foo}_search".to_sym => ""}}.reduce({}, :merge) } %> <% end %><% if @search_fields %>
81
+ <%= @search_fields.collect{|field_name| @columns_map[field_name.to_sym].code_to_reset_match_if_search_is_blank}.compact.join(" \n") %><% end %>
85
82
  load_all_<%= plural %><% if @pundit %><% if @pundit %>
86
83
  authorize @<%= plural_name %><% end %>
87
84
  rescue Pundit::NotAuthorizedError
88
85
  flash[:alert] = 'You are not authorized to perform this action.'
89
86
  render 'layouts/error'<% end %>
90
- end
87
+ end<% end %>
91
88
 
92
89
  <% if create_action %> def new<% if @object_owner_sym %>
93
90
  @<%= singular_name %> = <% if @pundit %>policy_scope(<% end %><%= class_name %><% if @pundit %>)<% end %>.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? %>
@@ -102,10 +99,11 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
102
99
  end
103
100
 
104
101
  def create
105
- modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup, <%= current_user_object %>, <%= datetime_fields_list %>) <% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>
102
+ flash[:alert] = +''
103
+ flash[:notice] = +''
104
+ modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup, <%= current_user_object %>, <%= datetime_fields_list %>)<% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>
106
105
  modified_params = modified_params.merge(<%= @object_owner_sym %>: <%= @object_owner_eval %>) <% elsif @object_owner_optional && any_nested? %>
107
- modified_params = modified_params.merge(<%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}) <% elsif !@object_owner_eval.empty? && !@god %>
108
- modified_params = modified_params.merge(<%= @object_owner_eval %>) <% end %>
106
+ modified_params = modified_params.merge(<%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}) <% end %>
109
107
 
110
108
  <% if @hawk_keys.any? %>
111
109
  modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %>
@@ -125,11 +123,9 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
125
123
  @action = 'new'
126
124
  render :create, status: :unprocessable_entity
127
125
  end<% if @pundit %>
128
- rescue Pundit::NotAuthorizedError
129
- flash[:alert] << 'Creating organization not authorized. '
130
- flash[:alert] << @<%= singular %>.errors.collect{|k| "#{k.attribute} #{k.message}"}.join(" ")
131
- flash[:alert] << flash[:notice]
132
- render :index <% end %>
126
+ rescue Pundit::NotAuthorizedError => e
127
+ @user.errors.add(:base, e.message)
128
+ render :create, status: :unprocessable_entity<% end %>
133
129
  end
134
130
 
135
131
  <% end %>
@@ -165,8 +161,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
165
161
 
166
162
  modified_params = modify_date_inputs_on_params(<% if @update_show_only %>update_<% end %><%= singular_name %>_params.dup<%= controller_update_params_tap_away_magic_buttons %>, <%= current_user_object %>, <%= datetime_fields_list %>) <% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>
167
163
  modified_params = modified_params.merge(<%= @object_owner_sym %>: <%= @object_owner_eval %>) <% elsif @object_owner_optional && any_nested? %>
168
- modified_params = modified_params.merge(<%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}) <% elsif ! @object_owner_eval.empty? && !@self_auth && ! @god%>
169
- modified_params = modified_params.merge(<%= @object_owner_eval %>) <% end %>
164
+ modified_params = modified_params.merge(<%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}) <% end %>
170
165
  <% if @pundit %><% @related_sets.each do |key, related_set| %>
171
166
  check_<%= related_set[:association_ids_method].to_s %>_permissions(modified_params, :update)<% end %><% end %>
172
167
 
@@ -212,27 +207,31 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
212
207
 
213
208
  <% if @pundit %><% @related_sets.each do |key, rs| %>
214
209
  def check_<%= rs[:association_ids_method] %>_permissions(modified_params, action)
215
- if modified_params[:<%= rs[:association_ids_method] %>].present? &&
216
- modified_params[:<%= rs[:association_ids_method] %>] != @<%= singular %>.<%= rs[:association_ids_method] %>
217
- # authorize the <%= rs[:association_ids_method] %> change using special modified_relations: {
218
- # <%= rs[:association_ids_method] %>: modified_params[:<%= rs[:association_ids_method] %>>]} syntax for Pundit
219
- if ! <%= singular_class %>Policy.new(current_user, @<%= singular %>,
220
- modified_relations: {role_ids: modified_params[:<%= rs[:association_ids_method] %>]
221
- }).method("#{action}?".to_sym).call
222
- authorize @<%= singular %>, "#{action}?".to_sym
223
- raise Pundit::NotAuthorizedError, message: @<%= singular %>.errors.collect{|k| "#{k.attribute} #{k.message}"}.join(" ")
224
- end
225
- end
210
+ # authorize the <%= rs[:association_ids_method] %> change using special modified_relations: {
211
+ # <%= rs[:association_ids_method] %>: modified_params[:<%= rs[:association_ids_method] %>>]} syntax for Pundit
212
+ modified_relations = { <%= rs[:association_ids_method] %>: modified_params[:<%= rs[:association_ids_method] %>] }
213
+ return unless modified_params[:<%= rs[:association_ids_method] %>].present?
214
+ policy_check = <%= singular_class %>Policy.new(current_user, @<%= singular %>,
215
+ modified_relations:).method("#{action}?".to_sym).call
216
+ return if policy_check
217
+ raise Pundit::NotAuthorizedError, message: @<%= singular %>.errors.collect{|k| "#{k.attribute} #{k.message}"}.join(" ")
226
218
  end<% end %><% end %>
227
219
 
228
220
  def <%=singular_name%>_params
229
221
  params.require(:<%= testing_name %>).permit(<%= ((fields_filtered_for_strong_params - @show_only ) + @magic_buttons.collect{|x| "__#{x}"}).collect{|sym| ":#{sym}"}.join(", ") %><%= ", " + @related_sets.collect{|key, rs| "#{rs[:association_ids_method]}: []"}.join(", ") if @related_sets.any? %>)
230
222
  end<% if @update_show_only %>
231
223
 
224
+ <% unless @no_edit %>
232
225
  def update_<%=singular_name%>_params
233
226
  params.require(:<%= testing_name %>).permit(<%= ((fields_filtered_for_strong_params - @update_show_only) + @magic_buttons.collect{|x| "__#{x}"}).collect{|sym| ":#{sym}"}.join(", ") %><%= ", " + @related_sets.collect{|key, rs| "#{rs[:association_ids_method]}: []"}.join(", ") if @related_sets.any? %>)
234
227
  end<% end %>
228
+ <% end %>
235
229
 
230
+ <% if @search %>
231
+ def search_params
232
+ params.permit(:q, :page)
233
+ end
234
+ <% end %>
236
235
  def namespace
237
236
  <% if @namespace %>'<%= @namespace %>/'<% else %><% end %>
238
237
  end
@@ -1,4 +1,5 @@
1
1
  <\%= turbo_frame_tag "<%= @namespace %>__<%= plural %>-list" <%= nested_for_turbo_id_list_constructor %> do %>
2
+
2
3
  <div class="<%= @container_name %> <%= @layout_strategy.list_classes %>">
3
4
  <% unless @no_list || @no_list_label || (@nested_set.any? && !@nested_set.collect{|x| x[:optional]}.any?) %>
4
5
  <% unless list_label.nil? %><h4>
@@ -40,6 +41,10 @@
40
41
  </div>
41
42
  <% end %>
42
43
 
44
+ <% if @search %>
45
+ <%= @template_builder.search_input_area %>
46
+ <% end %>
47
+
43
48
  <\% if <%= plural %>.empty? %>
44
49
  <div>
45
50
  None
@@ -0,0 +1,45 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="date-range-picker"
4
+ export default class extends Controller {
5
+
6
+ static targets = [ "matchSelector", "start", "end" ];
7
+ connect() {
8
+
9
+ console.log("date_range_picker_controller.js connect.....")
10
+ }
11
+
12
+ matchSelection(event) {
13
+
14
+ console.log("date_range_picker_controller.js matchSelection.....")
15
+ console.log(event.target.value)
16
+ // this.matchSelectorTarget.value = event.target.value
17
+
18
+ switch(event.target.value) {
19
+ case "is_on":
20
+ this.startTarget.disabled = false
21
+ this.endTarget.disabled = true
22
+ this.endTarget.value = ""
23
+ break;
24
+ case "is_between":
25
+ this.startTarget.disabled = false
26
+ this.endTarget.disabled = false
27
+ break;
28
+ case "is_on_or_after":
29
+ this.startTarget.disabled = false
30
+ this.endTarget.disabled = true
31
+ this.endTarget.value = ""
32
+ break;
33
+ case "is_before_or_on":
34
+ this.startTarget.disabled = true
35
+ this.startTarget.value = ""
36
+ this.endTarget.disabled = false
37
+ break;
38
+ case "not_on":
39
+ this.startTarget.disabled = false
40
+ this.endTarget.disabled = true
41
+ this.endTarget.value = ""
42
+ break;
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,16 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="search_form"
4
+ export default class extends Controller {
5
+ static targets = ["clearButton"];
6
+
7
+ connect() {
8
+
9
+ if (this.hasClearButtonTarget) {
10
+ this.clearButtonTarget.addEventListener("click", (event) => {
11
+ event.preventDefault()
12
+ this.element.reset()
13
+ })
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,38 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="time-range-picker"
4
+ export default class extends Controller {
5
+ static targets = [ "matchSelector", "start", "end" ];
6
+ connect() {
7
+ console.log("time_range_picker_controller.js connect.....")
8
+ }
9
+
10
+ matchSelection(event) {
11
+
12
+ console.log("time_range_picker_controller.js matchSelection.....")
13
+ console.log(event.target.value)
14
+ // this.matchSelectorTarget.value = event.target.value
15
+
16
+ switch(event.target.value) {
17
+ case "is_at":
18
+ this.startTarget.disabled = false
19
+ this.endTarget.disabled = true
20
+ this.endTarget.value = ""
21
+ break;
22
+ case "is_between":
23
+ this.startTarget.disabled = false
24
+ this.endTarget.disabled = false
25
+ break;
26
+ case "is_at_or_after":
27
+ this.startTarget.disabled = false
28
+ this.endTarget.disabled = true
29
+ this.endTarget.value = ""
30
+ break;
31
+ case "is_before_or_at":
32
+ this.startTarget.disabled = true
33
+ this.startTarget.value = ""
34
+ this.endTarget.disabled = false
35
+ break;
36
+ }
37
+ }
38
+ }
@@ -1,5 +1,5 @@
1
1
  module HotGlue
2
2
  class Version
3
- CURRENT = '0.6.2'
3
+ CURRENT = '0.6.3'
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.2
4
+ version: 0.6.3
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: 2023-12-02 00:00:00.000000000 Z
11
+ date: 2024-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -107,6 +107,7 @@ files:
107
107
  - lib/generators/hot_glue/markup_templates/erb.rb
108
108
  - lib/generators/hot_glue/nav_template_generator.rb
109
109
  - lib/generators/hot_glue/scaffold_generator.rb
110
+ - lib/generators/hot_glue/set_search_interface_install_generator.rb
110
111
  - lib/generators/hot_glue/templates/base_controller.rb.erb
111
112
  - lib/generators/hot_glue/templates/capybara_login.rb
112
113
  - lib/generators/hot_glue/templates/computer_code.jpg
@@ -127,7 +128,10 @@ files:
127
128
  - lib/generators/hot_glue/templates/erb/index.erb
128
129
  - lib/generators/hot_glue/templates/erb/new.erb
129
130
  - lib/generators/hot_glue/templates/erb/update.turbo_stream.erb
131
+ - lib/generators/hot_glue/templates/javascript/date_range_picker_controller.js
130
132
  - lib/generators/hot_glue/templates/javascript/dropzone_controller.js
133
+ - lib/generators/hot_glue/templates/javascript/search_form_controller.js
134
+ - lib/generators/hot_glue/templates/javascript/time_range_picker_controller.js
131
135
  - lib/generators/hot_glue/templates/system_spec.rb.erb
132
136
  - lib/generators/hot_glue/templates/themes/hotglue_scaffold_dark_knight.scss
133
137
  - lib/generators/hot_glue/templates/themes/hotglue_scaffold_like_bootstrap.scss