headmin 0.5.9 → 0.6.1

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -0
  3. data/CHANGELOG.md +12 -0
  4. data/Gemfile.lock +121 -117
  5. data/README.md +2 -2
  6. data/app/assets/javascripts/headmin/controllers/media_controller.js +38 -1
  7. data/app/assets/javascripts/headmin/controllers/textarea_controller.js +15 -1
  8. data/app/assets/javascripts/headmin.js +42 -2
  9. data/app/assets/stylesheets/headmin/overrides/redactorx.scss +2 -1
  10. data/app/assets/stylesheets/headmin.css +2 -1
  11. data/app/controllers/concerns/headmin/pagination.rb +1 -1
  12. data/app/models/concerns/headmin/attachment.rb +34 -0
  13. data/app/models/concerns/headmin/blob.rb +1 -1
  14. data/app/models/concerns/headmin/block.rb +6 -0
  15. data/app/models/concerns/headmin/fieldable.rb +10 -2
  16. data/app/models/headmin/filter/base.rb +2 -2
  17. data/app/models/headmin/form/blocks_view.rb +13 -0
  18. data/app/models/headmin/form/color_view.rb +1 -2
  19. data/app/models/headmin/form/media_view.rb +8 -4
  20. data/app/views/headmin/_blocks.html.erb +3 -6
  21. data/app/views/headmin/_filters.html.erb +2 -7
  22. data/app/views/headmin/_form.html.erb +1 -1
  23. data/app/views/headmin/_index.html.erb +1 -1
  24. data/app/views/headmin/forms/_blocks.html.erb +10 -3
  25. data/app/views/headmin/forms/_media.html.erb +7 -5
  26. data/app/views/headmin/forms/_repeater.html.erb +3 -1
  27. data/app/views/headmin/forms/blocks/_modal.html.erb +20 -0
  28. data/app/views/headmin/forms/fields/_base.html.erb +1 -1
  29. data/app/views/headmin/forms/fields/_group.html.erb +18 -11
  30. data/app/views/headmin/forms/fields/_list.html.erb +4 -1
  31. data/app/views/headmin/forms/media/_validation.html.erb +10 -0
  32. data/app/views/headmin/forms/repeater/_row.html.erb +2 -1
  33. data/app/views/headmin/layout/_content.html.erb +1 -1
  34. data/app/views/headmin/layout/_footer.html.erb +1 -1
  35. data/app/views/headmin/media/_media_item_modal.html.erb +26 -0
  36. data/app/views/headmin/nav/_item.html.erb +6 -1
  37. data/config/initializers/extend_active_storage_attachment.rb +3 -0
  38. data/config/locales/activerecord/en.yml +2 -0
  39. data/config/locales/activerecord/nl.yml +3 -0
  40. data/config/locales/headmin/forms/en.yml +12 -0
  41. data/config/locales/headmin/forms/nl.yml +13 -0
  42. data/config/locales/headmin/media/en.yml +1 -0
  43. data/config/locales/headmin/media/nl.yml +1 -0
  44. data/lib/generators/templates/migrations/create_blocks.rb +2 -0
  45. data/lib/headmin/version.rb +1 -1
  46. data/package.json +1 -1
  47. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de108dc4e7610d069568dcaca3710fe2b57c26f8937087503cba8becc0738134
4
- data.tar.gz: ab79adc7a81dd88069dabc832ed9f0b00bf77674cd378f30895a7469e0fea5fc
3
+ metadata.gz: 4f0d94377c6d3cf0d97bdffa08c34d9c95ef9b72036c8e7b1d0d1b89996ed52d
4
+ data.tar.gz: 9b263a38b16dacace7769f9eb2cab3b90dc478cc229fead7ae157c4fd48e7f65
5
5
  SHA512:
6
- metadata.gz: dc7180989c84f5c3362a93c61a22587c2b13f6b5f2af207b0de8556ec1a29a2844add4637c2430bb6d1db2b4b73a28642981a050dea30c4397117f3284b440a6
7
- data.tar.gz: d2abdb1d8806ffff2dd5af8cec68a3f87a37afa64ad6bdd4d59db4b9d469b0a22664f4a2cb6ee4539e8acf2deba7eda9f8f40b38b8c8641e9d74885da3591a09
6
+ metadata.gz: 3ee1ebb9dbc530154fd310c910dbab36e13272a0c3433b494588e6f552c5e8af6c6ee4f39b41f2737a7b2321805c02d9a5c22b7dfeea9c62455584ecc0cbc907
7
+ data.tar.gz: e88897ec516a9b4f83188f8eb12e1b49d46da547d03b459942da6f77266faee9031f0f3f06c5300529183e6f6cd9aa2112e92ce1b30ba7902edcd919b0f9ceaf
data/.gitignore CHANGED
@@ -25,3 +25,9 @@
25
25
  # Ingore editors
26
26
  /.idea
27
27
  /headmin.iml
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ Gemfile.lock
32
+ # .ruby-version
33
+ # .ruby-gemset
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Headmin Changelog
2
2
 
3
+ ## 0.6
4
+ - FEATURE: Blocks can now be configured to have custom anchor names and have its visibility toggled
5
+ - BREAK: Add this migration to current projects that make use of blocks
6
+ ```ruby
7
+ class AddVisibleHandleToBlock < ActiveRecord::Migration[7.0]
8
+ def change
9
+ add_column :blocks, :visible, :boolean, default: true
10
+ add_column :blocks, :handle, :string
11
+ end
12
+ end
13
+ ```
14
+
3
15
  ## 0.5
4
16
  - FEATURE: Filters now have support for operators and conditionals
5
17
  - BREAK: `headmin/filters` now return a form object that is required for each individual form
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- headmin (0.5.8)
4
+ headmin (0.6.0)
5
5
  closure_tree (~> 7.4)
6
6
  inline_svg (~> 1.7)
7
7
  redcarpet (~> 3.5)
@@ -10,81 +10,81 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- actioncable (7.0.2.4)
14
- actionpack (= 7.0.2.4)
15
- activesupport (= 7.0.2.4)
13
+ actioncable (7.0.4.1)
14
+ actionpack (= 7.0.4.1)
15
+ activesupport (= 7.0.4.1)
16
16
  nio4r (~> 2.0)
17
17
  websocket-driver (>= 0.6.1)
18
- actionmailbox (7.0.2.4)
19
- actionpack (= 7.0.2.4)
20
- activejob (= 7.0.2.4)
21
- activerecord (= 7.0.2.4)
22
- activestorage (= 7.0.2.4)
23
- activesupport (= 7.0.2.4)
18
+ actionmailbox (7.0.4.1)
19
+ actionpack (= 7.0.4.1)
20
+ activejob (= 7.0.4.1)
21
+ activerecord (= 7.0.4.1)
22
+ activestorage (= 7.0.4.1)
23
+ activesupport (= 7.0.4.1)
24
24
  mail (>= 2.7.1)
25
25
  net-imap
26
26
  net-pop
27
27
  net-smtp
28
- actionmailer (7.0.2.4)
29
- actionpack (= 7.0.2.4)
30
- actionview (= 7.0.2.4)
31
- activejob (= 7.0.2.4)
32
- activesupport (= 7.0.2.4)
28
+ actionmailer (7.0.4.1)
29
+ actionpack (= 7.0.4.1)
30
+ actionview (= 7.0.4.1)
31
+ activejob (= 7.0.4.1)
32
+ activesupport (= 7.0.4.1)
33
33
  mail (~> 2.5, >= 2.5.4)
34
34
  net-imap
35
35
  net-pop
36
36
  net-smtp
37
37
  rails-dom-testing (~> 2.0)
38
- actionpack (7.0.2.4)
39
- actionview (= 7.0.2.4)
40
- activesupport (= 7.0.2.4)
38
+ actionpack (7.0.4.1)
39
+ actionview (= 7.0.4.1)
40
+ activesupport (= 7.0.4.1)
41
41
  rack (~> 2.0, >= 2.2.0)
42
42
  rack-test (>= 0.6.3)
43
43
  rails-dom-testing (~> 2.0)
44
44
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
45
- actiontext (7.0.2.4)
46
- actionpack (= 7.0.2.4)
47
- activerecord (= 7.0.2.4)
48
- activestorage (= 7.0.2.4)
49
- activesupport (= 7.0.2.4)
45
+ actiontext (7.0.4.1)
46
+ actionpack (= 7.0.4.1)
47
+ activerecord (= 7.0.4.1)
48
+ activestorage (= 7.0.4.1)
49
+ activesupport (= 7.0.4.1)
50
50
  globalid (>= 0.6.0)
51
51
  nokogiri (>= 1.8.5)
52
- actionview (7.0.2.4)
53
- activesupport (= 7.0.2.4)
52
+ actionview (7.0.4.1)
53
+ activesupport (= 7.0.4.1)
54
54
  builder (~> 3.1)
55
55
  erubi (~> 1.4)
56
56
  rails-dom-testing (~> 2.0)
57
57
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
58
- activejob (7.0.2.4)
59
- activesupport (= 7.0.2.4)
58
+ activejob (7.0.4.1)
59
+ activesupport (= 7.0.4.1)
60
60
  globalid (>= 0.3.6)
61
- activemodel (7.0.2.4)
62
- activesupport (= 7.0.2.4)
63
- activerecord (7.0.2.4)
64
- activemodel (= 7.0.2.4)
65
- activesupport (= 7.0.2.4)
66
- activestorage (7.0.2.4)
67
- actionpack (= 7.0.2.4)
68
- activejob (= 7.0.2.4)
69
- activerecord (= 7.0.2.4)
70
- activesupport (= 7.0.2.4)
61
+ activemodel (7.0.4.1)
62
+ activesupport (= 7.0.4.1)
63
+ activerecord (7.0.4.1)
64
+ activemodel (= 7.0.4.1)
65
+ activesupport (= 7.0.4.1)
66
+ activestorage (7.0.4.1)
67
+ actionpack (= 7.0.4.1)
68
+ activejob (= 7.0.4.1)
69
+ activerecord (= 7.0.4.1)
70
+ activesupport (= 7.0.4.1)
71
71
  marcel (~> 1.0)
72
72
  mini_mime (>= 1.1.0)
73
- activesupport (7.0.2.4)
73
+ activesupport (7.0.4.1)
74
74
  concurrent-ruby (~> 1.0, >= 1.0.2)
75
75
  i18n (>= 1.6, < 2)
76
76
  minitest (>= 5.1)
77
77
  tzinfo (~> 2.0)
78
78
  acts_as_list (1.0.4)
79
79
  activerecord (>= 4.2)
80
- addressable (2.8.0)
81
- public_suffix (>= 2.0.2, < 5.0)
80
+ addressable (2.8.1)
81
+ public_suffix (>= 2.0.2, < 6.0)
82
82
  ast (2.4.2)
83
83
  bcrypt (3.1.18)
84
84
  breadcrumbs_on_rails (4.1.0)
85
85
  railties (>= 5.0)
86
86
  builder (3.2.4)
87
- capybara (3.36.0)
87
+ capybara (3.38.0)
88
88
  addressable
89
89
  matrix
90
90
  mini_mime (>= 0.1.3)
@@ -96,42 +96,43 @@ GEM
96
96
  closure_tree (7.4.0)
97
97
  activerecord (>= 4.2.10)
98
98
  with_advisory_lock (>= 4.0.0)
99
- concurrent-ruby (1.1.10)
99
+ concurrent-ruby (1.2.0)
100
100
  crass (1.0.6)
101
- debug (1.5.0)
102
- irb (>= 1.3.6)
103
- reline (>= 0.2.7)
101
+ date (3.3.3)
102
+ debug (1.7.1)
103
+ irb (>= 1.5.0)
104
+ reline (>= 0.3.1)
104
105
  devise (4.8.1)
105
106
  bcrypt (~> 3.0)
106
107
  orm_adapter (~> 0.1)
107
108
  railties (>= 4.1.0)
108
109
  responders
109
110
  warden (~> 1.2.3)
110
- digest (3.1.0)
111
111
  enumerize (2.5.0)
112
112
  activesupport (>= 3.2)
113
- erubi (1.10.0)
113
+ erubi (1.12.0)
114
114
  ffi (1.15.5)
115
- globalid (1.0.0)
115
+ globalid (1.0.1)
116
116
  activesupport (>= 5.0)
117
117
  hotwire-rails (0.1.3)
118
118
  rails (>= 6.0.0)
119
119
  stimulus-rails
120
120
  turbo-rails
121
- i18n (1.10.0)
121
+ i18n (1.12.0)
122
122
  concurrent-ruby (~> 1.0)
123
123
  image_processing (1.12.2)
124
124
  mini_magick (>= 4.9.5, < 5)
125
125
  ruby-vips (>= 2.0.17, < 3)
126
- importmap-rails (1.0.3)
126
+ importmap-rails (1.1.5)
127
127
  actionpack (>= 6.0.0)
128
128
  railties (>= 6.0.0)
129
129
  inline_svg (1.8.0)
130
130
  activesupport (>= 3.0)
131
131
  nokogiri (>= 1.6)
132
- io-console (0.5.11)
133
- irb (1.4.1)
132
+ io-console (0.6.0)
133
+ irb (1.6.2)
134
134
  reline (>= 0.3.0)
135
+ json (2.6.3)
135
136
  kaminari (1.2.2)
136
137
  activesupport (>= 4.1.0)
137
138
  kaminari-actionview (= 1.2.2)
@@ -144,74 +145,73 @@ GEM
144
145
  activerecord
145
146
  kaminari-core (= 1.2.2)
146
147
  kaminari-core (1.2.2)
147
- loofah (2.16.0)
148
+ language_server-protocol (3.17.0.2)
149
+ loofah (2.19.1)
148
150
  crass (~> 1.0.2)
149
151
  nokogiri (>= 1.5.9)
150
- mail (2.7.1)
152
+ mail (2.8.0.1)
151
153
  mini_mime (>= 0.1.1)
154
+ net-imap
155
+ net-pop
156
+ net-smtp
152
157
  marcel (1.0.2)
153
158
  matrix (0.4.2)
154
159
  method_source (1.0.0)
155
- mini_magick (4.11.0)
160
+ mini_magick (4.12.0)
156
161
  mini_mime (1.1.2)
157
- minitest (5.15.0)
158
- minitest-spec-rails (6.1.0)
162
+ minitest (5.17.0)
163
+ minitest-spec-rails (6.2.0)
159
164
  minitest (>= 5.0)
160
165
  railties (>= 4.1)
161
- net-imap (0.2.3)
162
- digest
166
+ net-imap (0.3.4)
167
+ date
163
168
  net-protocol
164
- strscan
165
- net-pop (0.1.1)
166
- digest
169
+ net-pop (0.1.2)
167
170
  net-protocol
171
+ net-protocol (0.2.1)
168
172
  timeout
169
- net-protocol (0.1.3)
170
- timeout
171
- net-smtp (0.3.1)
172
- digest
173
+ net-smtp (0.3.3)
173
174
  net-protocol
174
- timeout
175
175
  nio4r (2.5.8)
176
- nokogiri (1.13.4-arm64-darwin)
176
+ nokogiri (1.14.0-arm64-darwin)
177
177
  racc (~> 1.4)
178
- nokogiri (1.13.4-x86_64-darwin)
178
+ nokogiri (1.14.0-x86_64-darwin)
179
179
  racc (~> 1.4)
180
- nokogiri (1.13.4-x86_64-linux)
180
+ nokogiri (1.14.0-x86_64-linux)
181
181
  racc (~> 1.4)
182
182
  orm_adapter (0.5.0)
183
183
  parallel (1.22.1)
184
- parser (3.1.2.0)
184
+ parser (3.2.0.0)
185
185
  ast (~> 2.4.1)
186
- public_suffix (4.0.7)
187
- puma (5.6.4)
186
+ public_suffix (5.0.1)
187
+ puma (5.6.5)
188
188
  nio4r (~> 2.0)
189
- racc (1.6.0)
190
- rack (2.2.3)
191
- rack-test (1.1.0)
192
- rack (>= 1.0, < 3)
193
- rails (7.0.2.4)
194
- actioncable (= 7.0.2.4)
195
- actionmailbox (= 7.0.2.4)
196
- actionmailer (= 7.0.2.4)
197
- actionpack (= 7.0.2.4)
198
- actiontext (= 7.0.2.4)
199
- actionview (= 7.0.2.4)
200
- activejob (= 7.0.2.4)
201
- activemodel (= 7.0.2.4)
202
- activerecord (= 7.0.2.4)
203
- activestorage (= 7.0.2.4)
204
- activesupport (= 7.0.2.4)
189
+ racc (1.6.2)
190
+ rack (2.2.6.2)
191
+ rack-test (2.0.2)
192
+ rack (>= 1.3)
193
+ rails (7.0.4.1)
194
+ actioncable (= 7.0.4.1)
195
+ actionmailbox (= 7.0.4.1)
196
+ actionmailer (= 7.0.4.1)
197
+ actionpack (= 7.0.4.1)
198
+ actiontext (= 7.0.4.1)
199
+ actionview (= 7.0.4.1)
200
+ activejob (= 7.0.4.1)
201
+ activemodel (= 7.0.4.1)
202
+ activerecord (= 7.0.4.1)
203
+ activestorage (= 7.0.4.1)
204
+ activesupport (= 7.0.4.1)
205
205
  bundler (>= 1.15.0)
206
- railties (= 7.0.2.4)
206
+ railties (= 7.0.4.1)
207
207
  rails-dom-testing (2.0.3)
208
208
  activesupport (>= 4.2.0)
209
209
  nokogiri (>= 1.6)
210
- rails-html-sanitizer (1.4.2)
211
- loofah (~> 2.3)
212
- railties (7.0.2.4)
213
- actionpack (= 7.0.2.4)
214
- activesupport (= 7.0.2.4)
210
+ rails-html-sanitizer (1.5.0)
211
+ loofah (~> 2.19, >= 2.19.1)
212
+ railties (7.0.4.1)
213
+ actionpack (= 7.0.4.1)
214
+ activesupport (= 7.0.4.1)
215
215
  method_source
216
216
  rake (>= 12.2)
217
217
  thor (~> 1.0)
@@ -219,8 +219,8 @@ GEM
219
219
  rainbow (3.1.1)
220
220
  rake (13.0.6)
221
221
  redcarpet (3.5.1)
222
- regexp_parser (2.3.1)
223
- reline (0.3.1)
222
+ regexp_parser (2.6.2)
223
+ reline (0.3.2)
224
224
  io-console (~> 0.5)
225
225
  responders (3.0.1)
226
226
  actionpack (>= 5.0)
@@ -231,18 +231,19 @@ GEM
231
231
  actionpack (>= 5.2, < 7.1)
232
232
  activesupport (>= 5.2, < 7.1)
233
233
  addressable (~> 2.7)
234
- rubocop (1.28.2)
234
+ rubocop (1.42.0)
235
+ json (~> 2.3)
235
236
  parallel (~> 1.10)
236
- parser (>= 3.1.0.0)
237
+ parser (>= 3.1.2.1)
237
238
  rainbow (>= 2.2.2, < 4.0)
238
239
  regexp_parser (>= 1.8, < 3.0)
239
- rexml
240
- rubocop-ast (>= 1.17.0, < 2.0)
240
+ rexml (>= 3.2.5, < 4.0)
241
+ rubocop-ast (>= 1.24.1, < 2.0)
241
242
  ruby-progressbar (~> 1.7)
242
243
  unicode-display_width (>= 1.4.0, < 3.0)
243
- rubocop-ast (1.17.0)
244
+ rubocop-ast (1.24.1)
244
245
  parser (>= 3.1.1.0)
245
- rubocop-performance (1.13.3)
246
+ rubocop-performance (1.15.2)
246
247
  rubocop (>= 1.7.0, < 2.0)
247
248
  rubocop-ast (>= 0.4.0)
248
249
  ruby-progressbar (1.11.0)
@@ -256,29 +257,32 @@ GEM
256
257
  sprockets (> 3.0)
257
258
  sprockets-rails
258
259
  tilt
259
- sprockets (4.0.3)
260
+ sprockets (4.2.0)
260
261
  concurrent-ruby (~> 1.0)
261
- rack (> 1, < 3)
262
+ rack (>= 2.2.4, < 4)
262
263
  sprockets-rails (3.4.2)
263
264
  actionpack (>= 5.2)
264
265
  activesupport (>= 5.2)
265
266
  sprockets (>= 3.0.0)
266
- sqlite3 (1.4.2)
267
- standard (1.11.0)
268
- rubocop (= 1.28.2)
269
- rubocop-performance (= 1.13.3)
270
- stimulus-rails (1.0.4)
267
+ sqlite3 (1.6.0-arm64-darwin)
268
+ sqlite3 (1.6.0-x86_64-darwin)
269
+ sqlite3 (1.6.0-x86_64-linux)
270
+ standard (1.22.1)
271
+ language_server-protocol (~> 3.17.0.2)
272
+ rubocop (= 1.42.0)
273
+ rubocop-performance (= 1.15.2)
274
+ stimulus-rails (1.2.1)
271
275
  railties (>= 6.0.0)
272
- strscan (3.0.1)
273
276
  thor (1.2.1)
274
- tilt (2.0.10)
275
- timeout (0.2.0)
276
- turbo-rails (1.0.1)
277
+ tilt (2.0.11)
278
+ timeout (0.3.1)
279
+ turbo-rails (1.3.2)
277
280
  actionpack (>= 6.0.0)
281
+ activejob (>= 6.0.0)
278
282
  railties (>= 6.0.0)
279
- tzinfo (2.0.4)
283
+ tzinfo (2.0.5)
280
284
  concurrent-ruby (~> 1.0)
281
- unicode-display_width (2.1.0)
285
+ unicode-display_width (2.4.2)
282
286
  warden (1.2.9)
283
287
  rack (>= 2.0.9)
284
288
  websocket-driver (0.7.5)
@@ -288,7 +292,7 @@ GEM
288
292
  activerecord (>= 4.2)
289
293
  xpath (3.2.0)
290
294
  nokogiri (~> 1.8)
291
- zeitwerk (2.5.4)
295
+ zeitwerk (2.6.6)
292
296
 
293
297
  PLATFORMS
294
298
  arm64-darwin-21
data/README.md CHANGED
@@ -128,8 +128,8 @@ $ bundle
128
128
  # Update the version number, push commits and tag the release
129
129
  $ gem bump -v {patch,minor,major,...} --push --tag
130
130
 
131
- # Release to Rubygems
132
- $ gem release
131
+ # Release to Rubygems and create a Github release tag
132
+ $ gem release --github
133
133
  ```
134
134
 
135
135
  Update the node package
@@ -3,7 +3,7 @@ import Sortable from 'sortablejs'
3
3
 
4
4
  export default class extends Controller {
5
5
  static get targets () {
6
- return ['item', 'template', 'thumbnails', 'modalButton', 'placeholder', 'count', 'editButton']
6
+ return ['item', 'template', 'thumbnails', 'modalButton', 'placeholder', 'count', 'editButton', 'validationInput']
7
7
  }
8
8
 
9
9
  connect () {
@@ -17,6 +17,8 @@ export default class extends Controller {
17
17
  if (this.hasSorting()) {
18
18
  this.initSortable()
19
19
  }
20
+
21
+ this.validate()
20
22
  }
21
23
 
22
24
  // Actions
@@ -81,6 +83,41 @@ export default class extends Controller {
81
83
 
82
84
  // Toggle placeholder
83
85
  this.togglePlaceholder()
86
+
87
+ // Validate
88
+ this.validate()
89
+ }
90
+
91
+ validate () {
92
+ this.clearValidation()
93
+ this.validateMinimum()
94
+ this.validateMaximum()
95
+ }
96
+
97
+ clearValidation () {
98
+ this.validationInputTarget.setCustomValidity('')
99
+ }
100
+
101
+ validateMinimum () {
102
+ const count = this.activeItems().length
103
+ if (count < this.minActiveItems()) {
104
+ this.validationInputTarget.setCustomValidity(this.validationInputTarget.dataset.minMessage)
105
+ }
106
+ }
107
+
108
+ validateMaximum () {
109
+ const count = this.activeItems().length
110
+ if (count > this.maxActiveItems()) {
111
+ this.validationInputTarget.setCustomValidity(this.validationInputTarget.dataset.maxMessage)
112
+ }
113
+ }
114
+
115
+ minActiveItems () {
116
+ return parseInt(this.element.dataset.min, 10) || 0
117
+ }
118
+
119
+ maxActiveItems () {
120
+ return parseInt(this.element.dataset.max, 10) || Infinity
84
121
  }
85
122
 
86
123
  resetPositions () {
@@ -1,3 +1,4 @@
1
+ /* global IntersectionObserver */
1
2
  import { Controller } from '@hotwired/stimulus'
2
3
 
3
4
  export default class extends Controller {
@@ -6,7 +7,7 @@ export default class extends Controller {
6
7
  }
7
8
 
8
9
  connect () {
9
- this.update()
10
+ onVisible(this.textareaTarget, () => { this.update() })
10
11
  }
11
12
 
12
13
  update () {
@@ -32,3 +33,16 @@ export default class extends Controller {
32
33
  this.countTarget.textContent = `${currentLength}/${maximumLength}`
33
34
  }
34
35
  }
36
+
37
+ // Custom callback event that triggers when an element becomes visible.
38
+ // Solves the bug where textarea fields are not properly sized when they (or their parent) or hidden.
39
+ function onVisible (element, callback) {
40
+ new IntersectionObserver((entries, observer) => {
41
+ entries.forEach(entry => {
42
+ if (entry.intersectionRatio > 0) {
43
+ callback(element)
44
+ observer.disconnect()
45
+ }
46
+ })
47
+ }).observe(element)
48
+ }
@@ -10096,7 +10096,7 @@ var hello_controller_default = class extends Controller {
10096
10096
  // app/assets/javascripts/headmin/controllers/media_controller.js
10097
10097
  var media_controller_default = class extends Controller {
10098
10098
  static get targets() {
10099
- return ["item", "template", "thumbnails", "modalButton", "placeholder", "count", "editButton"];
10099
+ return ["item", "template", "thumbnails", "modalButton", "placeholder", "count", "editButton", "validationInput"];
10100
10100
  }
10101
10101
  connect() {
10102
10102
  document.addEventListener("mediaSelectionSubmitted", (event) => {
@@ -10107,6 +10107,7 @@ var media_controller_default = class extends Controller {
10107
10107
  if (this.hasSorting()) {
10108
10108
  this.initSortable();
10109
10109
  }
10110
+ this.validate();
10110
10111
  }
10111
10112
  destroy(event) {
10112
10113
  const item = event.currentTarget.closest("[data-media-target='item']");
@@ -10147,6 +10148,33 @@ var media_controller_default = class extends Controller {
10147
10148
  this.resetPositions();
10148
10149
  this.syncIds();
10149
10150
  this.togglePlaceholder();
10151
+ this.validate();
10152
+ }
10153
+ validate() {
10154
+ this.clearValidation();
10155
+ this.validateMinimum();
10156
+ this.validateMaximum();
10157
+ }
10158
+ clearValidation() {
10159
+ this.validationInputTarget.setCustomValidity("");
10160
+ }
10161
+ validateMinimum() {
10162
+ const count = this.activeItems().length;
10163
+ if (count < this.minActiveItems()) {
10164
+ this.validationInputTarget.setCustomValidity(this.validationInputTarget.dataset.minMessage);
10165
+ }
10166
+ }
10167
+ validateMaximum() {
10168
+ const count = this.activeItems().length;
10169
+ if (count > this.maxActiveItems()) {
10170
+ this.validationInputTarget.setCustomValidity(this.validationInputTarget.dataset.maxMessage);
10171
+ }
10172
+ }
10173
+ minActiveItems() {
10174
+ return parseInt(this.element.dataset.min, 10) || 0;
10175
+ }
10176
+ maxActiveItems() {
10177
+ return parseInt(this.element.dataset.max, 10) || Infinity;
10150
10178
  }
10151
10179
  resetPositions() {
10152
10180
  this.activeItems().forEach((item, index2) => {
@@ -15825,7 +15853,9 @@ var textarea_controller_default = class extends Controller {
15825
15853
  return ["textarea", "count"];
15826
15854
  }
15827
15855
  connect() {
15828
- this.update();
15856
+ onVisible(this.textareaTarget, () => {
15857
+ this.update();
15858
+ });
15829
15859
  }
15830
15860
  update() {
15831
15861
  this.resize();
@@ -15846,6 +15876,16 @@ var textarea_controller_default = class extends Controller {
15846
15876
  this.countTarget.textContent = `${currentLength}/${maximumLength}`;
15847
15877
  }
15848
15878
  };
15879
+ function onVisible(element, callback) {
15880
+ new IntersectionObserver((entries, observer) => {
15881
+ entries.forEach((entry) => {
15882
+ if (entry.intersectionRatio > 0) {
15883
+ callback(element);
15884
+ observer.disconnect();
15885
+ }
15886
+ });
15887
+ }).observe(element);
15888
+ }
15849
15889
 
15850
15890
  // app/assets/javascripts/headmin/index.js
15851
15891
  var Headmin = class {
@@ -32,7 +32,8 @@
32
32
  }
33
33
 
34
34
  .rx-toolbar-container.is-rx-toolbar {
35
- background: transparent;
35
+ border-top-left-radius: 0.25rem;
36
+ border-top-right-radius: 0.25rem;
36
37
  border-bottom: 1px solid $input-border-color;
37
38
  }
38
39
 
@@ -12936,7 +12936,8 @@ span.flatpickr-weekday {
12936
12936
  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
12937
12937
  }
12938
12938
  .rx-toolbar-container.is-rx-toolbar {
12939
- background: transparent;
12939
+ border-top-left-radius: 0.25rem;
12940
+ border-top-right-radius: 0.25rem;
12940
12941
  border-bottom: 1px solid #ced4da;
12941
12942
  }
12942
12943
  .rx-content {
@@ -21,7 +21,7 @@ module Headmin
21
21
 
22
22
  def per_page
23
23
  length = params[:per_page].to_i
24
- length > 0 ? length : 24
24
+ (length > 0) ? length : 24
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,34 @@
1
+ module Headmin
2
+ module Attachment
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ scope :not_a_variant, -> { where.not(record_type: "ActiveStorage::VariantRecord") }
6
+
7
+ def record_hierarchy
8
+ hierarchy = []
9
+
10
+ current = record
11
+
12
+ current, partial_hierarchy = process_fieldable(current)
13
+ hierarchy << partial_hierarchy if partial_hierarchy.present?
14
+
15
+ current, partial_hierarchy = process_blockable(current)
16
+ hierarchy << partial_hierarchy if partial_hierarchy.present?
17
+
18
+ hierarchy << current if current.present?
19
+
20
+ hierarchy.flatten
21
+ end
22
+
23
+ private
24
+
25
+ def process_blockable(field)
26
+ field.respond_to?(:blockable) ? [field.blockable, field] : [field, nil]
27
+ end
28
+
29
+ def process_fieldable(field)
30
+ field.respond_to?(:fieldable) ? [field.root.fieldable, field.self_and_ancestors] : [field, nil]
31
+ end
32
+ end
33
+ end
34
+ end