f5e625a1 by acetousk

Rename resourceId to htmlResource and grapesResource and tidy up comments and code

1 parent b0231d7f
......@@ -13,13 +13,8 @@ along with this software (see the LICENSE.md file). If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
-->
<entity-facade-xml type="seed-initial">
<!-- NOTE: subscreen configuration is now in the MoquiConf.xml file instead of DB records
<moqui.screen.SubscreensItem screenLocation="component://webroot/screen/webroot/apps.xml" subscreenName="mjml" menuTitle="Example"
menuIndex="97" menuInclude="Y" subscreenLocation="component://mjml/screen/MjmlApp.xml"/>
-->
<!-- Artifact group for all of the Moqui Mjml application via the MoquiMjmlApp screen (the root screen for the app) -->
<moqui.security.ArtifactGroup artifactGroupId="MOQUI_MJML_APP" description="Moqui Mjml App (via root screen)"/>
<moqui.security.ArtifactGroup artifactGroupId="MOQUI_MJML_APP" description="Moqui Mjml App"/>
<moqui.security.ArtifactGroupMember artifactGroupId="MOQUI_MJML_APP" artifactTypeEnumId="AT_XML_SCREEN"
inheritAuthz="Y" artifactName="component://moqui-mjml/screen/MjmlApp.xml"/>
<!-- Full permissions for the ADMIN user group -->
......@@ -27,7 +22,7 @@ along with this software (see the LICENSE.md file). If not, see
authzTypeEnumId="AUTHZT_ALWAYS" authzActionEnumId="AUTHZA_ALL"/>
<!-- Artifact group for all of the Moqui Mjml REST API via the mjml resource (the root resource) -->
<moqui.security.ArtifactGroup artifactGroupId="MOQUI_MJML_API" description="Example REST API (via root resource)"/>
<moqui.security.ArtifactGroup artifactGroupId="MOQUI_MJML_API" description="Moqui MJML REST API"/>
<moqui.security.ArtifactGroupMember artifactGroupId="MOQUI_MJML_API" artifactTypeEnumId="AT_REST_PATH"
inheritAuthz="Y" artifactName="/moqui-mjml/mjml"/>
<!-- Full permissions for the ADMIN user group -->
......
......@@ -20,17 +20,9 @@ along with this software (see the LICENSE.md file). If not, see
<moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="50" resourceTypeEnumId="STRT_STYLESHEET" resourceValue="/mjmlstatic/css/grapes.min.css"/>
<moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="52" resourceTypeEnumId="STRT_STYLESHEET" resourceValue="/mjmlstatic/css/grapesjs-mjml.css"/>
<delete-moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="10" resourceTypeEnumId="STRT_SCRIPT" resourceValue="/js/MoquiLib.js"/>
<moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="51" resourceTypeEnumId="STRT_SCRIPT" resourceValue="/mjmlstatic/js/grapes.min.js"/>
<moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="52" resourceTypeEnumId="STRT_SCRIPT" resourceValue="/mjmlstatic/js/grapesjs-mjml.min.js"/>
<!-- <moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="100" resourceTypeEnumId="STRT_HEADER_LOGO"-->
<!-- resourceValue="/images/MoquiLogoSmall.png"/>-->
<!-- <moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="101" resourceTypeEnumId="STRT_SHORTCUT_ICON"-->
<!-- resourceValue="/favicon.ico"/>-->
<!-- <moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="102" resourceTypeEnumId="STRT_BODY_CLASS"-->
<!-- resourceValue="bg-light"/>-->
<moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="110" resourceTypeEnumId="STRT_HEADER_TITLE"
resourceValue="Email Editor"/>
......
......@@ -15,8 +15,8 @@ along with this software (see the LICENSE.md file). If not, see
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/entity-definition-3.xsd">
<extend-entity entity-name="EmailTemplate" package="moqui.basic.email">
<field name="resourceId" type="id"/>
<relationship type="one" related="moqui.resource.DbResource" short-alias="dbResource"/>
<field name="grapesLocation" type="text-medium"/>
<field name="htmlLocation" type="text-medium"/>
</extend-entity>
<view-entity entity-name="ProductStoreEmailDetail" package="mantle.product.store">
<member-entity entity-alias="PSE" entity-name="mantle.product.store.ProductStoreEmail"/>
......
......@@ -23,7 +23,7 @@ along with this software (see the LICENSE.md file). If not, see
<form-list name="StoreEmailsForm">
<field name="editEmailTemplate" align="center"><default-field>
<link url="/mjml" parameter-map="[resourceId:resourceId,emailTemplateId:emailTemplateId]" url-type="plain" text="Edit Template"/>
<link url="/mjml" parameter-map="[grapesLocation:grapesLocation,htmlLocation:htmlLocation,emailTemplateId:emailTemplateId]" url-type="plain" text="Edit Template"/>
</default-field></field>
</form-list>
......
......@@ -16,20 +16,8 @@ along with this software (see the LICENSE.md file). If not, see
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="resourceId"/>
<transition name="handleGrapeJs" read-only="true" method="get">
<actions>
<log level="warn" message="context.toString() ${context.toString()}"/>
<service-call name="moqui.MjmlServices.get#GrapeJs" in-map="[resourceId:resourceId]" out-map="context"/>
</actions>
<default-response url="."/></transition>
<transition name="handleGrapeJs" read-only="true" method="post">
<actions>
<log level="warn" message="context.toString() ${context.toString()}"/>
<service-call name="moqui.MjmlServices.store#GrapeJs" in-map="context" out-map="context"/>
</actions>
<default-response url="."/></transition>
<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)"/>
......@@ -178,11 +166,12 @@ along with this software (see the LICENSE.md file). If not, see
<script type="text/javascript">
// Wait for the plugin to be injected by the dev server
window.onload = () => {
window.resourceId = new URLSearchParams(window.location.search).get('resourceId');
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?resourceId="+window.resourceId+"&emailTemplateId="+window.emailTemplateId), false); // `false` makes the request synchronous
request.open("GET", ("${baseLinkUrl}/rest/s1/moqui-mjml/mjml?grapesLocation="+window.grapesLocation+"&htmlLocation="+window.htmlLocation+"&emailTemplateId="+window.emailTemplateId), false); // `false` makes the request synchronous
request.send(null);
let response;
......@@ -212,8 +201,8 @@ along with this software (see the LICENSE.md file). If not, see
// Default storage options
options: {
remote: {
urlLoad: "${baseLinkUrl}/rest/s1/moqui-mjml/mjml?resourceId=" + window.resourceId,
urlStore: "${baseLinkUrl}/rest/s1/moqui-mjml/mjml?resourceId=" + window.resourceId,
urlLoad: "${baseLinkUrl}/rest/s1/moqui-mjml/mjml?grapesLocation="+window.grapesLocation+"&htmlLocation="+window.htmlLocation,
urlStore: "${baseLinkUrl}/rest/s1/moqui-mjml/mjml?grapesLocation="+window.grapesLocation+"&htmlLocation="+window.htmlLocation,
headers: {
"X-CSRF-Token": document.getElementById('confMoquiSessionToken').value
},
......@@ -224,14 +213,16 @@ along with this software (see the LICENSE.md file). If not, see
// we have to properly update the body before the store and extract the
// project data from the response result.
onStore: data => {
return { id: window.resourceId, data, html:window.editor.runCommand('mjml-code-to-html')?.html }
return { id: window.grapesLocation, data, 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('resourceId', result.resourceId);
url.searchParams.set('grapesLocation', result.grapesLocation);
url.searchParams.set('htmlLocation', result.htmlLocation);
window.history.pushState({}, '', url)
window.resourceId = result.resourceId;
window.grapesLocation = result.grapesLocation;
window.htmlLocation = result.htmlLocation;
}
// console.log('onLoad ', result)
return result.data
......
......@@ -17,78 +17,62 @@ along with this software (see the LICENSE.md file). If not, see
<service verb="load" noun="GrapeJs">
<description>Create MJML</description>
<in-parameters>
<parameter name="resourceId"/>
<parameter name="grapesLocation"/>
<parameter name="htmlLocation"/>
<parameter name="emailTemplateId"/>
</in-parameters>
<out-parameters>
<parameter name="resourceId"/>
<parameter name="grapesLocation"/>
<parameter name="htmlLocation"/>
<parameter name="data"/>
</out-parameters>
<actions>
<if condition="resourceId == 'null'"><set field="resourceId" from="null"/></if>
<if condition="grapesLocation == 'null'"><set field="grapesLocation" from="null"/></if>
<if condition="htmlLocation == 'null'"><set field="htmlLocation" from="null"/></if>
<!-- <log level="warn" message="resourceId is ${resourceId} resourceId.getClass().getName() ${resourceId.getClass().getName()} resourceId == 'null' ${resourceId == 'null'} resourceId == null ${resourceId == null}"/>-->
<!-- <log level="warn" message="load context.toString() ${context.toString()}"/>-->
<if condition="emailTemplateId">
<entity-find-one entity-name="moqui.basic.email.EmailTemplate" value-field="emailTemplate" auto-field-map="[emailTemplateId:emailTemplateId]"/>
<if condition="!resourceId"><set field="resourceId" from="emailTemplate?.resourceId"/></if>
<if condition="resourceId != emailTemplate?.resourceId">
<if condition="!grapesLocation"><set field="grapesLocation" from="emailTemplate?.grapesLocation"/></if>
<if condition="grapesLocation &amp;&amp; grapesLocation != emailTemplate?.grapesLocation">
<!-- This should almost never happen, but if it does it basically creates a resource leak for the previously used resource -->
<log message="Changing resource id from ${grapesLocation} to ${emailTemplate?.grapesLocation} for email template ${emailTemplateId}"/>
<service-call name="update#moqui.basic.email.EmailTemplate" in-map="[emailTemplateId:emailTemplateId,grapesLocation:grapesLocation]"/>
</if>
<if condition="!htmlLocation"><set field="htmlLocation" from="emailTemplate?.htmlLocation"/></if>
<if condition="htmlLocation &amp;&amp; htmlLocation != emailTemplate?.htmlLocation">
<!-- This should almost never happen, but if it does it basically creates a resource leak for the previously used resource -->
<log message="Changing resource id from ${resourceId} to ${emailTemplate?.resourceId} for email template ${emailTemplateId}"/>
<service-call name="update#moqui.basic.email.EmailTemplate" in-map="[emailTemplateId:emailTemplateId,resourceId:resourceId]"/>
<log message="Changing resource id from ${htmlLocation} to ${emailTemplate?.htmlLocation} for email template ${emailTemplateId}"/>
<service-call name="update#moqui.basic.email.EmailTemplate" in-map="[emailTemplateId:emailTemplateId,htmlLocation:htmlLocation]"/>
</if>
</if>
<if condition="!resourceId">
<then>
<set field="grapesJsResource" from="ec.resource.getLocationReference('dbresource://grapesjs/project')"/>
<service-call name="create#moqui.resource.DbResource" in-map="[parentResourceId:grapesJsResource.getDbResourceId(),isFile:'Y']" out-map="dbResource"/>
<service-call name="update#moqui.resource.DbResource" in-map="[resourceId:dbResource.resourceId,filename:dbResource.resourceId+'.json']" out-map="dbResource"/>
<set field="versionName" value="01"/>
<set field="defaultFile" from="ec.resource.getLocationReference('dbresource://grapesjs/template/default.json')"/>
<set field="data" from="defaultFile.getText()"/>
<service-call name="create#moqui.resource.DbResourceFile" in-map="[resourceId: dbResource.resourceId,mimeType: 'text/json',versionName: versionName,rootVersionName: versionName,fileData:data]"/>
<service-call name="create#moqui.resource.DbResourceFileHistory" in-map="[resourceId: dbResource.resourceId,versionDate: ec.user.nowTimestamp,userId: ec.user.userId,isDiff: 'N']"/>
<set field="resourceId" from="dbResource.resourceId"/>
<if condition="!grapesLocation &amp;&amp; htmlLocation">
<then>
<set field="htmlFile" from="project.makeFile(java.util.UUID.randomUUID().toString()+'.html')"/>
<set field="grapesFile" from="project.makeFile(java.util.UUID.randomUUID().toString()+'.json')"/>
<set field="data" from="ec.resource.getLocationReference('dbresource://grapesjs/template/default.json').getText()"/>
<script><![CDATA[
htmlFile.move(project.location + "/" + htmlFile.dbResourceId + ".html")
grapesFile.putText(data)
grapesFile.move(project.location + "/" + grapesFile.dbResourceId + ".json")
]]></script>
<set field="htmlLocation" from="htmlFile.location"/>
<set field="grapesLocation" from="grapesFile.location"/>
<if condition="emailTemplateId">
<service-call name="update#moqui.basic.email.EmailTemplate" in-map="[emailTemplateId:emailTemplateId,resourceId:resourceId]"/>
<service-call name="update#moqui.basic.email.EmailTemplate" in-map="[emailTemplateId:emailTemplateId,grapesLocation:grapesLocation,htmlLocation:htmlLocation]"/>
</if>
<!-- <set field="resourceId" from="null"/>-->
<!-- <set field="data" from="null"/>-->
</then>
<else>
<entity-find-one entity-name="moqui.resource.DbResource" value-field="dbResource" auto-field-map="[resourceId:resourceId]"/>
<!-- <log level="warn" message="dbResource ${dbResource}"/>-->
<if condition="!dbResource">
<return error="true" message="Resource not found"/>
</if>
<set field="actualDbResourcePath" from="null"/>
<set field="dbResourcePath" from="dbResource.filename"/>
<set field="lastDbResource" from="dbResource"/>
<!-- <log level="warn" message="lastDbResource ${lastDbResource}"/>-->
<script>
while (actualDbResourcePath == null) {
// ec.logger.warn('dbResourcePath: '+dbResourcePath)
if (lastDbResource.parentResourceId == null) {
dbResourcePath = 'dbresource://'+dbResourcePath
actualDbResourcePath = dbResourcePath
// ec.logger.warn('actualDbResourcePath: '+actualDbResourcePath)
} else {
lastDbResource = ec.entity.fastFindOne("moqui.resource.DbResource", true, false, lastDbResource.parentResourceId)
dbResourcePath = lastDbResource.filename+'/'+dbResourcePath
}
}
</script>
<set field="putDbResource" from="ec.resource.getLocationReference(actualDbResourcePath)"/>
<entity-find entity-name="moqui.resource.DbResourceFileHistory" list="dbResourceHistoryList" limit="1">
<econdition field-name="resourceId" from="resourceId"/>
<order-by field-name="-versionName"/>
</entity-find>
<if condition="dbResourceHistoryList.size() == 0">
<set field="putDbResource" from="ec.resource.getLocationReference(grapesLocation)"/>
<if condition="!putDbResource || putDbResource.parent?.dbResourceId != grapesJsResource.dbResourceId">
<return error="true" message="Resource not found"/>
</if>
<set field="data" from="putDbResource.getText(dbResourceHistoryList.getFirst().versionName)"/>
<set field="data" from="putDbResource.getText()"/>
</else>
</if>
</actions>
......
<?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/>.
-->
<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/service-definition-3.xsd">
<service verb="get" noun="GrapeJs">
<description>Create MJML</description>
<in-parameters>
<parameter name="resourceId"/>
</in-parameters>
<out-parameters>
<parameter name="data"/>
</out-parameters>
<actions>
<set field="file" from="ec.resource.getLocationReference('dbresource://grapesjs/project/'+resourceId)"/>
<set field="data" from="file.getText()"/>
</actions>
</service>
<service verb="store" noun="GrapeJs">
<description>Create MJML</description>
<in-parameters>
<parameter name="resourceId"/>
<parameter name="data" type="String"/>
</in-parameters>
<out-parameters>
<parameter name="resourceId"/>
</out-parameters>
<actions>
<!-- <log level="warn" message="context.toString() ${context.toString()}"/>-->
<!-- <log level="warn" message="store#GrapeJs ec.web.secureRequestParameters.data ${ec.web.secureRequestParameters.data}"/>-->
<log level="warn" message="store#GrapeJs ec.web.secureRequestParameters._requestBodyText ${ec.web.secureRequestParameters._requestBodyText}"/>
<log level="warn" message="store#GrapeJs data ${data} typeof data ${data.getClass().getName()}"/>
<!-- <set field="data" from="groovy.json.JsonOutput.toJson(data)"/>-->
<set field="project" from="ec.resource.getLocationReference('dbresource://grapesjs/project')"/>
<set field="file" from="project.makeFile(java.util.UUID.randomUUID().toString())"/>
<script><![CDATA[
file.putText(data)
file.move(project.location + "/" + file.dbResourceId)
]]></script>
<set field="resourceId" from="context.resourceId"/>
</actions>
</service>
</services>