activeadmin-tom_select 4.1.0
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 +7 -0
- data/.actrc +20 -0
- data/.claude/commands/fix-tests.md +203 -0
- data/.github/workflows/ci.yml +174 -0
- data/.github/workflows/npm-publish.yml +50 -0
- data/.gitignore +35 -0
- data/.npmignore +58 -0
- data/.rspec +1 -0
- data/.rubocop.yml +75 -0
- data/.yardopts +2 -0
- data/AGENTS.md +39 -0
- data/Appraisals +9 -0
- data/CHANGELOG.md +64 -0
- data/CLAUDE.md +157 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +368 -0
- data/LICENSE.txt +25 -0
- data/README.md +483 -0
- data/Rakefile +4 -0
- data/activeadmin-tom_select.gemspec +43 -0
- data/bin/rspec +17 -0
- data/config/database.yml +16 -0
- data/docs/activeadmin-4-detailed-reference.md +932 -0
- data/docs/activeadmin-4-gem-migration-guide.md +313 -0
- data/docs/combustion.md +213 -0
- data/docs/fail.png +0 -0
- data/docs/guide-update-your-app.md +283 -0
- data/docs/normal.png +0 -0
- data/docs/propshaft-readme.md +320 -0
- data/docs/propshaft-upgrade.md +484 -0
- data/docs/setup-activeadmin-app.md +552 -0
- data/docs/setup-activeadmin-gem.md +535 -0
- data/docs/tailwind/blog-page.md +341 -0
- data/docs/tailwind/upgrade-guide-enhanced.md +438 -0
- data/docs/tailwind/upgrade-guide.md +416 -0
- data/docs/tailwind-4/active_admin.rake +38 -0
- data/docs/tailwind-4/active_admin.tailwind.css +415 -0
- data/docs/tailwind-4/tailwind-active_admin.config.js +18 -0
- data/docs/test-app-change.md +154 -0
- data/docs/test-environment-fixes.md +58 -0
- data/docs/update-tom-select.md +184 -0
- data/docs/upload-system.md +225 -0
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile +10 -0
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile.lock +377 -0
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile +10 -0
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile.lock +372 -0
- data/lefthook.yml +17 -0
- data/lib/activeadmin/inputs/filters/searchable_select_input.rb +19 -0
- data/lib/activeadmin/inputs/searchable_select_input.rb +16 -0
- data/lib/activeadmin/tom_select/engine.rb +17 -0
- data/lib/activeadmin/tom_select/option_collection.rb +128 -0
- data/lib/activeadmin/tom_select/resource_dsl_extension.rb +56 -0
- data/lib/activeadmin/tom_select/resource_extension.rb +10 -0
- data/lib/activeadmin/tom_select/select_input_extension.rb +168 -0
- data/lib/activeadmin/tom_select/version.rb +5 -0
- data/lib/activeadmin/tom_select.rb +20 -0
- data/lib/activeadmin-tom_select.rb +5 -0
- data/lib/generators/active_admin/tom_select/install/install_generator.rb +180 -0
- data/npm-package/package-lock.json +51 -0
- data/npm-package/package.json +43 -0
- data/npm-package/src/index.js +153 -0
- data/npm-package/src/tom-select-tailwind.css +392 -0
- data/sonar-project.properties +25 -0
- data/spec/features/ajax_params_spec.rb +31 -0
- data/spec/features/asset_pipeline_diagnostic_spec.rb +155 -0
- data/spec/features/end_to_end_spec.rb +273 -0
- data/spec/features/filter_input_spec.rb +144 -0
- data/spec/features/form_input_spec.rb +122 -0
- data/spec/features/inline_ajax_setting_spec.rb +26 -0
- data/spec/features/input_errors_spec.rb +76 -0
- data/spec/features/input_html_options_spec.rb +30 -0
- data/spec/features/options_dsl_spec.rb +230 -0
- data/spec/features/production_build_spec.rb +108 -0
- data/spec/internal/.node-version +1 -0
- data/spec/internal/Gemfile +43 -0
- data/spec/internal/Gemfile.lock +333 -0
- data/spec/internal/Procfile.dev +3 -0
- data/spec/internal/README.md +24 -0
- data/spec/internal/Rakefile +6 -0
- data/spec/internal/app/admin/categories.rb +26 -0
- data/spec/internal/app/admin/dashboard.rb +29 -0
- data/spec/internal/app/admin/option_types.rb +19 -0
- data/spec/internal/app/admin/option_values.rb +30 -0
- data/spec/internal/app/admin/posts.rb +27 -0
- data/spec/internal/app/admin/products.rb +22 -0
- data/spec/internal/app/admin/rgb_colors.rb +25 -0
- data/spec/internal/app/admin/tag_names.rb +21 -0
- data/spec/internal/app/admin/test_ajax_params_category.rb +10 -0
- data/spec/internal/app/admin/test_ajax_params_post.rb +20 -0
- data/spec/internal/app/admin/test_form_post_class.rb +7 -0
- data/spec/internal/app/admin/test_form_post_custom.rb +11 -0
- data/spec/internal/app/admin/test_form_post_resource.rb +11 -0
- data/spec/internal/app/admin/test_form_post_resource_custom.rb +12 -0
- data/spec/internal/app/admin/test_inline_ajax_post.rb +9 -0
- data/spec/internal/app/admin/test_input_html_post.rb +11 -0
- data/spec/internal/app/admin/test_posts_display_text.rb +9 -0
- data/spec/internal/app/admin/test_posts_filter.rb +9 -0
- data/spec/internal/app/admin/test_posts_named.rb +9 -0
- data/spec/internal/app/admin/test_posts_pagination.rb +9 -0
- data/spec/internal/app/admin/test_posts_payload_lambda.rb +11 -0
- data/spec/internal/app/admin/test_posts_payload_proc.rb +9 -0
- data/spec/internal/app/admin/test_posts_scope_lambda.rb +8 -0
- data/spec/internal/app/admin/test_posts_scope_params.rb +8 -0
- data/spec/internal/app/admin/test_posts_scope_user.rb +8 -0
- data/spec/internal/app/admin/test_posts_text_attr.rb +5 -0
- data/spec/internal/app/admin/users.rb +23 -0
- data/spec/internal/app/admin/variants.rb +31 -0
- data/spec/internal/app/assets/config/manifest.js +2 -0
- data/spec/internal/app/assets/images/.keep +0 -0
- data/spec/internal/app/assets/stylesheets/active_admin.tailwind.css +16 -0
- data/spec/internal/app/assets/stylesheets/application.tailwind.css +15 -0
- data/spec/internal/app/controllers/application_controller.rb +9 -0
- data/spec/internal/app/controllers/concerns/.keep +0 -0
- data/spec/internal/app/helpers/application_helper.rb +2 -0
- data/spec/internal/app/javascript/active_admin.js +19 -0
- data/spec/internal/app/javascript/application.js +2 -0
- data/spec/internal/app/jobs/application_job.rb +7 -0
- data/spec/internal/app/mailers/application_mailer.rb +4 -0
- data/spec/internal/app/models/admin_user.rb +9 -0
- data/spec/internal/app/models/application_record.rb +3 -0
- data/spec/internal/app/models/article.rb +12 -0
- data/spec/internal/app/models/category.rb +12 -0
- data/spec/internal/app/models/color.rb +9 -0
- data/spec/internal/app/models/concerns/.keep +0 -0
- data/spec/internal/app/models/internal/tag_name.rb +14 -0
- data/spec/internal/app/models/internal_tag_name.rb +11 -0
- data/spec/internal/app/models/option_type.rb +12 -0
- data/spec/internal/app/models/option_value.rb +4 -0
- data/spec/internal/app/models/post.rb +15 -0
- data/spec/internal/app/models/product.rb +12 -0
- data/spec/internal/app/models/rgb_color.rb +16 -0
- data/spec/internal/app/models/tag.rb +12 -0
- data/spec/internal/app/models/tagging.rb +12 -0
- data/spec/internal/app/models/user.rb +12 -0
- data/spec/internal/app/models/variant.rb +12 -0
- data/spec/internal/app/views/layouts/application.html.erb +28 -0
- data/spec/internal/app/views/layouts/mailer.html.erb +13 -0
- data/spec/internal/app/views/layouts/mailer.text.erb +1 -0
- data/spec/internal/app/views/pwa/manifest.json.erb +22 -0
- data/spec/internal/app/views/pwa/service-worker.js +26 -0
- data/spec/internal/bin/bundle +117 -0
- data/spec/internal/bin/dev +11 -0
- data/spec/internal/bin/rackup +27 -0
- data/spec/internal/bin/rails +4 -0
- data/spec/internal/bin/rake +4 -0
- data/spec/internal/bin/setup +37 -0
- data/spec/internal/config/application.rb +50 -0
- data/spec/internal/config/boot.rb +3 -0
- data/spec/internal/config/credentials.yml.enc +1 -0
- data/spec/internal/config/database.yml +32 -0
- data/spec/internal/config/environment.rb +5 -0
- data/spec/internal/config/environments/development.rb +63 -0
- data/spec/internal/config/environments/production.rb +86 -0
- data/spec/internal/config/environments/test.rb +50 -0
- data/spec/internal/config/initializers/active_admin.rb +54 -0
- data/spec/internal/config/initializers/assets.rb +8 -0
- data/spec/internal/config/initializers/content_security_policy.rb +25 -0
- data/spec/internal/config/initializers/devise.rb +315 -0
- data/spec/internal/config/initializers/filter_parameter_logging.rb +8 -0
- data/spec/internal/config/initializers/inflections.rb +16 -0
- data/spec/internal/config/initializers/searchable_select.rb +6 -0
- data/spec/internal/config/locales/devise.en.yml +65 -0
- data/spec/internal/config/locales/en.yml +31 -0
- data/spec/internal/config/master.key +1 -0
- data/spec/internal/config/puma.rb +38 -0
- data/spec/internal/config/routes.rb +17 -0
- data/spec/internal/config.ru +6 -0
- data/spec/internal/db/schema.rb +174 -0
- data/spec/internal/db/seeds.rb +167 -0
- data/spec/internal/esbuild.config.js +34 -0
- data/spec/internal/lib/tasks/.keep +0 -0
- data/spec/internal/lib/tasks/active_admin.rake +55 -0
- data/spec/internal/log/.keep +0 -0
- data/spec/internal/package-lock.json +1954 -0
- data/spec/internal/package.json +21 -0
- data/spec/internal/public/400.html +114 -0
- data/spec/internal/public/404.html +114 -0
- data/spec/internal/public/406-unsupported-browser.html +114 -0
- data/spec/internal/public/422.html +114 -0
- data/spec/internal/public/500.html +114 -0
- data/spec/internal/public/icon.png +0 -0
- data/spec/internal/public/icon.svg +3 -0
- data/spec/internal/public/robots.txt +1 -0
- data/spec/internal/script/.keep +0 -0
- data/spec/internal/storage/.keep +0 -0
- data/spec/internal/tailwind.config.js +23 -0
- data/spec/internal/vendor/.keep +0 -0
- data/spec/internal/yarn.lock +824 -0
- data/spec/rails_helper.rb +62 -0
- data/spec/spec_helper.rb +138 -0
- data/spec/support/active_admin_helpers.rb +17 -0
- data/spec/support/capybara.rb +8 -0
- data/spec/support/models.rb +11 -0
- data/spec/support/pluck_polyfill.rb +12 -0
- data/spec/support/reset_settings.rb +5 -0
- metadata +497 -0
@@ -0,0 +1,415 @@
|
|
1
|
+
@import "tailwindcss";
|
2
|
+
|
3
|
+
@config "../../../config/tailwind-active_admin.config.js";
|
4
|
+
|
5
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
6
|
+
|
7
|
+
@utility ring-opacity-5 {
|
8
|
+
--tw-ring-opacity: 0.05;
|
9
|
+
}
|
10
|
+
|
11
|
+
@layer base {
|
12
|
+
*,
|
13
|
+
::after,
|
14
|
+
::before,
|
15
|
+
::backdrop,
|
16
|
+
::file-selector-button {
|
17
|
+
border-color: var(--color-gray-200, currentColor);
|
18
|
+
}
|
19
|
+
|
20
|
+
/* Form Inputs */
|
21
|
+
[type='text'],
|
22
|
+
[type='email'],
|
23
|
+
[type='url'],
|
24
|
+
[type='password'],
|
25
|
+
[type='number'],
|
26
|
+
[type='date'],
|
27
|
+
[type='datetime-local'],
|
28
|
+
[type='month'],
|
29
|
+
[type='search'],
|
30
|
+
[type='tel'],
|
31
|
+
[type='time'],
|
32
|
+
[type='week'],
|
33
|
+
textarea,
|
34
|
+
select {
|
35
|
+
@apply appearance-none bg-gray-50 dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md px-3 py-2 text-gray-900 dark:text-white w-full;
|
36
|
+
--tw-shadow: 0 0 #0000;
|
37
|
+
}
|
38
|
+
|
39
|
+
/* Form Input Focus States */
|
40
|
+
[type='text']:focus,
|
41
|
+
[type='email']:focus,
|
42
|
+
[type='url']:focus,
|
43
|
+
[type='password']:focus,
|
44
|
+
[type='number']:focus,
|
45
|
+
[type='date']:focus,
|
46
|
+
[type='datetime-local']:focus,
|
47
|
+
[type='month']:focus,
|
48
|
+
[type='search']:focus,
|
49
|
+
[type='tel']:focus,
|
50
|
+
[type='time']:focus,
|
51
|
+
[type='week']:focus,
|
52
|
+
textarea:focus,
|
53
|
+
select:focus {
|
54
|
+
@apply outline-none ring-2 ring-blue-500 dark:ring-blue-500 border-blue-500 dark:border-blue-500;
|
55
|
+
}
|
56
|
+
|
57
|
+
/* Placeholders */
|
58
|
+
input::placeholder,
|
59
|
+
textarea::placeholder {
|
60
|
+
@apply text-gray-500 dark:text-gray-400;
|
61
|
+
}
|
62
|
+
|
63
|
+
/* Checkbox and Radio */
|
64
|
+
[type='checkbox'],
|
65
|
+
[type='radio'] {
|
66
|
+
@apply appearance-none p-0 inline-block align-middle bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-none h-4 w-4 text-blue-600 dark:text-blue-500;
|
67
|
+
print-color-adjust: exact;
|
68
|
+
}
|
69
|
+
|
70
|
+
[type='radio'] {
|
71
|
+
@apply rounded-full;
|
72
|
+
}
|
73
|
+
|
74
|
+
/* Checkbox and Radio Focus States */
|
75
|
+
[type='checkbox']:focus,
|
76
|
+
[type='radio']:focus {
|
77
|
+
@apply outline-none ring-2 ring-blue-500 dark:ring-blue-500;
|
78
|
+
}
|
79
|
+
|
80
|
+
/* Checkbox and Radio Checked States */
|
81
|
+
[type='checkbox']:checked,
|
82
|
+
[type='radio']:checked {
|
83
|
+
@apply border-transparent bg-current bg-no-repeat bg-center;
|
84
|
+
background-size: 0.65rem 0.65rem;
|
85
|
+
}
|
86
|
+
|
87
|
+
[type='checkbox']:checked {
|
88
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 12'%3E%3Cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M1 5.917 5.724 10.5 15 1.5'/%3E%3C/svg%3E");
|
89
|
+
}
|
90
|
+
|
91
|
+
[type='radio']:checked {
|
92
|
+
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E");
|
93
|
+
background-size: 1rem 1rem;
|
94
|
+
}
|
95
|
+
|
96
|
+
/* File Input */
|
97
|
+
[type='file'] {
|
98
|
+
@apply bg-transparent border-0 p-0;
|
99
|
+
}
|
100
|
+
|
101
|
+
[type='file']:focus {
|
102
|
+
@apply outline-none;
|
103
|
+
}
|
104
|
+
|
105
|
+
/* File Selector Button */
|
106
|
+
input[type=file]::file-selector-button {
|
107
|
+
@apply text-white bg-gray-800 dark:bg-gray-600 border-0 font-medium text-sm cursor-pointer px-8 py-2.5 -ml-4 mr-4;
|
108
|
+
}
|
109
|
+
|
110
|
+
input[type=file]::file-selector-button:hover {
|
111
|
+
@apply bg-gray-700 dark:bg-gray-500;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
@layer components {
|
116
|
+
/* Action Item Button */
|
117
|
+
.action-item-button {
|
118
|
+
@apply py-2 px-3 text-sm font-medium no-underline text-gray-900 focus:outline-none bg-white rounded-md border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700;
|
119
|
+
}
|
120
|
+
|
121
|
+
/* Index Data Table Toolbar */
|
122
|
+
.index-data-table-toolbar {
|
123
|
+
@apply flex flex-col lg:flex-row gap-4 mb-4;
|
124
|
+
}
|
125
|
+
|
126
|
+
/* Scopes */
|
127
|
+
.scopes {
|
128
|
+
@apply flex flex-wrap gap-1.5;
|
129
|
+
}
|
130
|
+
|
131
|
+
/* Index Button Group */
|
132
|
+
.index-button-group {
|
133
|
+
@apply inline-flex flex-wrap items-stretch rounded-md;
|
134
|
+
}
|
135
|
+
|
136
|
+
.index-button-group > :where(*:not(:first-child)) {
|
137
|
+
@apply -ms-px my-0;
|
138
|
+
}
|
139
|
+
|
140
|
+
/* Index Button */
|
141
|
+
.index-button {
|
142
|
+
@apply inline-flex items-center justify-center px-3 py-2 text-sm font-medium no-underline text-gray-900 bg-white border border-gray-200 hover:bg-gray-100 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 first:rounded-s-md last:rounded-e-md dark:bg-gray-900 dark:border-gray-700 dark:text-gray-100 dark:hover:text-gray-200 dark:hover:bg-gray-800 dark:focus:ring-blue-500 dark:focus:text-white;
|
143
|
+
}
|
144
|
+
|
145
|
+
.index-button-selected {
|
146
|
+
@apply bg-gray-100 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-800;
|
147
|
+
}
|
148
|
+
|
149
|
+
/* Scopes Count */
|
150
|
+
.scopes-count {
|
151
|
+
@apply inline-flex items-center justify-center rounded-full bg-indigo-200/80 text-indigo-800 dark:bg-indigo-800 dark:text-indigo-200 px-1.5 py-1 text-xs font-normal ms-2 leading-none;
|
152
|
+
}
|
153
|
+
|
154
|
+
/* Paginated Collection */
|
155
|
+
.paginated-collection {
|
156
|
+
@apply border border-gray-200 dark:border-gray-800 rounded-md shadow-sm overflow-hidden;
|
157
|
+
}
|
158
|
+
|
159
|
+
.paginated-collection-contents {
|
160
|
+
@apply overflow-x-auto;
|
161
|
+
}
|
162
|
+
|
163
|
+
.paginated-collection-pagination {
|
164
|
+
@apply p-2 lg:p-3 flex flex-col-reverse lg:flex-row gap-4 items-center justify-between;
|
165
|
+
}
|
166
|
+
|
167
|
+
.paginated-collection-footer {
|
168
|
+
@apply p-3 flex gap-2 items-center justify-between text-sm border-t border-gray-200 dark:border-gray-800;
|
169
|
+
}
|
170
|
+
|
171
|
+
/* Data Table */
|
172
|
+
.data-table {
|
173
|
+
@apply w-full text-sm text-gray-800 dark:text-gray-300;
|
174
|
+
}
|
175
|
+
|
176
|
+
.data-table :where(thead > tr > th) {
|
177
|
+
@apply px-3 py-3.5 whitespace-nowrap font-semibold text-start text-xs uppercase border-b text-gray-700 bg-gray-50 dark:bg-gray-950/50 dark:border-gray-800 dark:text-white;
|
178
|
+
}
|
179
|
+
|
180
|
+
.data-table :where(tbody > tr) {
|
181
|
+
@apply border-b dark:border-gray-800;
|
182
|
+
}
|
183
|
+
|
184
|
+
.data-table :where(td) {
|
185
|
+
@apply px-3 py-4;
|
186
|
+
}
|
187
|
+
|
188
|
+
/* Data Table Resource Actions */
|
189
|
+
.data-table-resource-actions {
|
190
|
+
@apply flex gap-2 items-center;
|
191
|
+
}
|
192
|
+
|
193
|
+
.data-table-resource-actions > a {
|
194
|
+
@apply text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white;
|
195
|
+
}
|
196
|
+
|
197
|
+
/* Data Sortable */
|
198
|
+
.data-table :where(thead > tr > th[data-sortable]) {
|
199
|
+
@apply cursor-pointer;
|
200
|
+
}
|
201
|
+
|
202
|
+
.data-table-sorted-icon {
|
203
|
+
@apply invisible w-2 h-3;
|
204
|
+
}
|
205
|
+
|
206
|
+
.data-table :where(thead > tr > th[data-sort-direction]) .data-table-sorted-icon {
|
207
|
+
@apply visible;
|
208
|
+
}
|
209
|
+
|
210
|
+
.data-table :where(thead > tr > th[data-sort-direction="asc"]) .data-table-sorted-icon {
|
211
|
+
@apply rotate-180;
|
212
|
+
}
|
213
|
+
|
214
|
+
/* Filters Form */
|
215
|
+
.filters-form {
|
216
|
+
@apply text-sm mb-6;
|
217
|
+
}
|
218
|
+
|
219
|
+
.filters-form-title {
|
220
|
+
@apply text-gray-700 dark:text-gray-200 font-bold text-lg mb-4;
|
221
|
+
}
|
222
|
+
|
223
|
+
.filters-form :where(.label) {
|
224
|
+
@apply block mb-1.5 text-sm;
|
225
|
+
}
|
226
|
+
|
227
|
+
.filters-form-input-group {
|
228
|
+
@apply grid grid-cols-1 sm:grid-cols-2 gap-4;
|
229
|
+
}
|
230
|
+
|
231
|
+
.filters-form-input-group :where(.input) {
|
232
|
+
@apply w-full;
|
233
|
+
}
|
234
|
+
|
235
|
+
.filters-form-input-group :where(.label) {
|
236
|
+
@apply block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300;
|
237
|
+
}
|
238
|
+
|
239
|
+
.filters-form-input-group :where(.hint) {
|
240
|
+
@apply mt-1 text-sm text-gray-500 dark:text-gray-400;
|
241
|
+
}
|
242
|
+
|
243
|
+
.filters-form-field {
|
244
|
+
@apply mb-4;
|
245
|
+
}
|
246
|
+
|
247
|
+
.filters-form-buttons {
|
248
|
+
@apply flex gap-2 items-center;
|
249
|
+
}
|
250
|
+
|
251
|
+
.filters-form-submit {
|
252
|
+
@apply min-w-[6rem] font-bold text-white bg-blue-600 hover:bg-blue-700 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-md px-3 py-2 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 cursor-pointer;
|
253
|
+
}
|
254
|
+
|
255
|
+
.filters-form-clear {
|
256
|
+
@apply rounded-md px-3 py-2 font-semibold text-gray-700 hover:bg-gray-100 no-underline dark:text-gray-400 dark:hover:bg-inherit dark:hover:text-gray-100 dark:focus:ring-blue-800;
|
257
|
+
}
|
258
|
+
|
259
|
+
/* Panel */
|
260
|
+
.panel {
|
261
|
+
@apply mb-6 border border-gray-200 rounded-md shadow-sm dark:border-gray-800;
|
262
|
+
}
|
263
|
+
|
264
|
+
.panel-title {
|
265
|
+
@apply font-bold bg-gray-100 dark:bg-gray-900 rounded-t-md p-3;
|
266
|
+
}
|
267
|
+
|
268
|
+
.panel-body {
|
269
|
+
@apply py-5 px-3;
|
270
|
+
}
|
271
|
+
|
272
|
+
/* Attributes Table */
|
273
|
+
.attributes-table {
|
274
|
+
@apply overflow-hidden mb-6 border border-gray-200 rounded-md shadow-sm dark:border-gray-800;
|
275
|
+
}
|
276
|
+
|
277
|
+
.attributes-table :where(tbody > tr > th) {
|
278
|
+
@apply w-32 sm:w-40 text-start text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-800/60 dark:text-gray-300;
|
279
|
+
}
|
280
|
+
|
281
|
+
.attributes-table :where(tbody > tr > th, tbody > tr > td) {
|
282
|
+
@apply p-3;
|
283
|
+
}
|
284
|
+
|
285
|
+
/* Status Tag */
|
286
|
+
.status-tag {
|
287
|
+
@apply bg-gray-200 text-gray-600 dark:bg-gray-700 dark:text-gray-400 inline-flex items-center rounded-full text-sm font-medium px-2.5 py-0.5 whitespace-nowrap;
|
288
|
+
}
|
289
|
+
|
290
|
+
.status-tag:where([data-status=yes]) {
|
291
|
+
@apply bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300;
|
292
|
+
}
|
293
|
+
|
294
|
+
/* Tabs */
|
295
|
+
.tabs-nav {
|
296
|
+
@apply flex flex-wrap mb-2 text-sm font-medium text-center border-b border-gray-200 dark:border-gray-700;
|
297
|
+
}
|
298
|
+
|
299
|
+
.tabs-nav > :where(a) {
|
300
|
+
@apply block p-4 border-b-2 border-transparent rounded-t-md hover:text-gray-600 dark:hover:text-gray-300 no-underline;
|
301
|
+
}
|
302
|
+
|
303
|
+
.tabs-content {
|
304
|
+
@apply p-4 mb-6;
|
305
|
+
}
|
306
|
+
|
307
|
+
/* Formtastic */
|
308
|
+
.formtastic {
|
309
|
+
@apply text-sm;
|
310
|
+
}
|
311
|
+
|
312
|
+
.formtastic :where(.fieldset-title, .has-many-fields-title) {
|
313
|
+
@apply block w-full mb-3 border-b font-bold text-lg;
|
314
|
+
}
|
315
|
+
|
316
|
+
.formtastic :where(.label) {
|
317
|
+
@apply block mb-1.5 text-gray-700 dark:text-gray-300;
|
318
|
+
}
|
319
|
+
|
320
|
+
.formtastic :where(.label abbr) {
|
321
|
+
@apply ms-1 no-underline;
|
322
|
+
}
|
323
|
+
|
324
|
+
.formtastic :where(.input) {
|
325
|
+
@apply py-3;
|
326
|
+
}
|
327
|
+
|
328
|
+
.formtastic :where(.choice) {
|
329
|
+
@apply mb-1;
|
330
|
+
}
|
331
|
+
|
332
|
+
.formtastic :where(.boolean label, .choice label) {
|
333
|
+
@apply flex gap-2 items-center;
|
334
|
+
}
|
335
|
+
|
336
|
+
.formtastic :where(.fragments-group) {
|
337
|
+
@apply inline-flex flex-wrap gap-1;
|
338
|
+
}
|
339
|
+
|
340
|
+
.formtastic :where(.fragment label) {
|
341
|
+
@apply sr-only;
|
342
|
+
}
|
343
|
+
|
344
|
+
.formtastic :where(.inline-hints) {
|
345
|
+
@apply text-gray-500 mt-2;
|
346
|
+
}
|
347
|
+
|
348
|
+
.formtastic :where(.errors) {
|
349
|
+
@apply p-4 mb-6 rounded-md space-y-2 bg-red-50 text-red-800 dark:bg-red-800 dark:text-red-300;
|
350
|
+
}
|
351
|
+
|
352
|
+
.formtastic :where(.errors > li) {
|
353
|
+
@apply list-disc ms-4;
|
354
|
+
}
|
355
|
+
|
356
|
+
.formtastic :where(.inline-errors) {
|
357
|
+
@apply font-bold mt-2 text-red-600 dark:text-red-300;
|
358
|
+
}
|
359
|
+
|
360
|
+
.formtastic :where(.error [type=email], .error [type=number], .error [type=password], .error [type=tel], .error [type=text], .error [type=url], .error textarea) {
|
361
|
+
@apply border-red-500;
|
362
|
+
}
|
363
|
+
|
364
|
+
.formtastic :where(.buttons, .actions) {
|
365
|
+
@apply mt-3;
|
366
|
+
}
|
367
|
+
|
368
|
+
.formtastic :where(.actions > ol) {
|
369
|
+
@apply flex items-center gap-6;
|
370
|
+
}
|
371
|
+
|
372
|
+
.formtastic :where([type=submit], [type=button], button) {
|
373
|
+
@apply font-bold text-white bg-blue-600 hover:bg-blue-700 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg px-4 py-2 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 cursor-pointer;
|
374
|
+
}
|
375
|
+
|
376
|
+
.formtastic :where(.actions .cancel-link) {
|
377
|
+
@apply font-semibold leading-6 text-gray-900 dark:text-white no-underline;
|
378
|
+
}
|
379
|
+
|
380
|
+
.formtastic :where(.has-many-add) {
|
381
|
+
@apply inline-block py-3;
|
382
|
+
}
|
383
|
+
|
384
|
+
.formtastic :where(.has-many-container) {
|
385
|
+
@apply space-y-8;
|
386
|
+
}
|
387
|
+
|
388
|
+
.formtastic :where(.has-many-fields) {
|
389
|
+
@apply ps-3 border-s-4 border-s-gray-200 dark:border-s-gray-700;
|
390
|
+
}
|
391
|
+
|
392
|
+
/* Select Elements */
|
393
|
+
select {
|
394
|
+
@apply bg-no-repeat bg-[right_0.75rem_center] bg-[length:0.75em_0.75em] pr-8;
|
395
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 10 6'%3E%3Cpath stroke='%236B7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 1 4 4 4-4'/%3E%3C/svg%3E");
|
396
|
+
print-color-adjust: exact;
|
397
|
+
}
|
398
|
+
|
399
|
+
.dark select {
|
400
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 10 6'%3E%3Cpath stroke='%23D1D5DB' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 1 4 4 4-4'/%3E%3C/svg%3E");
|
401
|
+
}
|
402
|
+
|
403
|
+
/* Fix for Formtastic fragments (date/time selects) */
|
404
|
+
.fragments-group,
|
405
|
+
.fragments {
|
406
|
+
@apply flex flex-row gap-2 items-center;
|
407
|
+
}
|
408
|
+
.fragment {
|
409
|
+
@apply flex-shrink-0;
|
410
|
+
}
|
411
|
+
.fragments-group select,
|
412
|
+
.fragments select {
|
413
|
+
@apply w-auto min-w-[5rem];
|
414
|
+
}
|
415
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
const execSync = require("node:child_process").execSync;
|
2
|
+
const activeAdminPath = execSync("bundle show activeadmin", {
|
3
|
+
encoding: "utf-8",
|
4
|
+
}).trim();
|
5
|
+
|
6
|
+
module.exports = {
|
7
|
+
content: [
|
8
|
+
`${activeAdminPath}/vendor/javascript/flowbite.js`,
|
9
|
+
`${activeAdminPath}/plugin.js`,
|
10
|
+
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
11
|
+
"./app/admin/**/*.{arb,erb,html,rb}",
|
12
|
+
"./app/views/active_admin/**/*.{arb,erb,html,rb}",
|
13
|
+
"./app/views/admin/**/*.{arb,erb,html,rb}",
|
14
|
+
"./app/views/layouts/active_admin*.{erb,html}",
|
15
|
+
"./app/assets/controllers/active_admin/**/*.js",
|
16
|
+
],
|
17
|
+
darkMode: "selector"
|
18
|
+
};
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# Test App Migration from Combustion to Rails 8 (2025-09-11)
|
2
|
+
|
3
|
+
## Summary
|
4
|
+
Migrated the test environment from Combustion-based minimal app to a full Rails 8 application with Propshaft, Tom Select, and Tailwind CSS v3.
|
5
|
+
|
6
|
+
## Key Changes
|
7
|
+
|
8
|
+
### 1. Removed Combustion
|
9
|
+
- Backed up old `spec/internal` to `spec/internal.backup`
|
10
|
+
- Created new full Rails 8 app in `spec/internal`
|
11
|
+
- Removed all Combustion references from specs
|
12
|
+
- Fixed RSpec configuration to load Rails app directly
|
13
|
+
|
14
|
+
### 2. Rails 8 Test App Setup
|
15
|
+
```ruby
|
16
|
+
# Created with:
|
17
|
+
rails new spec/internal \
|
18
|
+
--skip-action-cable \
|
19
|
+
--skip-action-mailbox \
|
20
|
+
--skip-action-text \
|
21
|
+
--skip-active-storage \
|
22
|
+
--skip-bootsnap \
|
23
|
+
--skip-brakeman \
|
24
|
+
--skip-ci \
|
25
|
+
--skip-docker \
|
26
|
+
--skip-git \
|
27
|
+
--skip-hotwire \
|
28
|
+
--skip-jbuilder \
|
29
|
+
--skip-kamal \
|
30
|
+
--skip-rubocop \
|
31
|
+
--skip-solid \
|
32
|
+
--skip-system-test \
|
33
|
+
--skip-test \
|
34
|
+
--skip-thruster \
|
35
|
+
--css=tailwind \
|
36
|
+
--javascript=esbuild
|
37
|
+
```
|
38
|
+
|
39
|
+
### 3. Asset Pipeline (Propshaft)
|
40
|
+
- Removed sassc-rails (using Tailwind only)
|
41
|
+
- Configured Propshaft for asset serving
|
42
|
+
- Built CSS outputs to `app/assets/builds/active_admin.css`
|
43
|
+
- Tom Select styles integrated via Tailwind build process
|
44
|
+
|
45
|
+
### 4. Tom Select Integration
|
46
|
+
- Migrated from Select2 to Tom Select
|
47
|
+
- Full Tailwind CSS styling for Tom Select components
|
48
|
+
- Styles located in `/src/tom-select-tailwind.css`
|
49
|
+
- Credits: Based on https://github.com/orchidjs/tom-select/discussions/693 by @LeZellus
|
50
|
+
|
51
|
+
### 5. Database Setup
|
52
|
+
```ruby
|
53
|
+
# spec/internal/db/schema.rb includes:
|
54
|
+
- users (with name field)
|
55
|
+
- admin_users (for Devise/ActiveAdmin)
|
56
|
+
- categories, posts, colors, rgb_colors
|
57
|
+
- tags, taggings (many-to-many)
|
58
|
+
- option_types, internal_tag_names (for tests)
|
59
|
+
```
|
60
|
+
|
61
|
+
### 6. Build Process
|
62
|
+
```bash
|
63
|
+
# CSS Build (Tailwind with Tom Select)
|
64
|
+
cd spec/internal
|
65
|
+
bundle exec rake active_admin:build
|
66
|
+
|
67
|
+
# JavaScript Build
|
68
|
+
npm run build
|
69
|
+
|
70
|
+
# Watch mode
|
71
|
+
bundle exec rake active_admin:watch # CSS
|
72
|
+
npm run watch:js # JavaScript
|
73
|
+
```
|
74
|
+
|
75
|
+
### 7. Running the Test App
|
76
|
+
```bash
|
77
|
+
cd spec/internal
|
78
|
+
bundle exec rackup
|
79
|
+
# Available at http://localhost:9292
|
80
|
+
# Admin login: admin@example.com / password
|
81
|
+
```
|
82
|
+
|
83
|
+
### 8. Fixed Issues
|
84
|
+
- ✅ Removed duplicate config.ru from root
|
85
|
+
- ✅ Fixed empty schema.rb
|
86
|
+
- ✅ Added missing Devise gem
|
87
|
+
- ✅ Created missing models (AdminUser, Color, Tag, Tagging)
|
88
|
+
- ✅ Fixed seeds.rb to match schema
|
89
|
+
- ✅ Converted from Sprockets to Propshaft
|
90
|
+
- ✅ Downgraded Tailwind CSS from v4 to v3 for compatibility
|
91
|
+
- ✅ Fixed all RSpec/Capybara loading issues
|
92
|
+
|
93
|
+
### 9. File Structure
|
94
|
+
```
|
95
|
+
spec/internal/
|
96
|
+
├── app/
|
97
|
+
│ ├── admin/ # ActiveAdmin resources
|
98
|
+
│ ├── assets/
|
99
|
+
│ │ ├── builds/ # Built CSS/JS (Propshaft serves these)
|
100
|
+
│ │ └── stylesheets/
|
101
|
+
│ │ └── active_admin.tailwind.css
|
102
|
+
│ └── models/ # Test models
|
103
|
+
├── config/
|
104
|
+
│ ├── initializers/
|
105
|
+
│ │ ├── active_admin.rb
|
106
|
+
│ │ └── devise.rb
|
107
|
+
│ └── routes.rb
|
108
|
+
├── db/
|
109
|
+
│ ├── schema.rb # Complete test schema
|
110
|
+
│ └── seeds.rb # Test data
|
111
|
+
├── lib/
|
112
|
+
│ └── tasks/
|
113
|
+
│ └── active_admin.rake # Build tasks
|
114
|
+
├── package.json # Node dependencies
|
115
|
+
├── tailwind.config.js # Tailwind configuration
|
116
|
+
├── Gemfile # Ruby dependencies (Propshaft, no Sprockets)
|
117
|
+
└── config.ru # Rack configuration
|
118
|
+
```
|
119
|
+
|
120
|
+
### 10. Dependencies
|
121
|
+
- Rails 8.0.2+
|
122
|
+
- ActiveAdmin 4.0.0.beta16
|
123
|
+
- Propshaft (not Sprockets)
|
124
|
+
- Tailwind CSS v3 (not v4)
|
125
|
+
- Tom Select 2.4.3
|
126
|
+
- esbuild for JavaScript
|
127
|
+
- cssbundling-rails for CSS
|
128
|
+
|
129
|
+
### 11. Testing
|
130
|
+
```bash
|
131
|
+
# Run all specs
|
132
|
+
bundle exec rspec
|
133
|
+
|
134
|
+
# Run specific spec
|
135
|
+
bundle exec rspec spec/features/form_input_spec.rb
|
136
|
+
|
137
|
+
# Tests now work with:
|
138
|
+
- No Combustion dependency
|
139
|
+
- Proper Rails 8 app loading
|
140
|
+
- ActiveAdmin integration
|
141
|
+
- Tom Select functionality
|
142
|
+
```
|
143
|
+
|
144
|
+
### 12. Documentation Updates
|
145
|
+
- Updated CLAUDE.md with new test app instructions
|
146
|
+
- Updated README.md with development/testing section
|
147
|
+
- Added `bundle exec rackup` instructions for manual testing
|
148
|
+
|
149
|
+
## Important Notes
|
150
|
+
- Always use Tailwind v3 (v4 has breaking changes)
|
151
|
+
- Tom Select base CSS is concatenated during build
|
152
|
+
- All imports use proper @import directives
|
153
|
+
- Test app is a full Rails app, not a minimal Combustion app
|
154
|
+
- Propshaft serves assets from app/assets/builds/
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Test Environment Fixes for Tom Select Migration
|
2
|
+
|
3
|
+
## Issue
|
4
|
+
After migrating from Select2 to Tom Select, tests were failing because Propshaft wasn't being loaded in the test environment, causing assets not to be served properly.
|
5
|
+
|
6
|
+
## Root Cause
|
7
|
+
The Rails 8 test application wasn't loading Propshaft's railtie, which meant:
|
8
|
+
- No asset paths were configured
|
9
|
+
- Assets were being requested at wrong URLs (`/javascripts/` instead of `/assets/`)
|
10
|
+
- Tom Select JavaScript wasn't being loaded
|
11
|
+
- Tom Select wasn't initializing on searchable select inputs
|
12
|
+
|
13
|
+
## Solution
|
14
|
+
|
15
|
+
### 1. Load Propshaft Railtie
|
16
|
+
Added to `spec/internal/config/application.rb`:
|
17
|
+
```ruby
|
18
|
+
# Require Propshaft railtie for asset pipeline
|
19
|
+
require 'propshaft/railtie'
|
20
|
+
```
|
21
|
+
|
22
|
+
This ensures Propshaft is properly initialized with:
|
23
|
+
- Asset paths configured
|
24
|
+
- Dynamic resolver for test environment
|
25
|
+
- Proper asset serving with digest URLs
|
26
|
+
|
27
|
+
### 2. Key Configuration Details
|
28
|
+
After the fix, Propshaft in test environment has:
|
29
|
+
- **Asset paths**: 7 configured paths including app/assets/builds
|
30
|
+
- **Resolver**: `Propshaft::Resolver::Dynamic` (no precompilation needed)
|
31
|
+
- **Asset serving**: Enabled (`config.assets.server = true`)
|
32
|
+
- **URLs**: Proper digest URLs like `/assets/active_admin-f967af7b.js`
|
33
|
+
|
34
|
+
### 3. Test Adjustments
|
35
|
+
Minor adjustments to tests for Tom Select compatibility:
|
36
|
+
- Use `visible: :all` for finding dropdown options (Tom Select may create hidden options)
|
37
|
+
- More flexible selectors for Tom Select wrappers
|
38
|
+
- Removed hardcoded waits in favor of proper Capybara waiting
|
39
|
+
|
40
|
+
## Verification
|
41
|
+
Created comprehensive diagnostic test (`spec/features/asset_pipeline_diagnostic_spec.rb`) that verifies:
|
42
|
+
- Rails and Propshaft configuration
|
43
|
+
- Asset paths and files
|
44
|
+
- Built asset contents (checks for Tom Select code)
|
45
|
+
- Asset serving in browser
|
46
|
+
- JavaScript loading and initialization
|
47
|
+
|
48
|
+
## Results
|
49
|
+
- ✅ All production_build_spec tests passing
|
50
|
+
- ✅ Tom Select properly initializing
|
51
|
+
- ✅ Assets served with correct digest URLs
|
52
|
+
- ⚠️ Some end_to_end tests still need adjustment for Tom Select behavior differences
|
53
|
+
|
54
|
+
## Lessons Learned
|
55
|
+
1. Always verify that required railties are loaded in test environments
|
56
|
+
2. Use diagnostic tests to troubleshoot asset pipeline issues
|
57
|
+
3. Tom Select has slightly different DOM structure and behavior than Select2
|
58
|
+
4. Propshaft requires explicit railtie loading unlike Sprockets which was auto-loaded
|