activeadmin-tom_select 4.1.0 → 4.1.2
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 +4 -4
- data/.claude/commands/fix-tests.md +1 -1
- data/.github/workflows/ci.yml +13 -11
- data/.github/workflows/npm-publish.yml +3 -3
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/AGENTS.md +2 -2
- data/CHANGELOG.md +19 -1
- data/Gemfile.lock +85 -79
- data/README.md +20 -18
- data/activeadmin-tom_select.gemspec +3 -3
- data/docs/guide-update-your-app.md +198 -25
- data/docs/update-tom-select.md +322 -158
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile.lock +11 -11
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile.lock +66 -64
- data/lib/activeadmin/inputs/filters/searchable_select_input.rb +5 -12
- data/lib/activeadmin/inputs/filters/tom_select_input.rb +19 -0
- data/lib/activeadmin/inputs/searchable_select_input.rb +5 -11
- data/lib/activeadmin/inputs/tom_select_input.rb +16 -0
- data/lib/activeadmin/tom_select/engine.rb +3 -1
- data/lib/activeadmin/tom_select/option_collection.rb +1 -1
- data/lib/activeadmin/tom_select/resource_dsl_extension.rb +1 -1
- data/lib/activeadmin/tom_select/resource_extension.rb +1 -1
- data/lib/activeadmin/tom_select/select_input_extension.rb +39 -16
- data/lib/activeadmin/tom_select/version.rb +2 -2
- data/lib/activeadmin/tom_select.rb +3 -3
- data/lib/generators/active_admin/tom_select/install/install_generator.rb +5 -5
- data/npm-package/package-lock.json +2 -2
- data/npm-package/package.json +2 -2
- data/npm-package/src/index.js +1 -3
- data/npm-package/src/tom-select-tailwind.css +26 -20
- data/sonar-project.properties +14 -13
- data/spec/features/ajax_false_input_spec.rb +74 -0
- data/spec/features/end_to_end_spec.rb +33 -20
- data/spec/features/form_input_spec.rb +2 -2
- data/spec/features/inline_ajax_setting_spec.rb +1 -1
- data/spec/internal/Gemfile.lock +1 -1
- data/spec/internal/app/admin/articles.rb +28 -0
- data/spec/internal/app/admin/option_values.rb +6 -6
- data/spec/internal/app/admin/posts.rb +4 -4
- data/spec/internal/app/admin/test_ajax_false.rb +18 -0
- data/spec/internal/app/admin/variants.rb +2 -2
- data/spec/internal/app/assets/config/manifest.js +2 -1
- data/spec/internal/app/assets/stylesheets/active_admin.tailwind.css +1 -1
- data/spec/internal/app/assets/stylesheets/application.tailwind.css +0 -15
- data/spec/internal/app/javascript/active_admin.js +2 -4
- data/spec/internal/app/models/option_value.rb +8 -0
- data/spec/internal/db/schema.rb +3 -1
- data/spec/internal/db/seeds.rb +4 -7
- data/spec/internal/package-lock.json +3 -3
- data/spec/internal/package.json +1 -1
- data/spec/internal/yarn.lock +1 -1
- data/spec/support/reset_settings.rb +1 -1
- metadata +7 -2
@@ -28,7 +28,7 @@
|
|
28
28
|
}
|
29
29
|
|
30
30
|
.plugin-clear_button.single .clear-button {
|
31
|
-
|
31
|
+
right: 1.8rem;
|
32
32
|
}
|
33
33
|
|
34
34
|
.plugin-clear_button.focus.has-items .clear-button,
|
@@ -103,7 +103,7 @@
|
|
103
103
|
}
|
104
104
|
|
105
105
|
.ts-wrapper.plugin-remove_button .item .remove {
|
106
|
-
@apply text-inherit no-underline align-middle inline-block p-0 px-1.5 border-l border-gray-300 rounded-r-
|
106
|
+
@apply text-inherit no-underline align-middle inline-block p-0 px-1.5 border-l border-gray-300 rounded-r-md box-border ml-1.5;
|
107
107
|
}
|
108
108
|
|
109
109
|
.ts-wrapper.plugin-remove_button .item .remove:hover {
|
@@ -137,7 +137,7 @@
|
|
137
137
|
.ts-dropdown,
|
138
138
|
.ts-control,
|
139
139
|
.ts-control input {
|
140
|
-
|
140
|
+
@apply text-gray-900 dark:text-gray-100;
|
141
141
|
font-family: inherit;
|
142
142
|
font-size: 13px;
|
143
143
|
line-height: 18px;
|
@@ -146,12 +146,12 @@
|
|
146
146
|
/* Control (Input) Styles */
|
147
147
|
.ts-control,
|
148
148
|
.ts-wrapper.single.input-active .ts-control {
|
149
|
-
@apply bg-white dark:bg-gray-
|
149
|
+
@apply bg-white dark:bg-gray-700;
|
150
150
|
cursor: text;
|
151
151
|
}
|
152
152
|
|
153
153
|
.ts-control {
|
154
|
-
@apply border border-gray-300 dark:border-gray-600 p-2 w-full overflow-hidden relative z-10 box-border shadow-none rounded-
|
154
|
+
@apply border border-gray-300 dark:border-gray-600 p-2 w-full overflow-hidden relative z-10 box-border shadow-none rounded-md flex flex-wrap;
|
155
155
|
}
|
156
156
|
|
157
157
|
.ts-wrapper.multi.has-items .ts-control {
|
@@ -159,7 +159,7 @@
|
|
159
159
|
}
|
160
160
|
|
161
161
|
.full .ts-control {
|
162
|
-
@apply bg-gray-50 dark:bg-gray-
|
162
|
+
@apply bg-gray-50 dark:bg-gray-700 dark:text-gray-100;
|
163
163
|
}
|
164
164
|
|
165
165
|
.disabled .ts-control,
|
@@ -177,7 +177,7 @@
|
|
177
177
|
|
178
178
|
/* Multi-select Items */
|
179
179
|
.ts-wrapper.multi .ts-control > div {
|
180
|
-
@apply cursor-pointer m-0 mr-1 my-1 px-2 py-1 bg-gray-100 text-gray-800 border-0 rounded-
|
180
|
+
@apply cursor-pointer m-0 mr-1 my-1 px-2 py-1 bg-gray-100 text-gray-800 border-0 rounded-md;
|
181
181
|
}
|
182
182
|
|
183
183
|
.ts-wrapper.multi .ts-control > div.active {
|
@@ -242,7 +242,7 @@
|
|
242
242
|
|
243
243
|
/* Dropdown Styles */
|
244
244
|
.ts-dropdown {
|
245
|
-
@apply absolute top-full left-0 w-full z-50 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-
|
245
|
+
@apply absolute top-full left-0 w-full z-50 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 mt-1 box-border rounded-md shadow-sm overflow-hidden;
|
246
246
|
}
|
247
247
|
|
248
248
|
.ts-dropdown [data-selectable] {
|
@@ -284,7 +284,7 @@
|
|
284
284
|
.ts-dropdown .create:hover,
|
285
285
|
.ts-dropdown .option:hover,
|
286
286
|
.ts-dropdown .active {
|
287
|
-
@apply bg-indigo-50 dark:bg-gray-
|
287
|
+
@apply bg-indigo-50 dark:bg-gray-600 text-indigo-900 dark:text-gray-100;
|
288
288
|
}
|
289
289
|
|
290
290
|
.ts-dropdown .create:hover.create,
|
@@ -343,20 +343,20 @@
|
|
343
343
|
padding-right: 2.5rem;
|
344
344
|
}
|
345
345
|
|
346
|
-
/*
|
347
|
-
.ts-wrapper.single .ts-control,
|
346
|
+
/* Ensure single select inputs don't break layout */
|
348
347
|
.ts-wrapper.single .ts-control input {
|
349
348
|
width: auto !important;
|
350
349
|
}
|
351
350
|
|
352
351
|
/* ActiveAdmin Specific Overrides */
|
353
352
|
.searchable_select.input .ts-wrapper {
|
354
|
-
|
355
|
-
display:
|
353
|
+
width: 100%;
|
354
|
+
display: block;
|
356
355
|
}
|
357
356
|
|
358
357
|
.searchable_select.input .ts-control {
|
359
358
|
margin-top: 0;
|
359
|
+
width: 100% !important;
|
360
360
|
}
|
361
361
|
|
362
362
|
/* Filter Form Specific Styles */
|
@@ -364,18 +364,24 @@
|
|
364
364
|
width: 100%;
|
365
365
|
}
|
366
366
|
|
367
|
+
.filter_form .searchable_select.input .ts-control {
|
368
|
+
width: 100% !important;
|
369
|
+
}
|
370
|
+
|
371
|
+
/* Ensure full width for all searchable selects */
|
372
|
+
.ts-wrapper {
|
373
|
+
width: 100%;
|
374
|
+
}
|
375
|
+
|
367
376
|
/* Hide Duplicate Elements */
|
368
377
|
.ts-wrapper + .ts-control {
|
369
378
|
display: none;
|
370
379
|
}
|
371
380
|
|
372
|
-
/* Dark Mode Support */
|
373
|
-
.dark .ts-control {
|
374
|
-
@apply bg-gray-800 border-gray-600 text-gray-100;
|
375
|
-
}
|
381
|
+
/* Dark Mode Support - Already handled above, removing duplicate */
|
376
382
|
|
377
383
|
.dark .ts-dropdown {
|
378
|
-
@apply bg-gray-
|
384
|
+
@apply bg-gray-700 border-gray-600;
|
379
385
|
}
|
380
386
|
|
381
387
|
.dark .ts-dropdown .option {
|
@@ -384,9 +390,9 @@
|
|
384
390
|
|
385
391
|
.dark .ts-dropdown .option:hover,
|
386
392
|
.dark .ts-dropdown [data-selectable].active {
|
387
|
-
@apply bg-gray-
|
393
|
+
@apply bg-gray-600 text-white;
|
388
394
|
}
|
389
395
|
|
390
396
|
.dark .ts-wrapper.multi .ts-control > div {
|
391
|
-
@apply bg-gray-
|
397
|
+
@apply bg-gray-600 text-gray-100;
|
392
398
|
}
|
data/sonar-project.properties
CHANGED
@@ -1,25 +1,26 @@
|
|
1
1
|
# SonarQube project configuration
|
2
|
-
sonar.projectKey=
|
3
|
-
sonar.
|
4
|
-
sonar.
|
2
|
+
sonar.projectKey=rs-pro_activeadmin-tom_select
|
3
|
+
sonar.organization=rs-pro
|
4
|
+
sonar.projectName=activeadmin-tom_select
|
5
|
+
sonar.projectVersion=4.1.2
|
6
|
+
sonar.qualitygate.wait=true
|
5
7
|
|
6
8
|
# Source code directories
|
7
|
-
sonar.sources=lib,
|
9
|
+
sonar.sources=lib,npm-package
|
8
10
|
sonar.tests=spec
|
9
11
|
|
10
|
-
# Language
|
11
|
-
sonar.language=ruby
|
12
|
-
|
13
12
|
# Encoding
|
14
13
|
sonar.sourceEncoding=UTF-8
|
15
14
|
|
16
|
-
#
|
15
|
+
# File suffixes for different languages
|
17
16
|
sonar.ruby.file.suffixes=.rb,.rake
|
17
|
+
sonar.javascript.file.suffixes=.js,.jsx
|
18
|
+
sonar.css.file.suffixes=.css,.scss
|
19
|
+
|
20
|
+
# Test coverage and results reporting
|
18
21
|
sonar.ruby.coverage.reportPaths=coverage/coverage.json
|
22
|
+
sonar.ruby.rspec.reportPaths=rspec-results.xml
|
19
23
|
|
20
|
-
# Exclusions
|
21
|
-
sonar.exclusions=spec/**/*,vendor/**/*,coverage/**/*,tmp/**/*,*.gemspec,gemfiles/**/*,Appraisals
|
22
|
-
sonar.test.exclusions=spec/internal/app/assets/builds/**/*,spec/internal/public/**/*,spec/internal/node_modules/**/*
|
23
24
|
|
24
|
-
#
|
25
|
-
sonar.
|
25
|
+
# Exclusions
|
26
|
+
sonar.exclusions=**/*_test.rb,**/test/**,**/spec/**,**/vendor/**,**/node_modules/**,**/coverage/**,**/tmp/**,**/log/**,**/public/**,*.gemspec,gemfiles/**/*,Appraisals,spec/internal/app/assets/builds/**/*,**/app/assets/builds/**/*,npm-package/node_modules/**/*
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'ajax: false input behavior', type: :feature do
|
4
|
+
before do
|
5
|
+
# Create test data
|
6
|
+
@users = 3.times.map { |i| User.create!(name: "User #{i + 1}") }
|
7
|
+
@categories = 3.times.map { |i| Category.create!(name: "Category #{i + 1}") }
|
8
|
+
|
9
|
+
@post = Post.create!(
|
10
|
+
title: 'Test Post',
|
11
|
+
body: 'Test content',
|
12
|
+
category: @categories.first,
|
13
|
+
user: @users.first
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'filter inputs with ajax: false' do
|
18
|
+
it 'renders all options inline without ajax URL' do
|
19
|
+
visit '/admin/ajax_false_posts'
|
20
|
+
|
21
|
+
# Should have tom-select-input class
|
22
|
+
expect(page).to have_selector('.tom-select-input')
|
23
|
+
|
24
|
+
# Should NOT have data-ajax-url attribute
|
25
|
+
page_content = page.html
|
26
|
+
expect(page_content).not_to match(/<select[^>]*name="q\[category_id_eq\]"[^>]*data-ajax-url/)
|
27
|
+
expect(page_content).not_to match(/<select[^>]*name="q\[user_id_eq\]"[^>]*data-ajax-url/)
|
28
|
+
|
29
|
+
# Should have options rendered inline
|
30
|
+
within('select[name="q[category_id_eq]"]', visible: :all) do
|
31
|
+
@categories.each do |category|
|
32
|
+
expect(page).to have_selector("option[value='#{category.id}']", text: category.name,
|
33
|
+
visible: :all)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'form inputs with ajax: false' do
|
40
|
+
it 'renders all options inline in new form' do
|
41
|
+
visit '/admin/ajax_false_posts/new'
|
42
|
+
|
43
|
+
expect(page).to have_selector('.tom-select-input')
|
44
|
+
|
45
|
+
# Check that options are rendered inline
|
46
|
+
within('select#post_category_id', visible: :all) do
|
47
|
+
@categories.each do |category|
|
48
|
+
expect(page).to have_selector("option[value='#{category.id}']", text: category.name,
|
49
|
+
visible: :all)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'preselects value in edit form' do
|
55
|
+
visit "/admin/ajax_false_posts/#{@post.id}/edit"
|
56
|
+
|
57
|
+
# Should have the selected option
|
58
|
+
within('select#post_category_id', visible: :all) do
|
59
|
+
selected_option = find("option[value='#{@categories.first.id}']", visible: :all)
|
60
|
+
expect(selected_option).to be_selected
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'comparison with ajax: true (default)' do
|
66
|
+
it 'default inputs use ajax' do
|
67
|
+
visit '/admin/posts'
|
68
|
+
|
69
|
+
# Default searchable_select should have data-ajax-url
|
70
|
+
page_content = page.html
|
71
|
+
expect(page_content).to match(/<select[^>]*name="q\[category_id_eq\]"[^>]*data-ajax-url/)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -80,17 +80,16 @@ RSpec.describe 'end to end', type: :feature, js: true do
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
context 'class with nested belongs_to association'
|
84
|
-
skip: 'Nested routes issue with belongs_to in test environment' do
|
83
|
+
context 'class with nested belongs_to association' do
|
85
84
|
# Using static admin files: option_types.rb, products.rb, option_values.rb, variants.rb
|
86
85
|
|
87
86
|
describe 'new page with searchable select filter' do
|
88
87
|
it 'loads filter input options' do
|
89
88
|
option_type = OptionType.create(name: 'Color')
|
90
89
|
ot = OptionType.create(name: 'Size')
|
91
|
-
OptionValue.create(
|
92
|
-
OptionValue.create(
|
93
|
-
OptionValue.create(
|
90
|
+
OptionValue.create(name: 'Black', option_type: option_type)
|
91
|
+
OptionValue.create(name: 'Orange', option_type: option_type)
|
92
|
+
OptionValue.create(name: 'M', option_type: ot)
|
94
93
|
product = Product.create(name: 'Cap', option_type: option_type)
|
95
94
|
|
96
95
|
visit "/admin/products/#{product.id}/variants/new"
|
@@ -139,9 +138,9 @@ RSpec.describe 'end to end', type: :feature, js: true do
|
|
139
138
|
has_searchable = page.has_css?(searchable_select_css)
|
140
139
|
puts "Page HTML includes searchable-select-input: #{has_searchable}"
|
141
140
|
|
142
|
-
# Debug: Print
|
141
|
+
# Debug: Print HTML around the select - use first match if there are multiple
|
143
142
|
if page.has_css?(searchable_select_css)
|
144
|
-
select_element =
|
143
|
+
select_element = all(searchable_select_css, visible: :all).first
|
145
144
|
parent_html = begin
|
146
145
|
select_element.find(:xpath,
|
147
146
|
'..')['outerHTML'][0..500]
|
@@ -151,7 +150,10 @@ RSpec.describe 'end to end', type: :feature, js: true do
|
|
151
150
|
puts "Parent element HTML: #{parent_html}..."
|
152
151
|
end
|
153
152
|
|
154
|
-
|
153
|
+
# Target the option_value select specifically
|
154
|
+
within('#variant_option_value_input') do
|
155
|
+
find('.ts-control', match: :first).click
|
156
|
+
end
|
155
157
|
wait_for_ajax
|
156
158
|
|
157
159
|
expect(select_box_items).to eq(%w[Black Orange])
|
@@ -160,15 +162,18 @@ RSpec.describe 'end to end', type: :feature, js: true do
|
|
160
162
|
it 'allows filtering options by term' do
|
161
163
|
option_type = OptionType.create(name: 'Color')
|
162
164
|
ot = OptionType.create(name: 'Size')
|
163
|
-
OptionValue.create(
|
164
|
-
OptionValue.create(
|
165
|
-
OptionValue.create(
|
165
|
+
OptionValue.create(name: 'Black', option_type: option_type)
|
166
|
+
OptionValue.create(name: 'Orange', option_type: option_type)
|
167
|
+
OptionValue.create(name: 'M', option_type: ot)
|
166
168
|
product = Product.create(name: 'Cap', option_type: option_type)
|
167
169
|
|
168
170
|
visit "/admin/products/#{product.id}/variants/new"
|
169
171
|
|
170
|
-
|
171
|
-
|
172
|
+
# Target the option_value select specifically
|
173
|
+
within('#variant_option_value_input') do
|
174
|
+
find('.ts-control', match: :first).click
|
175
|
+
find('input[type="text"]', match: :first).send_keys('O')
|
176
|
+
end
|
172
177
|
wait_for_ajax
|
173
178
|
|
174
179
|
expect(select_box_items).to eq(%w[Orange])
|
@@ -176,17 +181,22 @@ RSpec.describe 'end to end', type: :feature, js: true do
|
|
176
181
|
|
177
182
|
it 'loads more items when scrolling down' do
|
178
183
|
option_type = OptionType.create(name: 'Color')
|
179
|
-
15.times { |i| OptionValue.create(
|
184
|
+
15.times { |i| OptionValue.create(name: "Black #{i}", option_type: option_type) }
|
180
185
|
product = Product.create(name: 'Cap', option_type: option_type)
|
181
186
|
|
182
187
|
visit "/admin/products/#{product.id}/variants/new"
|
183
188
|
|
184
|
-
|
189
|
+
# Target the option_value select specifically
|
190
|
+
within('#variant_option_value_input') do
|
191
|
+
find('.ts-control', match: :first).click
|
192
|
+
end
|
185
193
|
wait_for_ajax
|
186
194
|
scroll_select_box_list
|
187
195
|
wait_for_ajax
|
188
196
|
|
189
|
-
|
197
|
+
# Default page size is 10, scrolling might load 1 more page
|
198
|
+
expect(select_box_items.size).to be >= 10
|
199
|
+
expect(select_box_items.size).to be <= 15
|
190
200
|
end
|
191
201
|
end
|
192
202
|
|
@@ -194,15 +204,18 @@ RSpec.describe 'end to end', type: :feature, js: true do
|
|
194
204
|
it 'preselects item' do
|
195
205
|
option_type = OptionType.create(name: 'Color')
|
196
206
|
ot = OptionType.create(name: 'Size')
|
197
|
-
option_value = OptionValue.create(
|
198
|
-
OptionValue.create(
|
199
|
-
OptionValue.create(
|
207
|
+
option_value = OptionValue.create(name: 'Black', option_type: option_type)
|
208
|
+
OptionValue.create(name: 'Orange', option_type: option_type)
|
209
|
+
OptionValue.create(name: 'M', option_type: ot)
|
200
210
|
product = Product.create(name: 'Cap', option_type: option_type)
|
201
211
|
variant = Variant.create(product: product, option_value: option_value)
|
202
212
|
|
203
213
|
visit "/admin/products/#{product.id}/variants/#{variant.id}/edit"
|
204
214
|
|
205
|
-
|
215
|
+
# Target the option_value select specifically
|
216
|
+
within('#variant_option_value_input') do
|
217
|
+
expect(page).to have_css('.ts-control .item', text: 'Black')
|
218
|
+
end
|
206
219
|
end
|
207
220
|
end
|
208
221
|
end
|
@@ -10,11 +10,11 @@ RSpec.describe 'form input', type: :request do
|
|
10
10
|
# So we'll test with that configuration
|
11
11
|
describe 'with ajax option (from static admin file)' do
|
12
12
|
before(:each) do
|
13
|
-
ActiveAdmin::
|
13
|
+
ActiveAdmin::TomSelect.inline_ajax_options = true
|
14
14
|
end
|
15
15
|
|
16
16
|
after(:each) do
|
17
|
-
ActiveAdmin::
|
17
|
+
ActiveAdmin::TomSelect.inline_ajax_options = false
|
18
18
|
end
|
19
19
|
it 'renders select input with searchable-select-input css class' do
|
20
20
|
get "#{ADMIN_POSTS_PATH}/new"
|
@@ -12,7 +12,7 @@ RSpec.describe 'inline_ajax_options setting', type: :request do
|
|
12
12
|
Category.create!(name: 'Music')
|
13
13
|
Category.create!(name: 'Cooking')
|
14
14
|
|
15
|
-
ActiveAdmin::
|
15
|
+
ActiveAdmin::TomSelect.inline_ajax_options = true
|
16
16
|
get '/admin/test_inline_ajax_posts/new'
|
17
17
|
|
18
18
|
expect(response.body).to have_selector('.searchable-select-input option',
|
data/spec/internal/Gemfile.lock
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
ActiveAdmin.register Post, as: 'Article' do
|
2
|
+
permit_params :title, :body, :category_id, :user_id, :created_at, :updated_at
|
3
|
+
|
4
|
+
index do
|
5
|
+
selectable_column
|
6
|
+
id_column
|
7
|
+
column :title
|
8
|
+
column :category
|
9
|
+
column :user
|
10
|
+
column :created_at
|
11
|
+
actions
|
12
|
+
end
|
13
|
+
|
14
|
+
# Use the new tom_select input type
|
15
|
+
filter :title
|
16
|
+
filter :category, as: :tom_select, ajax: true
|
17
|
+
filter :user, as: :tom_select, ajax: true
|
18
|
+
|
19
|
+
form do |f|
|
20
|
+
f.inputs do
|
21
|
+
f.input :title
|
22
|
+
f.input :body
|
23
|
+
f.input :category, as: :tom_select, ajax: true
|
24
|
+
f.input :user, as: :tom_select, ajax: true
|
25
|
+
end
|
26
|
+
f.actions
|
27
|
+
end
|
28
|
+
end
|
@@ -1,28 +1,28 @@
|
|
1
1
|
ActiveAdmin.register OptionValue do
|
2
|
-
belongs_to :option_type
|
2
|
+
belongs_to :option_type, optional: true
|
3
3
|
|
4
|
-
permit_params :
|
4
|
+
permit_params :name, :option_type_id
|
5
5
|
|
6
6
|
searchable_select_options(scope: lambda do |params|
|
7
7
|
OptionValue.where(
|
8
8
|
option_type_id: params[:option_type_id]
|
9
9
|
)
|
10
10
|
end,
|
11
|
-
text_attribute: :
|
11
|
+
text_attribute: :name)
|
12
12
|
|
13
13
|
index do
|
14
14
|
selectable_column
|
15
15
|
id_column
|
16
|
-
column :
|
16
|
+
column :name
|
17
17
|
column :option_type
|
18
18
|
actions
|
19
19
|
end
|
20
20
|
|
21
|
-
filter :
|
21
|
+
filter :name
|
22
22
|
|
23
23
|
form do |f|
|
24
24
|
f.inputs do
|
25
|
-
f.input :
|
25
|
+
f.input :name
|
26
26
|
f.input :option_type
|
27
27
|
end
|
28
28
|
f.actions
|
@@ -12,15 +12,15 @@ ActiveAdmin.register Post do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
filter :title
|
15
|
-
filter :category, as: :searchable_select
|
16
|
-
filter :user, as: :searchable_select
|
15
|
+
filter :category, as: :searchable_select
|
16
|
+
filter :user, as: :searchable_select
|
17
17
|
|
18
18
|
form do |f|
|
19
19
|
f.inputs do
|
20
20
|
f.input :title
|
21
21
|
f.input :body
|
22
|
-
f.input :category, as: :searchable_select
|
23
|
-
f.input :user, as: :searchable_select
|
22
|
+
f.input :category, as: :searchable_select
|
23
|
+
f.input :user, as: :searchable_select
|
24
24
|
end
|
25
25
|
f.actions
|
26
26
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Test admin for ajax: false scenarios
|
2
|
+
ActiveAdmin.register Post, as: 'AjaxFalsePost' do
|
3
|
+
permit_params :title, :body, :category_id, :user_id, :color_id
|
4
|
+
|
5
|
+
filter :title
|
6
|
+
filter :category, as: :tom_select, ajax: false
|
7
|
+
filter :user, as: :searchable_select, ajax: false
|
8
|
+
|
9
|
+
form do |f|
|
10
|
+
f.inputs do
|
11
|
+
f.input :title
|
12
|
+
f.input :body
|
13
|
+
f.input :category, as: :tom_select, ajax: false
|
14
|
+
f.input :user, as: :searchable_select, ajax: false
|
15
|
+
end
|
16
|
+
f.actions
|
17
|
+
end
|
18
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
ActiveAdmin.register Variant do
|
2
|
-
belongs_to :product
|
2
|
+
belongs_to :product, optional: true
|
3
3
|
|
4
4
|
permit_params :price, :option_value_id, :product_id
|
5
5
|
|
@@ -21,7 +21,7 @@ ActiveAdmin.register Variant do
|
|
21
21
|
as: :searchable_select,
|
22
22
|
ajax: {
|
23
23
|
resource: OptionValue,
|
24
|
-
|
24
|
+
params: {
|
25
25
|
option_type_id: f.object.product&.option_type_id
|
26
26
|
}
|
27
27
|
})
|
@@ -2,7 +2,7 @@
|
|
2
2
|
@import "tailwindcss/components";
|
3
3
|
@import "tailwindcss/utilities";
|
4
4
|
|
5
|
-
@import "
|
5
|
+
@import "activeadmin-tom_select/src/tom-select-tailwind.css";
|
6
6
|
|
7
7
|
/* Additional batch actions dropdown styles that aren't in the ActiveAdmin plugin */
|
8
8
|
@layer components {
|
@@ -1,15 +0,0 @@
|
|
1
|
-
@import "tailwindcss";
|
2
|
-
|
3
|
-
/* Import our Tom Select Tailwind theme overrides */
|
4
|
-
@import '../../../../../src/tom-select-tailwind.css';
|
5
|
-
|
6
|
-
/* Additional batch actions dropdown styles that aren't in the ActiveAdmin plugin */
|
7
|
-
@layer components {
|
8
|
-
.batch-actions-dropdown-toggle:disabled {
|
9
|
-
@apply opacity-50 cursor-not-allowed;
|
10
|
-
}
|
11
|
-
|
12
|
-
.batch-actions-dropdown-arrow {
|
13
|
-
@apply w-2.5 h-2.5;
|
14
|
-
}
|
15
|
-
}
|
@@ -8,12 +8,10 @@ import TomSelect from 'tom-select';
|
|
8
8
|
window.TomSelect = TomSelect;
|
9
9
|
|
10
10
|
// Import and setup ActiveAdmin Tom Select
|
11
|
-
import { setupAutoInit, initSearchableSelects } from '
|
11
|
+
import { setupAutoInit, initSearchableSelects } from 'activeadmin-tom_select';
|
12
12
|
|
13
13
|
// Make the init function globally available for tests
|
14
14
|
window.initSearchableSelects = initSearchableSelects;
|
15
15
|
|
16
16
|
// Initialize the module after everything is loaded
|
17
|
-
setupAutoInit();
|
18
|
-
|
19
|
-
console.log('ActiveAdmin JS loaded with Tom Select');
|
17
|
+
setupAutoInit();
|
@@ -1,4 +1,12 @@
|
|
1
1
|
class OptionValue < ApplicationRecord
|
2
2
|
belongs_to :option_type
|
3
3
|
has_many :variants
|
4
|
+
|
5
|
+
def self.ransackable_attributes(_auth_object = nil)
|
6
|
+
%w[created_at id name option_type_id updated_at]
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.ransackable_associations(_auth_object = nil)
|
10
|
+
[]
|
11
|
+
end
|
4
12
|
end
|
data/spec/internal/db/schema.rb
CHANGED
@@ -10,7 +10,9 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
|
13
|
+
# Use appropriate version based on Rails version
|
14
|
+
schema_version = Rails.version.start_with?('8') ? '8.0' : '7.1'
|
15
|
+
ActiveRecord::Schema[schema_version].define(version: 0) do
|
14
16
|
create_table 'active_admin_comments', force: :cascade do |t|
|
15
17
|
t.string 'namespace'
|
16
18
|
t.text 'body'
|
data/spec/internal/db/seeds.rb
CHANGED
@@ -50,7 +50,7 @@ rgb_colors_data = [
|
|
50
50
|
{ code: '#FFFFFF', description: 'White' }
|
51
51
|
]
|
52
52
|
|
53
|
-
|
53
|
+
rgb_colors_data.map do |color|
|
54
54
|
RgbColor.find_or_create_by(code: color[:code]) do |rgb|
|
55
55
|
rgb.description = color[:description]
|
56
56
|
end
|
@@ -58,10 +58,7 @@ end
|
|
58
58
|
|
59
59
|
# Create internal tag names
|
60
60
|
10.times do |i|
|
61
|
-
InternalTagName.find_or_create_by(name: "Internal Tag #{i + 1}")
|
62
|
-
tag.description = "Description for internal tag #{i + 1}"
|
63
|
-
tag.color_id = rgb_colors.sample.id
|
64
|
-
end
|
61
|
+
InternalTagName.find_or_create_by(name: "Internal Tag #{i + 1}")
|
65
62
|
end
|
66
63
|
|
67
64
|
# Create option types and values
|
@@ -72,7 +69,7 @@ option_types = []
|
|
72
69
|
|
73
70
|
5.times do |j|
|
74
71
|
OptionValue.find_or_create_by(
|
75
|
-
|
72
|
+
name: "Value #{j + 1} for #{option_type.name}",
|
76
73
|
option_type_id: option_type.id
|
77
74
|
)
|
78
75
|
end
|
@@ -114,7 +111,7 @@ end
|
|
114
111
|
|
115
112
|
# Update posts with colors
|
116
113
|
Post.all.each do |post|
|
117
|
-
post.update(
|
114
|
+
post.update(color_id: colors.sample.id) if post.color_id.nil?
|
118
115
|
end
|
119
116
|
|
120
117
|
# Create Tags
|
@@ -8,7 +8,7 @@
|
|
8
8
|
"dependencies": {
|
9
9
|
"@activeadmin/activeadmin": "^4.0.0-beta16",
|
10
10
|
"@rails/ujs": "^7.1.400",
|
11
|
-
"
|
11
|
+
"activeadmin-tom_select": "file:../../npm-package",
|
12
12
|
"tailwindcss": "^3.4.17",
|
13
13
|
"tom-select": "^2.4.3"
|
14
14
|
},
|
@@ -17,7 +17,7 @@
|
|
17
17
|
}
|
18
18
|
},
|
19
19
|
"../../npm-package": {
|
20
|
-
"name": "
|
20
|
+
"name": "activeadmin-tom_select",
|
21
21
|
"version": "4.1.0",
|
22
22
|
"license": "MIT",
|
23
23
|
"peerDependencies": {
|
@@ -622,7 +622,7 @@
|
|
622
622
|
"integrity": "sha512-SFtA5X59BimNG8cy60pgZhPf1bGpg5KXVYF6Jj5H5hrwwNXKNmD2yNZhHC+WfuLqBN+972cZHR9Fto6nJQz+Xw==",
|
623
623
|
"license": "MIT"
|
624
624
|
},
|
625
|
-
"node_modules
|
625
|
+
"node_modules/activeadmin-tom_select": {
|
626
626
|
"resolved": "../../npm-package",
|
627
627
|
"link": true
|
628
628
|
},
|