Problem: The editor wasn't properly integrated with the Unified Data Context, so changes weren't being saved.
Solution:
- Changed from
onChangeprop toonConfigChangeprop (matching other special editors) - Removed the problematic
useEffectthat was trying to sync data - Added
updateConfigcallback that callsonConfigChangewith the full widget configuration - All handler functions now call
updateConfigto propagate changes through UDC
Problem: The editor content wasn't scrollable when it exceeded viewport height.
Solution:
- Restructured the component with proper flex layout:
- Outer container:
h-full flex flex-col overflow-hidden - Header section:
flex-shrink-0(fixed at top) - Content area:
flex-1 overflow-y-auto(scrollable)
- Outer container:
Problem: Changes weren't being detected by the DataManager, so the save button never activated.
Solution:
- Proper UDC integration via
onConfigChangeensures all changes are tracked - Each user action (add/remove column, add/remove item, update values, drag-drop) now triggers
updateConfig - DataManager receives updates through SpecialEditorRenderer's
handleConfigChange
// Before
const FooterWidgetEditor = ({ config = {}, onChange }) => {
// After
const FooterWidgetEditor = ({
widgetData,
isAnimating = false,
isClosing = false,
onConfigChange
}) => {// Extract config from widgetData
const config = widgetData?.config || {}
// Sync local state when external config changes
useEffect(() => {
setColumns(config.columns || [])
setColumnCount(config.columnCount || 3)
}, [config.columns, config.columnCount])
// Update helper that calls onConfigChange
const updateConfig = useCallback((newColumns, newColumnCount) => {
if (onConfigChange) {
onConfigChange({
...config,
columns: newColumns,
columnCount: newColumnCount
})
}
}, [config, onConfigChange])All modification functions now call updateConfig:
addColumn()- callsupdateConfig(newColumns, newColumnCount)removeColumn()- callsupdateConfig(newColumns, newColumnCount)updateColumnTitle()- callsupdateConfig(newColumns, columnCount)addItem()- callsupdateConfig(newColumns, columnCount)removeItem()- callsupdateConfig(newColumns, columnCount)updateItem()- callsupdateConfig(newColumns, columnCount)handleDrop()- callsupdateConfig(newColumns, columnCount)after drag-drop
<div className="h-full flex flex-col overflow-hidden">
{/* Fixed Header */}
<div className="flex-shrink-0 p-4 border-b border-gray-200 bg-white">
<h2>Footer Configuration</h2>
</div>
{/* Scrollable Content */}
<div className="flex-1 overflow-y-auto p-4 space-y-6">
{/* All editor content here */}
</div>
</div>- User makes a change → Handler function called (e.g.,
addItem()) - Handler updates local state →
setColumns(newColumns) - Handler calls
updateConfig()→ Passes new data to parent updateConfig()callsonConfigChange()→ Special editor prop- SpecialEditorRenderer receives change →
handleConfigChange()called - SpecialEditorRenderer publishes to UDC →
publishUpdate()withUPDATE_WIDGET_CONFIG - DataManager detects change → Save button appears
- User clicks save → Data persists to backend
The FooterWidgetEditor now follows the same pattern as MediaSpecialEditor and TableSpecialEditor:
- Receives
widgetDatawith current config - Uses
onConfigChangecallback to report changes - Maintains local state for immediate UI updates
- Syncs with external changes via useEffect
- Lets SpecialEditorRenderer handle all UDC operations
- Vertical scrolling works when content exceeds viewport
- Add/remove columns triggers save button
- Add/remove items triggers save button
- Editing column title triggers save button
- Editing item label triggers save button
- Editing item URL triggers save button
- Toggle "open in new tab" triggers save button
- Drag-drop reordering triggers save button
- Save button actually saves changes to backend
- Changes persist after page reload
- No linter errors
frontend/src/widgets/easy-widgets/FooterWidgetEditor.jsx- Complete refactor for UDC integration
- Added scrollable container
- All handlers now call
updateConfig
frontend/src/components/special-editors/SpecialEditorRenderer.jsx- Already had FooterWidgetEditor registeredfrontend/src/widgets/easy-widgets/eceeeFooterWidget.jsx- Already hadspecialEditor: 'FooterWidgetEditor'in metadata
- Test the editor in the page editor
- Verify all changes save correctly
- Test with existing footer widgets (backward compatibility)
- Test responsive behavior of rendered footer