brick 1.0.52 → 1.0.53
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/brick/extensions.rb +19 -2
- data/lib/brick/frameworks/rails/engine.rb +136 -61
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 737256fad5c987fa2ac603cf3708da959127a33ab9b27d164ceff858b71987b9
|
4
|
+
data.tar.gz: 144352db7686d19d9c330887069287da88de456276cc17aaeeaeb3c1de7a3281
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83ec370e06c18bf9d62ec3ed445daf78dc5cbff825a85ff017cc7b814efb62f86e68022f7577734dd01ddf7e2f74b4b59de4b40b9c07656e83d0859ba6a4333d
|
7
|
+
data.tar.gz: 9106373ca7878dcc75c596f1fa44d420980c50cb09f5b63a1110d4e02dc63f02dafe3d1bc0d4de38a75d5678d964e3b8f12a720a722d2f593934e2f6be97f818
|
data/lib/brick/extensions.rb
CHANGED
@@ -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
|
-
|
1160
|
-
|
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
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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
|
-
|
202
|
+
tr th {
|
199
203
|
background-color: #009879;
|
200
204
|
color: #fff;
|
201
205
|
text-align: left;
|
202
206
|
}
|
203
|
-
#headerTop
|
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
|
-
|
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
|
-
|
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
|
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:
|
461
|
-
headers: {
|
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
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
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
|
-
|
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
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
s <<
|
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
|
-
<%
|
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\\\"><< 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
|
-
|
608
|
-
|
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 =
|
614
|
-
txt = if col[
|
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
|
-
|
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 %>
|
data/lib/brick/version_number.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2022-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|