Skip to content

Conversation

@mreq
Copy link
Member

@mreq mreq commented Jan 9, 2026

Adds locale support to Tiptap editor, enabling separate content fields per locale with a locale switcher UI.

Changes

  • has_folio_tiptap_content now accepts locales: option to create locale-suffixed fields
  • Console UI shows locale switcher with flag icons when locales are configured
  • Autosave revisions track attribute_name to support per-locale drafts
  • Word count tracked independently per locale
  • Converted Folio::Console::Ui::FlagCell to FlagComponent

Usage

has_folio_tiptap_content(locales: %i[cs en])
# Creates: tiptap_content_cs, tiptap_content_enBackwards compatible - existing single-locale setups work unchanged.

mreq added 15 commits January 8, 2026 13:03
Add locales keyword argument to has_folio_tiptap_content to support
traco-like localized tiptap content fields. When locales are provided,
the method registers locale-suffixed fields (e.g., tiptap_content_cs,
tiptap_content_en) and includes locale in TIPTAP_CONTENT_JSON_STRUCTURE.
For non-localized content, locale is omitted from the structure.
- Add LocaleSwitchComponent with flag-based locale switcher in editors bar
- Update SimpleFormWrapComponent to group localized fields and handle locale switching
- Add onLocaleChanged handler to show/hide editors and trigger iframe resize
- Fix model_class extraction from array in SimpleFormWrapComponent
- Make has_folio_tiptap_content fully idempotent with proper cleanup
- Fix STI compatibility by always using base_class for field/locale tracking
- Update Folio::Page to conditionally use localized tiptap based on Traco config
- Convert Folio::Console::Ui::FlagCell to Folio::Console::Ui::FlagComponent
- Update all references from cell() to render()/render_view_component()
- Move SASS styles from cell to component
- Update tests to use component test pattern
- Update SimpleForm flag component to use @builder.template.render()
- Document leading slash requirement for Folio components in AGENTS.md
- Fix has_folio_tiptap_content idempotency to only skip when field is already configured
- Fix locale switch component test to use correct arguments (base_field and locales)
…c autosave

Add attribute_name column to folio_tiptap_revisions to enable per-field
revision tracking for localized tiptap fields (e.g. tiptap_content_en,
tiptap_content_cs). Updates controller, model, input, and frontend to
pass and filter by attribute_name. Maintains backward compatibility with
default 'tiptap_content' value.
Replace locale/base_field logic with unified attribute_name approach:
- Use data-attribute-name consistently for all fields
- Single loop through folio_tiptap_fields (no if/else branching)
- Locale switcher dispatches attributeName instead of locale+baseField
- Add common BEM class and stimulus target for editors and autosave
- Simplify JavaScript to loop through attributeWrap targets together
Add cookie-based persistence for selected tiptap attribute:
- Cookie key format: tiptap_attr_{table_name}_{id}
- Read cookie on backend to set initial state
- Validate cookie value against available fields, fallback to first
- Write cookie on frontend when user switches attributes
- Cookie expires in 1 day
- Locale switcher shows correct active button based on cookie
- Add word count loop in editors-bar with attribute-wrap structure
- Include attributeName in tiptap input updateWordCount dispatch
- Filter word count targets by attribute name before dispatching
- Remove early return filter from word count component (no longer needed)
- Each attribute now has its own word count display
@mreq mreq self-assigned this Jan 9, 2026
mreq added 6 commits January 9, 2026 12:08
Use unique sessionStorage key for each locale editor to preserve scroll positions independently when switching between locales
Set short-lived generic cookie on form submit to preserve locale selection through new -> save -> edit flow. Check record-specific cookie first, then generic cookie as fallback.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds comprehensive locale support to the Folio Tiptap editor, enabling separate content fields per locale with an intuitive locale switcher UI in the console. The implementation maintains full backwards compatibility with existing single-locale setups.

Changes:

  • Enhanced has_folio_tiptap_content to accept a locales: option that creates locale-suffixed fields
  • Added database migration for attribute_name column in tiptap revisions to track per-locale drafts
  • Converted Folio::Console::Ui::FlagCell to FlagComponent for better component architecture
  • Implemented locale switcher UI with flag icons and cookie-based state persistence

Reviewed changes

Copilot reviewed 38 out of 39 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
db/migrate/20260109083325_add_attribute_name_to_folio_tiptap_revisions.rb Adds attribute_name column to support per-locale revision tracking
test/dummy/db/schema.rb Updates schema with new attribute_name column
app/models/concerns/folio/tiptap/model.rb Core implementation of locale support with dynamic field generation
app/models/folio/tiptap/revision.rb Updates uniqueness validation to include attribute_name
app/models/folio/page.rb Integrates locale support with Traco and auditing
app/controllers/folio/console/api/tiptap_revisions_controller.rb Adds attribute_name handling to revision API endpoints
app/inputs/tiptap_input.rb Passes attribute_name to tiptap editor for autosave
app/components/folio/console/ui/flag_component.rb New ViewComponent replacing FlagCell
app/components/folio/console/tiptap/simple_form_wrap_component.rb Adds locale switcher logic and cookie-based state management
app/components/folio/console/tiptap/simple_form_wrap_component.js Implements locale switching and per-locale visibility toggling
app/components/folio/console/tiptap/simple_form_wrap/locale_switch_component.rb New component for rendering locale switcher buttons
app/components/folio/console/tiptap/simple_form_wrap/word_count_component.rb Updated to track word count per locale
app/components/folio/console/tiptap/simple_form_wrap/autosave_info_component.rb Updated to handle per-locale autosave revisions
app/assets/javascripts/folio/input/tiptap.js Adds attribute_name to autosave requests and scroll position storage
docs/tiptap.md Comprehensive documentation for locale support feature
test/models/concerns/folio/tiptap/model_test.rb Tests for locale-suffixed field registration
test/controllers/folio/console/api/tiptap_revisions_controller_test.rb Tests for per-locale revision handling
test/components/folio/console/ui/flag_component_test.rb Tests for new FlagComponent
test/components/folio/console/tiptap/simple_form_wrap/locale_switch_component_test.rb Tests for new LocaleSwitchComponent
CHANGELOG.md Documents the new TipTap Locale Support feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 6 to 15
test "has_folio_tiptap_content with locales registers locale-suffixed fields" do
model_class = Class.new(Folio::ApplicationRecord) do
self.table_name = "folio_pages"
include Folio::Tiptap::Model
end

model_class.has_folio_tiptap_content(locales: %i[cs en])

assert_equal %w[tiptap_content_cs tiptap_content_en], model_class.folio_tiptap_fields.sort
end
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test coverage for the folio_tiptap_locales class method. While folio_tiptap_fields is tested, there should be tests verifying that folio_tiptap_locales returns the correct hash mapping base field names to locale arrays.

Copilot uses AI. Check for mistakes.
Comment on lines 17 to 26
test "has_folio_tiptap_content without locales maintains existing behavior" do
model_class = Class.new(Folio::ApplicationRecord) do
self.table_name = "folio_pages"
include Folio::Tiptap::Model
end

model_class.has_folio_tiptap_content

assert_equal %w[tiptap_content], model_class.folio_tiptap_fields
end
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding test coverage for the idempotency behavior of has_folio_tiptap_content. The implementation includes logic to handle cases where the method is called multiple times with the same or different configuration, but this behavior is not explicitly tested.

Copilot uses AI. Check for mistakes.
mreq and others added 4 commits January 13, 2026 07:23
Move locale-related tests from model_test.rb to model_locales_test.rb for better organization. Adds test coverage for folio_tiptap_locales method and idempotency behavior.
…figurations

Eliminated reconnect_delay and reconnect_delay_max settings from Redis configuration in BatchService for cleaner code and improved clarity.
…ersions

Bumped sidekiq-cron to version 2.0 and sidekiq to version 7.0 in the gemspec for improved functionality and compatibility.
Included connection_pool version 2.x in the gemspec to ensure compatibility, as version 3.0.x introduces breaking changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants