зеркало из
https://github.com/rs-pro/activeadmin-quill_editor.git
synced 2026-08-28 15:36:17 +03:00
docs: Update guides for Quill Editor and ActiveAdmin 4.0.0.beta20
- Replace Tom Select references with Quill Editor - Update all version references to beta20 - Remove irrelevant guides (Tom Select migration, CKEditor upload system) - Add Quill Editor specific imports and configurations - Update package.json dependencies to use Quill instead of Tom Select Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Этот коммит содержится в:
@@ -1,20 +1,20 @@
|
|||||||
# ActiveAdmin 4 Asset Setup (Tailwind CSS v4)
|
# ActiveAdmin 4 Asset Setup (Tailwind CSS v4)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
This guide documents the current, working setup for ActiveAdmin 4.0.0.beta19 with Tailwind CSS v4 and Tom Select (no jQuery).
|
This guide documents the current, working setup for ActiveAdmin 4.0.0.beta20 with Tailwind CSS v4 and Quill Editor.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
- ActiveAdmin 4.0.0.beta19
|
- ActiveAdmin 4.0.0.beta20
|
||||||
- Tailwind CSS v4 via `tailwindcss-rails` (ships `bin/tailwindcss`)
|
- Tailwind CSS v4 via `tailwindcss-rails` (ships `bin/tailwindcss`)
|
||||||
- ESBuild (or other JS bundler) for ActiveAdmin JS + Tom Select
|
- ESBuild (or other JS bundler) for ActiveAdmin JS + Quill Editor
|
||||||
|
|
||||||
## 1. Gemfile
|
## 1. Gemfile
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
# ActiveAdmin 4 beta
|
# ActiveAdmin 4 beta
|
||||||
gem "activeadmin", "4.0.0.beta19"
|
gem "activeadmin", "4.0.0.beta20"
|
||||||
|
|
||||||
gem "activeadmin-tom_select"
|
gem "activeadmin_quill_editor"
|
||||||
|
|
||||||
# Tailwind CSS v4 (bundled CLI)
|
# Tailwind CSS v4 (bundled CLI)
|
||||||
gem "tailwindcss-rails", "~> 4.4.0"
|
gem "tailwindcss-rails", "~> 4.4.0"
|
||||||
@@ -25,9 +25,8 @@ gem "tailwindcss-rails", "~> 4.4.0"
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@activeadmin/activeadmin": "^4.0.0-beta19",
|
"@activeadmin/activeadmin": "^4.0.0-beta20",
|
||||||
"tom-select": "^2.4.3",
|
"quill": "^2.0.3"
|
||||||
"activeadmin-tom_select": "^4.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"esbuild": "^0.27.2"
|
"esbuild": "^0.27.2"
|
||||||
@@ -48,12 +47,10 @@ gem "tailwindcss-rails", "~> 4.4.0"
|
|||||||
```javascript
|
```javascript
|
||||||
import "@activeadmin/activeadmin";
|
import "@activeadmin/activeadmin";
|
||||||
|
|
||||||
import TomSelect from "tom-select";
|
import Quill from "quill";
|
||||||
window.TomSelect = TomSelect;
|
window.Quill = Quill;
|
||||||
|
|
||||||
import { setupAutoInit, initSearchableSelects } from "activeadmin-tom_select";
|
import "activeadmin_quill_editor";
|
||||||
window.initSearchableSelects = initSearchableSelects;
|
|
||||||
setupAutoInit();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. Tailwind Input (app/assets/stylesheets/active_admin.tailwind.css)
|
## 4. Tailwind Input (app/assets/stylesheets/active_admin.tailwind.css)
|
||||||
@@ -62,7 +59,8 @@ setupAutoInit();
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@config "../../../tailwind-active_admin.config.mjs";
|
@config "../../../tailwind-active_admin.config.mjs";
|
||||||
|
|
||||||
@import "activeadmin-tom_select/css";
|
@import "activeadmin/quill_editor/quill.snow";
|
||||||
|
@import "activeadmin/quill_editor_input";
|
||||||
```
|
```
|
||||||
|
|
||||||
## 5. Tailwind Config (tailwind-active_admin.config.mjs)
|
## 5. Tailwind Config (tailwind-active_admin.config.mjs)
|
||||||
@@ -80,10 +78,10 @@ export default {
|
|||||||
`${activeAdminPath}/vendor/javascript/flowbite.js`,
|
`${activeAdminPath}/vendor/javascript/flowbite.js`,
|
||||||
`${activeAdminPath}/plugin.js`,
|
`${activeAdminPath}/plugin.js`,
|
||||||
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/admin/**/*.{arb,erb,html,rb}",
|
"./app/admin/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/views/active_admin/**/*.{arb,erb,html,rb}",
|
"./app/views/active_admin/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/views/admin/**/*.{arb,erb,html,rb}",
|
"./app/views/admin/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/views/layouts/active_admin*.{erb,html}",
|
"./app/views/layouts/active_admin*.{erb,html}`,
|
||||||
"./app/javascript/**/*.js"
|
"./app/javascript/**/*.js"
|
||||||
],
|
],
|
||||||
darkMode: "selector",
|
darkMode: "selector",
|
||||||
@@ -133,7 +131,7 @@ Rake::Task["db:test:prepare"].enhance(["active_admin:build"]) if Rake::Task.task
|
|||||||
bundle binstubs tailwindcss-ruby --force
|
bundle binstubs tailwindcss-ruby --force
|
||||||
```
|
```
|
||||||
|
|
||||||
## 8. Upgrade Notes (ActiveAdmin 4.0.0.beta19)
|
## 8. Upgrade Notes (ActiveAdmin 4.0.0.beta20)
|
||||||
|
|
||||||
From ActiveAdmin's upgrade guide:
|
From ActiveAdmin's upgrade guide:
|
||||||
- `_site_header.html.erb` container class changed from `sticky` to `fixed`.
|
- `_site_header.html.erb` container class changed from `sticky` to `fixed`.
|
||||||
@@ -155,15 +153,15 @@ From ActiveAdmin's upgrade guide:
|
|||||||
|
|
||||||
### ActiveAdmin styles not loading
|
### ActiveAdmin styles not loading
|
||||||
- Verify `app/assets/builds/active_admin.css` exists.
|
- Verify `app/assets/builds/active_admin.css` exists.
|
||||||
- Check that `active_admin.tailwind.css` imports `activeadmin-tom_select/css`.
|
- Check that `active_admin.tailwind.css` imports Quill Editor styles.
|
||||||
|
|
||||||
### Tom Select not initializing
|
### Quill Editor not initializing
|
||||||
- Verify `window.TomSelect` in the console.
|
- Verify `window.Quill` in the console.
|
||||||
- Ensure `setupAutoInit()` is called.
|
- Ensure `activeadmin_quill_editor` is imported.
|
||||||
|
|
||||||
## Migration Checklist
|
## Migration Checklist
|
||||||
|
|
||||||
- [ ] Update ActiveAdmin to 4.0.0.beta19
|
- [ ] Update ActiveAdmin to 4.0.0.beta20
|
||||||
- [ ] Use Tailwind v4 `@import` + `@config`
|
- [ ] Use Tailwind v4 `@import` + `@config`
|
||||||
- [ ] Add `tailwindcss-rails` (~> 4.4.0) and binstub
|
- [ ] Add `tailwindcss-rails` (~> 4.4.0) and binstub
|
||||||
- [ ] Create `tailwind-active_admin.config.mjs` (ESM)
|
- [ ] Create `tailwind-active_admin.config.mjs` (ESM)
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
# ActiveAdmin + Tailwind CSS v4 Guide
|
# ActiveAdmin + Tailwind CSS v4 Guide
|
||||||
|
|
||||||
This guide consolidates the ActiveAdmin 4.0.0.beta19 upgrade notes with a working Tailwind v4 build setup. Use it as a template when updating other ActiveAdmin extension gems.
|
This guide consolidates the ActiveAdmin 4.0.0.beta20 upgrade notes with a working Tailwind v4 build setup. Use it as a template when updating other ActiveAdmin extension gems.
|
||||||
|
|
||||||
## What Changed in ActiveAdmin 4.0.0.beta19 (from UPGRADING.md)
|
## What Changed in ActiveAdmin 4.0.0.beta20 (from UPGRADING.md)
|
||||||
|
|
||||||
|
### Version Requirements
|
||||||
|
- Rails 7.2+ (Rails 7.0 and 7.1 are no longer supported)
|
||||||
|
- Ruby 3.2+ (Ruby 3.0 and 3.1 are no longer supported)
|
||||||
|
|
||||||
### Template Updates
|
### Template Updates
|
||||||
- `_site_header.html.erb` container class changed from `sticky` to `fixed`.
|
- `_site_header.html.erb` container class changed from `sticky` to `fixed`.
|
||||||
@@ -47,12 +51,19 @@ Tailwind config now uses ESM. To avoid the warning:
|
|||||||
- Deeply nested submenus removed (only one level supported).
|
- Deeply nested submenus removed (only one level supported).
|
||||||
- Removed `Panel#header_action` and `index_column`.
|
- Removed `Panel#header_action` and `index_column`.
|
||||||
|
|
||||||
|
### New in beta20
|
||||||
|
- Parent menu item linking support
|
||||||
|
- Improved comments pagination styling
|
||||||
|
- Better vertical spacing for has-many forms
|
||||||
|
- Pointer cursor restored on eligible buttons
|
||||||
|
- Various accessibility improvements
|
||||||
|
|
||||||
## Recommended Build Setup (tailwindcss-rails)
|
## Recommended Build Setup (tailwindcss-rails)
|
||||||
|
|
||||||
### 1. Gemfile
|
### 1. Gemfile
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
gem "activeadmin", "4.0.0.beta19"
|
gem "activeadmin", "4.0.0.beta20"
|
||||||
gem "tailwindcss-rails", "~> 4.4.0"
|
gem "tailwindcss-rails", "~> 4.4.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -81,9 +92,9 @@ export default {
|
|||||||
`${activeAdminPath}/plugin.js`,
|
`${activeAdminPath}/plugin.js`,
|
||||||
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/admin/**/*.{arb,erb,html,rb}",
|
"./app/admin/**/*.{arb,erb,html,rb}",
|
||||||
"./app/views/active_admin/**/*.{arb,erb,html,rb}",
|
"./app/views/active_admin/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/views/admin/**/*.{arb,erb,html,rb}",
|
"./app/views/admin/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/views/layouts/active_admin*.{erb,html}",
|
"./app/views/layouts/active_admin*.{erb,html}`,
|
||||||
"./app/javascript/**/*.js"
|
"./app/javascript/**/*.js"
|
||||||
],
|
],
|
||||||
darkMode: "selector",
|
darkMode: "selector",
|
||||||
|
|||||||
@@ -1,202 +0,0 @@
|
|||||||
# Migration Guide: ActiveAdmin Tom Select (Tailwind v4)
|
|
||||||
|
|
||||||
This guide helps you migrate from `activeadmin-searchable_select` to `activeadmin-tom_select` on ActiveAdmin 4.0.0.beta20 with Tailwind CSS v4.
|
|
||||||
|
|
||||||
## Quick Start (New Installation)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Gem
|
|
||||||
bundle add activeadmin-tom_select
|
|
||||||
|
|
||||||
# NPM
|
|
||||||
npm install activeadmin-tom_select tom-select
|
|
||||||
```
|
|
||||||
|
|
||||||
## Why Update?
|
|
||||||
|
|
||||||
- Tom Select replaces Select2 (no jQuery)
|
|
||||||
- ActiveAdmin 4.0.0.beta20 compatible (requires Rails 7.2+)
|
|
||||||
- Tailwind CSS v4 styles included
|
|
||||||
- Auto-init helpers for searchable selects
|
|
||||||
- Ruby 3.2+ and 4.0 compatible
|
|
||||||
|
|
||||||
## 1. Update Gemfile
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
# Remove legacy gem(s)
|
|
||||||
# gem "activeadmin-searchable_select"
|
|
||||||
# gem "rs-activeadmin-searchable_select"
|
|
||||||
|
|
||||||
gem "activeadmin-tom_select", "~> 4.1.0"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Update JavaScript Dependencies
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm uninstall @codevise/activeadmin-searchable_select activeadmin-searchable_select jquery select2
|
|
||||||
npm install activeadmin-tom_select tom-select
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. JavaScript Imports
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import "@activeadmin/activeadmin";
|
|
||||||
|
|
||||||
import TomSelect from "tom-select";
|
|
||||||
window.TomSelect = TomSelect;
|
|
||||||
|
|
||||||
import { setupAutoInit } from "activeadmin-tom_select";
|
|
||||||
setupAutoInit();
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4. Tailwind CSS Build (ActiveAdmin 4.0.0.beta20)
|
|
||||||
|
|
||||||
### 4.1 Tailwind Input
|
|
||||||
|
|
||||||
```css
|
|
||||||
/* app/assets/stylesheets/active_admin.tailwind.css */
|
|
||||||
@import "tailwindcss";
|
|
||||||
@config "../../../tailwind-active_admin.config.mjs";
|
|
||||||
|
|
||||||
@import "activeadmin-tom_select/css";
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.2 Tailwind Config (ESM)
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// tailwind-active_admin.config.mjs
|
|
||||||
import { execSync } from "child_process";
|
|
||||||
import activeAdminPlugin from "@activeadmin/activeadmin/plugin";
|
|
||||||
|
|
||||||
const activeAdminPath = execSync("bundle show activeadmin", {
|
|
||||||
encoding: "utf-8"
|
|
||||||
}).trim();
|
|
||||||
|
|
||||||
export default {
|
|
||||||
content: [
|
|
||||||
`${activeAdminPath}/vendor/javascript/flowbite.js`,
|
|
||||||
`${activeAdminPath}/plugin.js`,
|
|
||||||
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
|
||||||
"./app/admin/**/*.{arb,erb,html,rb}",
|
|
||||||
"./app/views/active_admin/**/*.{arb,erb,html,rb}",
|
|
||||||
"./app/views/admin/**/*.{arb,erb,html,rb}",
|
|
||||||
"./app/views/layouts/active_admin*.{erb,html}",
|
|
||||||
"./app/javascript/**/*.js"
|
|
||||||
],
|
|
||||||
darkMode: "selector",
|
|
||||||
plugins: [activeAdminPlugin]
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.3 Tailwind Build Tasks
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
# lib/tasks/active_admin.rake
|
|
||||||
namespace :active_admin do
|
|
||||||
desc "Build Active Admin Tailwind stylesheets"
|
|
||||||
task build: :environment do
|
|
||||||
command = [
|
|
||||||
Rails.root.join("bin/tailwindcss").to_s,
|
|
||||||
"-i", Rails.root.join("app/assets/stylesheets/active_admin.tailwind.css").to_s,
|
|
||||||
"-o", Rails.root.join("app/assets/builds/active_admin.css").to_s,
|
|
||||||
"-m"
|
|
||||||
]
|
|
||||||
|
|
||||||
system(*command, exception: true)
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "Watch Active Admin Tailwind stylesheets"
|
|
||||||
task watch: :environment do
|
|
||||||
command = [
|
|
||||||
Rails.root.join("bin/tailwindcss").to_s,
|
|
||||||
"--watch",
|
|
||||||
"-i", Rails.root.join("app/assets/stylesheets/active_admin.tailwind.css").to_s,
|
|
||||||
"-o", Rails.root.join("app/assets/builds/active_admin.css").to_s,
|
|
||||||
"-m"
|
|
||||||
]
|
|
||||||
|
|
||||||
system(*command, exception: true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Rake::Task["assets:precompile"].enhance(["active_admin:build"])
|
|
||||||
Rake::Task["spec:prepare"].enhance(["active_admin:build"]) if Rake::Task.task_defined?("spec:prepare")
|
|
||||||
Rake::Task["db:test:prepare"].enhance(["active_admin:build"]) if Rake::Task.task_defined?("db:test:prepare")
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.4 package.json scripts
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"build:js": "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets",
|
|
||||||
"build:css": "bundle exec rake active_admin:build",
|
|
||||||
"build": "npm run build:js && npm run build:css",
|
|
||||||
"watch:css": "bundle exec rake active_admin:watch"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.5 Tailwind CLI binstub
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bundle binstubs tailwindcss-ruby --force
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Importmap (Optional)
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
# config/importmap.rb
|
|
||||||
pin "tom-select", to: "https://ga.jspm.io/npm:tom-select@2.4.3/dist/js/tom-select.complete.min.js"
|
|
||||||
pin "activeadmin-tom_select", to: "activeadmin-tom_select.js"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6. ActiveAdmin Usage
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
ActiveAdmin.register Product do
|
|
||||||
form do |f|
|
|
||||||
f.inputs do
|
|
||||||
f.input :category, as: :searchable_select
|
|
||||||
f.input :tags, as: :searchable_select, ajax: true, multiple: true
|
|
||||||
end
|
|
||||||
f.actions
|
|
||||||
end
|
|
||||||
|
|
||||||
filter :category, as: :searchable_select
|
|
||||||
filter :tags, as: :searchable_select, ajax: true, multiple: true
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Styles missing
|
|
||||||
- Confirm `app/assets/builds/active_admin.css` exists.
|
|
||||||
- Verify `active_admin.tailwind.css` imports `activeadmin-tom_select/css`.
|
|
||||||
|
|
||||||
### Tom Select not initializing
|
|
||||||
- Ensure `window.TomSelect` is set.
|
|
||||||
- Ensure `setupAutoInit()` runs.
|
|
||||||
|
|
||||||
## ActiveAdmin 4.0.0.beta20 Notes (from upgrade guide)
|
|
||||||
|
|
||||||
**Version Requirements:**
|
|
||||||
- Rails 7.2+ (Rails 7.0 and 7.1 are no longer supported)
|
|
||||||
- Ruby 3.2+ (Ruby 3.0 and 3.1 are no longer supported)
|
|
||||||
|
|
||||||
**Breaking Changes from earlier v4 betas:**
|
|
||||||
- `_site_header.html.erb` container class changed from `sticky` to `fixed`.
|
|
||||||
- `active_admin.html.erb` adds the `pt-16` utility class.
|
|
||||||
- Tailwind v4 requires `@import "tailwindcss"` + `@config`.
|
|
||||||
- jQuery and jQuery UI removed; `columns` and `tabs` components removed.
|
|
||||||
- Replace `default_main_content` with `render "show_default"`.
|
|
||||||
- Replace `as: :datepicker` with `as: :date_picker`.
|
|
||||||
- Replace `active_admin_comments` with `active_admin_comments_for(resource)`.
|
|
||||||
- Replace `attributes_table` with `attributes_table_for(resource)` in sidebars.
|
|
||||||
|
|
||||||
**New in beta20:**
|
|
||||||
- Parent menu item linking support
|
|
||||||
- Improved comments pagination styling
|
|
||||||
- Better vertical spacing for has-many forms
|
|
||||||
- Pointer cursor restored on eligible buttons
|
|
||||||
- Various accessibility improvements
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Setting Up an ActiveAdmin 4 Extension Gem (Combustion)
|
# Setting Up an ActiveAdmin 4 Extension Gem (Combustion)
|
||||||
|
|
||||||
This guide mirrors the working setup used in this repo: ActiveAdmin 4.0.0.beta20 + Tailwind CSS v4 + Combustion test app.
|
This guide mirrors the working setup used in this repo: ActiveAdmin 4.0.0.beta20 + Tailwind CSS v4 + test app.
|
||||||
|
|
||||||
## 1. Gem Dependencies
|
## 1. Gem Dependencies
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ end
|
|||||||
|
|
||||||
require "importmap-rails"
|
require "importmap-rails"
|
||||||
require "active_admin"
|
require "active_admin"
|
||||||
require "activeadmin_your_feature"
|
require "activeadmin_quill_editor"
|
||||||
|
|
||||||
run Combustion::Application
|
run Combustion::Application
|
||||||
```
|
```
|
||||||
@@ -78,8 +78,9 @@ end
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@config "../../../tailwind-active_admin.config.mjs";
|
@config "../../../tailwind-active_admin.config.mjs";
|
||||||
|
|
||||||
/* Import your gem CSS if needed */
|
/* Import Quill Editor CSS */
|
||||||
@import "your_gem/css";
|
@import "activeadmin/quill_editor/quill.snow";
|
||||||
|
@import "activeadmin/quill_editor_input";
|
||||||
```
|
```
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -96,8 +97,8 @@ export default {
|
|||||||
`${activeAdminPath}/vendor/javascript/flowbite.js`,
|
`${activeAdminPath}/vendor/javascript/flowbite.js`,
|
||||||
`${activeAdminPath}/plugin.js`,
|
`${activeAdminPath}/plugin.js`,
|
||||||
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/admin/**/*.{arb,erb,html,rb}",
|
"./app/admin/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/views/**/*.{arb,erb,html,rb}",
|
"./app/views/**/*.{arb,erb,html,rb}`,
|
||||||
"./app/javascript/**/*.js",
|
"./app/javascript/**/*.js",
|
||||||
"../../app/assets/**/*.{js,css}"
|
"../../app/assets/**/*.{js,css}"
|
||||||
],
|
],
|
||||||
@@ -136,7 +137,11 @@ bundle binstubs tailwindcss-ruby --force
|
|||||||
```javascript
|
```javascript
|
||||||
// spec/internal/app/javascript/active_admin.js
|
// spec/internal/app/javascript/active_admin.js
|
||||||
import "@activeadmin/activeadmin";
|
import "@activeadmin/activeadmin";
|
||||||
import "your_gem";
|
|
||||||
|
import Quill from "quill";
|
||||||
|
window.Quill = Quill;
|
||||||
|
|
||||||
|
import "activeadmin_quill_editor";
|
||||||
```
|
```
|
||||||
|
|
||||||
## 10. package.json (internal)
|
## 10. package.json (internal)
|
||||||
@@ -152,6 +157,7 @@ import "your_gem";
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@activeadmin/activeadmin": "^4.0.0-beta20",
|
"@activeadmin/activeadmin": "^4.0.0-beta20",
|
||||||
|
"quill": "^2.0.3",
|
||||||
"esbuild": "^0.24.2"
|
"esbuild": "^0.24.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,225 +0,0 @@
|
|||||||
# CKEditor5-Rails Upload System Documentation
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The CKEditor5-Rails gem implements a flexible image upload system that allows users to upload images directly from the editor to a server endpoint instead of embedding them as Base64. The system is designed to be backend-agnostic and can integrate with various storage solutions including ActiveStorage and Shrine.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
### Core Components
|
|
||||||
|
|
||||||
#### 1. SimpleUploadAdapter Plugin (`lib/ckeditor5/rails/plugins/simple_upload_adapter.rb`)
|
|
||||||
|
|
||||||
The heart of the upload system is an inline JavaScript plugin that:
|
|
||||||
- Extends CKEditor5's Plugin class
|
|
||||||
- Requires the FileRepository plugin as a dependency
|
|
||||||
- Implements the upload adapter factory pattern
|
|
||||||
- Handles file uploads via XMLHttpRequest with progress tracking
|
|
||||||
|
|
||||||
**Location**: `lib/ckeditor5/rails/plugins/simple_upload_adapter.rb`
|
|
||||||
|
|
||||||
**Key Features**:
|
|
||||||
- Async/await based upload handling
|
|
||||||
- Progress tracking through XMLHttpRequest events
|
|
||||||
- CSRF token integration for Rails security
|
|
||||||
- Abort capability for cancelled uploads
|
|
||||||
- JSON response parsing for uploaded file URLs
|
|
||||||
|
|
||||||
#### 2. PropsInlinePlugin Base Class (`lib/ckeditor5/rails/editor/props_inline_plugin.rb`)
|
|
||||||
|
|
||||||
The upload adapter extends this base class which:
|
|
||||||
- Wraps JavaScript code in an async IIFE (Immediately Invoked Function Expression)
|
|
||||||
- Supports optional code compression via Terser
|
|
||||||
- Provides window-based plugin registration mechanism
|
|
||||||
- Handles plugin initialization errors gracefully
|
|
||||||
|
|
||||||
**Location**: `lib/ckeditor5/rails/editor/props_inline_plugin.rb`
|
|
||||||
|
|
||||||
#### 3. Plugin Registration System (`lib/ckeditor5/rails/plugins.rb`)
|
|
||||||
|
|
||||||
Central registry that:
|
|
||||||
- Loads all core plugins including SimpleUploadAdapter
|
|
||||||
- Manages plugin dependencies
|
|
||||||
- Handles plugin patches and fixes
|
|
||||||
|
|
||||||
**Location**: `lib/ckeditor5/rails/plugins.rb`
|
|
||||||
|
|
||||||
## Configuration System
|
|
||||||
|
|
||||||
### Preset Builder Integration (`lib/ckeditor5/rails/presets/preset_builder.rb`)
|
|
||||||
|
|
||||||
The upload adapter is configured through the preset system:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
def simple_upload_adapter(upload_url = '/uploads', compress: !@disallow_inline_plugin_compression)
|
|
||||||
plugins do
|
|
||||||
remove(:Base64UploadAdapter) # Remove default Base64 adapter
|
|
||||||
end
|
|
||||||
|
|
||||||
plugin(Plugins::SimpleUploadAdapter.new(compress: compress))
|
|
||||||
configure(:simpleUpload, { uploadUrl: upload_url })
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
**Location**: `lib/ckeditor5/rails/presets/preset_builder.rb:394-401`
|
|
||||||
|
|
||||||
**Configuration Steps**:
|
|
||||||
1. Removes the default Base64UploadAdapter plugin
|
|
||||||
2. Adds the SimpleUploadAdapter plugin
|
|
||||||
3. Configures the upload URL endpoint
|
|
||||||
4. Optionally enables/disables JavaScript compression
|
|
||||||
|
|
||||||
### Usage in Presets
|
|
||||||
|
|
||||||
Upload functionality is enabled in presets via:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
# In preset definition
|
|
||||||
simple_upload_adapter # Uses default '/uploads' endpoint
|
|
||||||
simple_upload_adapter '/custom' # Custom endpoint
|
|
||||||
```
|
|
||||||
|
|
||||||
**Example Location**: `sandbox/config/initializers/ckeditor5.rb:82`
|
|
||||||
|
|
||||||
## Frontend Implementation
|
|
||||||
|
|
||||||
### Upload Flow
|
|
||||||
|
|
||||||
1. **User Action**: User selects/pastes an image in the editor
|
|
||||||
2. **Plugin Activation**: FileRepository triggers createUploadAdapter
|
|
||||||
3. **Adapter Creation**: SimpleUploadAdapter creates an upload instance
|
|
||||||
4. **FormData Preparation**: File wrapped in FormData with 'upload' field name
|
|
||||||
5. **Security Headers**:
|
|
||||||
- X-Requested-With: XMLHttpRequest
|
|
||||||
- X-CSRF-Token: Extracted from meta tag
|
|
||||||
6. **Upload Process**:
|
|
||||||
- Progress events update loader.uploaded/uploadTotal
|
|
||||||
- Success (200-299): Parse JSON response for URL
|
|
||||||
- Error handling for failed/aborted uploads
|
|
||||||
7. **Editor Update**: Returned URL replaces placeholder image
|
|
||||||
|
|
||||||
### Response Format
|
|
||||||
|
|
||||||
Server must return JSON with structure:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"url": "https://example.com/uploads/image.jpg"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Integration Points
|
|
||||||
|
|
||||||
### 1. Rails Controller
|
|
||||||
|
|
||||||
The upload endpoint (not included in gem) should:
|
|
||||||
- Accept POST requests to configured URL
|
|
||||||
- Process multipart/form-data with 'upload' field
|
|
||||||
- Store file using preferred backend (ActiveStorage, Shrine, etc.)
|
|
||||||
- Return JSON with uploaded file URL
|
|
||||||
- Handle CSRF token validation
|
|
||||||
|
|
||||||
### 2. Helper Methods
|
|
||||||
|
|
||||||
Upload configuration accessible via:
|
|
||||||
- `ckeditor5_editor` helper in views
|
|
||||||
- Preset configuration in initializers
|
|
||||||
- Runtime configuration overrides
|
|
||||||
|
|
||||||
**Location**: `lib/ckeditor5/rails/editor/helpers/editor_helpers.rb`
|
|
||||||
|
|
||||||
### 3. Engine Registration
|
|
||||||
|
|
||||||
Upload adapter available through:
|
|
||||||
- Engine preset system
|
|
||||||
- Direct plugin inclusion
|
|
||||||
- Configuration DSL methods
|
|
||||||
|
|
||||||
**Location**: `lib/ckeditor5/rails/engine.rb:83`
|
|
||||||
|
|
||||||
## File Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
lib/ckeditor5/rails/
|
|
||||||
├── plugins/
|
|
||||||
│ ├── simple_upload_adapter.rb # Main upload adapter implementation
|
|
||||||
│ └── ...
|
|
||||||
├── editor/
|
|
||||||
│ ├── props_inline_plugin.rb # Base class for inline plugins
|
|
||||||
│ └── helpers/
|
|
||||||
│ └── editor_helpers.rb # View helpers for editor
|
|
||||||
├── presets/
|
|
||||||
│ └── preset_builder.rb # Configuration DSL with upload method
|
|
||||||
└── engine.rb # Rails engine with upload registration
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration Examples
|
|
||||||
|
|
||||||
### Basic Setup
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
CKEditor5::Rails.configure do
|
|
||||||
# Enable with default /uploads endpoint
|
|
||||||
simple_upload_adapter
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom Endpoint
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
CKEditor5::Rails.configure do
|
|
||||||
# Custom upload endpoint
|
|
||||||
simple_upload_adapter '/api/images/upload'
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
### With Compression Disabled
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
CKEditor5::Rails.configure do
|
|
||||||
# Disable JavaScript compression for debugging
|
|
||||||
simple_upload_adapter '/uploads', compress: false
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Implementation Details
|
|
||||||
|
|
||||||
### JavaScript Plugin Structure
|
|
||||||
|
|
||||||
The plugin is written as an ES6 module that:
|
|
||||||
1. Imports required CKEditor5 modules dynamically
|
|
||||||
2. Returns a class extending Plugin
|
|
||||||
3. Implements standard CKEditor5 plugin lifecycle
|
|
||||||
4. Integrates with FileRepository for upload management
|
|
||||||
|
|
||||||
### Security Considerations
|
|
||||||
|
|
||||||
- CSRF token automatically extracted from Rails meta tag
|
|
||||||
- XMLHttpRequest marked with X-Requested-With header
|
|
||||||
- Server-side validation responsibility lies with implementer
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
- Network errors caught and rejected with descriptive messages
|
|
||||||
- HTTP status codes outside 200-299 range treated as errors
|
|
||||||
- Upload abort capability for user cancellation
|
|
||||||
|
|
||||||
## Backend Requirements
|
|
||||||
|
|
||||||
To implement the upload endpoint:
|
|
||||||
|
|
||||||
1. **Route Definition**: Add POST route to configured URL
|
|
||||||
2. **File Processing**: Handle multipart upload with 'upload' parameter
|
|
||||||
3. **Storage Backend**: Integrate with ActiveStorage, Shrine, or custom solution
|
|
||||||
4. **Response Format**: Return JSON with 'url' key
|
|
||||||
5. **Security**: Validate CSRF tokens and user permissions
|
|
||||||
|
|
||||||
## Extension Points
|
|
||||||
|
|
||||||
The system supports:
|
|
||||||
- Multiple upload adapters via plugin system
|
|
||||||
- Custom configuration through preset builder
|
|
||||||
- Backend flexibility through endpoint abstraction
|
|
||||||
- Compression toggle for development/production
|
|
||||||
- Integration with various storage backends
|
|
||||||
|
|
||||||
This architecture provides a clean separation between the editor frontend and storage backend, allowing developers to implement uploads using their preferred Rails patterns and storage solutions.
|
|
||||||
Ссылка в новой задаче
Block a user