activeadmin_mitosis_editor 0.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/CHANGELOG.md +17 -0
- data/CLAUDE.md +118 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +126 -0
- data/RELEASE.md +80 -0
- data/Rakefile +2 -0
- data/activeadmin_mitosis_editor.gemspec +17 -0
- data/app/views/inputs/mitosis_editor_input/_dependencies.html.erb +9 -0
- data/app/views/inputs/mitosis_editor_input/_form.html.erb +52 -0
- data/bin/console +5 -0
- data/bin/setup +14 -0
- data/demo/.dockerignore +51 -0
- data/demo/.gitattributes +9 -0
- data/demo/.gitignore +37 -0
- data/demo/.kamal/hooks/docker-setup.sample +3 -0
- data/demo/.kamal/hooks/post-app-boot.sample +3 -0
- data/demo/.kamal/hooks/post-deploy.sample +14 -0
- data/demo/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/demo/.kamal/hooks/pre-app-boot.sample +3 -0
- data/demo/.kamal/hooks/pre-build.sample +51 -0
- data/demo/.kamal/hooks/pre-connect.sample +47 -0
- data/demo/.kamal/hooks/pre-deploy.sample +122 -0
- data/demo/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/demo/.kamal/secrets +20 -0
- data/demo/.rubocop.yml +8 -0
- data/demo/.ruby-version +1 -0
- data/demo/Dockerfile +76 -0
- data/demo/Gemfile +78 -0
- data/demo/Procfile.dev +2 -0
- data/demo/README.md +24 -0
- data/demo/Rakefile +6 -0
- data/demo/app/admin/articles.rb +12 -0
- data/demo/app/admin/dashboard.rb +17 -0
- data/demo/app/admin/pages.rb +12 -0
- data/demo/app/admin/posts.rb +12 -0
- data/demo/app/assets/builds/.keep +0 -0
- data/demo/app/assets/builds/active_admin.css +3852 -0
- data/demo/app/assets/images/.keep +0 -0
- data/demo/app/assets/stylesheets/active_admin.css +3 -0
- data/demo/app/assets/stylesheets/application.css +1 -0
- data/demo/app/assets/stylesheets/mitosis-editor.css +1 -0
- data/demo/app/assets/stylesheets/theme-dark.css +1 -0
- data/demo/app/assets/stylesheets/theme-light.css +1 -0
- data/demo/app/controllers/application_controller.rb +7 -0
- data/demo/app/controllers/articles_controller.rb +7 -0
- data/demo/app/controllers/concerns/.keep +0 -0
- data/demo/app/helpers/application_helper.rb +2 -0
- data/demo/app/helpers/articles_helper.rb +2 -0
- data/demo/app/javascript/application.js +3 -0
- data/demo/app/javascript/controllers/application.js +9 -0
- data/demo/app/javascript/controllers/hello_controller.js +7 -0
- data/demo/app/javascript/controllers/index.js +4 -0
- data/demo/app/jobs/application_job.rb +7 -0
- data/demo/app/mailers/application_mailer.rb +4 -0
- data/demo/app/models/application_record.rb +3 -0
- data/demo/app/models/article.rb +5 -0
- data/demo/app/models/concerns/.keep +0 -0
- data/demo/app/models/page.rb +5 -0
- data/demo/app/models/post.rb +5 -0
- data/demo/app/views/articles/_article.html.erb +12 -0
- data/demo/app/views/articles/_article.json.jbuilder +2 -0
- data/demo/app/views/articles/_form.html.erb +27 -0
- data/demo/app/views/articles/edit.html.erb +12 -0
- data/demo/app/views/articles/index.html.erb +16 -0
- data/demo/app/views/articles/index.json.jbuilder +1 -0
- data/demo/app/views/articles/new.html.erb +11 -0
- data/demo/app/views/articles/show.html.erb +10 -0
- data/demo/app/views/articles/show.json.jbuilder +1 -0
- data/demo/app/views/inputs/mitosis_editor_input/_dependencies.html.erb +17 -0
- data/demo/app/views/layouts/application.html.erb +29 -0
- data/demo/app/views/layouts/mailer.html.erb +13 -0
- data/demo/app/views/layouts/mailer.text.erb +1 -0
- data/demo/app/views/pwa/manifest.json.erb +22 -0
- data/demo/app/views/pwa/service-worker.js +26 -0
- data/demo/bin/brakeman +7 -0
- data/demo/bin/bundler-audit +6 -0
- data/demo/bin/ci +6 -0
- data/demo/bin/dev +8 -0
- data/demo/bin/docker-entrypoint +8 -0
- data/demo/bin/importmap +4 -0
- data/demo/bin/jobs +6 -0
- data/demo/bin/kamal +27 -0
- data/demo/bin/rails +4 -0
- data/demo/bin/rake +4 -0
- data/demo/bin/rubocop +8 -0
- data/demo/bin/setup +35 -0
- data/demo/bin/thrust +5 -0
- data/demo/config/application.rb +27 -0
- data/demo/config/boot.rb +4 -0
- data/demo/config/bundler-audit.yml +5 -0
- data/demo/config/cable.yml +17 -0
- data/demo/config/cache.yml +16 -0
- data/demo/config/ci.rb +23 -0
- data/demo/config/credentials.yml.enc +1 -0
- data/demo/config/database.yml +41 -0
- data/demo/config/deploy.yml +120 -0
- data/demo/config/environment.rb +21 -0
- data/demo/config/environments/development.rb +78 -0
- data/demo/config/environments/production.rb +90 -0
- data/demo/config/environments/test.rb +53 -0
- data/demo/config/importmap.rb +7 -0
- data/demo/config/initializers/active_admin.rb +275 -0
- data/demo/config/initializers/activeadmin_mitosis_editor.rb +19 -0
- data/demo/config/initializers/assets.rb +7 -0
- data/demo/config/initializers/content_security_policy.rb +29 -0
- data/demo/config/initializers/filter_parameter_logging.rb +8 -0
- data/demo/config/initializers/inflections.rb +16 -0
- data/demo/config/locales/en.yml +31 -0
- data/demo/config/puma.rb +42 -0
- data/demo/config/queue.yml +18 -0
- data/demo/config/recurring.yml +15 -0
- data/demo/config/routes.rb +16 -0
- data/demo/config/storage.yml +27 -0
- data/demo/config.ru +6 -0
- data/demo/db/cable_schema.rb +11 -0
- data/demo/db/cache_schema.rb +12 -0
- data/demo/db/migrate/20260215110410_create_active_admin_comments.rb +16 -0
- data/demo/db/migrate/20260215110416_create_articles.rb +10 -0
- data/demo/db/migrate/20260216124916_create_posts.rb +10 -0
- data/demo/db/migrate/20260216124919_create_pages.rb +10 -0
- data/demo/db/queue_schema.rb +129 -0
- data/demo/db/schema.rb +48 -0
- data/demo/db/seeds.rb +9 -0
- data/demo/lib/tasks/.keep +0 -0
- data/demo/log/.keep +0 -0
- data/demo/package-lock.json +1260 -0
- data/demo/package.json +13 -0
- data/demo/public/400.html +135 -0
- data/demo/public/404.html +135 -0
- data/demo/public/406-unsupported-browser.html +135 -0
- data/demo/public/422.html +135 -0
- data/demo/public/500.html +135 -0
- data/demo/public/icon.png +0 -0
- data/demo/public/icon.svg +3 -0
- data/demo/public/robots.txt +1 -0
- data/demo/script/.keep +0 -0
- data/demo/spec/rails_helper.rb +72 -0
- data/demo/spec/spec_helper.rb +94 -0
- data/demo/spec/system/admin_articles_spec.rb +22 -0
- data/demo/spec/system/mitosis_editor_prism_spec.rb +34 -0
- data/demo/spec/system/mitosis_editor_theme_spec.rb +63 -0
- data/demo/storage/.keep +0 -0
- data/demo/tailwind-active_admin.config.js +17 -0
- data/demo/tmp/.keep +0 -0
- data/demo/tmp/storage/.keep +0 -0
- data/demo/vendor/.keep +0 -0
- data/demo/vendor/javascript/.keep +0 -0
- data/docs/plans/2026-02-15-mitosis-editor-gem-design.md +70 -0
- data/docs/plans/2026-02-15-mitosis-editor-gem-implementation.md +407 -0
- data/lib/activeadmin_mitosis_editor/inputs/mitosis_editor_input.rb +29 -0
- data/lib/activeadmin_mitosis_editor/railtie.rb +7 -0
- data/lib/activeadmin_mitosis_editor/version.rb +3 -0
- data/lib/activeadmin_mitosis_editor.rb +13 -0
- data/lib/generators/mitosis_editor/styles_generator.rb +23 -0
- data/lib/generators/mitosis_editor/templates/_dependencies.html.erb +17 -0
- data/lib/generators/mitosis_editor/views_generator.rb +14 -0
- data/preview.png +0 -0
- data/script/bump-version +78 -0
- data/vendor/assets/javascripts/mitosis-editor.js +61 -0
- data/vendor/assets/stylesheets/mitosis-editor.css +1 -0
- data/vendor/assets/stylesheets/theme-dark.min.css +1 -0
- data/vendor/assets/stylesheets/theme-light.min.css +1 -0
- metadata +248 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# activeadmin-mitosis-editor Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Create a Ruby gem that wraps mitosis-js as a custom input type for ActiveAdmin, providing split-view markdown editing.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Gem provides Formtastic input class + ERB view template + bundled JS/CSS assets. Users add to Gemfile and use `as: :mitosis_editor` in ActiveAdmin DSL.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Ruby, Ruby Gems, ActiveAdmin, Formtastic, JavaScript (mitosis-js)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### Task 1: Initialize gem structure
|
|
14
|
+
|
|
15
|
+
**Files:**
|
|
16
|
+
- Create: `Gemfile`
|
|
17
|
+
- Create: `Rakefile`
|
|
18
|
+
- Create: `bin/setup`
|
|
19
|
+
- Create: `bin/console`
|
|
20
|
+
- Create: `Gemfile.lock`
|
|
21
|
+
- Create: `.gitignore`
|
|
22
|
+
|
|
23
|
+
**Step 1: Create basic gem structure**
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
mkdir -p lib/activeadmin_mitosis_editor
|
|
27
|
+
mkdir -p app/inputs
|
|
28
|
+
mkdir -p app/views/inputs/mitosis_editor_input
|
|
29
|
+
mkdir -p vendor/assets/javascripts
|
|
30
|
+
mkdir -p vendor/assets/stylesheets
|
|
31
|
+
mkdir -p spec
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Step 2: Create Gemfile**
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
source "https://rubygems.org"
|
|
38
|
+
|
|
39
|
+
gemspec
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Step 3: Create gemspec**
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
Gem::Specification.new do |spec|
|
|
46
|
+
spec.name = "activeadmin-mitosis-editor"
|
|
47
|
+
spec.version = "0.1.0"
|
|
48
|
+
spec.authors = ["Your Name"]
|
|
49
|
+
spec.summary = "A split-view markdown editor input for ActiveAdmin"
|
|
50
|
+
spec.license = "MIT"
|
|
51
|
+
spec.files = Dir["{app,lib,vendor}/**/*", "*.md"]
|
|
52
|
+
spec.require_paths = ["lib"]
|
|
53
|
+
|
|
54
|
+
spec.add_runtime_dependency "railties", ">= 6.0"
|
|
55
|
+
spec.add_runtime_dependency "formtastic", "~> 4.0"
|
|
56
|
+
end
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Step 4: Commit**
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
git init
|
|
63
|
+
git add .
|
|
64
|
+
git commit -m "feat: scaffold gem structure"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### Task 2: Create main gem entry point
|
|
70
|
+
|
|
71
|
+
**Files:**
|
|
72
|
+
- Create: `lib/activeadmin_mitosis_editor.rb`
|
|
73
|
+
- Create: `lib/activeadmin_mitosis_editor/version.rb`
|
|
74
|
+
|
|
75
|
+
**Step 1: Create version.rb**
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
module ActiveadminMitosisEditor
|
|
79
|
+
VERSION = "0.1.0"
|
|
80
|
+
end
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Step 2: Create main entry point**
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
require "activeadmin_mitosis_editor/version"
|
|
87
|
+
|
|
88
|
+
module ActiveadminMitosisEditor
|
|
89
|
+
module Inputs
|
|
90
|
+
autoload :MitosisEditorInput, "activeadmin_mitosis_editor/inputs/mitosis_editor_input"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Step 3: Commit**
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
git add lib/
|
|
99
|
+
git commit -m "feat: add gem entry point and version"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### Task 3: Create Formtastic input class
|
|
105
|
+
|
|
106
|
+
**Files:**
|
|
107
|
+
- Create: `lib/activeadmin_mitosis_editor/inputs/mitosis_editor_input.rb`
|
|
108
|
+
|
|
109
|
+
**Step 1: Create the input class**
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
require "formtastic/inputs/string_input"
|
|
113
|
+
|
|
114
|
+
module ActiveadminMitosisEditor
|
|
115
|
+
module Inputs
|
|
116
|
+
class MitosisEditorInput < Formtastic::Inputs::StringInput
|
|
117
|
+
def to_html
|
|
118
|
+
input_wrapping do
|
|
119
|
+
builder.hidden_field(method, input_html_options) +
|
|
120
|
+
template.render("inputs/mitosis_editor_input/form", { builder: builder, method: method, input_html_options: input_html_options })
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def input_html_options
|
|
125
|
+
super.merge(class: "mitosis-editor-input hidden", data: { mit_height: options[:height] || "500px", mit_placeholder: options[:placeholder] || "" })
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Step 2: Commit**
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
git add lib/
|
|
136
|
+
git commit -m "feat: add Formtastic input class"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### Task 4: Create ERB view template
|
|
142
|
+
|
|
143
|
+
**Files:**
|
|
144
|
+
- Create: `app/views/inputs/mitosis_editor_input/_form.html.erb`
|
|
145
|
+
|
|
146
|
+
**Step 1: Create the template**
|
|
147
|
+
|
|
148
|
+
```erb
|
|
149
|
+
<div class="mitosis-editor-wrapper"
|
|
150
|
+
data-input-name="<%= input_html_options[:name] %>"
|
|
151
|
+
data-height="<%= input_html_options[:data][:mit_height] %>"
|
|
152
|
+
data-placeholder="<%= input_html_options[:data][:mit_placeholder] %>">
|
|
153
|
+
<div id="mitosis-editor-<%= input_html_options[:id] %>" class="mitosis-editor-container"></div>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<script>
|
|
157
|
+
(function() {
|
|
158
|
+
var container = document.getElementById('mitosis-editor-<%= input_html_options[:id] %>');
|
|
159
|
+
var wrapper = container.closest('.mitosis-editor-wrapper');
|
|
160
|
+
var inputName = wrapper.dataset.inputName;
|
|
161
|
+
var height = wrapper.dataset.height || '500px';
|
|
162
|
+
var placeholder = wrapper.dataset.placeholder || '';
|
|
163
|
+
|
|
164
|
+
// Find the hidden input
|
|
165
|
+
var hiddenInput = document.querySelector('input[name="' + inputName + '"]');
|
|
166
|
+
|
|
167
|
+
if (window.MitosisEditor) {
|
|
168
|
+
var editor = window.MitosisEditor.createEditor({
|
|
169
|
+
container: container,
|
|
170
|
+
content: hiddenInput ? hiddenInput.value : '',
|
|
171
|
+
height: height,
|
|
172
|
+
placeholder: placeholder
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Sync editor content to hidden input on form submit
|
|
176
|
+
var form = container.closest('form');
|
|
177
|
+
if (form) {
|
|
178
|
+
form.addEventListener('submit', function() {
|
|
179
|
+
if (editor && editor.getMarkdown) {
|
|
180
|
+
hiddenInput.value = editor.getMarkdown();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
})();
|
|
186
|
+
</script>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Step 2: Commit**
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
git add app/views/
|
|
193
|
+
git commit -m "feat: add ERB view template for editor"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
### Task 5: Bundle mitosis-js assets
|
|
199
|
+
|
|
200
|
+
**Files:**
|
|
201
|
+
- Create: `vendor/assets/javascripts/mitosis-editor.js`
|
|
202
|
+
- Create: `vendor/assets/stylesheets/mitosis-editor.css`
|
|
203
|
+
- Create: `vendor/assets/javascripts/prism.js` (and language files)
|
|
204
|
+
|
|
205
|
+
**Step 1: Build mitosis-js**
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
cd /home/nadiar/Workspace/mitosis-js
|
|
209
|
+
pnpm install
|
|
210
|
+
pnpm build
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Step 2: Copy built assets**
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
cp /home/nadiar/Workspace/mitosis-js/dist/index.js vendor/assets/javascripts/mitosis-editor.js
|
|
217
|
+
cp /home/nadiar/Workspace/mitosis-js/dist/index.css vendor/assets/stylesheets/mitosis-editor.css 2>/dev/null || true
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Step 3: Download Prism.js**
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
curl -sL https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js -o vendor/assets/javascripts/prism.js
|
|
224
|
+
curl -sL https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css -o vendor/assets/stylesheets/prism-tomorrow.css
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Step 4: Create editor initialization wrapper**
|
|
228
|
+
|
|
229
|
+
```javascript
|
|
230
|
+
// vendor/assets/javascripts/mitosis-editor.js
|
|
231
|
+
// Wrapper to expose mitosis-js as window.MitosisEditor
|
|
232
|
+
|
|
233
|
+
(function() {
|
|
234
|
+
// mitosis-js will be loaded before this
|
|
235
|
+
window.MitosisEditor = window.MitosisEditor || window.createEditor || {};
|
|
236
|
+
})();
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Step 5: Commit**
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
git add vendor/
|
|
243
|
+
git commit -m "feat: bundle mitosis-js and Prism.js assets"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### Task 6: Create Railtie for asset registration
|
|
249
|
+
|
|
250
|
+
**Files:**
|
|
251
|
+
- Create: `lib/activeadmin_mitosis_editor/railtie.rb`
|
|
252
|
+
|
|
253
|
+
**Step 1: Create Railtie**
|
|
254
|
+
|
|
255
|
+
```ruby
|
|
256
|
+
module ActiveadminMitosisEditor
|
|
257
|
+
class Railtie < Rails::Railtie
|
|
258
|
+
initializer "activeadmin_mitosis_editor.assets" do
|
|
259
|
+
if defined?(Sprockets)
|
|
260
|
+
Rails.application.config.assets.paths << Gem.root.join("vendor/assets/javascripts").to_s
|
|
261
|
+
Rails.application.config.assets.paths << Gem.root.join("vendor/assets/stylesheets").to_s
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Step 2: Update main entry to require railtie**
|
|
269
|
+
|
|
270
|
+
```ruby
|
|
271
|
+
# lib/activeadmin_mitosis_editor.rb
|
|
272
|
+
require "activeadmin_mitosis_editor/version"
|
|
273
|
+
require "activeadmin_mitosis_editor/railtie" if defined?(Rails)
|
|
274
|
+
|
|
275
|
+
module ActiveadminMitosisEditor
|
|
276
|
+
# ...
|
|
277
|
+
end
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Step 3: Commit**
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
git add lib/
|
|
284
|
+
git commit -m "feat: add Railtie for asset pipeline integration"
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
### Task 7: Create gem spec file
|
|
290
|
+
|
|
291
|
+
**Files:**
|
|
292
|
+
- Create: `activeadmin_mitosis_editor.gemspec`
|
|
293
|
+
|
|
294
|
+
**Step 1: Create gemspec**
|
|
295
|
+
|
|
296
|
+
```ruby
|
|
297
|
+
Gem::Specification.new do |spec|
|
|
298
|
+
spec.name = "activeadmin_mitosis_editor"
|
|
299
|
+
spec.version = ActiveadminMitosisEditor::VERSION
|
|
300
|
+
spec.authors = ["Your Name"]
|
|
301
|
+
spec.summary = "A split-view markdown editor input for ActiveAdmin"
|
|
302
|
+
spec.description = "Wraps mitosis-js as a custom input for ActiveAdmin forms"
|
|
303
|
+
spec.license = "MIT"
|
|
304
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|\.git)}) }
|
|
305
|
+
spec.require_paths = ["lib"]
|
|
306
|
+
|
|
307
|
+
spec.add_runtime_dependency "railties", ">= 6.0"
|
|
308
|
+
spec.add_runtime_dependency "formtastic", "~> 4.0"
|
|
309
|
+
spec.add_runtime_dependency "activesupport", ">= 6.0"
|
|
310
|
+
end
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Step 2: Commit**
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
git add *.gemspec
|
|
317
|
+
git commit -m "feat: add gemspec file"
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### Task 8: Create usage instructions
|
|
323
|
+
|
|
324
|
+
**Files:**
|
|
325
|
+
- Create: `README.md`
|
|
326
|
+
|
|
327
|
+
**Step 1: Create README**
|
|
328
|
+
|
|
329
|
+
```markdown
|
|
330
|
+
# ActiveadminMitosisEditor
|
|
331
|
+
|
|
332
|
+
A Ruby gem that provides a split-view markdown editor input for ActiveAdmin, powered by mitosis-js.
|
|
333
|
+
|
|
334
|
+
## Installation
|
|
335
|
+
|
|
336
|
+
Add this line to your Rails application's Gemfile:
|
|
337
|
+
|
|
338
|
+
```ruby
|
|
339
|
+
gem "activeadmin_mitosis_editor"
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## Usage
|
|
343
|
+
|
|
344
|
+
In your ActiveAdmin resource:
|
|
345
|
+
|
|
346
|
+
```ruby
|
|
347
|
+
ActiveAdmin.register Article do
|
|
348
|
+
form do |f|
|
|
349
|
+
f.inputs do
|
|
350
|
+
f.input :title
|
|
351
|
+
f.input :body, as: :mitosis_editor
|
|
352
|
+
f.input :body, as: :mitosis_editor, height: "400px", placeholder: "Write markdown..."
|
|
353
|
+
end
|
|
354
|
+
f.actions
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Options
|
|
360
|
+
|
|
361
|
+
| Option | Type | Default | Description |
|
|
362
|
+
|--------|------|---------|-------------|
|
|
363
|
+
| height | string | '500px' | Editor height |
|
|
364
|
+
| placeholder | string | '' | Placeholder text |
|
|
365
|
+
|
|
366
|
+
## Requirements
|
|
367
|
+
|
|
368
|
+
- Rails >= 6.0
|
|
369
|
+
- ActiveAdmin
|
|
370
|
+
- Formtastic
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Step 2: Commit**
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
git add README.md
|
|
377
|
+
git commit -m "docs: add README with usage instructions"
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Summary
|
|
383
|
+
|
|
384
|
+
**Total Tasks:** 8
|
|
385
|
+
|
|
386
|
+
1. Initialize gem structure
|
|
387
|
+
2. Create main gem entry point
|
|
388
|
+
3. Create Formtastic input class
|
|
389
|
+
4. Create ERB view template
|
|
390
|
+
5. Bundle mitosis-js assets
|
|
391
|
+
6. Create Railtie for asset registration
|
|
392
|
+
7. Create gem spec file
|
|
393
|
+
8. Create usage instructions
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## Execution Choice
|
|
398
|
+
|
|
399
|
+
**Plan complete and saved to `docs/plans/2026-02-15-mitosis-editor-gem-design.md` (implementation plan in this file).**
|
|
400
|
+
|
|
401
|
+
**Two execution options:**
|
|
402
|
+
|
|
403
|
+
1. **Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
|
|
404
|
+
|
|
405
|
+
2. **Parallel Session (separate)** - Open new session with executing-plans, batch execution with checkpoints
|
|
406
|
+
|
|
407
|
+
Which approach?
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require "formtastic/inputs/string_input"
|
|
2
|
+
|
|
3
|
+
module ActiveAdminMitosisEditor
|
|
4
|
+
module Inputs
|
|
5
|
+
class MitosisEditorInput < Formtastic::Inputs::StringInput
|
|
6
|
+
def to_html
|
|
7
|
+
input_wrapping do
|
|
8
|
+
builder.hidden_field(method, input_html_options) +
|
|
9
|
+
template.render("inputs/mitosis_editor_input/form", {
|
|
10
|
+
builder: builder,
|
|
11
|
+
method: method,
|
|
12
|
+
input_html_options: input_html_options,
|
|
13
|
+
editor_options: editor_options
|
|
14
|
+
})
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def input_html_options
|
|
19
|
+
super.merge(class: "mitosis-editor-input hidden")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def editor_options
|
|
25
|
+
{ height: "500px", placeholder: "", theme: "auto" }.merge(options[:editor_options] || {})
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
module ActiveAdminMitosisEditor
|
|
2
|
+
class Engine < Rails::Engine
|
|
3
|
+
# Asset paths are not registered via Railtie to avoid conflicts with app-level
|
|
4
|
+
# asset overrides. Applications using this gem should copy the bundled assets
|
|
5
|
+
# from vendor/assets to their app/assets/stylesheets/mitosis_editor/ directory.
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "activeadmin_mitosis_editor/version"
|
|
2
|
+
require "activeadmin_mitosis_editor/inputs/mitosis_editor_input"
|
|
3
|
+
require "activeadmin_mitosis_editor/railtie" if defined?(Rails)
|
|
4
|
+
|
|
5
|
+
module ActiveAdminMitosisEditor
|
|
6
|
+
def self.root
|
|
7
|
+
@root ||= Pathname.new(File.dirname(__dir__))
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module Inputs
|
|
11
|
+
autoload :MitosisEditorInput, "activeadmin_mitosis_editor/inputs/mitosis_editor_input"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
3
|
+
module MitosisEditor
|
|
4
|
+
class StylesGenerator < Rails::Generators::Base
|
|
5
|
+
source_root File.expand_path("../../../vendor/assets/stylesheets", __dir__)
|
|
6
|
+
|
|
7
|
+
desc "Copy CSS files for customization"
|
|
8
|
+
|
|
9
|
+
def copy_css_files
|
|
10
|
+
copy_file "mitosis-editor.css",
|
|
11
|
+
"app/assets/stylesheets/mitosis-editor.css"
|
|
12
|
+
copy_file "theme-light.min.css",
|
|
13
|
+
"app/assets/stylesheets/theme-light.css"
|
|
14
|
+
copy_file "theme-dark.min.css",
|
|
15
|
+
"app/assets/stylesheets/theme-dark.css"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def show_readme
|
|
19
|
+
puts "\nDone! CSS files copied to app/assets/stylesheets/"
|
|
20
|
+
puts "You can customize the CSS variables in these files."
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<%# Parameters:
|
|
2
|
+
# theme - 'light', 'dark', or 'auto' (default: 'light') %>
|
|
3
|
+
<% theme = local_assigns[:theme] || "auto"
|
|
4
|
+
theme_light = %w[light auto].include?(theme)
|
|
5
|
+
theme_dark = %w[dark auto].include?(theme) %>
|
|
6
|
+
<%= stylesheet_link_tag "mitosis-editor" %>
|
|
7
|
+
<%= stylesheet_link_tag "theme-light" if theme_light %>
|
|
8
|
+
<%= stylesheet_link_tag "theme-dark" if theme_dark %>
|
|
9
|
+
<%= javascript_include_tag "mitosis-editor" %>
|
|
10
|
+
|
|
11
|
+
<%# Uncomment the lines below to enable syntax highlighting with Prism %>
|
|
12
|
+
<%#= stylesheet_link_tag "https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-tomorrow.min.css" %>
|
|
13
|
+
<%#= javascript_include_tag "https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js" %>
|
|
14
|
+
<%#= javascript_include_tag "https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-javascript.min.js" %>
|
|
15
|
+
<%#= javascript_include_tag "https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-typescript.min.js" %>
|
|
16
|
+
<%#= javascript_include_tag "https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-python.min.js" %>
|
|
17
|
+
<%#= javascript_include_tag "https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-css.min.js" %>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
3
|
+
module MitosisEditor
|
|
4
|
+
class ViewsGenerator < Rails::Generators::Base
|
|
5
|
+
source_root File.expand_path("templates", __dir__)
|
|
6
|
+
|
|
7
|
+
desc "Copy mitosis editor dependencies partial for customization"
|
|
8
|
+
|
|
9
|
+
def copy_dependencies_partial
|
|
10
|
+
copy_file "_dependencies.html.erb",
|
|
11
|
+
"app/views/inputs/mitosis_editor_input/_dependencies.html.erb"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/preview.png
ADDED
|
Binary file
|
data/script/bump-version
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative "../lib/activeadmin_mitosis_editor/version"
|
|
5
|
+
|
|
6
|
+
module BumpVersion
|
|
7
|
+
class << self
|
|
8
|
+
def run(type = nil)
|
|
9
|
+
current = ActiveAdminMitosisEditor::VERSION
|
|
10
|
+
major, minor, patch = current.split(".").map(&:to_i)
|
|
11
|
+
|
|
12
|
+
bump_type = type || detect_bump_type
|
|
13
|
+
|
|
14
|
+
case bump_type
|
|
15
|
+
when "major"
|
|
16
|
+
major += 1
|
|
17
|
+
minor = 0
|
|
18
|
+
patch = 0
|
|
19
|
+
when "minor"
|
|
20
|
+
minor += 1
|
|
21
|
+
patch = 0
|
|
22
|
+
when "patch"
|
|
23
|
+
patch += 1
|
|
24
|
+
else
|
|
25
|
+
puts "Usage: bump-version [major|minor|patch]"
|
|
26
|
+
exit 1
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
new_version = "#{major}.#{minor}.#{patch}"
|
|
30
|
+
update_version(new_version)
|
|
31
|
+
new_version
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def detect_bump_type
|
|
37
|
+
commits = `git log --oneline -10`.split("\n")
|
|
38
|
+
has_major = commits.any? { |c| c.include?("feat!:") || c.include?("BREAKING") }
|
|
39
|
+
has_fix = commits.any? { |c| c.include?("fix:") }
|
|
40
|
+
has_minor = commits.any? { |c| c.include?("feat:") }
|
|
41
|
+
|
|
42
|
+
return "major" if has_major
|
|
43
|
+
return "patch" if has_fix # fix has higher priority than feat
|
|
44
|
+
return "minor" if has_minor
|
|
45
|
+
|
|
46
|
+
"patch"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def update_version(new_version)
|
|
50
|
+
file = "lib/activeadmin_mitosis_editor/version.rb"
|
|
51
|
+
content = File.read(file)
|
|
52
|
+
new_content = content.gsub(/VERSION = "[^"]+"/, "VERSION = \"#{new_version}\"")
|
|
53
|
+
File.write(file, new_content)
|
|
54
|
+
|
|
55
|
+
# Update CHANGELOG
|
|
56
|
+
update_changelog(new_version)
|
|
57
|
+
|
|
58
|
+
puts "Bumped version to #{new_version}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def update_changelog(version)
|
|
62
|
+
return unless File.exist?("CHANGELOG.md")
|
|
63
|
+
|
|
64
|
+
date = Time.now.strftime("%Y-%m-%d")
|
|
65
|
+
content = File.read("CHANGELOG.md")
|
|
66
|
+
|
|
67
|
+
# Add new version section after "## [Unreleased]"
|
|
68
|
+
unreleased = "## [Unreleased]"
|
|
69
|
+
if content.include?(unreleased)
|
|
70
|
+
new_section = "#{unreleased}\n\n## [#{version}] - #{date}\n\n### Added\n- "
|
|
71
|
+
new_content = content.sub(unreleased, new_section)
|
|
72
|
+
File.write("CHANGELOG.md", new_content)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
BumpVersion.run(ARGV[0])
|