fix: created custom block widget which renders html,css,js from custom html block

This commit is contained in:
Shariq Ansari 2023-05-17 14:43:33 +05:30
parent 58c5a33f9b
commit 59514187cb
3 changed files with 99 additions and 0 deletions

View file

@ -0,0 +1,78 @@
import Widget from "./base_widget.js";
export default class CustomBlockWidget extends Widget {
constructor(opts) {
opts.shadow = true;
super(opts);
}
get_config() {
return {
custom_block_name: this.custom_block_name,
label: this.custom_block_name,
};
}
refresh() {
this.set_body();
this.make_custom_block();
}
set_body() {
this.widget.addClass("custom-block-widget-box");
this.widget.addClass("full-width");
}
async make_custom_block() {
await this.get_custom_block_data();
this.body.empty();
this.random_id = "custom-block-" + frappe.utils.get_random(5).toLowerCase();
let me = this;
class CustomBlock extends HTMLElement {
constructor() {
super();
// html
let div = document.createElement("div");
div.innerHTML = frappe.dom.remove_script_and_style(me.custom_block_doc.html);
// css
let style = document.createElement("style");
style.textContent = me.custom_block_doc.style;
// js
let script = document.createElement("script");
script.textContent = `
(function() {
let cname = ${JSON.stringify(me.random_id)};
let root_element = document.querySelector(cname).shadowRoot;
${me.custom_block_doc.script}
})();
`;
this.attachShadow({ mode: "open" });
this.shadowRoot?.appendChild(div);
this.shadowRoot?.appendChild(style);
this.shadowRoot?.appendChild(script);
}
}
if (!customElements.get(this.random_id)) {
customElements.define(this.random_id, CustomBlock);
}
this.body.append(`<${this.random_id}></${this.random_id}>`);
}
async get_custom_block_data() {
this.label = this.custom_block_name;
let custom_block_doc = await frappe.model.with_doc(
"Custom HTML Block",
this.custom_block_name
);
this.custom_block_doc = custom_block_doc ? custom_block_doc : "";
}
}

View file

@ -701,6 +701,24 @@ class NumberCardDialog extends WidgetDialog {
}
}
class CustomBlockDialog extends WidgetDialog {
constructor(opts) {
super(opts);
}
get_fields() {
return [
{
fieldtype: "Link",
fieldname: "custom_block_name",
label: "Custom Block Name",
options: "Custom HTML Block",
reqd: 1,
},
];
}
}
export default function get_dialog_constructor(type) {
const widget_map = {
chart: ChartDialog,
@ -709,6 +727,7 @@ export default function get_dialog_constructor(type) {
onboarding: OnboardingDialog,
quick_list: QuickListDialog,
number_card: NumberCardDialog,
custom_block: CustomBlockDialog,
};
return widget_map[type] || WidgetDialog;

View file

@ -6,6 +6,7 @@ import OnboardingWidget from "../widgets/onboarding_widget";
import NewWidget from "../widgets/new_widget";
import NumberCardWidget from "../widgets/number_card_widget";
import QuickListWidget from "../widgets/quick_list_widget";
import CustomBlock from "../widgets/custom_block_widget";
frappe.provide("frappe.widget");
@ -17,6 +18,7 @@ frappe.widget.widget_factory = {
onboarding: OnboardingWidget,
number_card: NumberCardWidget,
quick_list: QuickListWidget,
custom_block: CustomBlock,
};
frappe.widget.make_widget = (opts) => {