MjmlApp.xml 17.7 KB
<?xml version="1.0" encoding="UTF-8"?>
<!--
This software is in the public domain under CC0 1.0 Universal plus a 
Grant of Patent License.

To the extent possible under law, the author(s) have dedicated all
copyright and related and neighboring rights to this software to the
public domain worldwide. This software is distributed without any
warranty.

You should have received a copy of the CC0 Public Domain Dedication
along with this software (see the LICENSE.md file). If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
-->
<screen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/xml-screen-3.xsd"
        menu-image="fa fa-flash" menu-image-type="icon" standalone="true" screen-theme-type-enum-id="STT_MJML" >

    <parameter name="grapesLocation"/>
    <parameter name="htmlLocation"/>

    <actions>
        <set field="baseLinkUrl" from="!'production'.equals(System.getProperty('instance_purpose')) ? 'http://localhost:8080' : ec.web.getWebappRootUrl(true,true)"/>
    </actions>

    <widgets>
        <render-mode><text type="html" location="component://webroot/screen/includes/Header.html.ftl"/></render-mode>

        <render-mode><text type="html"><![CDATA[
            <input type="hidden" id="confMoquiSessionToken" value="${ec.web.sessionToken}">
            <style>
                body,
                html {
                    height: 100%;
                    margin: 0;
                }

                .cke_top {
                    background: #444 !important;
                }

                .cke_chrome {
                    border: none !important;
                }

                .cke_toolgroup {
                    border: none !important;
                    background: transparent !important;
                    box-shadow: none !important;
                }
            </style>
            <div id="gjs" style="height:0px; overflow:hidden">
                <mjml>
                    <mj-head>
                        <mj-font name="Barlow" href="https://fonts.googleapis.com/css?family=Barlow"></mj-font>

                        <mj-style>
                            .slogan {
                            background: #000;
                            }
                        </mj-style>
                    </mj-head>
                    <mj-body>
                        <!-- Company Header -->
                        <mj-section background-color="#f0f0f0">
                            <mj-column border="10px solid #F45E43">
                                <mj-text font-family="Barlow">A first line of text</mj-text>
                                <mj-spacer height="50px" />
                            </mj-column>
                        </mj-section>

                        <!-- Intro text -->
                        <mj-wrapper background-color="#ffe9f7" padding="10px">
                            <mj-section background-color="#eaeffa">
                                <mj-group background-color="#fffadd">
                                    <mj-column>
                                        <mj-text font-style="italic" font-size="20px" font-family="Helvetica Neue" color="#626262">My Awesome Text</mj-text>
                                        <mj-text color="#525252">
                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper.
                                            Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus, sit amet suscipit nibh. Proin nec
                                            commodo purus. Sed eget nulla elit. Nulla aliquet mollis faucibus.
                                        </mj-text>
                                        <mj-button background-color="#F45E43" href="#">Learn more</mj-button>
                                    </mj-column>
                                </mj-group>
                            </mj-section>
                        </mj-wrapper>

                        <!-- Side image -->
                        <mj-section background-color="white">
                            <mj-column>
                                <mj-text font-style="italic" font-size="20px" font-family="Helvetica Neue" color="#626262">
                                    Find amazing places ...
                                </mj-text>
                                <mj-text color="#525252">
                                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper.
                                    Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus.</mj-text>
                            </mj-column>
                        </mj-section>
                        <mj-section>
                            <mj-column>
                                <mj-text font-style="italic" font-size="20px" font-family="Helvetica Neue" color="#626262" align="center">
                                    ... with real-life images
                                </mj-text>
                            </mj-column>
                        </mj-section>

                        <!-- Footer -->
                        <mj-section background-color="#e7e7e7">
                            <mj-column>
                                <mj-button href="#">Hello There!</mj-button>
                                <mj-social font-size="15px" icon-size="30px" mode="horizontal">
                                    <mj-social-element name="facebook" href="https://moqui.org/">
                                        Facebook
                                    </mj-social-element>
                                    <mj-social-element name="google" href="https://moqui.org/">
                                        Google
                                    </mj-social-element>
                                    <mj-social-element name="twitter" href="https://moqui.org/">
                                        Twitter
                                    </mj-social-element>
                                </mj-social>
                            </mj-column>
                        </mj-section>
                        <!-- Footer -->
                    </mj-body>
                </mjml>
            </div>

            <script type="text/javascript">
                // Wait for the plugin to be injected by the dev server
                window.onload = () => {
                    window.htmlLocation = new URLSearchParams(window.location.search).get('htmlLocation');
                    window.grapesLocation = new URLSearchParams(window.location.search).get('grapesLocation');
                    window.emailTemplateId = new URLSearchParams(window.location.search).get('emailTemplateId');

                    const request = new XMLHttpRequest();
                    request.open("GET", ("${baseLinkUrl}/rest/s1/moqui-mjml/mjml?emailTemplateId="+window.emailTemplateId), false); // `false` makes the request synchronous
                    request.send(null);

                    let response;
                    if (request.status === 200) {
                        response = JSON.parse(request.responseText);
                    }
                    // console.log('response ', response)
                    window.htmlLocation = response.htmlLocation;
                    window.htmlVersionName = response.htmlVersionName;
                    window.htmlPublishedVersionName = response.htmlPublishedVersionName;
                    window.grapesLocation = response.grapesLocation;
                    window.grapesVersionName = response.grapesVersionName;
                    window.grapesPublishedVersionName = response.grapesPublishedVersionName;
                    // const url = new URL(window.location.href)
                    // url.searchParams.set('htmlLocation', response.htmlLocation);
                    // url.searchParams.set('grapesLocation', response.grapesLocation);
                    // window.history.pushState({}, '', url)

                    window.moquiVars = response.moquiVars;
                    // console.log('init window.moquiVars ', window.moquiVars)
                    const projectData = JSON.parse(response.data);
                    // console.log('window.projectData ', window.projectData)

                    function moquiPlugin(editor) {
                        // Use the API: https://grapesjs.com/docs/api/

                        window.moquiPublishText = 'moqui-publish';
                        editor.Commands.add(window.moquiPublishText, () => {
                            const request = new XMLHttpRequest();
                            request.open("POST", "${baseLinkUrl}/rest/s1/moqui-mjml/mjml?emailTemplateId="+window.emailTemplateId, false); // `false` makes the request synchronous
                            request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
                            request.setRequestHeader("X-CSRF-Token", document.getElementById('confMoquiSessionToken').value);
                            request.send(JSON.stringify({ publish:true, data: window.editor.getProjectData(), moquiVars:window.moquiVars, html:window.editor.runCommand('mjml-code-to-html')?.html }));
                            // console.log('request ', request)
                            if (request.status === 200) {
                                const result = JSON.parse(request.responseText);
                                window.htmlLocation = result.htmlLocation;
                                window.htmlVersionName = result.htmlVersionName;
                                window.htmlPublishedVersionName = result.htmlPublishedVersionName;
                                window.grapesLocation = result.grapesLocation;
                                window.grapesVersionName = result.grapesVersionName;
                                window.grapesPublishedVersionName = result.grapesPublishedVersionName;
                                if (window.grapesVersionName !== window.grapesPublishedVersionName && window.htmlVersionName !== window.htmlPublishedVersionName) {
                                    editor.Panels.addButton('options', window.moquiPublishButtonSettings);
                                } else {
                                    editor.Panels.removeButton('options', window.moquiPublishText);
                                }
                            }
                        });
                        editor.on('storage:end:store', () => {
                            // console.log('Storage store request ended');
                            const request = new XMLHttpRequest();
                            request.open("GET", "${baseLinkUrl}/rest/s1/moqui-mjml/mjml/afterMjmlStore?emailTemplateId="+window.emailTemplateId, false); // `false` makes the request synchronous
                            request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
                            request.setRequestHeader("X-CSRF-Token", document.getElementById('confMoquiSessionToken').value);
                            request.send();
                            if (request.status === 200) {
                                const result = JSON.parse(request.responseText);
                                window.htmlLocation = result.htmlLocation;
                                window.htmlVersionName = result.htmlVersionName;
                                window.htmlPublishedVersionName = result.htmlPublishedVersionName;
                                window.grapesLocation = result.grapesLocation;
                                window.grapesVersionName = result.grapesVersionName;
                                window.grapesPublishedVersionName = result.grapesPublishedVersionName;
                                if (window.grapesVersionName !== window.grapesPublishedVersionName && window.htmlVersionName !== window.htmlPublishedVersionName) {
                                    editor.Panels.addButton('options', window.moquiPublishButtonSettings);
                                } else {
                                    editor.Panels.removeButton('options', window.moquiPublishText);
                                }
                            }
                        });

                        // Add Publish button
                        window.moquiPublishButtonSettings = {
                            id: window.moquiPublishText,
                            command: 'moqui-publish',
                            attributes: { title: 'publish' },
                            label: `<div style="background-color: #f45e43; color:#2c2e35; padding: 0px 10px; border: none; border-radius: 10px; cursor: pointer;">Publish</div>`,
                        };
                        if (window.grapesVersionName !== window.grapesPublishedVersionName && window.htmlVersionName !== window.htmlPublishedVersionName) {
                            editor.Panels.addButton('options', window.moquiPublishButtonSettings);
                        }
                    }

                    window.editor = grapesjs.init({
                        projectData: projectData,
                        height: '100%',
                        noticeOnUnload: false,
                        // Default configurations
                        storageManager: {
                            type: 'remote', // Storage type. Available: local | remote
                            autosave: true, // Store data automatically
                            autoload: true, // Autoload stored data on init
                            stepsBeforeSave: 1, // If autosave is enabled, indicates how many changes are necessary before the store method is triggered
                            // ...
                            // Default storage options
                            options: {
                                remote: {
                                    urlLoad: "${baseLinkUrl}/rest/s1/moqui-mjml/mjml?emailTemplateId="+window.emailTemplateId,
                                    urlStore: "${baseLinkUrl}/rest/s1/moqui-mjml/mjml?emailTemplateId="+window.emailTemplateId,
                                    headers: {
                                        "X-CSRF-Token": document.getElementById('confMoquiSessionToken').value
                                    },
                                    // The `remote` storage uses the POST method when stores data but
                                    // the json-server API requires PATCH.
                                    // fetchOptions: opts => (opts.method === 'POST' ?  { method: 'PATCH' } : {}),
                                    // As the API stores projects in this format `{id: 1, data: projectData }`,
                                    // we have to properly update the body before the store and extract the
                                    // project data from the response result.
                                    onStore: data => {
                                        return { id: window.grapesLocation, data, moquiVars:window.moquiVars, html:window.editor.runCommand('mjml-code-to-html')?.html }
                                    },
                                    onLoad: result => {
                                        if (result.resourceId !== null) {
                                            const url = new URL(window.location.href)
                                            url.searchParams.set('grapesLocation', result.grapesLocation);
                                            // url.searchParams.set('htmlLocation', result.htmlLocation);
                                            // url.searchParams.set('emailTemplateId', result.emailTemplateId);
                                            window.history.pushState({}, '', url)
                                            window.htmlLocation = result.htmlLocation;
                                            window.htmlVersionName = result.htmlVersionName;
                                            window.htmlPublishedVersionName = result.htmlPublishedVersionName;
                                            window.grapesLocation = result.grapesLocation;
                                            window.grapesVersionName = result.grapesVersionName;
                                            window.grapesPublishedVersionName = result.grapesPublishedVersionName;
                                            window.emailTemplateId = result.emailTemplateId;
                                            window.moquiVars = result.moquiVars;
                                            if (window.grapesVersionName !== window.grapesPublishedVersionName && window.htmlVersionName !== window.htmlPublishedVersionName) {
                                                editor.Panels.addButton('options', window.moquiPublishButtonSettings);
                                            } else {
                                                editor.Panels.removeButton('options', window.moquiPublishText);
                                            }
                                        }
                                        // console.log('onLoad ', result)
                                        return result.data
                                    },
                                },
                            }
                        },
                        fromElement: true,
                        container: '#gjs',

                        plugins: ['grapesjs-mjml',moquiPlugin],
                        pluginsOpts: {
                            'grapesjs-mjml': {}
                        }
                    });
                }
            </script>
            ]]></text></render-mode>

        <render-mode><text type="html" location="component://webroot/screen/includes/Footer.html.ftl"/></render-mode>

    </widgets>
</screen>