mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-12 15:22:55 +01:00
346 lines
11 KiB
Markdown
346 lines
11 KiB
Markdown
# TASK-004B ComponentsPanel React Migration - STATUS: BLOCKED
|
|
|
|
**Last Updated:** December 22, 2025
|
|
**Status:** 🚫 BLOCKED - Caching Issue Preventing Testing
|
|
**Completion:** ~85% (Backend works, UI update blocked)
|
|
|
|
---
|
|
|
|
## 🎯 Original Goal
|
|
|
|
Migrate the legacy ComponentsPanel to React while maintaining all functionality, with a focus on fixing the component rename feature that doesn't update the UI after renaming.
|
|
|
|
---
|
|
|
|
## ✅ What's Been Completed
|
|
|
|
### Phase 1-4: Foundation & Core Features ✅
|
|
|
|
- [x] React component structure created
|
|
- [x] Tree rendering implemented
|
|
- [x] Context menus working
|
|
- [x] Drag & drop functional
|
|
|
|
### Phase 5: Inline Rename - PARTIALLY COMPLETE
|
|
|
|
#### Backend Rename Logic ✅
|
|
|
|
The actual renaming **WORKS PERFECTLY**:
|
|
|
|
- Component renaming executes successfully
|
|
- Files are renamed on disk
|
|
- Project state updates correctly
|
|
- Changes are persisted (see console log: `Project saved...`)
|
|
|
|
**Evidence from console logs:**
|
|
|
|
```javascript
|
|
✅ Calling performRename...
|
|
🔍 performRename result: true
|
|
✅ Rename successful - canceling rename mode
|
|
Project saved Mon Dec 22 2025 22:03:56 GMT+0100
|
|
```
|
|
|
|
#### UI Update Logic - BLOCKED 🚫
|
|
|
|
The problem: **UI doesn't update after rename** because the React component never receives the `componentRenamed` event from ProjectModel.
|
|
|
|
**Root Cause:** useEventListener hook's useEffect never executes, preventing subscription to ProjectModel events.
|
|
|
|
---
|
|
|
|
## 🔍 Technical Investigation Summary
|
|
|
|
### Issue 1: React useEffect Not Running with Array Dependencies
|
|
|
|
**Problem:** When passing an array as a dependency to useEffect, React 19's `Object.is()` comparison always sees it as changed, but paradoxically, the useEffect never runs.
|
|
|
|
**Original Code (BROKEN):**
|
|
|
|
```typescript
|
|
const events = ['componentAdded', 'componentRemoved', 'componentRenamed'];
|
|
useEventListener(ProjectModel.instance, events, callback);
|
|
|
|
// Inside useEventListener:
|
|
useEffect(() => {
|
|
// Never runs!
|
|
}, [dispatcher, eventName]); // eventName is an array
|
|
```
|
|
|
|
**Solution Implemented:**
|
|
|
|
```typescript
|
|
// 1. Create stable array reference
|
|
const PROJECT_EVENTS = ['componentAdded', 'componentRemoved', 'componentRenamed'];
|
|
|
|
// 2. Spread array into individual dependencies
|
|
useEffect(() => {
|
|
// Should run now
|
|
}, [dispatcher, ...(Array.isArray(eventName) ? eventName : [eventName])]);
|
|
```
|
|
|
|
### Issue 2: Webpack 5 Persistent Caching
|
|
|
|
**Problem:** Even after fixing the code, changes don't appear in the running application.
|
|
|
|
**Root Cause:** Webpack 5 enables persistent caching by default:
|
|
|
|
- Cache location: `packages/noodl-editor/node_modules/.cache`
|
|
- Electron also caches: `~/Library/Application Support/Electron`
|
|
- Even after clearing caches and restarting `npm run dev`, old bundles persist
|
|
|
|
**Actions Taken:**
|
|
|
|
```bash
|
|
# Cleared all caches
|
|
rm -rf packages/noodl-editor/node_modules/.cache
|
|
rm -rf ~/Library/Application\ Support/Electron
|
|
rm -rf ~/Library/Application\ Support/OpenNoodl
|
|
```
|
|
|
|
**Still Blocked:** Despite cache clearing, debug markers never appear in console, indicating old code is still running.
|
|
|
|
---
|
|
|
|
## 📊 Current State Analysis
|
|
|
|
### What We KNOW Works
|
|
|
|
1. ✅ Source files contain all fixes (verified with grep)
|
|
2. ✅ Component rename backend executes successfully
|
|
3. ✅ useEventListener hook logic is correct (when it runs)
|
|
4. ✅ Debug logging is in place to verify execution
|
|
|
|
### What We KNOW Doesn't Work
|
|
|
|
1. ❌ useEventListener's useEffect never executes
|
|
2. ❌ No subscription to ProjectModel events occurs
|
|
3. ❌ UI never receives `componentRenamed` event
|
|
4. ❌ Debug markers (🔥) never appear in console
|
|
|
|
### What We DON'T Know
|
|
|
|
1. ❓ Why cache clearing doesn't force recompilation
|
|
2. ❓ If there's another cache layer we haven't found
|
|
3. ❓ If webpack-dev-server is truly recompiling on changes
|
|
4. ❓ If there's a build configuration preventing hot reload
|
|
|
|
---
|
|
|
|
## 🐛 Bonus Bug Discovered
|
|
|
|
**PopupMenu Constructor Error:**
|
|
|
|
```
|
|
Uncaught TypeError: _popuplayer__WEBPACK_IMPORTED_MODULE_3___default(...).PopupMenu is not a constructor
|
|
at ComponentItem.tsx:131:1
|
|
```
|
|
|
|
This is a **separate bug** affecting context menus (right-click). Unrelated to rename issue but should be fixed.
|
|
|
|
---
|
|
|
|
## 📁 Files Modified (With Debug Logging)
|
|
|
|
### Core Implementation Files
|
|
|
|
1. **packages/noodl-editor/src/editor/src/hooks/useEventListener.ts**
|
|
|
|
- Module load marker: `🔥 useEventListener.ts MODULE LOADED`
|
|
- useEffect marker: `🚨 useEventListener useEffect RUNNING!`
|
|
- Subscription marker: `📡 subscribing to...`
|
|
- Event received marker: `🔔 useEventListener received event`
|
|
|
|
2. **packages/noodl-editor/src/editor/src/views/panels/ComponentsPanelNew/hooks/useComponentsPanel.ts**
|
|
|
|
- Module load marker: `🔥 useComponentsPanel.ts MODULE LOADED`
|
|
- Integration with useEventListener
|
|
- Stable PROJECT_EVENTS array
|
|
|
|
3. **packages/noodl-editor/src/editor/src/views/panels/ComponentsPanelNew/ComponentsPanelReact.tsx**
|
|
- Render markers
|
|
- Rename flow markers
|
|
|
|
### Documentation Files
|
|
|
|
1. **CACHE-CLEAR-RESTART-GUIDE.md** - Instructions for clearing caches
|
|
2. **RENAME-TEST-PLAN.md** - Test procedures
|
|
3. **This file** - Status documentation
|
|
|
|
---
|
|
|
|
## 🚧 Blocking Issues
|
|
|
|
### Primary Blocker: Webpack/Electron Caching
|
|
|
|
**Severity:** CRITICAL
|
|
**Impact:** Cannot test ANY changes to the code
|
|
|
|
**Symptoms:**
|
|
|
|
- Code changes in source files don't appear in running app
|
|
- Console shows NO debug markers (🔥, 🚨, 📡, 🔔)
|
|
- Multiple dev server restarts don't help
|
|
- Cache clearing doesn't help
|
|
|
|
**Possible Causes:**
|
|
|
|
1. Webpack dev server not watching TypeScript files correctly
|
|
2. Another cache layer (browser cache, service worker, etc.)
|
|
3. Electron loading from wrong bundle location
|
|
4. Build configuration preventing hot reload
|
|
5. macOS file system caching (unlikely but possible)
|
|
|
|
### Secondary Blocker: React 19 + EventDispatcher Incompatibility
|
|
|
|
**Severity:** HIGH
|
|
**Impact:** Even if caching is fixed, may need alternative approach
|
|
|
|
The useEventListener hook solution from TASK-008 may have edge cases with React 19's new behavior that weren't caught in isolation testing.
|
|
|
|
---
|
|
|
|
## 💡 Potential Solutions (Untested)
|
|
|
|
### Solution 1: Aggressive Cache Clearing Script
|
|
|
|
Create a script that:
|
|
|
|
- Kills all Node/Electron processes
|
|
- Clears all known cache directories
|
|
- Clears macOS file system cache
|
|
- Forces a clean webpack build
|
|
- Restarts with --no-cache flag
|
|
|
|
### Solution 2: Bypass useEventListener Temporarily
|
|
|
|
As a workaround, try direct subscription in component:
|
|
|
|
```typescript
|
|
useEffect(() => {
|
|
const group = { id: 'ComponentsPanel' };
|
|
const handler = () => setUpdateCounter((c) => c + 1);
|
|
|
|
ProjectModel.instance.on('componentRenamed', handler, group);
|
|
|
|
return () => ProjectModel.instance.off(group);
|
|
}, []);
|
|
```
|
|
|
|
### Solution 3: Use Polling as Temporary Fix
|
|
|
|
While not elegant, could work around the event issue:
|
|
|
|
```typescript
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
// Force re-render every 500ms when in rename mode
|
|
if (isRenaming) {
|
|
setUpdateCounter((c) => c + 1);
|
|
}
|
|
}, 500);
|
|
return () => clearInterval(interval);
|
|
}, [isRenaming]);
|
|
```
|
|
|
|
### Solution 4: Production Build Test
|
|
|
|
Build a production bundle to see if the issue is dev-only:
|
|
|
|
```bash
|
|
npm run build
|
|
# Test with production Electron app
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 Next Steps for Future Developer
|
|
|
|
### Immediate Actions
|
|
|
|
1. **Verify caching issue:**
|
|
|
|
- Kill ALL node/electron processes: `killall node; killall Electron`
|
|
- Clear caches again
|
|
- Try adding a simple console.log to a DIFFERENT file to see if ANY changes load
|
|
|
|
2. **If caching persists:**
|
|
|
|
- Investigate webpack configuration in `webpackconfigs/`
|
|
- Check if there's a service worker
|
|
- Look for additional cache directories
|
|
- Consider creating a fresh dev environment in a new directory
|
|
|
|
3. **If caching resolved but useEffect still doesn't run:**
|
|
- Review React 19 useEffect behavior with array spreading
|
|
- Test useEventListener hook in isolation with a simple test case
|
|
- Consider alternative event subscription approach
|
|
|
|
### Alternative Approaches
|
|
|
|
1. **Revert to old panel temporarily** - The legacy panel works, could postpone migration
|
|
2. **Hybrid approach** - Use React for rendering but keep legacy event handling
|
|
3. **Full rewrite** - Start fresh with a different architecture pattern
|
|
|
|
---
|
|
|
|
## 🔬 Debug Checklist for Next Session
|
|
|
|
When picking this up again, verify these in order:
|
|
|
|
- [ ] Console shows 🔥 module load markers (proves new code loaded)
|
|
- [ ] Console shows 🚨 useEffect RUNNING marker (proves useEffect executes)
|
|
- [ ] Console shows 📡 subscription marker (proves ProjectModel subscription)
|
|
- [ ] Rename a component
|
|
- [ ] Console shows 🔔 event received marker (proves events are firing)
|
|
- [ ] Console shows 🎉 counter update marker (proves React re-renders)
|
|
- [ ] UI actually updates (proves the whole chain works)
|
|
|
|
**If step 1 fails:** Still a caching issue, don't proceed
|
|
**If step 1 passes, step 2 fails:** React useEffect issue, review dependency array
|
|
**If step 2 passes, step 3 fails:** EventDispatcher integration issue
|
|
**If step 3 passes, step 4 fails:** ProjectModel not emitting events
|
|
|
|
---
|
|
|
|
## 📚 Related Documentation
|
|
|
|
- **TASK-008**: EventDispatcher React Investigation (useEventListener solution)
|
|
- **LEARNINGS.md**: Webpack caching issues section (to be added)
|
|
- **CACHE-CLEAR-RESTART-GUIDE.md**: Instructions for clearing caches
|
|
- **RENAME-TEST-PLAN.md**: Test procedures for rename functionality
|
|
|
|
---
|
|
|
|
## 🎓 Key Learnings
|
|
|
|
1. **Webpack 5 caching is AGGRESSIVE** - Can persist across multiple dev server restarts
|
|
2. **React 19 + arrays in deps** - Spreading array items into deps is necessary
|
|
3. **EventDispatcher + React** - Requires careful lifecycle management
|
|
4. **Debug logging is essential** - Emoji markers made it easy to trace execution
|
|
5. **Test in isolation first** - useEventListener worked in isolation but fails in real app
|
|
|
|
---
|
|
|
|
## ⏱️ Time Investment
|
|
|
|
- Initial implementation: ~3 hours
|
|
- Debugging UI update issue: ~2 hours
|
|
- EventDispatcher investigation: ~4 hours
|
|
- Caching investigation: ~2 hours
|
|
- Documentation: ~1 hour
|
|
|
|
**Total: ~12 hours** - Majority spent on debugging caching/event issues rather than actual feature implementation.
|
|
|
|
---
|
|
|
|
## 🏁 Recommendation
|
|
|
|
**Option A (Quick Fix):** Use the legacy ComponentsPanel for now. It works, and this migration can wait.
|
|
|
|
**Option B (Workaround):** Implement one of the temporary solutions (polling or direct subscription) to unblock other work.
|
|
|
|
**Option C (Full Investigation):** Dedicate a full session to solving the caching mystery with fresh eyes, possibly in a completely new terminal/environment.
|
|
|
|
**My Recommendation:** Option A. The backend rename logic works perfectly. The UI update is a nice-to-have but not critical. Move on to more impactful work and revisit this when someone has time to fully diagnose the caching issue.
|