brick 1.0.52 → 1.0.53

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: e3d0b398d1d3926fa3e59281c976fe2f7a54bfc16de4f99683928ce71d7ace97
4
- data.tar.gz: 344c0de3e8691583e9a940ee451ad29015d46b0cbc55756d3b36e10d9ce27edb
3
+ metadata.gz: 737256fad5c987fa2ac603cf3708da959127a33ab9b27d164ceff858b71987b9
4
+ data.tar.gz: 144352db7686d19d9c330887069287da88de456276cc17aaeeaeb3c1de7a3281
5
5
  SHA512:
6
- metadata.gz: e0cff4e30c30d33dd13bd5a6a4a888d52e0552fc692369c42a53846da00e9ce677ab48ba840ef1396728d339984e5f7ff35d9ce33ea60f8421b9fa19edc14575
7
- data.tar.gz: 5971fcc802dd1732f71d3bcd015e4b616f7775028a10205c7e4b9b1fa41d13c0318f581c966c223e9a0661b8b9fa52e1197ae78c007144e93ec96de61b084663
6
+ metadata.gz: 83ec370e06c18bf9d62ec3ed445daf78dc5cbff825a85ff017cc7b814efb62f86e68022f7577734dd01ddf7e2f74b4b59de4b40b9c07656e83d0859ba6a4333d
7
+ data.tar.gz: 9106373ca7878dcc75c596f1fa44d420980c50cb09f5b63a1110d4e02dc63f02dafe3d1bc0d4de38a75d5678d964e3b8f12a720a722d2f593934e2f6be97f818
@@ -1116,6 +1116,11 @@ class Object
1116
1116
  if namespace && (idx = lookup_context.prefixes.index(table_name))
1117
1117
  lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
1118
1118
  end
1119
+ @_brick_excl = session[:_brick_exclude]&.split(',')&.each_with_object([]) do |excl, s|
1120
+ if (excl_parts = excl.split('.')).first == table_name
1121
+ s << excl_parts.last
1122
+ end
1123
+ end
1119
1124
  @_brick_bt_descrip = model._br_bt_descrip
1120
1125
  @_brick_hm_counts = model._br_hm_counts
1121
1126
  @_brick_join_array = join_array
@@ -1156,8 +1161,20 @@ class Object
1156
1161
  code << " end\n"
1157
1162
  self.define_method :create do
1158
1163
  ::Brick.set_db_schema(params)
1159
- instance_variable_set("@#{singular_table_name}".to_sym,
1160
- model.send(:create, send(params_name_sym)))
1164
+ if (is_json = request.content_type == 'application/json') && (col = params['_brick_exclude'])
1165
+ session[:_brick_exclude] = ((session[:_brick_exclude]&.split(',') || []) + ["#{table_name}.#{col}"]).join(',')
1166
+ render json: { result: ::Brick.exclude_column(table_name, col) }
1167
+ elsif is_json && (col = params['_brick_unexclude'])
1168
+ if (excls = ((session[:_brick_exclude]&.split(',') || []) - ["#{table_name}.#{col}"]).join(',')).empty?
1169
+ session.delete(:_brick_exclude)
1170
+ else
1171
+ session[:_brick_exclude] = excls
1172
+ end
1173
+ render json: { result: ::Brick.unexclude_column(table_name, col) }
1174
+ else
1175
+ instance_variable_set("@#{singular_table_name}".to_sym,
1176
+ model.send(:create, send(params_name_sym)))
1177
+ end
1161
1178
  end
1162
1179
 
1163
1180
  if pk_col
@@ -132,23 +132,24 @@ module Brick
132
132
  end
133
133
  case args.first
134
134
  when 'index'
135
- hms_columns << if hm_assoc.macro == :has_many
136
- if hm_fk_name
137
- set_ct = if skip_klass_hms.key?(assoc_name.to_sym)
138
- 'nil'
139
- else
140
- # Postgres column names are limited to 63 characters
141
- attrib_name = "_br_#{assoc_name}_ct"[0..62]
142
- "#{obj_name}.#{attrib_name} || 0"
143
- end
144
- "#{hm_assoc.name}: [#{assoc_name.inspect}, #{set_ct}, #{path_keys(hm_assoc, hm_fk_name, obj_name, pk)}]"
145
- else # %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
146
- "#{hm_assoc.name}: [#{assoc_name.inspect}]"
147
- end
148
- else # has_one
149
- # 0..62 because Postgres column names are limited to 63 characters
150
- "#{hm_assoc.name}: [#{assoc_name.inspect}, nil, #{path_keys(hm_assoc, hm_fk_name, obj_name, pk)}]"
135
+ hm_entry = +"'#{hm_assoc.name}' => [#{assoc_name.inspect}"
136
+ hm_entry << if hm_assoc.macro == :has_many
137
+ if hm_fk_name # %%% Can remove this check when multiple foreign keys to same destination becomes bulletproof
138
+ set_ct = if skip_klass_hms.key?(assoc_name.to_sym)
139
+ 'nil'
140
+ else
141
+ # Postgres column names are limited to 63 characters
142
+ "#{obj_name}.#{"_br_#{assoc_name}_ct"[0..62]} || 0"
143
+ end
144
+ ", #{set_ct}, #{path_keys(hm_assoc, hm_fk_name, obj_name, pk)}"
151
145
  end
146
+ else # has_one
147
+ # 0..62 because Postgres column names are limited to 63 characters
148
+ ", nil, #{path_keys(hm_assoc, hm_fk_name, obj_name, pk)}"
149
+ end
150
+ hm_entry << ']'
151
+ puts hm_entry
152
+ hms_columns << hm_entry
152
153
  when 'show', 'update'
153
154
  hm_stuff << if hm_fk_name
154
155
  "<%= link_to '#{assoc_name}', #{hm_assoc.klass.name.underscore.tr('/', '_').pluralize}_path({ #{path_keys(hm_assoc, hm_fk_name, "@#{obj_name}", pk)} }) %>\n"
@@ -174,6 +175,9 @@ module Brick
174
175
  end.html_safe
175
176
  table_options << '<option value="brick_orphans">(Orphans)</option>'.html_safe if is_orphans
176
177
  css = +"<style>
178
+ h1, h3 {
179
+ margin-bottom: 0;
180
+ }
177
181
  #dropper {
178
182
  background-color: #eee;
179
183
  }
@@ -195,19 +199,41 @@ table {
195
199
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
196
200
  }
197
201
 
198
- table thead tr th, table tr th {
202
+ tr th {
199
203
  background-color: #009879;
200
204
  color: #fff;
201
205
  text-align: left;
202
206
  }
203
- #headerTop th:hover, #headerTop th:hover {
207
+ #headerTop tr th {
208
+ position: relative;
209
+ }
210
+ #headerTop tr th .exclude {
211
+ position: absolute;
212
+ display: none;
213
+ top: 0;
214
+ right: 0;
215
+ }
216
+ #headerTop tr th:hover {
204
217
  background-color: #18B090;
205
218
  }
206
- table thead tr th a, table tr th a {
219
+ #exclusions {
220
+ font-size: 0.7em;
221
+ }
222
+ #exclusions div {
223
+ border: 1px solid blue;
224
+ display: inline-block;
225
+ cursor: copy;
226
+ }
227
+ #headerTop tr th:hover .exclude {
228
+ display: inline;
229
+ cursor: pointer;
230
+ color: red;
231
+ }
232
+ tr th a {
207
233
  color: #80FFB8;
208
234
  }
209
235
 
210
- table th, table td {
236
+ tr th, tr td {
211
237
  padding: 0.2em 0.5em;
212
238
  }
213
239
 
@@ -253,6 +279,7 @@ a.big-arrow {
253
279
  }
254
280
  .dimmed {
255
281
  background-color: #C0C0C0;
282
+ text-align: center;
256
283
  }
257
284
  .orphan {
258
285
  color: red;
@@ -414,8 +441,19 @@ function setHeaderSizes() {
414
441
  for (var i = 0; i < row.childNodes.length; ++i) {
415
442
  node = row.childNodes[i];
416
443
  if (node.nodeType === 1) {
417
- var style = tr.childNodes[i].style;
418
- style.minWidth = style.maxWidth = getComputedStyle(node).width;
444
+ var th = tr.childNodes[i];
445
+ th.style.minWidth = th.style.maxWidth = getComputedStyle(node).width;
446
+ if (#{pk&.present? ? 'i > 0' : 'true'}) {
447
+ // Add <span> at the end
448
+ var span = document.createElement(\"SPAN\");
449
+ span.className = \"exclude\";
450
+ span.innerHTML = \"X\";
451
+ span.addEventListener(\"click\", function (e) {
452
+ e.stopPropagation();
453
+ doFetch(\"POST\", {_brick_exclude: this.parentElement.getAttribute(\"x-order\")});
454
+ });
455
+ th.appendChild(span);
456
+ }
419
457
  }
420
458
  }
421
459
  if (isEmpty) headerTop.appendChild(tr);
@@ -423,6 +461,18 @@ function setHeaderSizes() {
423
461
  grid.style.marginTop = \"-\" + getComputedStyle(headerTop).height;
424
462
  // console.log(\"end\");
425
463
  }
464
+ function doFetch(method, payload, success) {
465
+ payload.authenticity_token = <%= session[:_csrf_token].inspect.html_safe %>;
466
+ if (!success) {
467
+ success = function (p) {p.text().then(function (response) {
468
+ var result = JSON.parse(response).result;
469
+ if (result) location.href = location.href;
470
+ });};
471
+ }
472
+ var options = {method: method, headers: {\"Content-Type\": \"application/json\"}};
473
+ if (payload) options.body = JSON.stringify(payload);
474
+ return fetch(location.href, options).then(success);
475
+ }
426
476
  if (headerTop) {
427
477
  setHeaderSizes();
428
478
  window.addEventListener('resize', function(event) {
@@ -457,8 +507,8 @@ if (headerTop) {
457
507
  });
458
508
  btnImport.addEventListener(\"click\", function () {
459
509
  fetch(changeout(<%= #{path_obj_name}_path(-1, format: :csv).inspect.html_safe %>, \"_brick_schema\", brickSchema), {
460
- method: 'PATCH',
461
- headers: { 'Content-Type': 'text/tab-separated-values' },
510
+ method: \"PATCH\",
511
+ headers: { \"Content-Type\": \"text/tab-separated-values\" },
462
512
  body: droppedTSV
463
513
  }).then(function (tsvResponse) {
464
514
  btnImport.style.display = \"none\";
@@ -536,6 +586,7 @@ if (headerTop) {
536
586
  if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(:description, nil)) %><%=
537
587
  description %><br><%
538
588
  end
589
+ # FILTER PARAMETERS
539
590
  if @_brick_params&.present? %>
540
591
  <% if @_brick_params.length == 1 # %%% Does not yet work with composite keys
541
592
  k, id = @_brick_params.first
@@ -547,38 +598,62 @@ if (headerTop) {
547
598
  end
548
599
  end %>
549
600
  (<%= link_to 'See all #{model_plural.split('::').last}', #{path_obj_name.pluralize}_path %>)
601
+ <% end
602
+ # COLUMN EXCLUSIONS
603
+ if @_brick_excl&.present? %>
604
+ <div id=\"exclusions\">Excluded columns:
605
+ <% @_brick_excl.each do |excl| %>
606
+ <div class=\"colExclusion\"><%= excl %></div>
607
+ <% end %>
608
+ </div>
609
+ <script>
610
+ [... document.getElementsByClassName(\"colExclusion\")].forEach(function (excl) {
611
+ excl.addEventListener(\"click\", function () {
612
+ doFetch(\"POST\", {_brick_unexclude: this.innerHTML});
613
+ });
614
+ });
615
+ </script>
550
616
  <% end %>
551
- <br>
552
617
  <table id=\"headerTop\">
553
618
  <table id=\"#{table_name}\">
554
619
  <thead><tr>#{"<th x-order=\"#{pk.join(',')}\"></th>" if pk.present?}<%=
555
- col_order = []
556
- # Consider getting the name from the association -- h.first.name -- if a more \"friendly\" alias should be used for a screwy table name
557
- hms_hdrs = {#{hms_headers.map do |hm|
558
- "#{hm.first.name}: [#{hm.first.name.inspect}, #{(hm.first.options[:through] && !hm.first.through_reflection).inspect}, #{hm.first.klass.name}, #{hm[1].inspect}, #{hm[2].inspect}]"
559
- end.join(', ')}}
560
- (@#{table_name}.columns + hms_hdrs.values).each_with_object(+'') do |col, s|
561
- if col.is_a?(ActiveRecord::ConnectionAdapters::Column)
562
- next if (#{(pk || []).inspect}.include?(col_name = col.name) && col.type == :integer && !bts.key?(col_name)) ||
563
- ::Brick.config.metadata_columns.include?(col_name) || poly_cols.include?(col_name)
564
-
565
- col_order << col_name
620
+ # Consider getting the name from the association -- hm.first.name -- if a more \"friendly\" alias should be used for a screwy table name
621
+ cols = {#{hms_keys = []
622
+ hms_headers.map do |hm|
623
+ hms_keys << (assoc_name = (assoc = hm.first).name.to_s)
624
+ "#{assoc_name.inspect} => [#{(assoc.options[:through] && !assoc.through_reflection).inspect}, #{assoc.klass.name}, #{hm[1].inspect}, #{hm[2].inspect}]"
625
+ end.join(', ')}}
626
+ col_keys = @#{table_name}.columns.each_with_object([]) do |col, s|
627
+ col_name = col.name
628
+ next if @_brick_incl&.exclude?(col_name) ||
629
+ (#{(pk || []).inspect}.include?(col_name) && col.type == :integer && !bts.key?(col_name)) ||
630
+ ::Brick.config.metadata_columns.include?(col_name) || poly_cols.include?(col_name)
631
+
632
+ s << col_name
633
+ cols[col_name] = col
634
+ end
635
+ unless @_brick_sequence # If no sequence is defined, start with all inclusions
636
+ @_brick_sequence = col_keys + #{(hms_keys).inspect}.reject { |assoc_name| @_brick_incl&.exclude?(assoc_name) }
637
+ end
638
+ @_brick_sequence.reject! { |nm| @_brick_excl.include?(nm) } if @_brick_excl # Reject exclusions
639
+ @_brick_sequence.each_with_object(+'') do |col_name, s|
640
+ if (col = cols[col_name]).is_a?(ActiveRecord::ConnectionAdapters::Column)
641
+ s << '<th'
642
+ s << \" title=\\\"#\{col.comment}\\\"\" if col.respond_to?(:comment) && !col.comment.blank?
566
643
  s << if (bt = bts[col_name])
567
- \"<th#\{' x-order=\"' + bt.first.to_s + '\"' unless bt[2]}>BT \" + # Allow sorting any BT except polymorphics
644
+ # Allow sorting for any BT except polymorphics
645
+ \"#\{' x-order=\"' + bt.first.to_s + '\"' unless bt[2]}>BT \" +
568
646
  bt[1].map { |bt_pair| bt_pair.first.bt_link(bt.first) }.join(' ')
569
- else
570
- # Currently we always allow click to sort on non-BT columns
571
- \"<th#\{' x-order=\"' + col_name + '\"' if true}>#\{col_name}\"
572
- end + '</th>'
573
- else # Currently we always allow click to sort on all HM columns (col is the hm array)
574
- col_order << col.first # hm.name
575
- s << \"<th#\{' x-order=\"' + col.first.to_s + '\"' if true}>\"
576
- s << if col[1]
577
- \"#\{col[3]} #\{col[4]}\" # %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
578
- else
579
- \"#\{col[3]} #\{link_to(col[4], send(\"#\{col[2].name.underscore.tr('/', '_').pluralize}_path\"))}\"
580
- end + '</th>'
647
+ else # Normal column
648
+ \"#\{' x-order=\"' + col_name + '\"' if true}>#\{col_name}\"
649
+ end
650
+ elsif col # HM column
651
+ s << \"<th#\{' x-order=\"' + col_name + '\"' if true}>#\{col[2]} \"
652
+ s << (col.first ? \"#\{col[3]}\" : \"#\{link_to(col[3], send(\"#\{col[1].name.underscore.tr('/', '_').pluralize}_path\"))}\")
653
+ else # Bad column name!
654
+ s << \"<th title=\\\"<< Unknown column >>\\\">#\{col_name}\"
581
655
  end
656
+ s << '</th>'
582
657
  end.html_safe
583
658
  %></tr></thead>
584
659
  <tbody>
@@ -586,16 +661,15 @@ if (headerTop) {
586
661
  hms_cols = {#{hms_columns.join(', ')}} %>
587
662
  <tr>#{"
588
663
  <td><%= link_to '⇛', #{path_obj_name}_path(#{obj_pk}), { class: 'big-arrow' } %></td>" if obj_pk}
589
- <% col_order.each do |col_name|
664
+ <% @_brick_sequence.each do |col_name|
590
665
  val = #{obj_name}.attributes[col_name] %>
591
- <td><%
666
+ <td<%= ' class=\"dimmed\"'.html_safe unless cols.key?(col_name)%>><%
592
667
  if (bt = bts[col_name])
593
668
  if bt[2] # Polymorphic?
594
669
  bt_class = #{obj_name}.send(\"#\{bt.first\}_type\")
595
670
  base_class = (::Brick.existing_stis[bt_class] || bt_class).constantize.base_class.name.underscore
596
671
  poly_id = #{obj_name}.send(\"#\{bt.first\}_id\")
597
- %><%= link_to(\"#\{bt_class\} ##\{poly_id\}\",
598
- send(\"#\{base_class\}_path\".to_sym, poly_id)) if poly_id %><%
672
+ %><%= link_to(\"#\{bt_class\} ##\{poly_id\}\", send(\"#\{base_class\}_path\".to_sym, poly_id)) if poly_id %><%
599
673
  else
600
674
  bt_txt = (bt_class = bt[1].first.first).brick_descrip(
601
675
  # 0..62 because Postgres column names are limited to 63 characters
@@ -604,15 +678,14 @@ if (headerTop) {
604
678
  bt_txt ||= \"<span class=\\\"orphan\\\">&lt;&lt; Orphaned ID: #\{val} >></span>\".html_safe if val
605
679
  bt_id = bt_id_col.map { |id_col| #{obj_name}.send(id_col.to_sym) } %>
606
680
  <%= bt_id&.first ? link_to(bt_txt, send(\"#\{bt_class.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, bt_id)) : bt_txt %>
607
- <%#= Previously was: bt_obj = bt[1].first.first.find_by(bt[2] => val); link_to(bt_obj.brick_descrip, send(\"#\{bt[1].first.first.name.underscore\}_path\".to_sym, bt_obj.send(bt[1].first.first.primary_key.to_sym))) if bt_obj %>
608
- <% end %>
609
- <% elsif (hms_col = hms_cols[col_name])
681
+ <% end
682
+ elsif (hms_col = hms_cols[col_name])
610
683
  if hms_col.length == 1 %>
611
684
  <%= hms_col.first %>
612
685
  <% else
613
- klass = (col = hms_hdrs[col_name])[2]
614
- txt = if col[3] == 'HO'
615
- descrips = @_brick_bt_descrip[col_name][klass]
686
+ klass = (col = cols[col_name])[1]
687
+ txt = if col[2] == 'HO'
688
+ descrips = @_brick_bt_descrip[col_name.to_sym][klass]
616
689
  ho_txt = klass.brick_descrip(#{obj_name}, descrips[0..-2].map { |id| #{obj_name}.send(id.last[0..62]) }, (ho_id_col = descrips.last))
617
690
  ho_id = ho_id_col.map { |id_col| #{obj_name}.send(id_col.to_sym) }
618
691
  ho_id&.first ? link_to(ho_txt, send(\"#\{klass.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, ho_id)) : ho_txt
@@ -620,9 +693,11 @@ if (headerTop) {
620
693
  \"#\{hms_col[1] || 'View'\} #\{hms_col.first}\"
621
694
  end %>
622
695
  <%= link_to txt, send(\"#\{klass.name.underscore.tr('/', '_').pluralize}_path\".to_sym, hms_col[2]) unless hms_col[1]&.zero? %>
623
- <% end %>
624
- <% else
696
+ <% end
697
+ elsif cols.key?(col_name)
625
698
  %><%= hide_bcrypt(val) %><%
699
+ else # Bad column name!
700
+ %>?<%
626
701
  end
627
702
  %></td>
628
703
  <% end %>
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 52
8
+ TINY = 53
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
data/lib/brick.rb CHANGED
@@ -190,6 +190,15 @@ module Brick
190
190
  [bts, hms]
191
191
  end
192
192
 
193
+ def exclude_column(table, col)
194
+ puts "Excluding #{table}.#{col}"
195
+ true
196
+ end
197
+ def unexclude_column(table, col)
198
+ puts "Unexcluding #{table}.#{col}"
199
+ true
200
+ end
201
+
193
202
  # Switches Brick auto-models on or off, for all threads
194
203
  # @api public
195
204
  def enable_models=(value)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brick
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.52
4
+ version: 1.0.53
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-04 00:00:00.000000000 Z
11
+ date: 2022-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord