activeadmin-tom_select 4.1.2 → 4.2.0.beta2
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/Appraisals +2 -2
- data/CHANGELOG.md +12 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +146 -102
- data/README.md +1 -1
- data/activeadmin-tom_select.gemspec +1 -0
- data/docs/activeadmin-4-asset-setup.md +171 -0
- data/docs/activeadmin-tailwind-4.md +125 -0
- data/docs/guide-update-your-app.md +89 -356
- data/docs/setup-activeadmin-app.md +69 -492
- data/docs/setup-activeadmin-gem.md +83 -449
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile +2 -1
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile.lock +158 -116
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile +2 -1
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile.lock +145 -101
- data/lib/activeadmin/tom_select/option_collection.rb +4 -6
- data/lib/activeadmin/tom_select/select_input_extension.rb +15 -7
- data/lib/activeadmin/tom_select/version.rb +1 -1
- data/npm-package/package.json +1 -1
- data/spec/features/end_to_end_spec.rb +2 -2
- data/spec/features/input_errors_spec.rb +1 -3
- data/spec/features/options_dsl_spec.rb +6 -6
- data/spec/internal/Gemfile +1 -0
- data/spec/internal/Gemfile.lock +152 -107
- data/spec/internal/app/assets/stylesheets/active_admin.tailwind.css +8 -5
- data/spec/internal/bin/tailwindcss +27 -0
- data/spec/internal/lib/tasks/active_admin.rake +9 -4
- data/spec/internal/package-lock.json +15 -1371
- data/spec/internal/package.json +1 -2
- data/{docs/tailwind-4/tailwind-active_admin.config.js → spec/internal/tailwind-active_admin.config.mjs} +9 -4
- data/spec/internal/yarn.lock +128 -728
- metadata +21 -23
- data/docs/activeadmin-4-detailed-reference.md +0 -932
- data/docs/activeadmin-4-gem-migration-guide.md +0 -313
- data/docs/combustion.md +0 -213
- data/docs/fail.png +0 -0
- data/docs/normal.png +0 -0
- data/docs/propshaft-readme.md +0 -320
- data/docs/propshaft-upgrade.md +0 -484
- data/docs/tailwind/blog-page.md +0 -341
- data/docs/tailwind/upgrade-guide-enhanced.md +0 -438
- data/docs/tailwind/upgrade-guide.md +0 -416
- data/docs/tailwind-4/active_admin.rake +0 -38
- data/docs/tailwind-4/active_admin.tailwind.css +0 -415
- data/docs/test-app-change.md +0 -154
- data/docs/test-environment-fixes.md +0 -58
- data/docs/update-tom-select.md +0 -348
|
@@ -1,54 +1,8 @@
|
|
|
1
|
-
# Setting Up ActiveAdmin 4 Extension Gem
|
|
1
|
+
# Setting Up an ActiveAdmin 4 Extension Gem (Combustion)
|
|
2
2
|
|
|
3
|
-
This guide
|
|
3
|
+
This guide mirrors the working setup used in this repo: ActiveAdmin 4.0.0.beta19 + Tailwind CSS v4 + Combustion test app.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
**Your gem's JavaScript code must live in the gem, NOT be copied to user apps!**
|
|
8
|
-
|
|
9
|
-
✅ **Correct approach:**
|
|
10
|
-
- Main JS module in `app/assets/javascripts/your_gem.js`
|
|
11
|
-
- Generator adds single import: `import 'your_gem_name'`
|
|
12
|
-
- Users get updates when they update your gem
|
|
13
|
-
- Code is maintainable and reusable
|
|
14
|
-
|
|
15
|
-
❌ **Wrong approach:**
|
|
16
|
-
- Generator copies large code blocks to user's app
|
|
17
|
-
- Users never get updates without re-running generator
|
|
18
|
-
- Code duplication across all installations
|
|
19
|
-
- Maintenance nightmare
|
|
20
|
-
|
|
21
|
-
## 1. Create Gem Structure
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
# Create new gem
|
|
25
|
-
bundle gem activeadmin_your_feature --test=rspec
|
|
26
|
-
cd activeadmin_your_feature
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 2. Update Gemspec
|
|
30
|
-
|
|
31
|
-
```ruby
|
|
32
|
-
# activeadmin_your_feature.gemspec
|
|
33
|
-
Gem::Specification.new do |spec|
|
|
34
|
-
spec.name = "activeadmin_your_feature"
|
|
35
|
-
# ... other standard fields ...
|
|
36
|
-
|
|
37
|
-
spec.required_ruby_version = ">= 3.2"
|
|
38
|
-
|
|
39
|
-
# Runtime dependencies
|
|
40
|
-
spec.add_runtime_dependency "activeadmin", [">= 1.0", "< 5"]
|
|
41
|
-
|
|
42
|
-
# Development dependencies
|
|
43
|
-
spec.add_development_dependency "combustion", "~> 1.3"
|
|
44
|
-
spec.add_development_dependency "rspec-rails", "~> 6.0"
|
|
45
|
-
spec.add_development_dependency "capybara", "~> 3.39"
|
|
46
|
-
spec.add_development_dependency "importmap-rails", "~> 2.0"
|
|
47
|
-
spec.add_development_dependency "propshaft" # Required - Sprockets not supported
|
|
48
|
-
end
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## 3. Set Up Gemfile
|
|
5
|
+
## 1. Gem Dependencies
|
|
52
6
|
|
|
53
7
|
```ruby
|
|
54
8
|
# Gemfile
|
|
@@ -56,13 +10,14 @@ source "https://rubygems.org"
|
|
|
56
10
|
gemspec
|
|
57
11
|
|
|
58
12
|
gem "rails", "~> 7.2"
|
|
59
|
-
gem "activeadmin", "
|
|
13
|
+
gem "activeadmin", "4.0.0.beta19"
|
|
60
14
|
gem "sqlite3"
|
|
61
15
|
gem "puma"
|
|
62
16
|
|
|
63
|
-
# Required for ActiveAdmin 4
|
|
64
17
|
gem "importmap-rails", "~> 2.0"
|
|
65
|
-
gem "propshaft"
|
|
18
|
+
gem "propshaft"
|
|
19
|
+
|
|
20
|
+
gem "tailwindcss-rails", "~> 4.4.0"
|
|
66
21
|
|
|
67
22
|
group :development, :test do
|
|
68
23
|
gem "combustion", "~> 1.3"
|
|
@@ -71,79 +26,41 @@ group :development, :test do
|
|
|
71
26
|
end
|
|
72
27
|
```
|
|
73
28
|
|
|
74
|
-
##
|
|
29
|
+
## 2. Combustion Test App
|
|
75
30
|
|
|
76
31
|
```bash
|
|
77
|
-
# This creates spec/internal directory
|
|
78
32
|
bundle exec combust
|
|
79
33
|
```
|
|
80
34
|
|
|
81
|
-
##
|
|
35
|
+
## 3. config.ru Loading Order
|
|
82
36
|
|
|
83
37
|
```ruby
|
|
84
38
|
# config.ru
|
|
85
39
|
require "rubygems"
|
|
86
40
|
require "bundler"
|
|
87
41
|
|
|
88
|
-
# DON'T use Bundler.require - loads gems too early!
|
|
89
42
|
Bundler.setup(:default, :development)
|
|
90
43
|
|
|
91
|
-
|
|
92
|
-
require 'combustion'
|
|
93
|
-
|
|
94
|
-
# Initialize Combustion with Rails components
|
|
44
|
+
require "combustion"
|
|
95
45
|
Combustion.initialize! :active_record, :action_controller, :action_view do
|
|
96
46
|
config.load_defaults Rails::VERSION::STRING.to_f if Rails::VERSION::MAJOR >= 7
|
|
97
47
|
end
|
|
98
48
|
|
|
99
|
-
|
|
100
|
-
require
|
|
101
|
-
require
|
|
102
|
-
require 'activeadmin_your_feature'
|
|
103
|
-
|
|
104
|
-
# If you have custom Formtastic inputs
|
|
105
|
-
# require 'formtastic/inputs/your_input'
|
|
49
|
+
require "importmap-rails"
|
|
50
|
+
require "active_admin"
|
|
51
|
+
require "activeadmin_your_feature"
|
|
106
52
|
|
|
107
53
|
run Combustion::Application
|
|
108
54
|
```
|
|
109
55
|
|
|
110
|
-
##
|
|
56
|
+
## 4. Internal App Structure
|
|
111
57
|
|
|
112
58
|
```bash
|
|
113
59
|
cd spec/internal
|
|
114
|
-
|
|
115
|
-
# Create necessary directories
|
|
116
|
-
mkdir -p app/admin
|
|
117
|
-
mkdir -p app/assets/{builds,config,stylesheets,javascripts}
|
|
118
|
-
mkdir -p app/js
|
|
119
|
-
mkdir -p app/models
|
|
120
|
-
mkdir -p config/initializers
|
|
121
|
-
mkdir -p db
|
|
60
|
+
mkdir -p app/admin app/assets/{builds,config,stylesheets} app/javascript
|
|
122
61
|
```
|
|
123
62
|
|
|
124
|
-
##
|
|
125
|
-
|
|
126
|
-
```ruby
|
|
127
|
-
# spec/internal/db/schema.rb
|
|
128
|
-
ActiveRecord::Schema.define do
|
|
129
|
-
create_table :active_admin_comments, force: true do |t|
|
|
130
|
-
t.string :namespace
|
|
131
|
-
t.text :body
|
|
132
|
-
t.references :resource, polymorphic: true
|
|
133
|
-
t.references :author, polymorphic: true
|
|
134
|
-
t.timestamps
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# Add your test models
|
|
138
|
-
create_table :posts, force: true do |t|
|
|
139
|
-
t.string :title
|
|
140
|
-
t.text :body
|
|
141
|
-
t.timestamps
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## 8. ActiveAdmin Configuration
|
|
63
|
+
## 5. ActiveAdmin Setup
|
|
147
64
|
|
|
148
65
|
```ruby
|
|
149
66
|
# spec/internal/config/initializers/active_admin.rb
|
|
@@ -151,385 +68,102 @@ ActiveAdmin.setup do |config|
|
|
|
151
68
|
config.site_title = "Test App"
|
|
152
69
|
config.authentication_method = false
|
|
153
70
|
config.current_user_method = false
|
|
154
|
-
config.batch_actions = true
|
|
155
71
|
end
|
|
156
72
|
```
|
|
157
73
|
|
|
158
|
-
##
|
|
74
|
+
## 6. Tailwind Input + Config
|
|
159
75
|
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
root to: 'admin/dashboard#index'
|
|
165
|
-
end
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## 10. Install NPM Dependencies
|
|
169
|
-
|
|
170
|
-
```bash
|
|
171
|
-
cd spec/internal
|
|
172
|
-
npm init -y
|
|
173
|
-
|
|
174
|
-
# Install required packages
|
|
175
|
-
npm install --save-dev \
|
|
176
|
-
@activeadmin/activeadmin@^3.3.0 \
|
|
177
|
-
tailwindcss@^3.4.17 \
|
|
178
|
-
esbuild@^0.24.2
|
|
179
|
-
|
|
180
|
-
# Install runtime dependencies (if your gem needs jQuery plugins)
|
|
181
|
-
npm install \
|
|
182
|
-
jquery@^3.7.1 \
|
|
183
|
-
your-vendor-package
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
## 11. Create Package.json Scripts
|
|
76
|
+
```css
|
|
77
|
+
/* spec/internal/app/assets/stylesheets/active_admin.tailwind.css */
|
|
78
|
+
@import "tailwindcss";
|
|
79
|
+
@config "../../../tailwind-active_admin.config.mjs";
|
|
187
80
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
"name": "internal",
|
|
191
|
-
"version": "1.0.0",
|
|
192
|
-
"scripts": {
|
|
193
|
-
"build:css": "node ./build_css.js",
|
|
194
|
-
"build:js": "node esbuild.config.js",
|
|
195
|
-
"build": "npm run build:js && npm run build:css",
|
|
196
|
-
"watch": "npm run build:js --watch & npm run build:css -- --watch"
|
|
197
|
-
},
|
|
198
|
-
"dependencies": {
|
|
199
|
-
"esbuild": "^0.24.2",
|
|
200
|
-
"jquery": "^3.7.1"
|
|
201
|
-
},
|
|
202
|
-
"devDependencies": {
|
|
203
|
-
"@activeadmin/activeadmin": "^3.3.0",
|
|
204
|
-
"tailwindcss": "^3.4.17"
|
|
205
|
-
}
|
|
206
|
-
}
|
|
81
|
+
/* Import your gem CSS if needed */
|
|
82
|
+
@import "your_gem/css";
|
|
207
83
|
```
|
|
208
84
|
|
|
209
|
-
## 12. Create Tailwind Config (WITH SAFELIST!)
|
|
210
|
-
|
|
211
85
|
```javascript
|
|
212
|
-
// spec/internal/tailwind.config.mjs
|
|
213
|
-
import
|
|
214
|
-
import
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
} catch (e) {
|
|
220
|
-
// Continue without scanning if bundler unavailable
|
|
221
|
-
}
|
|
86
|
+
// spec/internal/tailwind-active_admin.config.mjs
|
|
87
|
+
import { execSync } from "child_process";
|
|
88
|
+
import activeAdminPlugin from "@activeadmin/activeadmin/plugin";
|
|
89
|
+
|
|
90
|
+
const activeAdminPath = execSync("bundle show activeadmin", {
|
|
91
|
+
encoding: "utf-8"
|
|
92
|
+
}).trim();
|
|
222
93
|
|
|
223
94
|
export default {
|
|
224
95
|
content: [
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
|
233
|
-
] : [])
|
|
96
|
+
`${activeAdminPath}/vendor/javascript/flowbite.js`,
|
|
97
|
+
`${activeAdminPath}/plugin.js`,
|
|
98
|
+
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
|
99
|
+
"./app/admin/**/*.{arb,erb,html,rb}",
|
|
100
|
+
"./app/views/**/*.{arb,erb,html,rb}",
|
|
101
|
+
"./app/javascript/**/*.js",
|
|
102
|
+
"../../app/assets/**/*.{js,css}"
|
|
234
103
|
],
|
|
235
|
-
darkMode:
|
|
236
|
-
plugins: [activeAdminPlugin]
|
|
237
|
-
// CRITICAL: Without safelist, ActiveAdmin layout breaks!
|
|
238
|
-
safelist: [
|
|
239
|
-
// Grid and layout
|
|
240
|
-
'grid', 'gap-4', 'gap-6', 'lg:grid-cols-3', 'md:grid-cols-2',
|
|
241
|
-
'col-span-2', 'col-span-3', 'lg:col-span-2', 'lg:col-span-1',
|
|
242
|
-
// Flexbox
|
|
243
|
-
'flex', 'flex-col', 'flex-row', 'flex-wrap', 'items-center',
|
|
244
|
-
'justify-between', 'justify-center', 'items-start', 'items-end',
|
|
245
|
-
// Spacing
|
|
246
|
-
'p-4', 'p-6', 'px-4', 'px-6', 'py-2', 'py-4', 'm-0', 'mx-auto',
|
|
247
|
-
'mt-4', 'mb-4', 'ml-auto', 'mr-auto', 'space-y-4', 'space-x-4',
|
|
248
|
-
// Display
|
|
249
|
-
'block', 'inline-block', 'hidden', 'lg:hidden', 'lg:block', 'lg:flex',
|
|
250
|
-
// Width/Height
|
|
251
|
-
'w-full', 'w-auto', 'w-64', 'h-full', 'min-h-screen', 'max-w-7xl',
|
|
252
|
-
// Typography
|
|
253
|
-
'text-sm', 'text-base', 'text-lg', 'text-xl', 'font-medium', 'font-semibold',
|
|
254
|
-
// Colors
|
|
255
|
-
'bg-white', 'bg-gray-50', 'bg-gray-100', 'text-gray-900', 'text-gray-600',
|
|
256
|
-
'dark:bg-gray-800', 'dark:bg-gray-900', 'dark:text-white', 'dark:text-gray-300',
|
|
257
|
-
// Borders
|
|
258
|
-
'border', 'border-gray-200', 'dark:border-gray-700', 'rounded-lg', 'rounded-md',
|
|
259
|
-
// Forms
|
|
260
|
-
'form-input', 'form-select', 'form-checkbox',
|
|
261
|
-
// Position & Z-index
|
|
262
|
-
'relative', 'absolute', 'fixed', 'sticky', 'top-0', 'left-0', 'right-0',
|
|
263
|
-
'z-10', 'z-20', 'z-30', 'z-40', 'z-50',
|
|
264
|
-
// Shadows
|
|
265
|
-
'shadow', 'shadow-md', 'shadow-lg'
|
|
266
|
-
]
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
## 13. Create Build Script for CSS
|
|
271
|
-
|
|
272
|
-
```javascript
|
|
273
|
-
// spec/internal/build_css.js
|
|
274
|
-
#!/usr/bin/env node
|
|
275
|
-
const fs = require('fs');
|
|
276
|
-
const path = require('path');
|
|
277
|
-
const { spawnSync } = require('child_process');
|
|
278
|
-
|
|
279
|
-
const root = __dirname;
|
|
280
|
-
const inputPath = path.join(root, 'app/assets/stylesheets/active_admin_source.css');
|
|
281
|
-
const tmpPath = path.join(root, 'app/assets/stylesheets/__aa_tmp.css');
|
|
282
|
-
const outPath = path.join(root, 'app/assets/builds/active_admin.css');
|
|
283
|
-
|
|
284
|
-
function build() {
|
|
285
|
-
// Read source file
|
|
286
|
-
const src = fs.readFileSync(inputPath, 'utf8');
|
|
287
|
-
|
|
288
|
-
// If you have vendor CSS to include:
|
|
289
|
-
// const vendorCssPath = path.join(root, 'node_modules/your-package/dist/styles.css');
|
|
290
|
-
// const vendorCss = fs.readFileSync(vendorCssPath, 'utf8');
|
|
291
|
-
|
|
292
|
-
// Ensure Tailwind directives are first
|
|
293
|
-
const tailwindDirectives = '@tailwind base;\n@tailwind components;\n@tailwind utilities;';
|
|
294
|
-
|
|
295
|
-
// Build final CSS
|
|
296
|
-
// With vendor: const tmpCss = `${tailwindDirectives}\n\n/* Vendor */\n${vendorCss}\n\n/* Custom */\n${src}`;
|
|
297
|
-
const tmpCss = `${tailwindDirectives}\n\n${src}`;
|
|
298
|
-
|
|
299
|
-
fs.writeFileSync(tmpPath, tmpCss, 'utf8');
|
|
300
|
-
|
|
301
|
-
// Run Tailwind
|
|
302
|
-
const res = spawnSync('npx', [
|
|
303
|
-
'tailwindcss',
|
|
304
|
-
'-c', 'tailwind.config.mjs',
|
|
305
|
-
'-i', tmpPath,
|
|
306
|
-
'-o', outPath
|
|
307
|
-
], { stdio: 'inherit', cwd: root });
|
|
308
|
-
|
|
309
|
-
if (res.status !== 0) {
|
|
310
|
-
process.exit(res.status);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
fs.unlinkSync(tmpPath);
|
|
314
|
-
console.log(`CSS built: ${outPath}`);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
build();
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
## 14. Create jQuery Injection (if needed)
|
|
321
|
-
|
|
322
|
-
```javascript
|
|
323
|
-
// spec/internal/inject-jquery.js
|
|
324
|
-
// https://github.com/evanw/esbuild/issues/1681
|
|
325
|
-
export { default as $ } from 'jquery/dist/jquery.js'
|
|
326
|
-
export { default as jQuery } from 'jquery/dist/jquery.js'
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
## 15. Create JavaScript Entry Point
|
|
330
|
-
|
|
331
|
-
```javascript
|
|
332
|
-
// spec/internal/app/js/active_admin.js
|
|
333
|
-
import '@activeadmin/activeadmin';
|
|
334
|
-
|
|
335
|
-
// Import your gem's JavaScript module - users will use this exact import
|
|
336
|
-
// NOTE: In development, this needs to be resolved via esbuild alias to your local gem
|
|
337
|
-
import 'your_gem_name';
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
For development testing, create an esbuild config:
|
|
341
|
-
|
|
342
|
-
```javascript
|
|
343
|
-
// spec/internal/esbuild.config.js
|
|
344
|
-
const esbuild = require('esbuild');
|
|
345
|
-
const path = require('path');
|
|
346
|
-
|
|
347
|
-
const config = {
|
|
348
|
-
entryPoints: ['app/js/active_admin.js'],
|
|
349
|
-
bundle: true,
|
|
350
|
-
sourcemap: true,
|
|
351
|
-
format: 'esm',
|
|
352
|
-
outdir: 'app/assets/builds',
|
|
353
|
-
publicPath: '/assets',
|
|
354
|
-
inject: ['./inject-jquery.js'],
|
|
355
|
-
alias: {
|
|
356
|
-
// Map your gem's module name to the actual file for development
|
|
357
|
-
'your_gem_name': path.resolve(__dirname, '../../app/assets/javascripts/your_gem_main.js')
|
|
358
|
-
}
|
|
104
|
+
darkMode: "selector",
|
|
105
|
+
plugins: [activeAdminPlugin]
|
|
359
106
|
};
|
|
360
|
-
|
|
361
|
-
// Build logic...
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
## 16. Create CSS Source
|
|
365
|
-
|
|
366
|
-
```css
|
|
367
|
-
/* spec/internal/app/assets/stylesheets/active_admin_source.css */
|
|
368
|
-
@tailwind base;
|
|
369
|
-
@tailwind components;
|
|
370
|
-
@tailwind utilities;
|
|
371
|
-
|
|
372
|
-
/* Your custom styles here */
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
## 17. Set Up Propshaft Assets
|
|
376
|
-
|
|
377
|
-
With Propshaft, assets in `app/assets/builds` are automatically served. No manifest configuration needed.
|
|
378
|
-
|
|
379
|
-
```css
|
|
380
|
-
/* spec/internal/app/assets/stylesheets/active_admin.css */
|
|
381
|
-
/*
|
|
382
|
-
* This file can be empty or include custom overrides
|
|
383
|
-
* The real CSS is in builds/active_admin.css
|
|
384
|
-
*/
|
|
385
107
|
```
|
|
386
108
|
|
|
387
|
-
##
|
|
109
|
+
## 7. Tailwind Build Tasks
|
|
388
110
|
|
|
389
111
|
```ruby
|
|
390
|
-
# spec/internal/
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
112
|
+
# spec/internal/lib/tasks/active_admin.rake
|
|
113
|
+
namespace :active_admin do
|
|
114
|
+
desc "Build Active Admin Tailwind stylesheets"
|
|
115
|
+
task build: :environment do
|
|
116
|
+
command = [
|
|
117
|
+
Rails.root.join("bin/tailwindcss").to_s,
|
|
118
|
+
"-i", Rails.root.join("app/assets/stylesheets/active_admin.tailwind.css").to_s,
|
|
119
|
+
"-o", Rails.root.join("app/assets/builds/active_admin.css").to_s,
|
|
120
|
+
"-m"
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
system(*command, exception: true)
|
|
394
124
|
end
|
|
395
125
|
end
|
|
396
126
|
```
|
|
397
127
|
|
|
398
|
-
##
|
|
399
|
-
|
|
400
|
-
```ruby
|
|
401
|
-
# spec/internal/app/admin/posts.rb
|
|
402
|
-
ActiveAdmin.register Post do
|
|
403
|
-
permit_params :title, :body
|
|
404
|
-
|
|
405
|
-
form do |f|
|
|
406
|
-
f.semantic_errors
|
|
407
|
-
f.inputs do
|
|
408
|
-
f.input :title
|
|
409
|
-
f.input :body, as: :text
|
|
410
|
-
# Use your custom input types here
|
|
411
|
-
end
|
|
412
|
-
f.actions
|
|
413
|
-
end
|
|
414
|
-
end
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
## 21. Build Assets
|
|
418
|
-
|
|
419
|
-
```bash
|
|
420
|
-
cd spec/internal
|
|
421
|
-
npm install
|
|
422
|
-
npm run build
|
|
423
|
-
|
|
424
|
-
# Verify output
|
|
425
|
-
ls -lah app/assets/builds/
|
|
426
|
-
# Should see active_admin.css (100KB+) and active_admin.js
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
## 22. Test the Setup
|
|
128
|
+
## 8. Tailwind Binstub
|
|
430
129
|
|
|
431
130
|
```bash
|
|
432
|
-
|
|
433
|
-
bundle exec rackup
|
|
434
|
-
|
|
435
|
-
# Visit http://localhost:9292/admin
|
|
436
|
-
# Should see styled ActiveAdmin interface
|
|
131
|
+
bundle binstubs tailwindcss-ruby --force
|
|
437
132
|
```
|
|
438
133
|
|
|
439
|
-
##
|
|
440
|
-
|
|
441
|
-
```ruby
|
|
442
|
-
# spec/rails_helper.rb
|
|
443
|
-
ENV['RAILS_ENV'] ||= 'test'
|
|
444
|
-
|
|
445
|
-
require 'combustion'
|
|
134
|
+
## 9. JS Entry
|
|
446
135
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
require 'rspec/rails'
|
|
453
|
-
require 'capybara/rails'
|
|
454
|
-
|
|
455
|
-
RSpec.configure do |config|
|
|
456
|
-
config.use_transactional_fixtures = true
|
|
457
|
-
config.infer_spec_type_from_file_location!
|
|
458
|
-
config.filter_rails_from_backtrace!
|
|
459
|
-
end
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
## 24. Create Basic Spec
|
|
463
|
-
|
|
464
|
-
```ruby
|
|
465
|
-
# spec/features/admin_spec.rb
|
|
466
|
-
require 'rails_helper'
|
|
467
|
-
|
|
468
|
-
RSpec.describe 'Admin Interface', type: :feature do
|
|
469
|
-
it 'loads the admin dashboard' do
|
|
470
|
-
visit '/admin'
|
|
471
|
-
expect(page).to have_content('Dashboard')
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
it 'has properly styled interface' do
|
|
475
|
-
visit '/admin'
|
|
476
|
-
# Check for Tailwind classes indicating proper styling
|
|
477
|
-
expect(page).to have_css('.flex')
|
|
478
|
-
expect(page).to have_css('.grid')
|
|
479
|
-
end
|
|
480
|
-
end
|
|
136
|
+
```javascript
|
|
137
|
+
// spec/internal/app/javascript/active_admin.js
|
|
138
|
+
import "@activeadmin/activeadmin";
|
|
139
|
+
import "your_gem";
|
|
481
140
|
```
|
|
482
141
|
|
|
483
|
-
##
|
|
142
|
+
## 10. package.json (internal)
|
|
484
143
|
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"name": "internal",
|
|
147
|
+
"private": true,
|
|
148
|
+
"scripts": {
|
|
149
|
+
"build:js": "node esbuild.config.js",
|
|
150
|
+
"build:css": "bundle exec rake active_admin:build",
|
|
151
|
+
"build": "npm run build:js && npm run build:css"
|
|
152
|
+
},
|
|
153
|
+
"devDependencies": {
|
|
154
|
+
"@activeadmin/activeadmin": "^4.0.0-beta19",
|
|
155
|
+
"esbuild": "^0.24.2"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
485
158
|
```
|
|
486
|
-
# .gitignore
|
|
487
|
-
spec/internal/node_modules/
|
|
488
|
-
spec/internal/app/assets/builds/
|
|
489
|
-
spec/internal/tmp/
|
|
490
|
-
spec/internal/log/
|
|
491
|
-
spec/internal/db/*.sqlite3
|
|
492
|
-
spec/internal/package-lock.json
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
## Checklist
|
|
496
|
-
|
|
497
|
-
- [ ] Gem structure created with proper dependencies
|
|
498
|
-
- [ ] Combustion test app generated
|
|
499
|
-
- [ ] config.ru with correct loading order
|
|
500
|
-
- [ ] NPM packages installed
|
|
501
|
-
- [ ] Tailwind configured with safelist
|
|
502
|
-
- [ ] CSS build script created
|
|
503
|
-
- [ ] JavaScript entry point set up
|
|
504
|
-
- [ ] jQuery injection (if needed)
|
|
505
|
-
- [ ] Asset manifests configured
|
|
506
|
-
- [ ] Test models and admin resources created
|
|
507
|
-
- [ ] Assets built successfully (>100KB CSS file)
|
|
508
|
-
- [ ] Server starts and admin interface is styled
|
|
509
|
-
- [ ] RSpec tests pass
|
|
510
|
-
|
|
511
|
-
## Common Issues
|
|
512
|
-
|
|
513
|
-
### Issue: "uninitialized constant ActiveAdmin"
|
|
514
|
-
**Solution**: Check config.ru loading order - ActiveAdmin must load AFTER Combustion.initialize!
|
|
515
|
-
|
|
516
|
-
### Issue: Unstyled admin pages
|
|
517
|
-
**Solution**: Ensure Tailwind safelist is included and CSS file is >100KB
|
|
518
|
-
|
|
519
|
-
### Issue: jQuery not defined
|
|
520
|
-
**Solution**: Add inject-jquery.js and use with esbuild --inject flag
|
|
521
|
-
|
|
522
|
-
### Issue: Vendor CSS not loading
|
|
523
|
-
**Solution**: Use build_css.js to concatenate vendor CSS before Tailwind processing
|
|
524
|
-
|
|
525
|
-
### Issue: Assets not loading / 404 errors
|
|
526
|
-
**Solution**: Ensure you're using Propshaft, not Sprockets. Check that assets are in `app/assets/builds/`
|
|
527
159
|
|
|
528
|
-
##
|
|
160
|
+
## 11. ActiveAdmin 4.0.0.beta19 Notes (from upgrade guide)
|
|
529
161
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
162
|
+
- `_site_header.html.erb` container class changed from `sticky` to `fixed`.
|
|
163
|
+
- `active_admin.html.erb` adds the `pt-16` utility class.
|
|
164
|
+
- Tailwind v4 requires `@import "tailwindcss"` + `@config`.
|
|
165
|
+
- jQuery and jQuery UI removed; `columns` and `tabs` removed.
|
|
166
|
+
- Replace `default_main_content` with `render "show_default"`.
|
|
167
|
+
- Replace `as: :datepicker` with `as: :date_picker`.
|
|
168
|
+
- Replace `active_admin_comments` with `active_admin_comments_for(resource)`.
|
|
169
|
+
- Replace `attributes_table` with `attributes_table_for(resource)` in sidebars.
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
|
-
gem "activeadmin", "4.0.0.
|
|
5
|
+
gem "activeadmin", "4.0.0.beta19"
|
|
6
6
|
gem "devise", "~> 4.9", group: :test
|
|
7
7
|
gem "propshaft", "~> 1.2", group: :test
|
|
8
8
|
gem "rails", "~> 7.1"
|
|
9
|
+
gem "tailwindcss-rails", "~> 4.4.0", group: :test
|
|
9
10
|
|
|
10
11
|
gemspec name: "activeadmin-tom_select", path: "../"
|