Replace delta-based approach with direct mouse-position-to-column-edge calculation:
newW = ev.clientX - thLeft. No setPointerCapture needed, no coordinate drift.
- Column resize: use getBoundingClientRect() + setPointerCapture for proper tracking
- Context menu 'Name' field: click to edit, Enter to save, Escape to cancel
- Rename persists to server via PUT /db/properties/{id}/api
- Column resize: drag handle between headers to resize column width
- SVG outline icons per property type in header (Aa, #, ☰, 📅, ☑, 🔗, ✉, 📞)
- Header context menu on click: Show page icon toggle, AI Autofill, Filter,
Sort (asc/desc), Group, Calculate (None/Count/Percent), Freeze, Wrap,
Insert left/right
- Submenus for AI Autofill, Sort, Calculate with nested options
- New Page button moved below last data row (bottom of table)
- New rows inserted at end of table
Alpine 3.14.9 evaluates x-data expressions before Alpine.data() registration,
causing 'pages is not defined', 'emptyRows is not defined', etc.
Solution: pure vanilla JS DOM rendering (same pattern as Library fix).
- _database_table.html: static DOM with IDs only, no Alpine directives
- _database_table_scripts.html: vanilla JS state, render, cell editing, modals
- Removes all x-data, x-for, x-show, x-model from database table
- Migration: add collection_id column to pages table
- POST /api/pages/{id}/convert-to-database: transforms page into database
- GET /api/collections/{id}/table-data: returns props + pages for table view
- POST /api/collections/{id}/pages: creates new row in collection
- New page_editor_collection.html template for database view
- _database_table.html: Notion-style table with columns, rows, New Page, Add Property
- Alpine.js component for cell editing, new page creation, property mgmt
- CSS: complete database table styling (view bar, table, cells, modals, dropdowns)
- Frontend: createDatabase() now converts page to full-page DB (was inline embed)