Skip to content

Commit

Permalink
FORMS-16351 Support for string in file attachment (#1418)
Browse files Browse the repository at this point in the history
* initial check in

* Adding test collateral

* FORMS-16351 Support for string in file attachment
@review @vdua
DOD(Yes)

* Adding field description for type string

* Adding test collateral

* updating field description

* Adding read attachments

* moving to released version

* @releng updating af-core
  • Loading branch information
rismehta authored Oct 1, 2024
1 parent 649a7d7 commit a0b4060
Show file tree
Hide file tree
Showing 21 changed files with 707 additions and 280 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Map;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Default;
Expand Down Expand Up @@ -72,12 +73,23 @@ public Integer getMaxItems() {

@Override
public Type getType() {
// file upload does not work for type string in core component, hence default it to file
if (!isMultiple()) {
return Type.FILE;
} else {
return Type.FILE_ARRAY;
Type superType = super.getType();
if (superType == null || StringUtils.isBlank(typeJcr) || superType == Type.FILE) {
return isMultiple() ? Type.FILE_ARRAY : Type.FILE;
}
if (isMultiple() && superType == Type.STRING) {
return Type.STRING_ARRAY;
}
return superType;
}

@Override
public String getFormat() {
Type type = getType();
if (type == Type.STRING || type == Type.STRING_ARRAY) {
return "data-url";
}
return null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

import org.osgi.annotation.versioning.ProviderType;

import com.fasterxml.jackson.annotation.JsonInclude;

/**
* Interface for constraints applicable to file attachments
*
Expand Down Expand Up @@ -54,4 +56,15 @@ default String getMaxFileSize() {
default List<String> getAccept() {
return DEFAULT_ACCEPT;
}

/**
* The constraint is
* applicable for file attachment field. If the type is {@code String}, the format will always be {@code data-url}.
*
* @since com.adobe.cq.forms.core.components.models.form 5.7.4
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
default String getFormat() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* </p>
*/

@Version("5.6.4")
@Version("5.7.4")
package com.adobe.cq.forms.core.components.models.form;

import org.osgi.annotation.versioning.Version;
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class FileInputImplTest {
private static final String PATH_FILEINPUT_DATALAYER = CONTENT_ROOT + "/fileinput-datalayer";
private static final String PATH_MULTISELECT_FILEINPUT = CONTENT_ROOT + "/multiselect-fileinput";
private static final String PATH_MULTISELECT_FILEINPUT_WITHNOTYPE = CONTENT_ROOT + "/multiselect-fileinput-withNoType";
private static final String PATH_MULTISELECT_FILEINPUT_WITH_TYPE = CONTENT_ROOT + "/fileInput-withType";
private static final String PATH_FILEINPUT_WITHOUT_FIELDTYPE = CONTENT_ROOT + "/fileinput-without-fieldtype";

private final AemContext context = FormsCoreComponentTestContext.newAemContext();
Expand Down Expand Up @@ -86,7 +87,13 @@ void testFieldType() {
@Test
void testType() {
FileInput fileInput = Utils.getComponentUnderTest(PATH_MULTISELECT_FILEINPUT_WITHNOTYPE, FileInput.class, context);
assertEquals(fileInput.getType(), fileInput.getType());
assertEquals(BaseConstraint.Type.FILE_ARRAY, fileInput.getType());
}

@Test
void testStringType() {
FileInput fileInput = Utils.getComponentUnderTest(PATH_MULTISELECT_FILEINPUT_WITH_TYPE, FileInput.class, context);
assertEquals(BaseConstraint.Type.STRING_ARRAY, fileInput.getType());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,26 @@
"maxFileSize" : "4096",
"accept" : ["text/*", "application/pdf"]
},
"fileInput-withType": {
"jcr:primaryType": "nt:unstructured",
"sling:resourceType" : "core/fd/components/form/fileinput/v1/fileinput",
"fieldType": "file-input",
"name" : "abc",
"jcr:title" : "def",
"description" : "dummy",
"visible" : false,
"assistPriority" : "custom",
"dataRef" : "a.b",
"custom" : "Custom screen reader text",
"typeMessage" : "incorrect type",
"tooltip": "test-short-description",
"multiSelection" : true,
"type" : "string",
"minItems" : 1,
"maxItems" : 2,
"maxFileSize" : "4096",
"accept" : ["text/*", "application/pdf"]
},
"fileinput-without-fieldtype": {
"jcr:primaryType": "nt:unstructured",
"sling:resourceType" : "core/fd/components/form/fileinput/v1/fileinput",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<!-- Adding core.forms.components.it.runtime.all as we need to embed all component client libraries inside all due to inter dependency between them -->
<!-- core.forms.components.it.textinput.v1.runtime is embedded as part of core.forms.components.it.runtime.all -->
<sly data-sly-use.clientlib="core/wcm/components/commons/v1/templates/clientlib.html">
<sly data-sly-test="${!wcmmode.edit}" data-sly-call="${clientlib.js @ categories=['core.forms.components.runtime.base','core.forms.components.container.v2.runtime','core.forms.components.fileinput.v2.runtime','core.forms.components.button.v1.runtime'], async=false}"/>
<sly data-sly-test="${!wcmmode.edit}" data-sly-call="${clientlib.js @ categories=['core.forms.components.runtime.base','core.forms.components.container.v2.runtime','core.forms.components.fileinput.v3.runtime','core.forms.components.button.v1.runtime'], async=false}"/>
</sly>
<sly data-sly-use.page="com.adobe.cq.wcm.core.components.models.Page">
<sly data-sly-test="${page.data && page.dataLayerClientlibIncluded}" data-sly-call="${clientlib.js @ categories='core.forms.components.commons.v1.datalayer', async=true}"></sly>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
jcr:mixinTypes="[rep:AccessControllable]"
jcr:primaryType="sling:Folder"
lcFolder="{Long}0"
type="lcFolder"
/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:dam="http://www.day.com/dam/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:fd="http://www.adobe.com/aemfd/fd/1.0"
jcr:primaryType="dam:Asset">
<jcr:content
jcr:lastModified="{Date}2023-01-25T17:24:29.344+05:30"
jcr:primaryType="dam:AssetContent"
sling:resourceType="fd/fm/af/render"
guide="1"
type="guide">
<metadata
fd:version="2.1"
jcr:primaryType="nt:unstructured"
allowedRenderFormat="HTML"
author="admin"
availableInMobileApp="{Boolean}false"
dorTemplateChanged="Boolean"
dorType="none"
formmodel="none"
hasCustomThumbnail="{Boolean}false"
themeRef="/libs/fd/af/themes/canvas"
title="File Input (String)"/>
</jcr:content>
</jcr:root>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
jcr:mixinTypes="[rep:AccessControllable]"
jcr:primaryType="sling:Folder"
hidden="true"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:fd="http://www.adobe.com/aemfd/fd/1.0"
jcr:primaryType="cq:Page">
<jcr:content
cq:deviceGroups="[mobile/groups/responsive]"
cq:lastModified="{Date}2023-01-25T17:24:29.344+05:30"
cq:lastModifiedBy="admin"
cq:template="/conf/core-components-examples/settings/wcm/templates/af-blank-v2"
jcr:language="en"
jcr:primaryType="cq:PageContent"
jcr:title="File Input (String)"
sling:configRef="/conf/forms/core-components-it/samples/fileinput/fileinputv3/basic/"
sling:resourceType="forms-core-components-it/components/page-fileinputv3">
<guideContainer
fd:version="2.1"
jcr:lastModified="{Date}2023-01-17T16:29:57.778+05:30"
jcr:lastModifiedBy="admin"
jcr:primaryType="nt:unstructured"
sling:resourceType="forms-components-examples/components/form/container"
actionType="forms-core-components-it/customsubmission/logsubmit"
dorType="none"
fieldType="form"
prefillService="Core Custom Pre-fill Service"
textIsRich="true"
thankYouMessage="Thank you for submitting the form."
thankYouOption="page">
<fileinput1
jcr:lastModified="{Date}2023-01-24T16:47:36.882+05:30"
jcr:lastModifiedBy="admin"
jcr:primaryType="nt:unstructured"
jcr:title="File Input - File[]"
sling:resourceType="core/fd/components/form/fileinput/v3/fileinput"
accept="[audio/*, video/*, image/*, text/*, application/pdf]"
buttonText="Attach Files"
fieldType="file-input"
multiSelection="true"
name="fileinput1"
type="file"
visible="{Boolean}true"/>
<fileinput2
jcr:primaryType="nt:unstructured"
jcr:title="File Input - String"
sling:resourceType="core/fd/components/form/fileinput/v3/fileinput"
accept="[audio/*, video/*, image/*, text/*, application/pdf]"
fieldType="file-input"
name="fileinput2"
type="string"/>
<fileinput3
jcr:primaryType="nt:unstructured"
jcr:title="File Input - File"
sling:resourceType="core/fd/components/form/fileinput/v3/fileinput"
accept="[audio/*, video/*, image/*, text/*, application/pdf]"
description="This is long description"
fieldType="file-input"
name="fileinput3"
tooltip="This is short description"
tooltipVisible="true"
type="file"/>
<fileinput4
jcr:primaryType="nt:unstructured"
jcr:title="File Input - String[]"
sling:resourceType="core/fd/components/form/fileinput/v3/fileinput"
description="This is long description"
fieldType="file-input"
accept="[audio/*, video/*, image/*, text/*, application/pdf]"
name="fileinput4"
tooltip="This is short description"
multiSelection="true"
type="string"/>
<submit
jcr:lastModified="{Date}2023-01-17T16:28:58.844+05:30"
jcr:lastModifiedBy="admin"
jcr:primaryType="nt:unstructured"
jcr:title="Submit"
sling:resourceType="forms-components-examples/components/form/actions/submit"
buttonType="submit"
dorExclusion="true"
fieldType="button"
name="submit1673953138924">
<fd:rules
fd:click="[{&quot;nodeName&quot;:&quot;ROOT&quot;\,&quot;items&quot;:[{&quot;nodeName&quot;:&quot;STATEMENT&quot;\,&quot;choice&quot;:{&quot;nodeName&quot;:&quot;EVENT_SCRIPTS&quot;\,&quot;items&quot;:[{&quot;nodeName&quot;:&quot;EVENT_CONDITION&quot;\,&quot;choice&quot;:{&quot;nodeName&quot;:&quot;EVENT_AND_COMPARISON&quot;\,&quot;items&quot;:[{&quot;nodeName&quot;:&quot;COMPONENT&quot;\,&quot;value&quot;:{&quot;id&quot;:&quot;$form.button1667450213112&quot;\,&quot;type&quot;:&quot;BUTTON&quot;\,&quot;name&quot;:&quot;button1667450213112&quot;}}\,{&quot;nodeName&quot;:&quot;EVENT_AND_COMPARISON_OPERATOR&quot;\,&quot;choice&quot;:{&quot;nodeName&quot;:&quot;is clicked&quot;\,&quot;value&quot;:null}}\,{&quot;nodeName&quot;:&quot;PRIMITIVE_EXPRESSION&quot;\,&quot;choice&quot;:null}]}\,&quot;nested&quot;:false}\,{&quot;nodeName&quot;:&quot;Then&quot;\,&quot;value&quot;:null}\,{&quot;nodeName&quot;:&quot;BLOCK_STATEMENTS&quot;\,&quot;items&quot;:[{&quot;nodeName&quot;:&quot;BLOCK_STATEMENT&quot;\,&quot;choice&quot;:{&quot;nodeName&quot;:&quot;SUBMIT_FORM&quot;\,&quot;items&quot;:[]}}]}]}}]\,&quot;isValid&quot;:true\,&quot;enabled&quot;:true\,&quot;version&quot;:1\,&quot;script&quot;:[&quot;submitForm()&quot;]\,&quot;eventName&quot;:&quot;Click&quot;\,&quot;ruleType&quot;:&quot;&quot;\,&quot;description&quot;:&quot;&quot;}]"
jcr:primaryType="nt:unstructured"/>
<fd:events
jcr:primaryType="nt:unstructured"
click="[submitForm()]"/>
</submit>
</guideContainer>
</jcr:content>
</jcr:root>
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@
fieldLabel="Button title"
name="./buttonText">
</buttonText>
<type jcr:primaryType="nt:unstructured"
sling:orderBefore="visible"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
granite:class="cmp-adaptiveform-radiobutton__type"
fieldLabel="Data type of submitted value"
fieldDescription="Selecting the String data type option would increase the upload size by 30%."
required="{Boolean}true"
name="./type"
key="File"
value="file">
<items jcr:primaryType="nt:unstructured">
<string jcr:primaryType="nt:unstructured" text="String" value="string"/>
<boolean jcr:primaryType="nt:unstructured" text="File" value="file"/>
</items>
</type>
<showComment
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true">
Expand Down
32 changes: 16 additions & 16 deletions ui.frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions ui.frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"webpack-merge": "^5.8.0"
},
"dependencies": {
"@aemforms/af-core": "^0.22.104",
"@aemforms/af-formatters": "^0.22.104",
"@aemforms/af-core": "^0.22.109",
"@aemforms/af-formatters": "^0.22.109",
"@aemforms/af-custom-functions": "1.0.10"
}
}
20 changes: 11 additions & 9 deletions ui.frontend/src/GuideBridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import {Constants} from "./constants.js";
import Response from "./Response.js";
import AfFormData from "./FormData.js";
import {readAttachments} from "@aemforms/af-core";

/**
* The GuideBridge class represents the bridge between an adaptive form and JavaScript APIs.
Expand Down Expand Up @@ -118,16 +119,17 @@ class GuideBridge {
if (!formModel) {
throw new Error("formModel is not defined");
}
let attachmentAsObj = formModel.getState().attachments;
let attachmentAsArray = Object.keys(attachmentAsObj).flatMap((key) => attachmentAsObj[key]);
let formData = new AfFormData({
"data": JSON.stringify(formModel.exportData()),
"attachments": attachmentAsArray
readAttachments(formModel).then(attachmentAsObj => {
let attachmentAsArray = Object.keys(attachmentAsObj).flatMap((key) => attachmentAsObj[key]);
let formData = new AfFormData({
"data": JSON.stringify(formModel.exportData()),
"attachments": attachmentAsArray
});
let resultObject = new Response({"data": formData});
if (options && typeof options.success === 'function') {
options.success(resultObject);
}
});
let resultObject = new Response({"data": formData});
if (options && typeof options.success === 'function') {
options.success(resultObject);
}
}


Expand Down
Loading

0 comments on commit a0b4060

Please sign in to comment.