Admin menu: - PDF Templates is now a top-level submenu under Admin (same level as System Settings) so it opens without opening System Settings first. - Remove PDF routes from admin_settings_open so only PDF Templates expands on invoice/quote PDF pages. - Set pdfDropdown parent to adminDropdown in nested dropdown click handler. PDF layout (invoice & quote): - Preserve table groups (Items, Expenses) on save by skipping Groups in cleanup and ensuring table names are set and restored from design_json. - Add test for saving and reloading layout with tables. Docs: - Update PDF layout access path to Admin → PDF Templates → Invoice PDF (and Quote PDF) in PDF_LAYOUT_CUSTOMIZATION.md, PDF_EDITOR_ENHANCED_FEATURES.md, PDF_EDITOR_QUICK_START.md, INVOICE_EXTRA_GOODS_PDF_EXPORT.md.
9.7 KiB
Enhanced PDF Invoice Editor with Konva.js
Overview
The PDF Invoice Editor has been significantly enhanced to use Konva.js, providing a powerful drag-and-drop interface for designing custom invoice layouts. Users can now add, position, and customize any element with an intuitive visual editor.
New Features
1. Expanded Element Library
The editor now includes a comprehensive set of draggable elements organized into categories:
Basic Elements
- Text: Generic text field for custom content
- Heading: Large, bold text for titles
- Line: Horizontal divider line
- Rectangle: Customizable rectangular shape
- Circle: Customizable circular shape
- Decorative Image: Placeholder that you can assign an uploaded image to; appears in the PDF when an image is set. Supports position, size, and opacity. Save the layout after uploading to persist the image with the design.
Company Information Elements
- Company Logo: Displays uploaded company logo
- Company Name: Formatted company name
- Company Details: Combined address, email, and phone
- Company Address: Dedicated address field
- Company Email: Email address with label
- Company Phone: Phone number with label
- Company Website: Website URL
- Company Tax ID: Tax identification number
Invoice Data Elements
- Invoice Number: Auto-formatted invoice number
- Invoice Date: Issue date
- Due Date: Payment due date
- Invoice Status: Current status (draft, sent, paid, etc.)
- Client Info: Combined client information block
- Client Name: Client name only
- Client Address: Client address only
- Items Table: Dynamic table of invoice items
- Subtotal: Pre-tax amount
- Tax: Tax amount with rate
- Total Amount: Final total
- Notes: Invoice notes field
- Terms: Payment terms
Advanced Elements
- QR Code: QR code placeholder (for invoice number/link)
- Barcode: Barcode placeholder
- Page Number: Page numbering
- Current Date: Auto-updating current date
- Watermark: Large, semi-transparent text overlay
2. Properties Panel
The right sidebar now features a comprehensive properties panel that displays editable properties for the selected element:
Text Element Properties
- Position X/Y: Precise positioning
- Text Content: Edit text inline
- Font Size: Size in pixels
- Font Family: Choose from 6 fonts (Arial, Times New Roman, Courier New, Georgia, Verdana, Helvetica)
- Font Style: Normal, Bold, or Italic
- Text Color: Color picker
- Width: Text box width
- Opacity: Transparency slider (0-100%)
Shape Element Properties (Rectangle/Circle)
- Position X/Y: Precise positioning
- Fill Color: Interior color
- Stroke Color: Border color
- Stroke Width: Border thickness
- Dimensions: Width/Height for rectangles, Radius for circles
Line Element Properties
- Stroke Color: Line color
- Stroke Width: Line thickness
All Elements
- Layer Order Controls: Move up/down/top/bottom in z-index
3. Canvas Toolbar
Enhanced toolbar with powerful editing tools:
- Zoom In/Out: Scale the canvas view
- Delete: Remove selected element
- Align Left/Center/Right: Horizontal alignment
- Align Top/Middle/Bottom: Vertical alignment
4. Keyboard Shortcuts
For power users, the editor supports keyboard shortcuts:
- Delete/Backspace: Remove selected element
- Ctrl+C: Copy selected element
- Ctrl+V: Paste copied element (offset by 20px)
- Ctrl+D: Duplicate selected element
- Arrow Keys: Move element by 1px
- Shift+Arrow Keys: Move element by 10px
- Click Background: Deselect all
5. Visual Feedback
- Transform Handles: Resize and rotate elements with intuitive handles
- Real-time Updates: See changes immediately on the canvas
- Selection Indicator: Visual highlight of selected elements
- Snap to Pixel: Automatic pixel-perfect positioning
6. Advanced Canvas Features
Layer Management
- Move elements forward/backward in z-index
- Bring to front/send to back
- Visual layer indicators in properties panel
Alignment Tools
- Align to left/center/right edge
- Align to top/middle/bottom
- Center elements on canvas
Copy/Paste/Duplicate
- Copy elements to clipboard
- Paste with automatic offset
- Duplicate with keyboard shortcut
Technical Implementation
Architecture
The enhanced editor uses:
- Konva.js 9.x: Canvas-based rendering engine
- HTML5 Canvas: High-performance graphics
- Dynamic Properties Panel: React-like property binding
- JSON State Management: Serialize/deserialize designs
Code Generation
The editor generates clean HTML and CSS:
<!-- Text elements become divs -->
<div class="element text-element" style="position:absolute;left:50px;top:30px;...">
Invoice Text
</div>
<!-- Shapes become styled divs -->
<div class="rectangle-element" style="position:absolute;..."></div>
<!-- Images use Jinja2 templates -->
<img src="{{ get_logo_base64(settings.get_logo_path()) }}" style="..." alt="Logo">
State Persistence
Designs are saved as:
- design_json: Complete Konva.js stage state (for re-opening the editor). Custom attributes such as decorative-image
nameandimageUrlare injected into the serialized JSON so they survive save/load. - template_json: ReportLab template (elements list) used for PDF generation. Decorative image elements are only included when they have a non-empty image source, so the PDF is never broken by missing images.
- HTML/CSS: Generated template markup and styles (legacy preview).
Decorative images: The editor syncs each decorative image’s imageUrl onto its group before generating the template and uses position-based matching when injecting URLs into the saved design JSON. On load, name and imageUrl are restored from the saved JSON onto the live nodes so decorative images appear correctly even if Konva does not persist custom attributes. Placeholders (no image uploaded) remain visible in the editor but are omitted from the PDF.
Usage Guide
Creating a New Layout
- Navigate to Admin → PDF Templates → Invoice PDF (or Quote PDF for quote layouts)
- Click elements from the left sidebar to add them to the canvas
- Click an element to select it
- Use the properties panel (right) to customize:
- Position, size, colors
- Text content and fonts
- Layer order
- Use toolbar buttons for alignment and zoom
- Click Generate Preview to see the rendered result
- Click Save Design to persist changes
Editing Existing Layouts
- Existing elements are loaded automatically from saved JSON
- Click any element to edit its properties
- Use keyboard shortcuts for faster editing
- Preview changes before saving
Best Practices
- Start with Structure: Add heading, company info, and major sections first
- Use Alignment Tools: Keep elements properly aligned
- Test with Real Data: Use "Generate Preview" to see actual invoice data
- Layer Management: Keep important elements on top
- Save Frequently: Use "Save Design" to preserve work
API Integration
Backend Routes
The editor integrates with existing routes:
GET /admin/pdf-layout: Load editor with current designPOST /admin/pdf-layout: Save design (HTML, CSS, JSON)POST /admin/pdf-layout/preview: Generate live previewPOST /admin/pdf-layout/reset: Reset to defaults
Data Flow
User Action → Konva.js Canvas → generateCode() → HTML/CSS → Backend → Database
↓
Preview Generation
Extensibility
Adding New Element Types
To add a new element type:
- Add to sidebar HTML:
<div class="element-item" data-type="new-element">
<i class="fas fa-icon"></i>
<span>New Element</span>
</div>
- Add to templates object:
'new-element': { text: 'Default Text', fontSize: 14, ... }
-
Handle in
addElement()if special rendering needed -
Update
generateCode()for HTML output
Custom Properties
Add custom properties by:
- Extending
updatePropertiesPanel() - Adding input fields for new properties
- Attaching listeners in
attachPropertyListeners()
Troubleshooting
Decorative Image Missing After Save
If a decorative image disappears when you reopen the layout, ensure you clicked Save Design after uploading the image. The editor persists decorative images by syncing the image URL to the design and template before save; if you leave before the save completes or before uploading an image, the placeholder may not be stored correctly. If the PDF preview shows a black or wrong area, the same fix applies: save the layout after assigning the image.
Element Not Appearing
- Check console for errors
- Verify element type in templates object
- Ensure layer.draw() is called
Properties Not Updating
- Verify event listeners are attached
- Check selectedElement is not null
- Ensure layer.draw() after changes
Preview Not Generating
- Check network tab for API errors
- Verify HTML/CSS generation
- Check backend template rendering
Performance Considerations
- Canvas is rendered at 595x842px (A4 size at 72dpi)
- Large designs with many elements remain performant
- Transformer handles are optimized for smooth interaction
- Properties panel updates use debouncing
Future Enhancements
Potential additions:
- Image upload for custom backgrounds
- Grid/snap to grid functionality
- Undo/redo history
- Templates/presets library
- Multi-page support
- Export to multiple formats