Files
OpenNoodl/dev-docs/tasks/phase-2-react-migration/TASK-004B-componentsPanel-react-migration/phases/PHASE-7-POLISH-CLEANUP.md

11 KiB

Phase 7: Polish & Cleanup

Estimated Time: 1 hour
Complexity: Low
Prerequisites: Phase 6 complete (sheet selector working)

Overview

Final polish, remove legacy files, ensure all functionality works correctly, and prepare the component for TASK-004 (migration status badges). This phase ensures the migration is complete and production-ready.


Goals

  • Polish UI/UX (spacing, hover states, focus states)
  • Remove legacy files
  • Clean up code (remove TODOs, add missing JSDoc)
  • Verify all functionality works
  • Prepare extension points for TASK-004
  • Update documentation
  • Final testing pass

Step 1: UI Polish

1.1 Review All Styles

Check and fix any styling inconsistencies:

// Verify all spacing is consistent
.TreeItem {
  padding: 6px 10px; // Should match across all items
}

// Verify hover states work
.TreeItem:hover {
  background-color: var(--theme-color-bg-3);
}

// Verify selection states are clear
.TreeItem.Selected {
  background-color: var(--theme-color-primary-transparent);
  color: var(--theme-color-primary);
}

// Verify focus states for accessibility
.RenameInput:focus {
  border-color: var(--theme-color-primary);
  box-shadow: 0 0 0 2px var(--theme-color-primary-transparent);
}

1.2 Test Color Tokens

Verify all colors use design tokens (no hardcoded hex values):

# Search for hardcoded colors
grep -r "#[0-9a-fA-F]\{3,6\}" packages/noodl-editor/src/editor/src/views/panels/ComponentsPanel/

If any found, replace with appropriate tokens from --theme-color-*.

1.3 Test Dark Theme (if applicable)

If OpenNoodl supports theme switching, test the panel in dark theme to ensure all colors are legible.


Step 2: Code Cleanup

2.1 Remove TODO Comments

Search for and resolve all TODO comments:

grep -rn "TODO" packages/noodl-editor/src/editor/src/views/panels/ComponentsPanel/

Either implement the TODOs or remove them if they're no longer relevant.

2.2 Remove TSFixme Types

Ensure no TSFixme types were added:

grep -rn "TSFixme" packages/noodl-editor/src/editor/src/views/panels/ComponentsPanel/

Replace any with proper types.

2.3 Add JSDoc Comments

Ensure all exported functions and components have JSDoc:

/**
 * ComponentsPanel
 *
 * Modern React implementation of the components sidebar panel.
 * Displays project component hierarchy with folders, allows drag-drop reorganization,
 * and provides context menus for component/folder operations.
 *
 * @example
 * ```tsx
 * <ComponentsPanel
 *   nodeGraphEditor={editor}
 *   showSheetList={true}
 *   hideSheets={['__cloud__']}
 * />
 * ```
 */
export function ComponentsPanel(props: ComponentsPanelProps) {
  // ...
}

2.4 Clean Up Imports

Remove unused imports and organize them:

// External packages (alphabetical)

import PopupLayer from '@noodl-views/popuplayer';
import classNames from 'classnames';
import React, { useCallback, useEffect, useState } from 'react';

import { ProjectModel } from '@noodl-models/projectmodel';
import { UndoQueue } from '@noodl-models/undo-queue-model';

// Internal packages (alphabetical by alias)
import { IconName } from '@noodl-core-ui/components/common/Icon';

// Relative imports
import { ComponentTree } from './components/ComponentTree';
import css from './ComponentsPanel.module.scss';
import { useComponentsPanel } from './hooks/useComponentsPanel';
import { ComponentsPanelProps } from './types';

Step 3: Remove Legacy Files

3.1 Verify All Functionality Works

Before removing legacy files, thoroughly test the new implementation:

  • All features from old panel work in new panel
  • No regressions identified
  • All tests pass

3.2 Update Imports

Find all files that import the old ComponentsPanel:

grep -r "from.*componentspanel/ComponentsPanel" packages/noodl-editor/src/

Update to import from new location:

// Old

// New
import { ComponentsPanel } from './views/panels/ComponentsPanel';
import { ComponentsPanelView } from './views/panels/componentspanel/ComponentsPanel';

3.3 Delete Legacy Files

Once all imports are updated and verified:

# Delete old implementation (DO NOT run this until 100% sure)
# rm packages/noodl-editor/src/editor/src/views/panels/componentspanel/ComponentsPanel.ts
# rm packages/noodl-editor/src/editor/src/templates/componentspanel.html

IMPORTANT: Keep ComponentsPanelFolder.ts and ComponentTemplates.ts as they're reused.


Step 4: Prepare for TASK-004

4.1 Add Migration Status Type

In types.ts, add placeholder for migration status:

/**
 * Migration status for components (for TASK-004)
 */
export type MigrationStatus = 'needs-review' | 'ai-migrated' | 'auto' | 'manually-fixed' | null;

export interface ComponentItemData {
  type: 'component';
  component: ComponentModel;
  folder: ComponentsPanelFolder;
  name: string;
  fullName: string;
  isSelected: boolean;
  isRoot: boolean;
  isPage: boolean;
  isCloudFunction: boolean;
  isVisual: boolean;
  canBecomeRoot: boolean;
  hasWarnings: boolean;

  // Migration status (for TASK-004)
  migrationStatus?: MigrationStatus;
}

4.2 Add Badge Placeholder in ComponentItem

export function ComponentItem({ component, level, isSelected, onClick }: ComponentItemProps) {
  // ... existing code ...

  return (
    <div className={css.TreeItem} onClick={onClick}>
      <div className={css.ItemContent}>
        <div className={css.Icon}>{icon}</div>
        <div className={css.Label}>{component.name}</div>

        {/* Migration badge (for TASK-004) */}
        {component.migrationStatus && (
          <div className={css.MigrationBadge} data-status={component.migrationStatus}>
            {/* Badge will be implemented in TASK-004 */}
          </div>
        )}

        {component.hasWarnings && <div className={css.Warning}>!</div>}
      </div>
    </div>
  );
}

4.3 Add Filter Placeholder in Panel Header

<div className={css.Header}>
  <div className={css.Title}>{componentTitle}</div>

  {/* Filter button (for TASK-004) */}
  {/* <button className={css.FilterButton} title="Filter components">
    <IconName.Filter />
  </button> */}

  <button className={css.AddButton} title="Add component" onClick={handleAddButtonClick}>
    <div className={css.AddIcon}>+</div>
  </button>
</div>

Step 5: Documentation

5.1 Update CHANGELOG.md

Add final entry to CHANGELOG:

## [2024-12-21] - Migration Complete

### Summary

Completed ComponentsPanel React migration. All 7 phases implemented and tested.

### Files Created

- All files in `views/panels/ComponentsPanel/` directory

### Files Modified

- `router.setup.ts` - Updated ComponentsPanel import

### Files Removed

- `views/panels/componentspanel/ComponentsPanel.ts` (legacy)
- `templates/componentspanel.html` (legacy)

### Technical Notes

- Full feature parity achieved
- All functionality uses UndoQueue
- Ready for TASK-004 badges/filters integration

### Testing Notes

- All manual tests passed
- No console errors
- Performance is good even with large component trees

### Next Steps

- TASK-004 Part 2: Add migration status badges
- TASK-004 Part 3: Add filter system

5.2 Create Migration Pattern Document

Document the pattern for future panel migrations:

File: dev-docs/reference/PANEL-MIGRATION-PATTERN.md

# Panel Migration Pattern

Based on ComponentsPanel React migration (TASK-004B).

## Steps

1. **Foundation** - Create directory, types, basic component
2. **Data Integration** - Connect to models, subscribe to events
3. **UI Features** - Implement interactions (menus, selection, etc.)
4. **Advanced Features** - Implement complex features (drag-drop, inline editing)
5. **Polish** - Clean up, remove legacy files

## Key Patterns

### Model Subscription

Use `useEffect` with cleanup:

\`\`\`typescript
useEffect(() => {
const handler = () => setUpdateCounter(c => c + 1);
Model.instance.on('event', handler);
return () => Model.instance.off('event', handler);
}, []);
\`\`\`

### UndoQueue Integration

All mutations should use UndoQueue:

\`\`\`typescript
UndoQueue.instance.pushAndDo(new UndoActionGroup({
label: 'Action description',
do: () => { /_ perform action _/ },
undo: () => { /_ reverse action _/ }
}));
\`\`\`

## Lessons Learned

[Add lessons from ComponentsPanel migration]

Step 6: Final Testing

6.1 Comprehensive Testing Checklist

Test all features end-to-end:

Basic Functionality

  • Panel appears in sidebar
  • Component tree renders correctly
  • Folders expand/collapse
  • Components can be selected
  • Selection opens in editor

Context Menus

  • Header "+" menu works
  • Component context menu works
  • Folder context menu works
  • All menu actions work

Drag-Drop

  • Can drag components
  • Can drag folders
  • Invalid drops prevented
  • Drops execute correctly
  • Undo works

Rename

  • Double-click triggers rename
  • Inline input works
  • Validation works
  • Enter/Escape work correctly

Sheets

  • Sheet tabs display
  • Sheet selection works
  • Tree filters by sheet

Undo/Redo

  • All actions can be undone
  • All actions can be redone
  • Undo queue labels are clear

6.2 Edge Case Testing

  • Empty project
  • Very large project (100+ components)
  • Deep nesting (10+ levels)
  • Special characters in names
  • Rapid clicking/operations
  • Browser back/forward buttons

6.3 Performance Testing

  • Large tree renders quickly
  • Expand/collapse is smooth
  • Drag-drop is responsive
  • No memory leaks (check dev tools)

Step 7: Update Task Status

7.1 Update README

Mark task as complete in main README.

7.2 Update CHECKLIST

Check off all items in CHECKLIST.md.

7.3 Commit Changes

git add .
git commit -m "feat(editor): migrate ComponentsPanel to React

- Implement all 7 migration phases
- Full feature parity with legacy implementation
- Ready for TASK-004 badges/filters
- Remove legacy jQuery-based ComponentsPanel

BREAKING CHANGE: ComponentsPanel now requires React"

Success Criteria

Phase 7 is complete when:

  1. All UI polish is complete
  2. Code is clean (no TODOs, TSFixme, unused code)
  3. Legacy files are removed
  4. All imports are updated
  5. Documentation is updated
  6. All tests pass
  7. TASK-004 extension points are in place
  8. Ready for production use

Final Checklist

  • All styling uses design tokens
  • All functions have JSDoc comments
  • No console errors or warnings
  • TypeScript compiles without errors
  • All manual tests pass
  • Legacy files removed
  • All imports updated
  • Documentation complete
  • Git commit made
  • Task marked complete

What's Next?

After completing this phase:

  1. TASK-004 Part 2 - Add migration status badges to components
  2. TASK-004 Part 3 - Add filter dropdown to show/hide migrated components
  3. Pattern Documentation - Document patterns for future migrations
  4. Team Review - Share migration approach with team

Congratulations on completing the ComponentsPanel React migration! 🎉