diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java index 5d7c410231..86b1df5de4 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java @@ -146,4 +146,13 @@ private FormConstants() { /** The resource type for date time input field v1 */ public static final String RT_FD_FORM_DATETIME_V1 = RT_FD_FORM_PREFIX + "datetime/v1/datetime"; + /** The resource type for signature step v1 */ + public static final String RT_FD_FORM_SIGNATURE_STEP_V1 = RT_FD_FORM_PREFIX + "signaturestep/v1/signaturestep"; + + /** The resource type for summary step v1 */ + public static final String RT_FD_FORM_SUMMARY_STEP_V1 = RT_FD_FORM_PREFIX + "summarystep/v1/summarystep"; + + /** The resource type for Adobe Sign block v1 */ + public static final String RT_FD_FORM_ADOBE_SIGN_BLOCK_V1 = RT_FD_FORM_PREFIX + "adobesignblock/v1/adobesignblock"; + } diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImpl.java new file mode 100644 index 0000000000..0a11b38956 --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImpl.java @@ -0,0 +1,111 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.Map; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Default; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; +import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.forms.core.components.internal.form.FormConstants; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.SignatureStep; +import com.adobe.cq.forms.core.components.util.AbstractBaseImpl; + +@Model( + adaptables = { SlingHttpServletRequest.class, Resource.class }, + adapters = { SignatureStep.class, ComponentExporter.class }, + resourceType = { FormConstants.RT_FD_FORM_SIGNATURE_STEP_V1 }) +@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class SignatureStepImpl extends AbstractBaseImpl implements SignatureStep { + + static final String PROP_SIGNING_SERVICE = "signingService"; + static final String PROP_CLOUD_SERVICE_CONFIG = "cq:cloudserviceconfigs"; + static final String PROP_DISPLAY_MSG = "displayMsg"; + static final String PROP_TARGET_VERSION = "fd:targetVersion"; + + static final String DEFAULT_SIGNING_SERVICE = "echosign"; + static final String DEFAULT_DISPLAY_MSG = ""; + static final String DEFAULT_TARGET_VERSION = ""; + + static final String VIEW_TYPE_SIGNATURE_STEP = "signature-step"; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_SIGNING_SERVICE) + @Default(values = DEFAULT_SIGNING_SERVICE) + private String signingService; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_CLOUD_SERVICE_CONFIG) + @Nullable + private String cloudServiceConfig; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_DISPLAY_MSG) + @Nullable + private String displayMsg; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_TARGET_VERSION) + @Nullable + private String targetVersion; + + @Override + public String getSigningService() { + return signingService; + } + + @Override + public String getCloudServiceConfig() { + return cloudServiceConfig != null ? cloudServiceConfig : ""; + } + + @Override + public String getDisplayMsg() { + return displayMsg; + } + + @Override + public String getTargetVersion() { + return targetVersion; + } + + @Override + public String getFieldType() { + return super.getFieldType(FieldType.PLAIN_TEXT); + } + + @Override + public @NotNull Map getProperties() { + Map properties = super.getProperties(); + properties.put("fd:signingService", getSigningService()); + if (!getCloudServiceConfig().isEmpty()) { + properties.put("fd:cloudServiceConfig", getCloudServiceConfig()); + } + if (getDisplayMsg() != null) { + properties.put("fd:displayMsg", getDisplayMsg()); + } + if (getTargetVersion() != null && !getTargetVersion().isEmpty()) { + properties.put("fd:targetVersion", getTargetVersion()); + } + return properties; + } +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImpl.java new file mode 100644 index 0000000000..8cd1d1274e --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImpl.java @@ -0,0 +1,81 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.Map; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Default; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; +import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.forms.core.components.internal.form.FormConstants; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.SummaryStep; +import com.adobe.cq.forms.core.components.util.AbstractBaseImpl; + +@Model( + adaptables = { SlingHttpServletRequest.class, Resource.class }, + adapters = { SummaryStep.class, ComponentExporter.class }, + resourceType = { FormConstants.RT_FD_FORM_SUMMARY_STEP_V1 }) +@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class SummaryStepImpl extends AbstractBaseImpl implements SummaryStep { + + static final String PROP_DISPLAY_MSG = "displayMsg"; + static final String PROP_AUTO_SUBMIT = "autoSubmit"; + + static final String VIEW_TYPE_SUMMARY_STEP = "summary-step"; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_DISPLAY_MSG) + @Nullable + private String displayMsg; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_AUTO_SUBMIT) + @Default(booleanValues = true) + private boolean autoSubmit; + + @Override + public String getDisplayMsg() { + return displayMsg; + } + + @Override + public boolean isAutoSubmit() { + return autoSubmit; + } + + @Override + public String getFieldType() { + return super.getFieldType(FieldType.PLAIN_TEXT); + } + + @Override + public @NotNull Map getProperties() { + Map properties = super.getProperties(); + if (getDisplayMsg() != null) { + properties.put("fd:displayMsg", getDisplayMsg()); + } + properties.put("fd:autoSubmit", isAutoSubmit()); + return properties; + } +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TextImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TextImpl.java index de6d93342a..16bcf358e6 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TextImpl.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TextImpl.java @@ -15,6 +15,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ package com.adobe.cq.forms.core.components.internal.models.v1.form; +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; @@ -37,20 +38,31 @@ adaptables = { SlingHttpServletRequest.class, Resource.class }, adapters = { Text.class, ComponentExporter.class }, - resourceType = { FormConstants.RT_FD_FORM_TEXT_DRAW_V1 }) + resourceType = { + FormConstants.RT_FD_FORM_TEXT_DRAW_V1, + FormConstants.RT_FD_FORM_ADOBE_SIGN_BLOCK_V1 }) @Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) public class TextImpl extends AbstractFormComponentImpl implements Text { + private static final String PN_LEGACY_VALUE = "_value"; + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.PN_TEXT_IS_RICH) @Default(booleanValues = false) private boolean textIsRich; + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PN_LEGACY_VALUE) + private String legacyValue; + @SlingObject private Resource resource; @Override public String getValue() { - return translate("value", value); + String resolvedValue = translate("value", value); + if (StringUtils.isBlank(resolvedValue) && StringUtils.isNotBlank(legacyValue)) { + return legacyValue; + } + return resolvedValue; } @Override diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImpl.java index ee8580198c..e6194a39c6 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImpl.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImpl.java @@ -15,6 +15,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ package com.adobe.cq.forms.core.components.internal.models.v2.form; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; @@ -88,6 +89,30 @@ public class FormContainerImpl extends AbstractContainerImpl implements FormCont private static final String FD_DATA_URL = "fd:dataUrl"; private static final String FD_VIEW_PRINT_PATH = "fd:view/print"; private static final String EXCLUDE_FROM_DOR_IF_HIDDEN = "excludeFromDoRIfHidden"; + private static final String PN_USE_SIGNED_PDF = "_useSignedPdf"; + private static final String PN_SIGNER_INFO = "signerInfo"; + private static final String PN_FIRST_SIGNER_FORM_FILLER = "firstSignerFormFiller"; + private static final String PN_SIGN_CONFIG_PATH = "signConfigPath"; + private static final String PN_WORKFLOW_TYPE = "workflowType"; + private static final String PN_DAYS_UNTIL_SIGNING_DEADLINE = "daysUntilSigningDeadline"; + private static final String PN_SIGNERS = "signers"; + private static final String PN_SIGNER_TITLE = "signerTitle"; + private static final String PN_IS_FORM_FILLER = "isFormFiller"; + private static final String PN_SIGNER_EMAIL_TYPE = "signerEmailType"; + private static final String PN_SIGNER_EMAIL_REF = "signerEmailRef"; + private static final String PN_SIGNER_EMAIL = "signerEmail"; + private static final String PN_AUTHENTICATION_METHOD = "authenticationMethod"; + private static final String PN_COUNTRY_CODE_SOURCE = "countryCodeSource"; + private static final String PN_COUNTRY_CODE = "countryCode"; + private static final String PN_PHONE_SOURCE = "phoneSource"; + private static final String PN_PHONE = "phone"; + private static final String PN_SIGNATURE_TYPE = "signatureType"; + private static final String FD_USE_SIGNED_PDF = "fd:useSignedPdf"; + private static final String FD_IS_FORM_FILLER_FIRST_SIGNER = "fd:isFormFillerFirstSigner"; + private static final String FD_SIGNING_CLOUD_SERVICE = "fd:signingCloudService"; + private static final String FD_WORKFLOW_TYPE = "fd:workflowType"; + private static final String FD_DAYS_UNTIL_SIGNING_DEADLINE = "fd:daysUntilSigningDeadline"; + private static final String FD_SIGNERS = "fd:signers"; /** Constant representing email submit action type */ private static final String SS_EMAIL = "email"; @@ -159,6 +184,16 @@ public class FormContainerImpl extends AbstractContainerImpl implements FormCont @Self(injectionStrategy = InjectionStrategy.OPTIONAL) private AutoSaveConfiguration autoSaveConfig; + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PN_USE_SIGNED_PDF) + @Default(booleanValues = false) + private boolean useSignedPdf; + + private boolean formFillerFirstSigner = false; + private String signingCloudService = null; + private String workflowType = "SEQUENTIAL"; + private int daysUntilSigningDeadline = 1; + private List> signers = new ArrayList<>(); + @Inject private ResourceResolver resourceResolver; @@ -199,6 +234,52 @@ private void initExcludeFromDoRIfHidden() { } } + @PostConstruct + private void initSignerInfo() { + Resource signerInfoResource = resource.getChild(PN_SIGNER_INFO); + if (signerInfoResource != null) { + ValueMap vm = signerInfoResource.getValueMap(); + formFillerFirstSigner = vm.get(PN_FIRST_SIGNER_FORM_FILLER, false); + signingCloudService = vm.get(PN_SIGN_CONFIG_PATH, String.class); + workflowType = vm.get(PN_WORKFLOW_TYPE, "SEQUENTIAL"); + daysUntilSigningDeadline = vm.get(PN_DAYS_UNTIL_SIGNING_DEADLINE, 1); + Resource signersResource = signerInfoResource.getChild(PN_SIGNERS); + if (signersResource != null) { + for (Resource signerItem : signersResource.getChildren()) { + ValueMap signerVm = signerItem.getValueMap(); + Map signerMap = new LinkedHashMap<>(); + + String title = signerVm.get(PN_SIGNER_TITLE, String.class); + String isFormFillerVal = signerVm.get(PN_IS_FORM_FILLER, "true"); + String emailType = signerVm.get(PN_SIGNER_EMAIL_TYPE, "fromForm"); + String emailRef = signerVm.get(PN_SIGNER_EMAIL_REF, String.class); + String signerEmail = signerVm.get(PN_SIGNER_EMAIL, String.class); + String authMethod = signerVm.get(PN_AUTHENTICATION_METHOD, "NONE"); + String countryCodeSource = signerVm.get(PN_COUNTRY_CODE_SOURCE, "form"); + String countryCode = signerVm.get(PN_COUNTRY_CODE, String.class); + String phoneSource = signerVm.get(PN_PHONE_SOURCE, "form"); + String phone = signerVm.get(PN_PHONE, String.class); + String sigType = signerVm.get(PN_SIGNATURE_TYPE, "ESIGN"); + + if (title != null) signerMap.put(PN_SIGNER_TITLE, title); + signerMap.put(PN_IS_FORM_FILLER, Boolean.parseBoolean(isFormFillerVal)); + signerMap.put(PN_SIGNER_EMAIL_TYPE, emailType); + if (emailRef != null) signerMap.put(PN_SIGNER_EMAIL_REF, emailRef); + if (signerEmail != null) signerMap.put(PN_SIGNER_EMAIL, signerEmail); + signerMap.put(PN_AUTHENTICATION_METHOD, authMethod); + if ("PHONE".equals(authMethod)) { + signerMap.put(PN_COUNTRY_CODE_SOURCE, countryCodeSource); + if (countryCode != null) signerMap.put(PN_COUNTRY_CODE, countryCode); + signerMap.put(PN_PHONE_SOURCE, phoneSource); + if (phone != null) signerMap.put(PN_PHONE, phone); + } + signerMap.put(PN_SIGNATURE_TYPE, sigType); + signers.add(signerMap); + } + } + } + } + @Override public void setContextPath(String contextPath) { this.contextPath = contextPath; @@ -420,6 +501,18 @@ public String getLanguageDirection() { if (submitProperties != null && !submitProperties.isEmpty()) { properties.put(ReservedProperties.FD_SUBMIT_PROPERTIES, submitProperties); } + if (isAdobeSignEnabled()) { + properties.put(FD_USE_SIGNED_PDF, true); + properties.put(FD_IS_FORM_FILLER_FIRST_SIGNER, isFormFillerFirstSigner()); + if (signingCloudService != null) { + properties.put(FD_SIGNING_CLOUD_SERVICE, signingCloudService); + } + properties.put(FD_WORKFLOW_TYPE, workflowType); + properties.put(FD_DAYS_UNTIL_SIGNING_DEADLINE, daysUntilSigningDeadline); + if (!signers.isEmpty()) { + properties.put(FD_SIGNERS, signers); + } + } return properties; } @@ -488,6 +581,18 @@ public AutoSaveConfiguration getAutoSaveConfig() { return autoSaveConfig; } + @JsonIgnore + @Override + public boolean isAdobeSignEnabled() { + return useSignedPdf; + } + + @JsonIgnore + @Override + public boolean isFormFillerFirstSigner() { + return formFillerFirstSigner; + } + private Map getSubmitProperties() { Map submitProps = null; diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormContainer.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormContainer.java index a617157c7b..20396013f5 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormContainer.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormContainer.java @@ -402,4 +402,28 @@ default AutoSaveConfiguration getAutoSaveConfig() { return null; } + /** + * Returns whether Adobe Sign (echosign) is enabled for this form. + * Reads the {@code _useSignedPdf} JCR property on the form container node. + * + * @return {@code true} if Adobe Sign is enabled, {@code false} otherwise + * @since com.adobe.cq.forms.core.components.models.form 5.12.5 + */ + @JsonIgnore + default boolean isAdobeSignEnabled() { + return false; + } + + /** + * Returns whether the form filler is the first signer in the Adobe Sign workflow. + * Reads the {@code firstSignerFormFiller} property from the {@code signerInfo} child resource. + * + * @return {@code true} if the form filler is the first signer, {@code false} otherwise + * @since com.adobe.cq.forms.core.components.models.form 5.12.5 + */ + @JsonIgnore + default boolean isFormFillerFirstSigner() { + return false; + } + } diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SignatureStep.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SignatureStep.java new file mode 100644 index 0000000000..b4267e1445 --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SignatureStep.java @@ -0,0 +1,66 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.models.form; + +import org.osgi.annotation.versioning.ConsumerType; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Defines the {@code SignatureStep} Sling Model used for the + * {@code /apps/core/fd/components/form/signaturestep} component. + * + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ +@ConsumerType +public interface SignatureStep extends Base { + + /** + * Returns the signing service configured for this step (e.g. "echosign" for Adobe Sign). + * + * @return the signing service identifier + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getSigningService(); + + /** + * Returns the Adobe Sign cloud service configuration path. + * + * @return cloud service config path, or empty string if not configured + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getCloudServiceConfig(); + + /** + * Returns the template message displayed inside the signing area. + * + * @return display message, or {@code null} if not set + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getDisplayMsg(); + + /** + * Returns the Adobe Sign agreement target version. + * + * @return target version string, or {@code null} if not set + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getTargetVersion(); +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SummaryStep.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SummaryStep.java new file mode 100644 index 0000000000..bd16ac34b7 --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SummaryStep.java @@ -0,0 +1,48 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.models.form; + +import org.osgi.annotation.versioning.ConsumerType; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Defines the {@code SummaryStep} Sling Model used for the + * {@code /apps/core/fd/components/form/summarystep} component. + * + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ +@ConsumerType +public interface SummaryStep extends Base { + + /** + * Returns the rich-text summary message displayed after form submission. + * + * @return HTML display message, or {@code null} if not set + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getDisplayMsg(); + + /** + * Returns whether the form should be auto-submitted when this step is reached. + * + * @return {@code true} if auto-submit is enabled + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + boolean isAutoSubmit(); +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java index 28bc21d5c0..f2979e29a1 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java @@ -35,7 +35,7 @@ *

*/ -@Version("5.12.3") +@Version("5.12.5") package com.adobe.cq.forms.core.components.models.form; import org.osgi.annotation.versioning.Version; diff --git a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImplTest.java b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImplTest.java new file mode 100644 index 0000000000..bebd1f8e0b --- /dev/null +++ b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImplTest.java @@ -0,0 +1,136 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.adobe.cq.forms.core.Utils; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.SignatureStep; +import com.adobe.cq.forms.core.context.FormsCoreComponentTestContext; +import io.wcm.testing.mock.aem.junit5.AemContext; +import io.wcm.testing.mock.aem.junit5.AemContextExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(AemContextExtension.class) +public class SignatureStepImplTest { + + private static final String TEST_BASE = "/form/signaturestep"; + private static final String APPS_ROOT = "/apps"; + private static final String PATH_SIGNATURE_STEP = APPS_ROOT + "/signaturestep"; + private static final String PATH_SIGNATURE_STEP_DEFAULTS = APPS_ROOT + "/signaturestep-defaults"; + + private final AemContext context = FormsCoreComponentTestContext.newAemContext(); + + @BeforeEach + void setUp() { + context.load().json(TEST_BASE + FormsCoreComponentTestContext.TEST_CONTENT_JSON, APPS_ROOT); + } + + @Test + void testGetFieldType() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals(FieldType.PLAIN_TEXT.getValue(), signatureStep.getFieldType()); + } + + @Test + void testGetFieldTypeOnNewInstance() { + SignatureStep signatureStep = new SignatureStepImpl(); + assertEquals(FieldType.PLAIN_TEXT.getValue(), signatureStep.getFieldType()); + } + + @Test + void testGetSigningService() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("echosign", signatureStep.getSigningService()); + } + + @Test + void testGetSigningServiceDefault() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + assertEquals(SignatureStepImpl.DEFAULT_SIGNING_SERVICE, signatureStep.getSigningService()); + } + + @Test + void testGetDisplayMsg() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("Please sign the document", signatureStep.getDisplayMsg()); + } + + @Test + void testGetDisplayMsgDefault() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + assertNull(signatureStep.getDisplayMsg()); + } + + @Test + void testGetCloudServiceConfig() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("/etc/cloudservices/echosign/myConfig", signatureStep.getCloudServiceConfig()); + } + + @Test + void testGetCloudServiceConfigDefault() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + assertEquals("", signatureStep.getCloudServiceConfig()); + } + + @Test + void testGetTargetVersion() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("1.0", signatureStep.getTargetVersion()); + } + + @Test + void testGetTargetVersionDefault() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + assertNull(signatureStep.getTargetVersion()); + } + + @Test + void testGetProperties() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + Map properties = signatureStep.getProperties(); + assertNotNull(properties); + assertEquals("echosign", properties.get("fd:signingService")); + assertEquals("/etc/cloudservices/echosign/myConfig", properties.get("fd:cloudServiceConfig")); + assertEquals("Please sign the document", properties.get("fd:displayMsg")); + assertEquals("1.0", properties.get("fd:targetVersion")); + assertEquals(APPS_ROOT + "/signaturestep", properties.get("fd:path")); + } + + @Test + void testGetPropertiesDefaults() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + Map properties = signatureStep.getProperties(); + assertNotNull(properties); + assertEquals(SignatureStepImpl.DEFAULT_SIGNING_SERVICE, properties.get("fd:signingService")); + assertFalse(properties.containsKey("fd:cloudServiceConfig")); + assertFalse(properties.containsKey("fd:displayMsg")); + assertFalse(properties.containsKey("fd:targetVersion")); + } + + @Test + void testGetExportedType() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("core/fd/components/form/signaturestep/v1/signaturestep", signatureStep.getExportedType()); + } +} diff --git a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImplTest.java b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImplTest.java new file mode 100644 index 0000000000..39ad8eaa0d --- /dev/null +++ b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImplTest.java @@ -0,0 +1,108 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.adobe.cq.forms.core.Utils; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.SummaryStep; +import com.adobe.cq.forms.core.context.FormsCoreComponentTestContext; +import io.wcm.testing.mock.aem.junit5.AemContext; +import io.wcm.testing.mock.aem.junit5.AemContextExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(AemContextExtension.class) +public class SummaryStepImplTest { + + private static final String TEST_BASE = "/form/summarystep"; + private static final String APPS_ROOT = "/apps"; + private static final String PATH_SUMMARY_STEP = APPS_ROOT + "/summarystep"; + private static final String PATH_SUMMARY_STEP_DEFAULTS = APPS_ROOT + "/summarystep-defaults"; + + private final AemContext context = FormsCoreComponentTestContext.newAemContext(); + + @BeforeEach + void setUp() { + context.load().json(TEST_BASE + FormsCoreComponentTestContext.TEST_CONTENT_JSON, APPS_ROOT); + } + + @Test + void testGetFieldType() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + assertEquals(FieldType.PLAIN_TEXT.getValue(), summaryStep.getFieldType()); + } + + @Test + void testGetFieldTypeOnNewInstance() { + SummaryStep summaryStep = new SummaryStepImpl(); + assertEquals(FieldType.PLAIN_TEXT.getValue(), summaryStep.getFieldType()); + } + + @Test + void testGetDisplayMsg() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + assertEquals("

Thank you for submitting the form.

", summaryStep.getDisplayMsg()); + } + + @Test + void testGetDisplayMsgDefault() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP_DEFAULTS, SummaryStepImpl.class, context); + assertNull(summaryStep.getDisplayMsg()); + } + + @Test + void testIsAutoSubmit() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + assertTrue(summaryStep.isAutoSubmit()); + } + + @Test + void testIsAutoSubmitDefault() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP_DEFAULTS, SummaryStepImpl.class, context); + assertTrue(summaryStep.isAutoSubmit()); + } + + @Test + void testGetProperties() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + Map properties = summaryStep.getProperties(); + assertNotNull(properties); + assertEquals("

Thank you for submitting the form.

", properties.get("fd:displayMsg")); + assertEquals(true, properties.get("fd:autoSubmit")); + assertEquals(APPS_ROOT + "/summarystep", properties.get("fd:path")); + } + + @Test + void testGetPropertiesDefaults() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP_DEFAULTS, SummaryStepImpl.class, context); + Map properties = summaryStep.getProperties(); + assertNotNull(properties); + assertFalse(properties.containsKey("fd:displayMsg")); + assertEquals(true, properties.get("fd:autoSubmit")); + } + + @Test + void testGetExportedType() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + assertEquals("core/fd/components/form/summarystep/v1/summarystep", summaryStep.getExportedType()); + } +} diff --git a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImplTest.java b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImplTest.java index 43b2d53428..ca68999abb 100644 --- a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImplTest.java +++ b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImplTest.java @@ -117,6 +117,8 @@ public class FormContainerImplTest { private static final String SS_SPREADSHEET = "spreadsheet"; private static final String PATH_FORM_EXCLUDE_FROM_DOR_IF_HIDDEN = "/content/forms/af/demo/jcr:content/formcontainerv2-excludeFromDoRIfHidden"; + private static final String PATH_FORM_WITH_ADOBE_SIGN = CONTENT_ROOT + "/formcontainerv2WithAdobeSign"; + private static final String PATH_FORM_WITH_ADOBE_SIGN_NO_FIRST_SIGNER = CONTENT_ROOT + "/formcontainerv2WithAdobeSignNoFirstSigner"; private final AemContext context = FormsCoreComponentTestContext.newAemContext(); @@ -917,4 +919,53 @@ void testSetLang() throws Exception { formContainer.setLang(null); assertEquals(formContainer.getLang(), "en"); } + + @Test + void testIsAdobeSignEnabled() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_WITH_ADOBE_SIGN, FormContainer.class, context); + assertTrue(formContainer.isAdobeSignEnabled()); + } + + @Test + void testIsAdobeSignEnabledDefault() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_1, FormContainer.class, context); + assertFalse(formContainer.isAdobeSignEnabled()); + } + + @Test + void testIsFormFillerFirstSigner() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_WITH_ADOBE_SIGN, FormContainer.class, context); + assertTrue(formContainer.isFormFillerFirstSigner()); + } + + @Test + void testIsFormFillerFirstSignerDefault() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_1, FormContainer.class, context); + assertFalse(formContainer.isFormFillerFirstSigner()); + } + + @Test + void testIsFormFillerFirstSignerWhenFalse() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_WITH_ADOBE_SIGN_NO_FIRST_SIGNER, FormContainer.class, context); + assertTrue(formContainer.isAdobeSignEnabled()); + assertFalse(formContainer.isFormFillerFirstSigner()); + } + + @Test + void testGetPropertiesWithAdobeSign() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_WITH_ADOBE_SIGN, FormContainer.class, context); + Map properties = formContainer.getProperties(); + assertNotNull(properties); + assertTrue((Boolean) properties.get("fd:useSignedPdf")); + assertTrue((Boolean) properties.get("fd:isFormFillerFirstSigner")); + } + + @Test + void testGetPropertiesWithoutAdobeSign() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_1, FormContainer.class, context); + Map properties = formContainer.getProperties(); + assertNotNull(properties); + assertFalse(properties.containsKey("fd:useSignedPdf")); + assertFalse(properties.containsKey("fd:isFormFillerFirstSigner")); + } } diff --git a/bundles/af-core/src/test/resources/form/formcontainer/test-page-content.json b/bundles/af-core/src/test/resources/form/formcontainer/test-page-content.json index 7a9ca98bf2..5bcfc1612b 100644 --- a/bundles/af-core/src/test/resources/form/formcontainer/test-page-content.json +++ b/bundles/af-core/src/test/resources/form/formcontainer/test-page-content.json @@ -210,6 +210,26 @@ "visible": false }, "actionType": "fd/af/components/guidesubmittype/rest" + }, + "formcontainerv2WithAdobeSign": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/container/v2/container", + "fieldType": "form", + "_useSignedPdf": true, + "signerInfo": { + "jcr:primaryType": "nt:unstructured", + "firstSignerFormFiller": true + } + }, + "formcontainerv2WithAdobeSignNoFirstSigner": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/container/v2/container", + "fieldType": "form", + "_useSignedPdf": true, + "signerInfo": { + "jcr:primaryType": "nt:unstructured", + "firstSignerFormFiller": false + } } } } diff --git a/bundles/af-core/src/test/resources/form/signaturestep/test-content.json b/bundles/af-core/src/test/resources/form/signaturestep/test-content.json new file mode 100644 index 0000000000..e16ef24ee7 --- /dev/null +++ b/bundles/af-core/src/test/resources/form/signaturestep/test-content.json @@ -0,0 +1,22 @@ +{ + "signaturestep": { + "jcr:primaryType": "nt:unstructured", + "jcr:title": "Signature Step", + "id": "signaturestep-test", + "name": "signaturestep1", + "fieldType": "plain-text", + "signingService": "echosign", + "displayMsg": "Please sign the document", + "cq:cloudserviceconfigs": "/etc/cloudservices/echosign/myConfig", + "fd:targetVersion": "1.0", + "sling:resourceType": "core/fd/components/form/signaturestep/v1/signaturestep" + }, + "signaturestep-defaults": { + "jcr:primaryType": "nt:unstructured", + "jcr:title": "Signature Step Defaults", + "id": "signaturestep-defaults-test", + "name": "signaturestepDefaults", + "fieldType": "plain-text", + "sling:resourceType": "core/fd/components/form/signaturestep/v1/signaturestep" + } +} diff --git a/bundles/af-core/src/test/resources/form/summarystep/test-content.json b/bundles/af-core/src/test/resources/form/summarystep/test-content.json new file mode 100644 index 0000000000..e53063e967 --- /dev/null +++ b/bundles/af-core/src/test/resources/form/summarystep/test-content.json @@ -0,0 +1,20 @@ +{ + "summarystep": { + "jcr:primaryType": "nt:unstructured", + "jcr:title": "Summary Step", + "id": "summarystep-test", + "name": "summarystep1", + "fieldType": "plain-text", + "displayMsg": "

Thank you for submitting the form.

", + "autoSubmit": true, + "sling:resourceType": "core/fd/components/form/summarystep/v1/summarystep" + }, + "summarystep-defaults": { + "jcr:primaryType": "nt:unstructured", + "jcr:title": "Summary Step Defaults", + "id": "summarystep-defaults-test", + "name": "summarystepDefaults", + "fieldType": "plain-text", + "sling:resourceType": "core/fd/components/form/summarystep/v1/summarystep" + } +} diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/.content.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/.content.xml new file mode 100644 index 0000000000..3014749074 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/.content.xml @@ -0,0 +1,7 @@ + + diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/_cq_template.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/_cq_template.xml new file mode 100644 index 0000000000..45edf9ec5f --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/_cq_template.xml @@ -0,0 +1,9 @@ + + diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/.content.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/.content.xml new file mode 100644 index 0000000000..ccfce437c5 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/.content.xml @@ -0,0 +1,7 @@ + + diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/_cq_template.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/_cq_template.xml new file mode 100644 index 0000000000..2bb7f769e9 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/_cq_template.xml @@ -0,0 +1,7 @@ + + diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/signaturestep/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/signaturestep/.content.xml new file mode 100644 index 0000000000..bbf62ed22c --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/signaturestep/.content.xml @@ -0,0 +1,5 @@ + +