Skip to content

Commit

Permalink
feat: Multi Page and Multi Header/Footer 🎉 (#278)
Browse files Browse the repository at this point in the history
  • Loading branch information
maharshivpatel authored Jun 11, 2024
2 parents d4c18f8 + f3cada7 commit d598553
Show file tree
Hide file tree
Showing 29 changed files with 1,715 additions and 974 deletions.
1 change: 1 addition & 0 deletions print_designer/patches.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ print_designer.patches.introduce_dynamic_height
print_designer.patches.remove_unused_rectangle_gs_properties
print_designer.patches.change_dynamic_height_variable
print_designer.patches.introduce_z_index
print_designer.patches.move_header_footers_to_new_schema
96 changes: 96 additions & 0 deletions print_designer/patches/move_header_footers_to_new_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import frappe

from print_designer.pdf import is_older_schema


def patch_format():
print_formats = frappe.get_all(
"Print Format",
filters={"print_designer": 1},
fields=[
"name",
"print_designer_header",
"print_designer_body",
"print_designer_after_table",
"print_designer_footer",
"print_designer_print_format",
"print_designer_settings",
],
)
for pf in print_formats:
settings = frappe.json.loads(pf.print_designer_settings or "{}")

header_childrens = frappe.json.loads(pf.print_designer_header or "[]")
header_data = [
{
"type": "page",
"childrens": header_childrens,
"firstPage": True,
"oddPage": True,
"evenPage": True,
"lastPage": True,
}
]

footer_childrens = frappe.json.loads(pf.print_designer_footer or "[]")
footer_data = [
{
"type": "page",
"childrens": footer_childrens,
"firstPage": True,
"oddPage": True,
"evenPage": True,
"lastPage": True,
}
]
for child in footer_childrens:
child["startY"] -= (
settings["page"].get("height", 0)
- settings["page"].get("marginTop", 0)
- settings["page"].get("footerHeight", 0)
)

childrens = frappe.json.loads(pf.print_designer_body or "[]")
bodyPage = [
{
"index": 0,
"type": "page",
"childrens": childrens,
"isDropZone": True,
}
]
object_to_save = {
"print_designer_header": frappe.json.dumps(header_data),
"print_designer_body": frappe.json.dumps(bodyPage),
"print_designer_footer": frappe.json.dumps(footer_data),
"print_designer_settings": frappe.json.dumps(settings),
}
if not is_older_schema(settings=settings, current_version="1.1.0"):
pf_print_format = frappe.json.loads(pf.print_designer_print_format)
if "header" in pf_print_format:
pf_print_format["header"] = {
"firstPage": pf_print_format["header"],
"oddPage": pf_print_format["header"],
"evenPage": pf_print_format["header"],
"lastPage": pf_print_format["header"],
}
if "footer" in pf_print_format:
pf_print_format["footer"] = {
"firstPage": pf_print_format["footer"],
"oddPage": pf_print_format["footer"],
"evenPage": pf_print_format["footer"],
"lastPage": pf_print_format["footer"],
}
object_to_save["print_designer_print_format"] = frappe.json.dumps(pf_print_format)

frappe.set_value(
"Print Format",
pf.name,
object_to_save,
)
return print_formats


def execute():
"""Updating Table and Dynamic Text Elements to have property isDynamicHeight with default value as True"""
patch_format()
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,70 @@
y[j].textContent = vars[x[i]];
}
}
}

const headers = {
firstPage : document.getElementById("firstPageHeader"),
oddPage : document.getElementById("oddPageHeader"),
evenPage : document.getElementById("evenPageHeader"),
lastPage : document.getElementById("lastPageHeader"),
}
const footers = {
firstPage : document.getElementById("firstPageFooter"),
oddPage : document.getElementById("oddPageFooter"),
evenPage : document.getElementById("evenPageFooter"),
lastPage : document.getElementById("lastPageFooter"),
}
function displayHeaderFooter(elements, selectedElements) {
for (var key in elements) {
if (elements[key]) {
if (elements[key] === selectedElements) {
elements[key].style.display = "block";
} else {
elements[key].style.display = "none";
}
}
}
}
var page_no = parseInt(vars["page"]);
var total_page_no = parseInt(vars["topage"]);
if (page_no == 1) {
if (headers.firstPage) {
displayHeaderFooter(headers, headers.firstPage);
} else {
displayHeaderFooter(headers, headers.oddPage);
}
if (footers.firstPage) {
displayHeaderFooter(footers, footers.firstPage);
} else {
displayHeaderFooter(footers, footers.oddPage);
}
} else if (page_no == total_page_no) {
if (headers.lastPage) {
displayHeaderFooter(headers, headers.lastPage);
} else {
if (total_page_no % 2 == 0) {
displayHeaderFooter(headers, headers.evenPage);
} else {
displayHeaderFooter(headers, headers.oddPage);
}
}
if (footers.lastPage) {
displayHeaderFooter(footers, footers.lastPage);
} else {
if (total_page_no % 2 == 0) {
displayHeaderFooter(footers, footers.evenPage);
} else {
displayHeaderFooter(footers, footers.oddPage);
}
}
} else if (page_no % 2 == 0) {
displayHeaderFooter(headers, headers.evenPage);
displayHeaderFooter(footers, footers.evenPage);
} else {
displayHeaderFooter(headers, headers.oddPage);
displayHeaderFooter(footers, footers.oddPage);
}
}
</script>

{% for tag in styles -%}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{% macro rectangle(element, render_element, send_to_jinja, heightType) -%}
{%- set heightType = element.get("heightType") -%}
{%- if settings.get("schema_version") == "1.1.0" -%}
{%- if settings.get("schema_version") == "1.1.0" or heightType == None -%}
{%- set heightType = "auto" if element.get("isDynamicHeight", False) else "fixed" -%}
{%- endif -%}
<div id="{{ element.id }}" style="position:{%- if heightType != 'fixed' -%}relative{% else %}absolute{%- endif -%}; {%- if heightType == 'fixed' -%}top: {%- else -%}margin-top: {%- endif -%}{{ element.startY }}px; left:{{ element.startX }}px; width:{{ element.width }}px; {%- if heightType != 'auto' -%} {%- if heightType == 'auto-min-height' -%}min-{%- endif -%}height:{{ element.height }}px; {%- endif -%} {{convert_css(element.style)}}"
<div id="{{ element.id }}" style="position:{%- if heightType and heightType != 'fixed' -%}relative{% else %}absolute{%- endif -%}; {%- if heightType == 'fixed' -%}top: {%- else -%}margin-top: {%- endif -%}{{ element.startY }}px; left:{{ element.startX }}px; width:{{ element.width }}px; {%- if heightType != 'auto' -%} {%- if heightType == 'auto-min-height' -%}min-{%- endif -%}height:{{ element.height }}px; {%- endif -%} {{convert_css(element.style)}}"
class="rectangle {{ element.classes | join(' ') }}">
{% if element.childrens %}
{% for object in element.childrens %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
{{ _(field.label) }}
</span>
{% endif %}
<span class="dynamic-span {% if not field.is_static and field.is_labelled %}valueSpanTag{%endif%} {{page_class(field)}} }}"
<span class="dynamic-span {% if not field.is_static and field.is_labelled %}valueSpanTag{%endif%} {{page_class(field)}}"
style="{%- if element.style.get('color') -%}{{ convert_css({'color': element.style.get('color')})}}{%- endif -%} {{convert_css(field.style)}} user-select:auto;">
{{ span_value }}
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@
<!-- user_generated_jinja_code -->
<!-- end of user generated code -->

{% set renderHeader = render_element(headerElement, send_to_jinja) %}
{% set renderBody = render_element(bodyElement, send_to_jinja) %}
{% set renderFooter = render_element(footerElement, send_to_jinja) %}
{% set renderHeader = render_element(headerElement[0].childrens, send_to_jinja) %}
{% set renderBody = render_element(bodyElement[0].childrens, send_to_jinja) %}
{% set renderFooter = render_element(footerElement[0].childrens, send_to_jinja) %}
<link rel="preconnect" href="https://fonts.gstatic.com" />
{% if settings.printHeaderFonts %}
{% set printHeaderFonts = getFontStyles(settings.printHeaderFonts) %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,26 @@

<div id="__print_designer">
<div id="header-html">
<div style="position: relative; top:0px; left: 0px; width: 100%; height:{{ settings.page.headerHeightWithMargin }}px;">
<div style="position: relative; top:0px; left: 0px; width: 100%; height:{{ settings.page.headerHeightWithMargin }}px; overflow: hidden;" id="header-render-container">
<div class="visible-pdf" style="height: {{ settings.page.marginTop }}px;"></div>
<div class="hidden-pdf printview-header-margin" style="height: {{ settings.page.marginTop }}px;"></div>
{% if headerElement %}{{ render(pd_format.header, send_to_jinja) }}{%endif%}
<div class="hidden-pdf">{% if pd_format.header.firstPage %}{{ render(pd_format.header.firstPage, send_to_jinja) }}{%endif%}</div>
<div id="firstPageHeader" style="display: none;">{% if pd_format.header.firstPage %}{{ render(pd_format.header.firstPage, send_to_jinja) }}{%endif%}</div>
<div id="oddPageHeader" style="display: none;">{% if pd_format.header.oddPage %}{{ render(pd_format.header.oddPage, send_to_jinja) }}{%endif%}</div>
<div id="evenPageHeader" style="display: none;">{% if pd_format.header.evenPage %}{{ render(pd_format.header.evenPage, send_to_jinja) }}{%endif%}</div>
<div id="lastPageHeader" style="display: none;">{% if pd_format.header.lastPage %}{{ render(pd_format.header.lastPage, send_to_jinja) }}{%endif%}</div>
</div>
</div>
{% if bodyElement %}{{ render(pd_format.body, send_to_jinja) }}{%endif%}
{%- for body in pd_format.body -%}
{{ render(body.childrens, send_to_jinja) }}
{%- endfor -%}
<div id="footer-html">
<div style="width: 100%; position: relative; top:0px; left: 0px; height:{{ settings.page.footerHeightWithMargin }}px;">
{% if footerElement %}{{ render(pd_format.footer, send_to_jinja) }}{%endif%}
<div class="hidden-pdf">{% if pd_format.footer.firstPage %}{{ render(pd_format.footer.firstPage, send_to_jinja) }}{%endif%}</div>
<div id="firstPageFooter" style="display: none;">{% if pd_format.footer.firstPage %}{{ render(pd_format.footer.firstPage, send_to_jinja) }}{%endif%}</div>
<div id="oddPageFooter" style="display: none;">{% if pd_format.footer.oddPage %}{{ render(pd_format.footer.oddPage, send_to_jinja) }}{%endif%}</div>
<div id="evenPageFooter" style="display: none;">{% if pd_format.footer.evenPage %}{{ render(pd_format.footer.evenPage, send_to_jinja) }}{%endif%}</div>
<div id="lastPageFooter" style="display: none;">{% if pd_format.footer.lastPage %}{{ render(pd_format.footer.lastPage, send_to_jinja) }}{%endif%}</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,37 @@ const printDesignerDialog = () => {
name: print_format_name,
doc_type: doctype,
print_designer: 1,
print_designer_header: JSON.stringify([
{
type: "page",
childrens: [],
firstPage: true,
oddPage: true,
evenPage: true,
lastPage: true,
DOMRef: null,
},
]),
print_designer_body: JSON.stringify([
{
type: "page",
index: 0,
DOMRef: null,
isDropZone: true,
childrens: [],
},
]),
print_designer_footer: JSON.stringify([
{
type: "page",
childrens: [],
firstPage: true,
oddPage: true,
evenPage: true,
lastPage: true,
DOMRef: null,
},
]),
})
.then((doc) => {
// Incase Route is Same, set_route() is needed to refresh.
Expand Down
Loading

0 comments on commit d598553

Please sign in to comment.