diff --git a/base-component/tools/screen/Tools/Entity/DataExport.xml b/base-component/tools/screen/Tools/Entity/DataExport.xml index 489644059..e442a20d8 100644 --- a/base-component/tools/screen/Tools/Entity/DataExport.xml +++ b/base-component/tools/screen/Tools/Entity/DataExport.xml @@ -66,13 +66,23 @@ along with this software (see the LICENSE.md file). If not, see } else if (context.output == "browser") { // stream to ec.web.response def response = ec.web.response - if (fileType == 'JSON') response.setContentType('application/json') - if (fileType == 'CSV') response.setContentType('text/csv') - else response.setContentType('text/xml') response.setCharacterEncoding("UTF-8") - response.setHeader("Content-Disposition", "attachment; filename=\"EntityExport_${ec.l10n.format(ec.user.nowTimestamp, 'yyyyMMdd_HHmm')}.${fileType == 'JSON' ? 'json' : fileType == 'CSV' ? 'csv' : 'xml'}\";") response.setHeader("Cache-Control", "no-cache, must-revalidate, private") - edw.writer(response.getWriter()) + + if (fileType == 'CSV' && entityNames instanceof List && entityNames.size() > 1) { + // if trying to export more than one entity as CSV, send a .zip file instead + response.setContentType('application/zip') + response.setHeader("Content-Disposition", "attachment; filename=\"EntityExport_${ec.l10n.format(ec.user.nowTimestamp, 'yyyyMMdd_HHmm')}.zip\";") + edw.zipDirectory('', response.getOutputStream()) + + } else { + if (fileType == 'JSON') response.setContentType('application/json') + else if (fileType == 'CSV') response.setContentType('text/csv') + else response.setContentType('text/xml') + + response.setHeader("Content-Disposition", "attachment; filename=\"EntityExport_${ec.l10n.format(ec.user.nowTimestamp, 'yyyyMMdd_HHmm')}.${fileType == 'JSON' ? 'json' : fileType == 'CSV' ? 'csv' : 'xml'}\";") + edw.writer(response.getWriter()) + } noResponse = true } ]]> diff --git a/base-component/tools/screen/Tools/Entity/DataSnapshot.xml b/base-component/tools/screen/Tools/Entity/DataSnapshot.xml index 33e2fb63d..269fdbdd1 100644 --- a/base-component/tools/screen/Tools/Entity/DataSnapshot.xml +++ b/base-component/tools/screen/Tools/Entity/DataSnapshot.xml @@ -19,13 +19,15 @@ along with this software (see the LICENSE.md file). If not, see Started Export Entity Data Snapshot ${baseFilename} (Job ID ${jobRunId}) @@ -86,12 +88,15 @@ along with this software (see the LICENSE.md file). If not, see - - - + + - - + + + + + + @@ -101,14 +106,12 @@ along with this software (see the LICENSE.md file). If not, see - @@ -128,7 +131,7 @@ along with this software (see the LICENSE.md file). If not, see - + diff --git a/template/screen-macro/DefaultScreenMacros.qvt.ftl b/template/screen-macro/DefaultScreenMacros.qvt.ftl index 43bb2bc06..087664c7d 100644 --- a/template/screen-macro/DefaultScreenMacros.qvt.ftl +++ b/template/screen-macro/DefaultScreenMacros.qvt.ftl @@ -574,6 +574,10 @@ ${sri.renderIncludeScreen(.node["@location"], .node["@share-scope"]!)} <#return> + +<#-- for visible-when do nothing, handled explicitly as child element --> +<#macro "visible-when"> + <#macro formSingleWidget fieldSubNode formSingleId colPrefix inFieldRow bigRow> <#assign fieldSubParent = fieldSubNode?parent> <#if fieldSubNode["ignored"]?has_content><#return> @@ -581,10 +585,30 @@ ${sri.renderIncludeScreen(.node["@location"], .node["@share-scope"]!)} <#if fieldSubNode["hidden"]?has_content><#recurse fieldSubNode/><#return> <#assign containerStyle = ec.getResource().expandNoL10n(fieldSubNode["@container-style"]!, "")> <#assign curFieldTitle><@fieldTitle fieldSubNode/> + + <#assign visibleWhenNode = (fieldSubNode["visible-when"][0])!> + <#assign visibleAttrText = ""> + <#if visibleWhenNode??> + <#assign visibleVal = ""> + <#if visibleWhenNode["@from"]?has_content> + <#assign visibleVal = ec.getResource().expression(visibleWhenNode["@from"], "")!> + <#else> + <#assign visibleVal = ec.getResource().expand(visibleWhenNode["@value"]!, "")!> + + <#if visibleVal?has_content> + <#-- NOTE: FreeMarker is sometimes ridiculous, is_string returns true even if the type is ArrayList in one test case, so DO NOT TRUST is_string!!! --> + <#if visibleVal?is_string && !visibleVal?is_enumerable && visibleVal?contains(",")><#assign visibleVal = visibleVal?split(",")> + <#if visibleVal?is_enumerable> + <#assign visibleAttrText> :style="{display:([<#list visibleVal as entryVal>'${entryVal}'<#sep>,].includes(formProps.fields.${visibleWhenNode["@field"]})?'':'none')}" + <#else> + <#assign visibleAttrText> :style="{display:('${visibleVal}'==formProps.fields.${visibleWhenNode["@field"]}?'':'none')}" + + + <#if bigRow> -
+
<#else> -
+
<#t>${sri.pushContext()} <#assign fieldFormId = formSingleId><#-- set this globally so fieldId macro picks up the proper formSingleId, clear after --> @@ -1916,12 +1940,12 @@ a => A, d => D, y => Y <#assign fieldLabel><@fieldTitle .node?parent/> <#assign curTooltip = ec.getResource().expand(.node?parent["@tooltip"]!, "")>
- form="${ownerForm}"<#rt> + form="${ownerForm}"<#rt> <#t> size="${.node.@size!"10"}"<#if .node.@maxlength?has_content> maxlength="${.node.@maxlength}" <#t><#if fieldsJsName?has_content> v-model="${fieldsJsName}.${curFieldName}_from"<#else> value="${ec.getContext().get(curFieldName + "_from")!?default(.node["@default-value-from"]!"")?html}"> <#if curTooltip?has_content>${curTooltip} - form="${ownerForm}"<#rt> + form="${ownerForm}"<#rt> <#t> size="${.node.@size!"10"}"<#if .node.@maxlength?has_content> maxlength="${.node.@maxlength}" <#t><#if fieldsJsName?has_content> v-model="${fieldsJsName}.${curFieldName}_thru"<#else> value="${ec.getContext().get(curFieldName + "_thru")!?default(.node["@default-value-thru"]!"")?html}"> <#if curTooltip?has_content>${curTooltip}