Wires the new /consolidated_printview backend route into the List View
bulk-actions menu so users can print selected records as one continuous
layout without page breaks between them.
- BulkOperations.consolidated_print() validates docs against the same
draft/cancelled print-settings rules as the existing print(), enforces
a 100-document limit, and opens a dialog to pick Letter Head and Print
Format before launching the consolidated print window
- bulk_consolidated_printing() action added to list_view.js and
registered immediately after the existing "Print" entry, gated by the
same frappe.model.can_print() permission check
Made-with: Cursor
Adds a new WWW page at /consolidated_printview that renders multiple
documents of the same DocType in a single continuous HTML layout with
no forced page breaks between records.
- get_context() iterates over a JSON list of names, renders each doc
via the existing get_rendered_template() pipeline (falls back to
WeasyPrint for beta print-format-builder formats), and joins the
results with a thin visual separator
- Per-document page-break-after is suppressed via CSS override so all
records flow as one uninterrupted printable page
- trigger_print=1 fires window.print() automatically, matching the
behaviour of the existing single-doc /printview route
- Permission and render errors are caught per-document and logged so
one bad record does not abort the whole batch
- Access log entry recorded for auditing (first 10 doc names)
Made-with: Cursor
* fix: allow dangerous HTML in link exists exception
* fix: Allow `a` tags
* Revert "fix: allow dangerous HTML in link exists exception"
This reverts commit 9a37f5092ed6c27ff6a0c427df6494561e971ac3.
---------
Co-authored-by: Ankush Menat <ankush@frappe.io>
[setup_main_sidebar_toggle()](cci:1://file:///workspace/development/frappe-bench/apps/frappe/frappe/public/js/frappe/ui/page.js:243:1-249:2) uses a global jQuery selector to bind
click handlers to `.sidebar-toggle-btn.navbar-brand`, but is called
from each Page constructor. Since Pages from different view factories
(Workspaces, Form, List, etc.) coexist in the DOM, each new Page
creation adds duplicate handlers to all existing hamburger buttons.
When a button accumulates an even number of handlers, [toggle_width()](cci:1://file:///workspace/development/frappe-bench/apps/frappe/frappe/public/js/frappe/ui/sidebar/sidebar_header.js:337:1-348:2)
fires an even number of times — open() and close() cancel each other
out, and the sidebar drawer appears unresponsive.
Scope the selector to `this.wrapper.find()` so each Page only binds
to its own hamburger button.