admin-form-input has fixed height (36px) causing overflow. Replaced
with a styled div matching the editor appearance. No new CSS needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added section-content class with proper ul/ol/li/p margins and
overflow:hidden. Browser defaults for lists were causing content
to extend outside the form input box.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added isLockedByOther check to:
- All disabled={} on selects (currency, language) and checkboxes (apply_vat)
- All conditional renders that swap date pickers for read-only inputs
- Rich editor conditional that swaps editor for static HTML display
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When user A opens an offer, a lock is acquired (locked_by + locked_at).
User B opening the same offer sees a warning banner and the form is
read-only. Lock expires after 5 minutes without heartbeat.
Backend:
- POST /:id/lock — acquire lock (returns 423 if locked by another)
- POST /:id/heartbeat — refresh lock timestamp (every 2 min)
- POST /:id/unlock — release lock
- GET /:id — includes locked_by info
- PUT /:id — auto-releases lock on save
Frontend:
- Acquires lock on page load (edit mode only)
- Sends heartbeat every 2 minutes
- Releases lock on page unmount (navigate away)
- Shows warning banner with locker's name
- All inputs read-only + action buttons hidden when locked
Migration: adds locked_by (INT) and locked_at (DATETIME) to quotations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Item reordering: replaced placeholder with @dnd-kit drag-and-drop.
Each item row has a drag handle for reordering via vertical drag.
Uses SortableContext with verticalListSortingStrategy.
2. Scope template insertion: fixed template loading to use already-fetched
data instead of re-fetching from non-existent endpoint. Templates with
sections are now stored fully and inserted directly on selection.
Also copies template description to scope_description.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>