Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: recursive dynamic containers #224

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions print_designer/patches.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ print_designer.patches.introduce_dynamic_containers
print_designer.patches.introduce_dynamic_height
print_designer.patches.remove_unused_rectangle_gs_properties
execute:from print_designer.patches.create_custom_fields import custom_field_patch; custom_field_patch()
print_designer.patches.change_dynamic_height_variable
24 changes: 24 additions & 0 deletions print_designer/patches/change_dynamic_height_variable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import frappe

from print_designer.patches.patch_utils import patch_formats


def execute():
"""changing isDynamicHeight property to heightType property in text and table elements"""

def element_callback(el):
if el.get("type") == "text" and not (el.get("isDynamic") or el.get("parseJinja")):
return

if not "isDynamicHeight" in el:
el["isDynamicHeight"] = False

if el["isDynamicHeight"]:
el["heightType"] = "auto"
else:
el["heightType"] = "fixed"

patch_formats(
{"element": element_callback},
types=["text", "table"],
)
21 changes: 19 additions & 2 deletions print_designer/patches/patch_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import frappe

from print_designer.pdf import is_older_schema

"""
Example Callback Functions used to Demonstrate Data Structure.
Example functions are just printing the values of the object passed to them.
Expand Down Expand Up @@ -71,6 +73,7 @@ def dynamic_content_style(style):
def patch_formats(
callbacks: Union[Callable[[Dict], None], Dict[str, Callable[[Dict], None]]],
types: Optional[List[str]] = None,
update_print_json: bool = False,
save: bool = True,
) -> None:
"""
Expand All @@ -81,7 +84,7 @@ def patch_formats(
`element, dynamic_content, style, dynamic_content_style` each with a function as its value.
Each callback function should take a dictionary as an argument and can modify it and return nothing.
The dictionary passed to the callback function represents a element or style object.

:param update_print_json: If True, the function will update the generated print format json that is used by jinja template.
:param types: A list of print format types to which the callback function should be applied.
If not provided, it defaults to ["text", "image", "barcode", "rectangle", "table"].
"""
Expand All @@ -98,10 +101,23 @@ def patch_formats(
"print_designer_body",
"print_designer_after_table",
"print_designer_footer",
"print_designer_print_format",
"print_designer_settings",
],
as_list=1,
)
for pf in print_formats:
if update_print_json:
for pf in print_formats:
# print_designer_print_format was introduced in schema version 1.1.0 so running this on older version is not required
if not is_older_schema(settings=frappe.json.loads(pf[6] or "{}"), current_version="1.1.0"):
print_json = frappe.json.loads(pf[5] or "{}")
if print_json.get("header", None):
print_json["header"] = patch_elements(print_json["header"], callbacks, types)
if print_json.get("body", None):
print_json["body"] = patch_elements(print_json["body"], callbacks, types)
if print_json.get("footer", None):
print_json["footer"] = patch_elements(print_json["footer"], callbacks, types)

updated_doc = frappe.get_doc("Print Format", pf[0]).update(
{
"print_designer_header": frappe.json.dumps(
Expand All @@ -116,6 +132,7 @@ def patch_formats(
"print_designer_footer": frappe.json.dumps(
patch_elements(frappe.json.loads(pf[4] or "[]"), callbacks, types)
),
"print_designer_print_format": frappe.json.dumps(print_json),
}
)
if save:
Expand Down
2 changes: 1 addition & 1 deletion print_designer/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def pdf_body_html(print_format, jenv, args, template):


def is_older_schema(settings, current_version):
format_version = settings.get("schema_version")
format_version = settings.get("schema_version", "1.0.0")
format_version = format_version.split(".")
current_version = current_version.split(".")
if int(format_version[0]) < int(current_version[0]):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% from 'print_designer/page/print_designer/jinja/macros/spantag.html' import span_tag with context %}

{% macro dynamictext(element, send_to_jinja, is_parent_dynamic_height) -%}
<div style="position:{%- if is_parent_dynamic_height -%}relative{% else %}absolute{%- endif -%}; {%- if not is_parent_dynamic_height -%}top: {%- else -%}margin-top: {%- endif -%}{{ element.startY }}px; left:{{ element.startX }}px;{% if element.isFixedSize %}width:{{ element.width }}px; {%- if not is_parent_dynamic_height -%}height:{{ element.height }}px; {%- endif -%} {% else %} width:fit-content; height:fit-content; white-space:nowrap; max-width: {{ (settings.page.width - settings.page.marginLeft - settings.page.marginRight - element.startX) + 2 }}px;{%endif%}" class="
<div style="position:{%- if is_parent_dynamic_height != 'fixed' -%}relative{% else %}absolute{%- endif -%}; {%- if is_parent_dynamic_height == 'fixed' -%}top: {%- else -%}margin-top: {%- endif -%}{{ element.startY }}px; left:{{ element.startX }}px;{% if element.isFixedSize %}width:{{ element.width }}px; {%- if is_parent_dynamic_height == 'fixed' -%}height:{{ element.height }}px; {%- endif -%} {% else %} width:fit-content; height:fit-content; white-space:nowrap; max-width: {{ (settings.page.width - settings.page.marginLeft - settings.page.marginRight - element.startX) + 2 }}px;{%endif%}" class="
{{ element.classes | join(' ') }}">
<div style="{% if element.isFixedSize %}width:{{ element.width }}px; {%- if not is_parent_dynamic_height -%}height:{{ element.height }}px; {%- endif -%}{% else %}width:fit-content; height:fit-content; white-space:nowrap; max-width: {{ (settings.page.width - settings.page.marginLeft - settings.page.marginRight - element.startX) + 2 }}px;{%endif%} {{convert_css(element.style)}}"
class="dynamicText {{ element.classes | join(' ') }}">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
{% macro rectangle(element, render_element, send_to_jinja) -%}
<div id="{{ element.id }}" style="position:absolute; top:{{ element.startY }}px; left:{{ element.startX }}px; width:{{ element.width }}px; height:{{ element.height }}px; {{convert_css(element.style)}}"
{% macro rectangle(element, render_element, send_to_jinja, is_parent_dynamic_height) -%}
{%- set heightType = element.get("heightType") -%}
{%- if settings.get("schema_version") == "1.1.0" -%}
{%- set heightType = "auto" if element.get("isDynamicHeight", False) else "fixed" -%}
{%- endif -%}
<div id="{{ element.id }}" style="position:{%- if is_parent_dynamic_height != 'fixed' -%}relative{% else %}absolute{%- endif -%}; {%- if is_parent_dynamic_height == '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 %}
{{ render_element(object, send_to_jinja) }}
{{ render_element(object, send_to_jinja, is_parent_dynamic_height) }}
{% endfor %}
{% endif %}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
{% from 'print_designer/page/print_designer/jinja/macros/render_element.html' import render_element with context %}

{% macro relative_columns(element, send_to_jinja) -%}
<div style="position:relative; top: 0px; width:{{ element.width }}px; {%- if not element.isDynamicHeight -%} height:{{ element.height }}px; {%- endif -%} {{convert_css(element.style)}}"
{%- set heightType = element.get("heightType") -%}
{%- if settings.get("schema_version") == "1.1.0" -%}
{%- set heightType = "auto" if element.get("isDynamicHeight", False) else "fixed" -%}
{%- endif -%}
<div style="position:relative; top: 0px; {%- if element.rectangleContainer -%}margin-top:{{element.startY}}px; margin-left:{{element.startX}}px;{%- endif -%} 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 %}
{{ render_element(object, send_to_jinja, element.get("isDynamicHeight", false)) }}
{%- if object.layoutType == "row" -%}
{{ relative_containers(object, send_to_jinja) }}
{%- elif object.layoutType == "column" -%}
{{ relative_columns(object, send_to_jinja) }}
{%- else -%}
{{ render_element(object, send_to_jinja, heightType) }}
{%- endif -%}
{% endfor %}
{% endif %}
</div>
{%- endmacro %}

{% macro relative_containers(element, send_to_jinja) -%}
<div style="position:relative; left:{{ element.startX }}px; {%- if not element.isDynamicHeight -%} height:{{ element.height }}px; {%- endif -%} {{convert_css(element.style)}}"
{%- set heightType = element.get("heightType") -%}
{%- if settings.get("schema_version") == "1.1.0" -%}
{%- set heightType = "auto" if element.get("isDynamicHeight", False) else "fixed" -%}
{%- endif -%}
<div style="position:relative; left:{{ element.startX }}px; {%- if heightType != 'auto' -%}{%- if heightType == 'auto-min-height' -%}min-{%- endif -%}height:{{ element.height }}px; {%- endif -%} {{convert_css(element.style)}}"
class="rectangle relative-row {{ element.classes | join(' ') }}">
{% if element.childrens %}
{% for object in element.childrens %}
{{ relative_columns(object, send_to_jinja) }}
{%- if object.layoutType == "column" -%}
{{ relative_columns(object, send_to_jinja) }}
{%- elif object.layoutType == "row" -%}
{{ relative_containers(object, send_to_jinja) }}
{%- else -%}
{{ render_element(object, send_to_jinja, heightType) }}
{%- endif -%}
{% endfor %}
{% endif %}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
{% from 'print_designer/page/print_designer/jinja/macros/table.html' import table with context %}


{% macro render_element(element, send_to_jinja, is_parent_dynamic_height = false) -%}
{% macro render_element(element, send_to_jinja, is_parent_dynamic_height = 'fixed') -%}
{% if element.type == "rectangle" %}
{{ rectangle(element, render_element, send_to_jinja) }}
{{ rectangle(element, render_element, send_to_jinja, is_parent_dynamic_height) }}
{% elif element.type == "image" %}
{{image(element)}}
{% elif element.type == "table" %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<!-- third Arg in render_user_text is row which is not sent outside table -->
{% macro statictext(element, send_to_jinja, dynamic_containers) -%}
<div style="position:{%- if dynamic_containers -%}relative{% else %}absolute{%- endif -%}; top:{{ element.startY }}px; left:{{ element.startX }}px;{% if element.isFixedSize %}width:{{ element.width }}px;{%- if not is_parent_dynamic_height -%}height:{{ element.height }}px; {%- endif -%}{% else %}width:fit-content; height:fit-content; max-width: {{ (settings.page.width - settings.page.marginLeft - settings.page.marginRight - element.startX) + 2 }}px; white-space:nowrap; {%endif%}" class="
{% macro statictext(element, send_to_jinja, is_parent_dynamic_height) -%}
<div style="position:{%- if is_parent_dynamic_height != 'fixed' -%}relative{% else %}absolute{%- endif -%}; {%- if is_parent_dynamic_height == 'fixed' -%}top: {%- else -%}margin-top: {%- endif -%}{{ element.startY }}px; left:{{ element.startX }}px;{% if element.isFixedSize %}width:{{ element.width }}px;{%- if is_parent_dynamic_height == 'fixed' -%}height:{{ element.height }}px; {%- endif -%}{% else %}width:fit-content; height:fit-content; max-width: {{ (settings.page.width - settings.page.marginLeft - settings.page.marginRight - element.startX) + 2 }}px; white-space:nowrap; {%endif%}" class="
{{ element.classes | join(' ') }}">
<p style="{% if element.isFixedSize %}width:{{ element.width }}px; {%- if not is_parent_dynamic_height -%}height:{{ element.height }}px; {%- endif -%}{% else %}width:fit-content; height:fit-content; max-width: {{ (settings.page.width - settings.page.marginLeft - settings.page.marginRight - element.startX ) + 2 }}px; white-space:nowrap;{%endif%} {{convert_css(element.style)}}"
<p style="{% if element.isFixedSize %}width:{{ element.width }}px; {%- if is_parent_dynamic_height == 'fixed' -%}height:{{ element.height }}px; {%- endif -%}{% else %}width:fit-content; height:fit-content; max-width: {{ (settings.page.width - settings.page.marginLeft - settings.page.marginRight - element.startX ) + 2 }}px; white-space:nowrap;{%endif%} {{convert_css(element.style)}}"
class="staticText {{ element.classes | join(' ') }}">
{% if element.parseJinja %}
{{ render_user_text(element.content, doc, {}, send_to_jinja).get("message", "") }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@
border-width: 0 !important;
}
.relative-column {
border-width: 1px !important;
border-color: white !important;
border-width: 0px !important;
border-color: transparent !important;
}
* {
-webkit-box-sizing: border-box;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{% macro table(element, send_to_jinja, is_parent_dynamic_height) -%}
<table style="position:{%- if is_parent_dynamic_height -%}relative{% else %}absolute{%- endif -%}; {%- if not is_parent_dynamic_height -%}top: {%- else -%}margin-top: {%- endif -%}{{ element.startY }}px; left:{{ element.startX }}px; width:{{ element.width }}px;{%- if is_parent_dynamic_height and not element.isDynamicHeight -%} height:{{ element.height }}px; {%- endif -%} max-width:{{ element.width }}px;" class="table-container printTable {{ element.classes | join(' ') }}">
{%- set heightType = element.get("heightType") -%}
{%- if settings.get("schema_version") == "1.1.0" -%}
{%- set heightType = "auto" if element.get("isDynamicHeight", False) else "fixed" -%}
{%- endif -%}
<table style="position:{%- if is_parent_dynamic_height != 'fixed' -%}relative{% else %}absolute{%- endif -%}; {%- if is_parent_dynamic_height == 'fixed' -%}top: {%- else -%}margin-top: {%- endif -%}{{ element.startY }}px; left:{{ element.startX }}px; width:{{ element.width }}px;{%- if is_parent_dynamic_height != 'fixed' and heightType != 'auto' -%}{%- if heightType == 'auto-min-height' -%}min-{%- endif -%}height:{{ element.height }}px;{%- endif -%} max-width:{{ element.width }}px;" class="table-container printTable {{ element.classes | join(' ') }}">
<thead>
{% if element.columns %}
<tr>
Expand Down
22 changes: 6 additions & 16 deletions print_designer/public/js/print_designer/PropertiesPanelState.js
Original file line number Diff line number Diff line change
Expand Up @@ -437,15 +437,15 @@ export const createPropertiesPanel = () => {
[
{
label: "Height",
name: "isDynamicHeight",
name: "heightType",
isLabelled: true,
labelDirection: "column",
condtional: () => {
const currentEl = MainStore.getCurrentElementsValues[0];
if (
(currentEl.parent === ElementStore.Elements &&
currentEl?.type === "table") ||
(currentEl.type === "text" && currentEl.isDynamic)
currentEl?.type === "table" ||
(currentEl.type === "text" &&
(currentEl.isDynamic || currentEl.parseJinja))
) {
return true;
}
Expand All @@ -459,23 +459,13 @@ export const createPropertiesPanel = () => {
fieldtype: "Select",
requiredData: [MainStore.getCurrentElementsValues[0]],
reactiveObject: () => MainStore.getCurrentElementsValues[0],
propertyName: "isDynamicHeight",
propertyName: "heightType",
isStyle: false,
options: () => [
{ label: "Auto", value: "auto" },
{ label: "Auto ( min-height)", value: "auto-min-height" },
{ label: "Fixed", value: "fixed" },
],
formatValue: (object, property, isStyle) => {
if (!object) return;
return object[property] ? "auto" : "fixed";
},
onChangeCallback: (value = null) => {
if (value && MainStore.getCurrentElementsValues[0]) {
MainStore.getCurrentElementsValues[0]["isDynamicHeight"] =
value === "auto";
MainStore.frappeControls[name].$input.blur();
}
},
});
},
flex: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ const {
selectedColumn,
selectedDynamicText,
DOMRef,
isDynamicHeight,
} = toRefs(props.object);

watch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -639,11 +639,12 @@ watch(
background-color: transparent !important;
border: none !important;
z-index: 9999 !important;
outline: 1px double var(--primary) !important;
}
.relative-column {
background-color: transparent !important;
outline: 1px double var(--primary) !important;
border: none !important;
z-index: 9999 !important;
outline: 1px solid var(--primary) !important;
}
</style>
4 changes: 2 additions & 2 deletions print_designer/public/js/print_designer/defaultObjects.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export const createTable = (cordinates, parent = null) => {
labelStyle: {},
headerStyle: {},
altStyle: {},
isDynamicHeight: true,
heightType: "auto",
classes: [],
};

Expand Down Expand Up @@ -259,7 +259,7 @@ export const createDynamicText = (cordinates, parent = null) => {
labelDisplayStyle: "standard",
style: {},
labelStyle: {},
isDynamicHeight: true,
heightType: "auto",
classes: [],
};
parent !== ElementStore.Elements
Expand Down
Loading
Loading