diff --git a/README.md b/README.md index 5a0086a..ae24f37 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,10 @@ There are many ways you can contribute even if you don't code: - [HomeBrew](https://brew.sh/) and `brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman` - If you have **xcode 10.0 or higher** installed, in order to build from source you need **NPM 6.4.1 or higher** `npm install -g npm@latest`. +3. Linux ARM CPU Installation Error + - If error has `node-pre-gyp WARN Pre-built binaries not installable for canvas@x.x.x and node@x.x.x` it means that there aren't any pre-built binaries for your system so it will try to compile them + - In order to do that you need `sudo apt-get update && sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev` + ## License [GNU Affero General Public License v3.0](license.txt) diff --git a/print_designer/hooks.py b/print_designer/hooks.py index 166f781..68e9d5e 100644 --- a/print_designer/hooks.py +++ b/print_designer/hooks.py @@ -11,7 +11,7 @@ # ------------------ # include js, css files in header of desk.html -app_include_js = "pdf.worker.bundle.js" +# app_include_js = "" # include js, css files in header of web template @@ -26,7 +26,10 @@ # webform_include_css = {"doctype": "public/css/doctype.css"} # include js in page -page_js = {"print": "print_designer/client_scripts/print.js"} +page_js = { + "print": "print_designer/client_scripts/print.js", + "point-of-sale": "print_designer/client_scripts/point_of_sale.js", +} # include js in doctype views doctype_js = {"Print Format": "print_designer/client_scripts/print_format.js"} @@ -84,6 +87,7 @@ pdf_body_html = "print_designer.pdf.pdf_body_html" pdf_footer_html = "print_designer.pdf.pdf_header_footer_html" +get_print_format_template = "print_designer.pdf.get_print_format_template" # Desk Notifications # ------------------ # See frappe.core.notifications.get_notification_config diff --git a/print_designer/patches.txt b/print_designer/patches.txt index 1869987..ffb6301 100644 --- a/print_designer/patches.txt +++ b/print_designer/patches.txt @@ -2,4 +2,7 @@ print_designer.patches.update_white_space_property print_designer.patches.introduce_barcode print_designer.patches.introduce_jinja print_designer.patches.introduce_schema_versioning -print_designer.patches.rerun_introduce_jinja \ No newline at end of file +print_designer.patches.rerun_introduce_jinja +print_designer.patches.introduce_table_alt_row_styles +print_designer.patches.introduce_column_style +print_designer.patches.introduce_suffix_dynamic_content \ No newline at end of file diff --git a/print_designer/patches/introduce_column_style.py b/print_designer/patches/introduce_column_style.py new file mode 100644 index 0000000..3d2b551 --- /dev/null +++ b/print_designer/patches/introduce_column_style.py @@ -0,0 +1,18 @@ +import frappe + +from print_designer.patches.patch_utils import patch_formats + + +def execute(): + """Modify Formats to work with New Column Style Feature""" + + def element_callback(el): + el["selectedColumn"] = None + for col in el["columns"]: + col["style"] = {} + col["applyStyleToHeader"] = False + + patch_formats( + {"element": element_callback}, + types=["table"], + ) diff --git a/print_designer/patches/introduce_suffix_dynamic_content.py b/print_designer/patches/introduce_suffix_dynamic_content.py new file mode 100644 index 0000000..07640f3 --- /dev/null +++ b/print_designer/patches/introduce_suffix_dynamic_content.py @@ -0,0 +1,17 @@ +import frappe + +from print_designer.patches.patch_utils import patch_formats + + +def execute(): + """Introduce suffix to dynamic content elements""" + + def dynamic_content_callback(el): + if not el.get("is_static", True): + if not "suffix" in el: + el["suffix"] = None + + patch_formats( + {"dynamic_content": dynamic_content_callback}, + types=["text", "table"], + ) diff --git a/print_designer/patches/introduce_table_alt_row_styles.py b/print_designer/patches/introduce_table_alt_row_styles.py new file mode 100644 index 0000000..2c22f78 --- /dev/null +++ b/print_designer/patches/introduce_table_alt_row_styles.py @@ -0,0 +1,30 @@ +import frappe + +from print_designer.patches.patch_utils import patch_formats + + +def execute(): + """Add altStyle object for alternate rows in table elements and in globalStyles of print formats that uses print designer""" + print_formats = frappe.get_all( + "Print Format", + filters={"print_designer": 1}, + fields=["name", "print_designer_settings"], + as_list=1, + ) + for pf in print_formats: + settings = frappe.parse_json(pf[1]) + if settings: + # If globalStyles is not present, skip + if not (gs := settings.get("globalStyles")): + continue + + gs["table"]["altStyle"] = {} + frappe.db.set_value("Print Format", pf[0], "print_designer_settings", frappe.as_json(settings)) + + def element_callback(el): + el["altStyle"] = {} + + patch_formats( + {"element": element_callback}, + types=["table"], + ) diff --git a/print_designer/pdf.py b/print_designer/pdf.py index 7b58a7d..f10684f 100644 --- a/print_designer/pdf.py +++ b/print_designer/pdf.py @@ -1,25 +1,36 @@ +import hashlib +import html import json import frappe +from frappe.monitor import add_data_to_monitor +from frappe.utils.error import log_error from frappe.utils.jinja_globals import is_rtl def pdf_header_footer_html(soup, head, content, styles, html_id, css): if soup.find(id="__print_designer"): - return frappe.render_template( - "print_designer/page/print_designer/jinja/header_footer.html", - { - "head": head, - "content": content, - "styles": styles, - "html_id": html_id, - "css": css, - "headerFonts": soup.find(id="headerFontsLinkTag"), - "footerFonts": soup.find(id="footerFontsLinkTag"), - "lang": frappe.local.lang, - "layout_direction": "rtl" if is_rtl() else "ltr", - }, - ) + try: + return frappe.render_template( + "print_designer/page/print_designer/jinja/header_footer.html", + { + "head": head, + "content": content, + "styles": styles, + "html_id": html_id, + "css": css, + "headerFonts": soup.find(id="headerFontsLinkTag"), + "footerFonts": soup.find(id="footerFontsLinkTag"), + "lang": frappe.local.lang, + "layout_direction": "rtl" if is_rtl() else "ltr", + }, + ) + except Exception as e: + error = log_error(title=e, reference_doctype="Print Format") + frappe.throw( + msg=f"Something went wrong ( Error ) : If you don't know what just happened, and wish to file a ticket or issue on github, please copy the error from Error Log {error.name} or ask Administrator.", + exc=e, + ) else: from frappe.utils.pdf import pdf_footer_html, pdf_header_html @@ -35,7 +46,11 @@ def pdf_header_footer_html(soup, head, content, styles, html_id, css): def pdf_body_html(print_format, jenv, args, template): if print_format and print_format.print_designer and print_format.print_designer_body: - template = jenv.loader.get_source(jenv, "print_designer/page/print_designer/jinja/main.html")[0] + print_format_name = hashlib.md5(print_format.name.encode(), usedforsecurity=False).hexdigest() + add_data_to_monitor(print_designer=print_format_name, print_designer_action="download_pdf") + # DEPRECATED: remove this in few months added for backward compatibility incase user didn't update frappe framework. + if not frappe.get_hooks("get_print_format_template"): + template = jenv.loader.get_source(jenv, "print_designer/page/print_designer/jinja/main.html")[0] args.update( { "headerElement": json.loads(print_format.print_designer_header), @@ -49,5 +64,21 @@ def pdf_body_html(print_format, jenv, args, template): template_source = template.replace( "", args["settings"].get("userProvidedJinja", "") ) - template = jenv.from_string(template_source) + try: + template = jenv.from_string(template_source) + return template.render(args, filters={"len": len}) + + except Exception as e: + error = log_error(title=e, reference_doctype="Print Format", reference_name=print_format.name) + if frappe.conf.developer_mode: + return f"
Error Log {error.name}
or ask Administrator.{html.escape(error.error)}" + else: + return f"
Error Log {error.name}
or ask Administrator.{% if element.parseJinja %} @@ -18,9 +18,9 @@ {% endif %} {% endmacro %} {% macro render_dynamictext(element, send_to_jinja) -%} -
{
let width = MainStore.currentDrawListener.parameters.width;
let columns = Math.floor(width / 100);
let elementColumns = MainStore.lastCreatedElement.columns;
- !elementColumns.length && elementColumns.push({ id: 0, label: "" });
+ !elementColumns.length &&
+ elementColumns.push({ id: 0, label: "", style: {}, applyStyleToHeader: false });
if (width > 100) {
let columnDif = columns - elementColumns.length;
if (columnDif == 0) {
@@ -187,6 +188,8 @@ const handleMouseMove = (e) => {
elementColumns.push({
id: elementColumns.length,
label: "",
+ style: {},
+ applyStyleToHeader: false,
});
}
}
@@ -229,6 +232,9 @@ const handleMouseUp = (e) => {
}
if (MainStore.activeControl == "table") {
MainStore.setActiveControl("MousePointer");
+ if (MainStore.frappeControls.table?.get_value() == "") {
+ MainStore.frappeControls.table.set_focus();
+ }
}
} else {
MainStore.currentDrawListener?.drawEventHandler.mouseup(e);
@@ -430,6 +436,23 @@ onMounted(() => {
{ deep: true, immediate: true }
);
}
+ if (element[1].altStyle) {
+ watch(
+ () => MainStore.globalStyles[element[0]].altStyle,
+ () => {
+ if (MainStore.screenStyleSheet && element[1].altCssRule) {
+ Object.entries(
+ MainStore.globalStyles[element[0]].altStyle
+ ).forEach((style) => {
+ if (element[1].altCssRule.style[style[0]] != style[1]) {
+ element[1].altCssRule.style[style[0]] = style[1];
+ }
+ });
+ }
+ },
+ { deep: true, immediate: true }
+ );
+ }
});
}
}
diff --git a/print_designer/public/js/print_designer/components/layout/AppDynamicPreviewModal.vue b/print_designer/public/js/print_designer/components/layout/AppDynamicPreviewModal.vue
index f16e6a0..403c292 100644
--- a/print_designer/public/js/print_designer/components/layout/AppDynamicPreviewModal.vue
+++ b/print_designer/public/js/print_designer/components/layout/AppDynamicPreviewModal.vue
@@ -42,21 +42,16 @@
:contenteditable="contenteditable"
:class="['label-text', selectedEl?.field == field && 'label-text-selected']"
:ref="(el) => (field.labelRef = el)"
- @dblclick="handleDblClick($event, field)"
+ @dblclick="handleDblClick($event, field, 'label')"
@blur="handleBlur($event, field)"
- v-html="
- `${field.label}` ||
- `{{ ${field.parentField ? field.parentField + '.' : ''}${
- field.fieldname
- } }}`
- "
+ v-html="field.label || 'Add Label'"
>
+
@@ -95,6 +99,22 @@ >{{ selectedEl.field.is_labelled ? "Remove Label" : "Add Label" }} +
+
+ {{ selectedEl.field.suffix ? "Remove Suffix" : "Add Suffix" }}
+
|