mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-11 23:02:56 +01:00
232 lines
6.0 KiB
Markdown
232 lines
6.0 KiB
Markdown
# TASK-005 Working Notes
|
|
|
|
## Quick Links
|
|
|
|
- Legacy implementation: `packages/noodl-editor/src/editor/src/views/panels/componentspanel/ComponentsPanel.ts`
|
|
- Template: `packages/noodl-editor/src/editor/src/templates/componentspanel.html`
|
|
- Styles: `packages/noodl-editor/src/editor/src/styles/componentspanel.css`
|
|
- Folder model: `packages/noodl-editor/src/editor/src/views/panels/componentspanel/ComponentsPanelFolder.ts`
|
|
- Templates: `packages/noodl-editor/src/editor/src/views/panels/componentspanel/ComponentTemplates.ts`
|
|
- Sidebar docs: `packages/noodl-editor/docs/sidebar.md`
|
|
|
|
## Reference Components
|
|
|
|
Good patterns to follow:
|
|
- `views/SidePanel/SidePanel.tsx` - Container for sidebar panels
|
|
- `views/panels/SearchPanel/SearchPanel.tsx` - Modern React panel example
|
|
- `views/panels/VersionControlPanel/VersionControlPanel.tsx` - Another React panel
|
|
- `views/PopupLayer/PopupMenu.tsx` - Context menu component
|
|
|
|
## Key Decisions
|
|
|
|
### Decision 1: State Management Approach
|
|
|
|
**Options considered:**
|
|
1. useState + useEffect for ProjectModel subscription
|
|
2. useModernModel hook (existing pattern)
|
|
3. New Zustand store
|
|
|
|
**Decision:** Use `useModernModel` hook
|
|
|
|
**Reasoning:** Matches existing patterns in codebase, already handles subscription cleanup, proven to work with ProjectModel.
|
|
|
|
---
|
|
|
|
### Decision 2: Tree Structure Representation
|
|
|
|
**Options considered:**
|
|
1. Reuse ComponentsPanelFolder class
|
|
2. Create new TreeNode interface
|
|
3. Flat array with parent references
|
|
|
|
**Decision:** [TBD during implementation]
|
|
|
|
**Reasoning:** [TBD]
|
|
|
|
---
|
|
|
|
### Decision 3: Drag-Drop Implementation
|
|
|
|
**Options considered:**
|
|
1. Native HTML5 drag-drop with PopupLayer
|
|
2. @dnd-kit library
|
|
3. react-dnd
|
|
|
|
**Decision:** Native HTML5 with PopupLayer (initially)
|
|
|
|
**Reasoning:** Maintains consistency with existing drag-drop patterns in codebase, no new dependencies. Can upgrade to dnd-kit later if needed for DASH-003.
|
|
|
|
---
|
|
|
|
## Technical Discoveries
|
|
|
|
### ProjectModel Events
|
|
|
|
Key events to subscribe to:
|
|
```typescript
|
|
const events = [
|
|
'componentAdded',
|
|
'componentRemoved',
|
|
'componentRenamed',
|
|
'rootComponentChanged',
|
|
'projectLoaded'
|
|
];
|
|
```
|
|
|
|
### ComponentsPanelFolder Structure
|
|
|
|
The folder structure is built dynamically from component names:
|
|
```
|
|
/Component1 → root folder
|
|
/Folder1/Component2 → Folder1 contains Component2
|
|
/Folder1/ → Folder1 (folder component - both folder AND component)
|
|
```
|
|
|
|
Key insight: A folder can also BE a component. This is the "folder component" pattern where `folder.component` is set.
|
|
|
|
### Icon Type Detection
|
|
|
|
From `ComponentIcon.ts`:
|
|
```typescript
|
|
export function getComponentIconType(component: ComponentModel): ComponentIconType {
|
|
// Cloud functions
|
|
if (isComponentModel_CloudRuntime(component)) {
|
|
return ComponentIconType.CloudFunction;
|
|
}
|
|
// Pages (visual with router)
|
|
if (hasRouterChildren(component)) {
|
|
return ComponentIconType.Page;
|
|
}
|
|
// Visual components
|
|
if (isVisualComponent(component)) {
|
|
return ComponentIconType.Visual;
|
|
}
|
|
// Default: logic
|
|
return ComponentIconType.Logic;
|
|
}
|
|
```
|
|
|
|
### Sheet System
|
|
|
|
Sheets are special top-level folders that start with `#`:
|
|
- `/#__cloud__` - Cloud functions sheet (often hidden)
|
|
- `/#pages` - Pages sheet
|
|
- `/` - Default sheet (root)
|
|
|
|
The `hideSheets` option filters these from display.
|
|
|
|
### PopupLayer Drag-Drop Pattern
|
|
|
|
```typescript
|
|
// Start drag
|
|
PopupLayer.instance.startDragging({
|
|
label: 'Component Name',
|
|
type: 'component',
|
|
component: componentModel,
|
|
folder: parentFolder
|
|
});
|
|
|
|
// During drag (on drop target)
|
|
PopupLayer.instance.isDragging(); // Check if drag active
|
|
PopupLayer.instance.dragItem; // Get current drag item
|
|
PopupLayer.instance.indicateDropType('move' | 'none');
|
|
|
|
// On drop
|
|
PopupLayer.instance.dragCompleted();
|
|
```
|
|
|
|
---
|
|
|
|
## Gotchas Discovered
|
|
|
|
### Gotcha 1: Folder Component Selection
|
|
|
|
When clicking a "folder component", the folder scope should be selected, not the component scope. See `selectComponent()` in original.
|
|
|
|
### Gotcha 2: Sheet Auto-Selection
|
|
|
|
When a component is selected, its sheet should automatically become active. See `selectSheet()` calls.
|
|
|
|
### Gotcha 3: Rename Input Focus
|
|
|
|
The rename input needs careful focus management - it should select all text on focus and prevent click-through issues.
|
|
|
|
### Gotcha 4: Empty Folder Cleanup
|
|
|
|
When a folder becomes empty (no components, no subfolders), and it's a "folder component", it should revert to a regular component.
|
|
|
|
---
|
|
|
|
## Useful Commands
|
|
|
|
```bash
|
|
# Find all usages of ComponentsPanel
|
|
grep -r "ComponentsPanel" packages/noodl-editor/src/ --include="*.ts" --include="*.tsx"
|
|
|
|
# Find ProjectModel event subscriptions
|
|
grep -r "ProjectModel.instance.on" packages/noodl-editor/src/editor/
|
|
|
|
# Find useModernModel usage examples
|
|
grep -r "useModernModel" packages/noodl-editor/src/editor/
|
|
|
|
# Find PopupLayer drag-drop usage
|
|
grep -r "startDragging" packages/noodl-editor/src/editor/
|
|
|
|
# Test build
|
|
cd packages/noodl-editor && npm run build
|
|
|
|
# Type check
|
|
cd packages/noodl-editor && npx tsc --noEmit
|
|
```
|
|
|
|
---
|
|
|
|
## Debug Log
|
|
|
|
_Add entries as you work through implementation_
|
|
|
|
### [Date/Time] - Phase 1: Foundation
|
|
|
|
- Trying: [what you're attempting]
|
|
- Result: [what happened]
|
|
- Next: [what to try next]
|
|
|
|
---
|
|
|
|
## Questions to Resolve
|
|
|
|
- [ ] Does SidebarModel need changes to accept React functional components directly?
|
|
- [ ] Should we keep ComponentsPanelFolder.ts or inline the logic?
|
|
- [ ] How do we handle the `nodeGraphEditor` reference passed via options?
|
|
- [ ] What's the right pattern for context menu positioning?
|
|
|
|
---
|
|
|
|
## Discoveries for LEARNINGS.md
|
|
|
|
_Note patterns discovered that should be added to dev-docs/reference/LEARNINGS.md_
|
|
|
|
### Pattern: Migrating Legacy View to React
|
|
|
|
**Context:** Converting jQuery View classes to React components
|
|
|
|
**Pattern:**
|
|
1. Create React component with same props
|
|
2. Use useModernModel for model subscriptions
|
|
3. Replace data-click handlers with onClick props
|
|
4. Replace data-class bindings with conditional classNames
|
|
5. Replace $(selector) queries with refs or state
|
|
6. Port CSS to CSS modules
|
|
|
|
**Location:** Sidebar panels
|
|
|
|
---
|
|
|
|
### Pattern: [TBD]
|
|
|
|
**Context:** [TBD during implementation]
|
|
|
|
**Pattern:** [TBD]
|
|
|
|
**Location:** [TBD]
|