@@ -0,0 +1,107 @@ | |||||
<template> | |||||
<div class="h-100"> | |||||
<div class="row"> | |||||
<div class="col"> | |||||
<div ref="doc-select"></div> | |||||
</div> | |||||
<div class="col"> | |||||
<div ref="preview-type"></div> | |||||
</div> | |||||
<div class="col d-flex"> | |||||
<a v-if="url" class="btn btn-default btn-sm btn-new-tab" target="_blank" :href="url"> | |||||
{{ __("Open in a new tab") }} | |||||
</a> | |||||
</div> | |||||
</div> | |||||
<div v-if="url && !preview_loaded">Generating preview...</div> | |||||
<iframe | |||||
:src="url" | |||||
v-if="url" | |||||
v-show="preview_loaded" | |||||
class="preview-iframe" | |||||
@load="preview_loaded = true" | |||||
></iframe> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { storeMixin } from "./store"; | |||||
export default { | |||||
name: "Preview", | |||||
mixins: [storeMixin], | |||||
data() { | |||||
return { | |||||
type: "PDF", | |||||
docname: null, | |||||
preview_loaded: false | |||||
}; | |||||
}, | |||||
mounted() { | |||||
this.doc_select = frappe.ui.form.make_control({ | |||||
parent: this.$refs["doc-select"], | |||||
df: { | |||||
label: __("Select {0}", [__(this.doctype)]), | |||||
fieldname: "docname", | |||||
fieldtype: "Link", | |||||
options: this.doctype, | |||||
change: () => { | |||||
this.docname = this.doc_select.get_value(); | |||||
} | |||||
}, | |||||
render_input: true | |||||
}); | |||||
this.preview_type = frappe.ui.form.make_control({ | |||||
parent: this.$refs["preview-type"], | |||||
df: { | |||||
label: __("Preview type"), | |||||
fieldname: "docname", | |||||
fieldtype: "Select", | |||||
options: ["PDF", "HTML"], | |||||
change: () => { | |||||
this.type = this.preview_type.get_value(); | |||||
} | |||||
}, | |||||
render_input: true | |||||
}); | |||||
this.preview_type.set_value(this.type); | |||||
this.get_default_docname().then( | |||||
docname => docname && this.doc_select.set_value(docname) | |||||
); | |||||
}, | |||||
methods: { | |||||
get_default_docname() { | |||||
return frappe.db.get_list(this.doctype, { limit: 1 }).then(doc => { | |||||
return doc.length > 0 ? doc[0].name : null; | |||||
}); | |||||
} | |||||
}, | |||||
computed: { | |||||
doctype() { | |||||
return this.print_format.doc_type; | |||||
}, | |||||
url() { | |||||
if (!this.docname) return null; | |||||
let params = new URLSearchParams(); | |||||
params.append("doctype", this.doctype); | |||||
params.append("name", this.docname); | |||||
params.append("print_format", this.print_format.name); | |||||
let url = | |||||
this.type == "PDF" | |||||
? `/api/method/frappe.utils.weasyprint.download_pdf` | |||||
: "/printpreview"; | |||||
return `${url}?${params.toString()}`; | |||||
} | |||||
} | |||||
}; | |||||
</script> | |||||
<style scoped> | |||||
.preview-iframe { | |||||
width: 100%; | |||||
height: 96%; | |||||
border: none; | |||||
border-radius: var(--border-radius); | |||||
} | |||||
.btn-new-tab { | |||||
margin-top: auto; | |||||
margin-bottom: 1.2rem; | |||||
} | |||||
</style> |
@@ -4,13 +4,17 @@ | |||||
<PrintFormatControls /> | <PrintFormatControls /> | ||||
</div> | </div> | ||||
<div class="print-format-container col-9"> | <div class="print-format-container col-9"> | ||||
<PrintFormat /> | |||||
<keep-alive> | |||||
<Preview v-if="show_preview" /> | |||||
<PrintFormat v-else /> | |||||
</keep-alive> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import PrintFormat from "./PrintFormat.vue"; | import PrintFormat from "./PrintFormat.vue"; | ||||
import Preview from "./Preview.vue"; | |||||
import PrintFormatControls from "./PrintFormatControls.vue"; | import PrintFormatControls from "./PrintFormatControls.vue"; | ||||
import { getStore } from "./store"; | import { getStore } from "./store"; | ||||
@@ -19,7 +23,13 @@ export default { | |||||
props: ["print_format_name"], | props: ["print_format_name"], | ||||
components: { | components: { | ||||
PrintFormat, | PrintFormat, | ||||
PrintFormatControls | |||||
PrintFormatControls, | |||||
Preview | |||||
}, | |||||
data() { | |||||
return { | |||||
show_preview: false | |||||
}; | |||||
}, | }, | ||||
provide() { | provide() { | ||||
return { | return { | ||||
@@ -29,6 +39,11 @@ export default { | |||||
mounted() { | mounted() { | ||||
this.$store.fetch(); | this.$store.fetch(); | ||||
}, | }, | ||||
methods: { | |||||
toggle_preview() { | |||||
this.show_preview = !this.show_preview; | |||||
} | |||||
}, | |||||
computed: { | computed: { | ||||
$store() { | $store() { | ||||
return getStore(this.print_format_name); | return getStore(this.print_format_name); | ||||
@@ -6,8 +6,8 @@ class PrintFormatBuilder { | |||||
this.page = page; | this.page = page; | ||||
this.print_format = print_format; | this.print_format = print_format; | ||||
this.page.clear_actions() | |||||
this.page.clear_custom_actions() | |||||
this.page.clear_actions(); | |||||
this.page.clear_custom_actions(); | |||||
this.page.set_title(__("Editing {0}", [this.print_format])); | this.page.set_title(__("Editing {0}", [this.print_format])); | ||||
this.page.set_primary_action(__("Save changes"), () => { | this.page.set_primary_action(__("Save changes"), () => { | ||||
@@ -17,10 +17,8 @@ class PrintFormatBuilder { | |||||
this.$component.$store.reset_changes(); | this.$component.$store.reset_changes(); | ||||
}); | }); | ||||
this.page.add_button( | this.page.add_button( | ||||
__("Preview"), | |||||
() => { | |||||
this.preview(); | |||||
}, | |||||
__("Toggle Preview"), | |||||
() => this.$component.toggle_preview(), | |||||
{ icon: "small-file" } | { icon: "small-file" } | ||||
); | ); | ||||
@@ -35,46 +33,6 @@ class PrintFormatBuilder { | |||||
}); | }); | ||||
this.$component = $vm.$children[0]; | this.$component = $vm.$children[0]; | ||||
} | } | ||||
async preview() { | |||||
let doctype = this.$component.$store.print_format.doc_type; | |||||
let default_doc = await frappe.db.get_list(doctype, { | |||||
limit: 1 | |||||
}); | |||||
let d = new frappe.ui.Dialog({ | |||||
title: __("Preview Print Format"), | |||||
fields: [ | |||||
{ | |||||
label: __("Type"), | |||||
fieldname: "type", | |||||
fieldtype: "Select", | |||||
options: ["PDF", "HTML"], | |||||
default: "PDF" | |||||
}, | |||||
{ | |||||
label: __("Select Document"), | |||||
fieldname: "docname", | |||||
fieldtype: "Link", | |||||
options: doctype, | |||||
reqd: 1, | |||||
default: default_doc.length > 0 ? default_doc[0].name : null | |||||
} | |||||
], | |||||
primary_action: ({ docname, type }) => { | |||||
let params = new URLSearchParams(); | |||||
params.append("doctype", doctype); | |||||
params.append("name", docname); | |||||
params.append("print_format", this.print_format); | |||||
let url = | |||||
type == "PDF" | |||||
? `/api/method/frappe.utils.weasyprint.download_pdf` | |||||
: "/printpreview"; | |||||
window.open(`${url}?${params.toString()}`, "_blank"); | |||||
} | |||||
}); | |||||
d.show(); | |||||
} | |||||
} | } | ||||
frappe.provide("frappe.ui"); | frappe.provide("frappe.ui"); | ||||