const toolTemplate = function (values, isViewer = false) { return `

${values.productTitle}

${values.productDescription}
${isViewer ? modalTemplate({ products: values.data.products }) : ""} `; }; const modalTemplate = function (data) { return ` `; }; const productItemsTemplate = _.template(` <% _.forEach(products, function(item) { %> > > <%= item.title %> <%= item.price %> <% }); %> `); unlayer.registerTool({ name: "product_tool", label: "Product", icon: "fa-tag", supportedDisplayModes: ["web", "email"], options: { productContent: { title: "Product Content", position: 1, options: { productLibrary: { label: "Add Product from store", defaultValue: "", widget: "product_library", }, productImage: { label: "Product Image", defaultValue: { url: "https://s3.amazonaws.com/unroll-images-production/projects/6553/1604576441796-339575", }, widget: "image", }, productBackground: { label: "Product Background", defaultValue: "#ffffff", widget: "color_picker", }, productBorderColor: { label: "Product Border Color", defaultValue: "#ffffff", widget: "color_picker", }, productBorderSize: { label: "Product Border Size", defaultValue: "1", widget: "counter", }, productTitleFontSize: { label: "Product Title Font Size", defaultValue: "16", widget: "counter", }, productTitleFont: { label: "Product Title Font", defaultValue: "Arial", // Tutaj ustawiamy wartość domyślną widget: "dropdown", data: { options: [ { label: "Global Font", value: "Global Font" }, { label: "Andale Mono", value: "Andale Mono" }, { label: "Arial", value: "Arial" }, { label: "Arial Black", value: "Arial Black" }, { label: "Book Antiqua", value: "Book Antiqua" }, { label: "Cabin", value: "Cabin" }, { label: "Comic Sans MS", value: "Comic Sans MS" }, { label: "Courier New", value: "Courier New" }, { label: "Crimson Text", value: "Crimson Text" }, { label: "Georgia", value: "Georgia" }, { label: "Helvetica", value: "Helvetica" }, { label: "Impact", value: "Impact" }, { label: "Jost", value: "Jost" }, { label: "Lato", value: "Lato" }, { label: "Lobster Two", value: "Lobster Two" }, { label: "Montserrat", value: "Montserrat" }, { label: "Old Standard TT", value: "Old Standard TT" }, { label: "Open Sans", value: "Open Sans" }, { label: "Pacifico", value: "Pacifico" }, { label: "Playfair Display", value: "Playfair Display" }, { label: "Poppins", value: "Poppins" }, { label: "Raleway", value: "Raleway" }, { label: "Rubik", value: "Rubik" }, { label: "Source Sans Pro", value: "Source Sans Pro" }, { label: "Symbol", value: "Symbol" }, { label: "Syne", value: "Syne" }, { label: "Tahoma", value: "Tahoma" }, { label: "Terminal", value: "Terminal" }, { label: "Times New Roman", value: "Times New Roman" }, { label: "Trebuchet MS", value: "Trebuchet MS" }, { label: "Verdana", value: "Verdana" }, ], }, }, productTitle: { label: "Product Title", defaultValue: "Product Title", widget: "rich_text", }, productDescriptionFontSize: { label: "Product Description Font Size", defaultValue: "14", widget: "counter", }, productDescriptionFont: { label: "Product Description Font", defaultValue: "Arial", // Tutaj ustawiamy wartość domyślną widget: "dropdown", data: { options: [ { label: "Global Font", value: "Global Font" }, { label: "Andale Mono", value: "Andale Mono" }, { label: "Arial", value: "Arial" }, { label: "Arial Black", value: "Arial Black" }, { label: "Book Antiqua", value: "Book Antiqua" }, { label: "Cabin", value: "Cabin" }, { label: "Comic Sans MS", value: "Comic Sans MS" }, { label: "Courier New", value: "Courier New" }, { label: "Crimson Text", value: "Crimson Text" }, { label: "Georgia", value: "Georgia" }, { label: "Helvetica", value: "Helvetica" }, { label: "Impact", value: "Impact" }, { label: "Jost", value: "Jost" }, { label: "Lato", value: "Lato" }, { label: "Lobster Two", value: "Lobster Two" }, { label: "Montserrat", value: "Montserrat" }, { label: "Old Standard TT", value: "Old Standard TT" }, { label: "Open Sans", value: "Open Sans" }, { label: "Pacifico", value: "Pacifico" }, { label: "Playfair Display", value: "Playfair Display" }, { label: "Poppins", value: "Poppins" }, { label: "Raleway", value: "Raleway" }, { label: "Rubik", value: "Rubik" }, { label: "Source Sans Pro", value: "Source Sans Pro" }, { label: "Symbol", value: "Symbol" }, { label: "Syne", value: "Syne" }, { label: "Tahoma", value: "Tahoma" }, { label: "Terminal", value: "Terminal" }, { label: "Times New Roman", value: "Times New Roman" }, { label: "Trebuchet MS", value: "Trebuchet MS" }, { label: "Verdana", value: "Verdana" }, ], }, }, productDescription: { label: "Product Description", defaultValue: "Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups.", widget: "rich_text", }, productPrice: { label: "Product Price", defaultValue: "7.99", widget: "text", }, productPriceColor: { label: "Product Price Color", defaultValue: "#000000", widget: "color_picker", }, productPriceBackgroundColor: { label: "Product Price Background", defaultValue: "#ffffff", widget: "color_picker", }, productCTA: { label: "Button Name", defaultValue: "Buy Now", widget: "text", }, productCTAColor: { label: "Button Color", defaultValue: "#FFFF8C", widget: "color_picker", }, productCTATextColor: { label: "Button Text Color", defaultValue: "#000000", widget: "color_picker", }, productCTAPosition: { label: "Horizontal Button", defaultValue: true, widget: "toggle", }, productCTAAction: { label: "Action Type", defaultValue: { name: "web", values: { href: "http://google.com", target: "_blank", }, }, widget: "link", }, }, }, }, transformer: (values, source) => { console.log(values, source); let newValues = { ...values, productTitle: values.productLibrary.selected !== undefined ? values.productLibrary.selected.title : values.productTitle, productPrice: values.productLibrary.selected !== undefined ? values.productLibrary.selected.price : values.productPrice, productDescription: values.productLibrary.selected !== undefined ? values.productLibrary.selected.description : values.productDescription, productImage: { url: values.productLibrary.selected !== undefined ? values.productLibrary.selected.image : values.productImage.url, }, productCTAAction: { name: "web", values: { href: values.productLibrary.selected !== undefined ? values.productLibrary.selected.url : values.productCTAAction.values.href, target: "_blank", }, }, }; if (source.name === "productTitle") { newValues.productTitle = values.productTitle; } if (source.name === "productDescription") { newValues.productDescription = values.productDescription; } if (source.name === "productPrice") { newValues.productPrice = values.productPrice; } if (source.name === "productImage") { newValues.productImage = values.productImage; } if (source.name === "productCTAAction") { newValues.productCTAAction = values.productCTAAction; } // Return updated values return newValues; }, values: {}, renderer: { Viewer: unlayer.createViewer({ render(values) { return toolTemplate(values, true); }, }), exporters: { web: function (values) { return toolTemplate(values); }, email: function (values) { return toolTemplate(values); }, }, head: { // As we need custom styling in export as well that's why we put those styles here css: function (values) { return ` .product-card-main { position: relative; min-width: 0; word-wrap: break-word; background-color: #fff; background-clip: border-box; border-radius: .25rem; margin: auto; text-align: center; border-style:solid; } .product-card-body { padding: 0 1rem 1rem; text-align: left; } .product-card-body p { margin: 0.7rem 0; color:#000; } .product-card-body h3{ margin: 0.7rem 0; color:#000; } .product-card-main img { width: 100%; object-fit: contain; border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; } .product-card-main .product-footer.horizontal { display: flex; border-bottom-left-radius: 0.25rem; border-bottom-right-radius: 0.25rem; align-items: center; font-weight: bold; } .product-card-main .product-footer.vertical { border-bottom-left-radius: 0.25rem; border-bottom-right-radius: 0.25rem; font-weight: bold; } .product-card-main .product-footer.horizontal > div, .product-card-main .product-footer.horizontal > .button{ width: 50%; } .product-card-main .product-footer.vertical > div, .product-card-main .product-footer.vertical > .button{ width: calc(100% - 1.65rem) } .product-card-main .product-footer.horizontal > div { border-bottom-left-radius: 0.25rem; margin: auto; } .product-card-main .product-footer.vertical > div { border-bottom-left-radius: 0.25rem; padding: 0.75rem; } .product-card-main .product-footer.horizontal > .button { border-bottom-right-radius: 0.25rem; } .button { display: inline-block; font-weight: 400; color: #ffffff; text-align: center; vertical-align: middle; background-color: transparent; border: 1px solid transparent; border-radius: 0.25rem; padding: .75rem; font-size: 1rem; line-height: 1.5; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; background-color: rgb(0, 123, 255); cursor: pointer; } .m-0 { margin: 0px; } .no-underline { text-decoration: none; } .no-border-radius { border-radius: 0px; } `; }, js: function (values) {}, }, }, }); const editorTemplate = ''; const showModal = function () { const modal = document.getElementById("product_library_modal"); modal.classList.add("show"); }; const hideModal = function () { const modal = document.getElementById("product_library_modal"); modal.classList.remove("show"); }; const productLibrary = []; unlayer.registerPropertyEditor({ name: "product_library", layout: "bottom", Widget: unlayer.createWidget({ // eslint-disable-next-line @typescript-eslint/no-unused-vars render(value, updateValue, data) { return editorTemplate; }, mount(node, value, updateValue, data) { var addButton = node.querySelector("#addProduct"); addButton.onclick = function () { let o = {}; o.source = "edrone"; o.type = "feed"; o.message = "check feed"; window.parent.postMessage(o, "*"); if (data.products.length === 1 && data.products[0].title === "Product Title") { const list = document.querySelector("#product_library_modal .products-list"); list[removed] = "

To fully utilize this functionality, a product feed for your store is required.

Click here to add your store’s product feed.

"; } showModal(); setTimeout(() => { // We are using event bubling to capture clicked item instead of registering click event on all product items. var link = document.querySelector("#toFeed"); if (link !== null && link !== undefined) { link.onclick = function (e) { let o = {}; o.source = "edrone"; o.type = "feed"; o.message = "to feed"; window.parent.postMessage(o, "*"); }; } var selectButton = document.querySelector(".products-list"); if (!selectButton) { return; } selectButton.onclick = function (e) { if (e.target.id === "product-item") { let selectedProduct = {}; if (productLibrary.length === 0) { selectedProduct = data.products.find((item) => item.id === parseInt(e.target.dataset.uuid)); } else { selectedProduct = productLibrary.find((item) => item.id === parseInt(e.target.dataset.uuid)); } updateValue({ selected: selectedProduct }); } else { const parent = e.target.parentElement; if (parent && parent.id !== "product-item") { return; } let selectedProduct = {}; if (productLibrary.length === 0) { selectedProduct = data.products.find((item) => item.id === parseInt(parent.dataset.uuid)); } else { selectedProduct = productLibrary.find((item) => item.id === parseInt(parent.dataset.uuid)); } updateValue({ selected: selectedProduct }); } hideModal(); // This is a hack to close property editor right bar on selecting an item from products list. var outerBody = document.querySelector("#u_body"); outerBody.click(); }; /* Register event listeners for search */ var searchBar = document.querySelector("#search-bar"); var searchButton = document.querySelector("#search-btn"); // eslint-disable-next-line @typescript-eslint/no-unused-vars searchButton.onclick = async function (e) { let o = {}; o.source = "edrone"; o.type = "search"; o.message = searchBar.value; window.parent.postMessage(o, "*"); const list = document.querySelector("#product_library_modal .products-list"); list[removed] = "

Loading...

"; }; }, 200); }; }, }), }); window.addEventListener("message", (event) => { let isProductsMessage = false; try { isProductsMessage = event.data.source === "edrone" && event.data.type === "products"; } catch (error) { isProductsMessage = false; } if (isProductsMessage) { productLibrary.length = 0; productLibrary.push(...event.data.message); const list = document.querySelector("#product_library_modal .products-list"); let filteredItem; let productsListHtml; if (list && productLibrary) { filteredItem = productLibrary; productsListHtml = productItemsTemplate({ products: productLibrary, }); if (filteredItem.length > 0) { list[removed] = productsListHtml; } else { list[removed] = "

No products found. Start searching for products by their titles or ids

"; } } } });