diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java
index 80db2c2157..e32da39217 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java
@@ -158,6 +158,10 @@ private ReservedProperties() {
public static final String PN_EXCLUDE_FROM_DOR = "excludeFromDor";
public static final String PN_MANDATORY = "mandatory";
public static final String PN_HTML_ELEMENT_TYPE_V2 = "fd:htmlelementType";
+ public static final String FD_AUTO_SAVE_PROPERTY_WRAPPER = "fd:autoSave";
+ public static final String FD_ENABLE_AUTO_SAVE = "fd:enableAutoSave";
+ public static final String FD_AUTO_SAVE_STRATEGY_TYPE = "fd:autoSaveStrategyType";
+ public static final String FD_AUTO_SAVE_INTERVAL = "fd:autoSaveInterval";
private static final Set reservedProperties = aggregateReservedProperties();
private static Set aggregateReservedProperties() {
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/AutoSaveConfigurationImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/AutoSaveConfigurationImpl.java
new file mode 100644
index 0000000000..5f97e8e022
--- /dev/null
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/AutoSaveConfigurationImpl.java
@@ -0,0 +1,79 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.v2.form;
+
+import javax.annotation.PostConstruct;
+
+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 com.adobe.cq.export.json.ExporterConstants;
+import com.adobe.cq.forms.core.components.internal.form.ReservedProperties;
+import com.adobe.cq.forms.core.components.models.form.AutoSaveConfiguration;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@Model(
+ adaptables = { SlingHttpServletRequest.class, Resource.class },
+ adapters = AutoSaveConfiguration.class)
+@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)
+public class AutoSaveConfigurationImpl implements AutoSaveConfiguration {
+
+ @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.FD_ENABLE_AUTO_SAVE)
+ @Default(booleanValues = false)
+ @JsonProperty(ReservedProperties.FD_ENABLE_AUTO_SAVE)
+ private boolean enableAutoSave;
+
+ @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.FD_AUTO_SAVE_STRATEGY_TYPE)
+ @JsonIgnore
+ private String autoSaveStrategyJcr;
+
+ @JsonProperty(ReservedProperties.FD_AUTO_SAVE_STRATEGY_TYPE)
+ private AutoSaveStrategyType autoSaveStrategyType;
+
+ @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.FD_AUTO_SAVE_INTERVAL)
+ @JsonProperty(ReservedProperties.FD_AUTO_SAVE_INTERVAL)
+ private Integer autoSaveInterval;
+
+ @Override
+ public boolean isEnableAutoSave() {
+ return enableAutoSave;
+ }
+
+ @Override
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public AutoSaveStrategyType getAutoSaveStrategyType() {
+ return autoSaveStrategyType;
+ }
+
+ @Override
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public Integer getAutoSaveInterval() {
+ return autoSaveInterval;
+ }
+
+ @PostConstruct
+ protected void initAutoSaveConfiguration() {
+ autoSaveStrategyType = AutoSaveStrategyType.fromString(autoSaveStrategyJcr);
+ }
+
+}
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 af40e4d3a3..ed89546728 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
@@ -28,6 +28,7 @@
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.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.jetbrains.annotations.NotNull;
@@ -46,6 +47,7 @@
import com.adobe.cq.forms.core.components.internal.form.FormConstants;
import com.adobe.cq.forms.core.components.internal.form.ReservedProperties;
import com.adobe.cq.forms.core.components.internal.models.v1.form.FormMetaDataImpl;
+import com.adobe.cq.forms.core.components.models.form.AutoSaveConfiguration;
import com.adobe.cq.forms.core.components.models.form.Container;
import com.adobe.cq.forms.core.components.models.form.FormClientLibManager;
import com.adobe.cq.forms.core.components.models.form.FormContainer;
@@ -119,6 +121,9 @@ public class FormContainerImpl extends AbstractContainerImpl implements FormCont
@Default(values = DEFAULT_FORMS_SPEC_VERSION)
private String specVersion;
+ @Self(injectionStrategy = InjectionStrategy.OPTIONAL)
+ private AutoSaveConfiguration autoSaveConfig;
+
@PostConstruct
protected void initFormContainerModel() {
if (request != null) {
@@ -314,6 +319,7 @@ public String getLanguageDirection() {
}
properties.put(FD_ROLE_ATTRIBUTE, getRoleAttribute());
properties.put(FD_FORM_DATA_ENABLED, formDataEnabled);
+ properties.put(ReservedProperties.FD_AUTO_SAVE_PROPERTY_WRAPPER, this.autoSaveConfig);
return properties;
}
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/AutoSaveConfiguration.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/AutoSaveConfiguration.java
new file mode 100644
index 0000000000..8671eb3ca7
--- /dev/null
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/AutoSaveConfiguration.java
@@ -0,0 +1,79 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.apache.commons.lang3.StringUtils;
+import org.osgi.annotation.versioning.ProviderType;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/**
+ * Defines the auto save configuration {@code AutoSaveConfiguration}
+ *
+ * @since com.adobe.cq.forms.core.components.models.form 5.5.4
+ */
+@ProviderType
+public interface AutoSaveConfiguration {
+
+ enum AutoSaveStrategyType {
+ TIME("time");
+
+ private String strategyType;
+
+ AutoSaveStrategyType(String strategyType) {
+ this.strategyType = strategyType;
+ }
+
+ public String getStrategyType() {
+ return strategyType;
+ }
+
+ /**
+ * Given a {@link String} strategyType, this method returns the enum's value that corresponds to the provided string
+ * representation
+ *
+ * @param strategyType the string representation for which an enum value should be returned
+ * @return the corresponding enum value, if one was found
+ * @since com.adobe.cq.forms.core.components.models.form 5.5.4
+ */
+ public static AutoSaveStrategyType fromString(String strategyType) {
+ for (AutoSaveStrategyType type : AutoSaveStrategyType.values()) {
+ if (StringUtils.equals(strategyType, type.strategyType)) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ @JsonValue
+ public String toString() {
+ return getStrategyType();
+ }
+ }
+
+ default boolean isEnableAutoSave() {
+ return false;
+ }
+
+ default AutoSaveStrategyType getAutoSaveStrategyType() {
+ return AutoSaveStrategyType.TIME;
+ }
+
+ default Integer getAutoSaveInterval() {
+ return 0;
+ }
+}
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 d48bd538f7..3d71430765 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.5.3") // aligning this with release/650 since af2-rest-api is compiled with 5.2.0 in release/650
+@Version("5.5.4") // aligning this with release/650 since af2-rest-api is compiled with 5.2.0 in release/650
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/v2/form/AutoSaveConfigurationTest.java b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/AutoSaveConfigurationTest.java
new file mode 100644
index 0000000000..71037f4131
--- /dev/null
+++ b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/AutoSaveConfigurationTest.java
@@ -0,0 +1,72 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.v2.form;
+
+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.components.models.form.AutoSaveConfiguration;
+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.Assert.assertEquals;
+
+@ExtendWith(AemContextExtension.class)
+public class AutoSaveConfigurationTest {
+
+ private static final String BASE = "/form/formcontainer";
+ private static final String TEST_CONTENT = BASE + "/test-content-auto-save.json";
+ private static final String GUIDE_CONTAINER_ROOT = "/content/forms/af/testform/jcr:content/guideContainer";
+
+ private final AemContext context = FormsCoreComponentTestContext.newAemContext();
+
+ @BeforeEach
+ void setUp() {
+ context.load().json(TEST_CONTENT, GUIDE_CONTAINER_ROOT);
+ context.request().setResource(context.currentResource(GUIDE_CONTAINER_ROOT));
+ }
+
+ @Test
+ void testAutoSaveConfigurationForDefaultImplementation() {
+ final AutoSaveConfiguration autoSaveConfiguration = new AutoSaveConfiguration() {
+
+ };
+ assertEquals(false, autoSaveConfiguration.isEnableAutoSave());
+ assertEquals(AutoSaveConfiguration.AutoSaveStrategyType.TIME, autoSaveConfiguration.getAutoSaveStrategyType());
+ assertEquals((Integer) 0, autoSaveConfiguration.getAutoSaveInterval());
+ }
+
+ @Test
+ void testAutoSaveConfigurationForResourceAdaptation() {
+
+ final AutoSaveConfiguration autoSaveConfiguration = context.currentResource(GUIDE_CONTAINER_ROOT).adaptTo(
+ AutoSaveConfiguration.class);
+ assertEquals(true, autoSaveConfiguration.isEnableAutoSave());
+ assertEquals(AutoSaveConfiguration.AutoSaveStrategyType.TIME, autoSaveConfiguration.getAutoSaveStrategyType());
+ assertEquals((Integer) 2, autoSaveConfiguration.getAutoSaveInterval());
+ }
+
+ @Test
+ void testAutoSaveConfigurationForRequestAdaptation() {
+ final AutoSaveConfiguration autoSaveConfiguration = context.request().adaptTo(AutoSaveConfiguration.class);
+ assertEquals(true, autoSaveConfiguration.isEnableAutoSave());
+ assertEquals(AutoSaveConfiguration.AutoSaveStrategyType.TIME, autoSaveConfiguration.getAutoSaveStrategyType());
+ assertEquals((Integer) 2, autoSaveConfiguration.getAutoSaveInterval());
+ }
+
+}
diff --git a/bundles/af-core/src/test/resources/form/formcontainer/exporter-formcontainerv2.json b/bundles/af-core/src/test/resources/form/formcontainer/exporter-formcontainerv2.json
index d27184ca07..2a9db08623 100644
--- a/bundles/af-core/src/test/resources/form/formcontainer/exporter-formcontainerv2.json
+++ b/bundles/af-core/src/test/resources/form/formcontainer/exporter-formcontainerv2.json
@@ -8,6 +8,9 @@
"dorType": "generate",
"dorTemplateRef": "xyz"
},
+ "fd:autoSave": {
+ "fd:enableAutoSave":false
+ },
"fd:path": "/content/forms/af/demo/jcr:content/formcontainerv2",
"fd:schemaType": "BASIC",
"fd:formDataEnabled": true,
diff --git a/bundles/af-core/src/test/resources/form/formcontainer/test-content-auto-save.json b/bundles/af-core/src/test/resources/form/formcontainer/test-content-auto-save.json
new file mode 100644
index 0000000000..6117603567
--- /dev/null
+++ b/bundles/af-core/src/test/resources/form/formcontainer/test-content-auto-save.json
@@ -0,0 +1,11 @@
+{
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType" : "core/fd/components/form/container/v2/container",
+ "thankyouPage": "/a/b/c",
+ "thankyouMessage": "message",
+ "fieldType" : "form",
+ "prefillService" : "abc",
+ "fd:enableAutoSave": "true",
+ "fd:autoSaveInterval": "2",
+ "fd:autoSaveStrategyType": "time"
+}
diff --git a/it/config/src/main/content/jcr_root/apps/system/config/com.adobe.granite.toggle.impl.dev.DynamicToggleProviderImpl.cfg.json b/it/config/src/main/content/jcr_root/apps/system/config/com.adobe.granite.toggle.impl.dev.DynamicToggleProviderImpl.cfg.json
index 86d79314d0..5b455dbc34 100644
--- a/it/config/src/main/content/jcr_root/apps/system/config/com.adobe.granite.toggle.impl.dev.DynamicToggleProviderImpl.cfg.json
+++ b/it/config/src/main/content/jcr_root/apps/system/config/com.adobe.granite.toggle.impl.dev.DynamicToggleProviderImpl.cfg.json
@@ -18,6 +18,7 @@
"FT_FORMS-13209",
"FT_FORMS-11581",
"FT_FORMS-14545",
- "FT_SITES-19631"
+ "FT_SITES-19631",
+ "FT_FORMS-14255"
]
}
diff --git a/it/content/src/main/content/META-INF/vault/filter.xml b/it/content/src/main/content/META-INF/vault/filter.xml
index 6610ec450a..5ae72b9afa 100644
--- a/it/content/src/main/content/META-INF/vault/filter.xml
+++ b/it/content/src/main/content/META-INF/vault/filter.xml
@@ -6,6 +6,7 @@
+
diff --git a/it/content/src/main/content/jcr_root/conf/global/settings/forms/.content.xml b/it/content/src/main/content/jcr_root/conf/global/settings/forms/.content.xml
new file mode 100644
index 0000000000..a0ac99e384
--- /dev/null
+++ b/it/content/src/main/content/jcr_root/conf/global/settings/forms/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/.content.xml b/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/.content.xml
new file mode 100644
index 0000000000..a0ac99e384
--- /dev/null
+++ b/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/portal/.content.xml b/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/portal/.content.xml
new file mode 100644
index 0000000000..a0ac99e384
--- /dev/null
+++ b/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/portal/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/portal/portal/.content.xml b/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/portal/portal/.content.xml
new file mode 100644
index 0000000000..3a6dde7cd0
--- /dev/null
+++ b/it/content/src/main/content/jcr_root/conf/global/settings/forms/usc/portal/portal/.content.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/autosave/.content.xml b/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/autosave/.content.xml
new file mode 100644
index 0000000000..74aeef758a
--- /dev/null
+++ b/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/autosave/.content.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/autosave/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/autosave/.content.xml
new file mode 100644
index 0000000000..e4b53a79e9
--- /dev/null
+++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/autosave/.content.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v1/container/clientlibs/editor/js/editDialog.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v1/container/clientlibs/editor/js/editDialog.js
index c1049dd3ef..58bca1b835 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v1/container/clientlibs/editor/js/editDialog.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v1/container/clientlibs/editor/js/editDialog.js
@@ -41,6 +41,8 @@
REST_ENDPOINT = ".rest",
FDM = ".fdm",
EMAIL = ".email",
+ ENABLE_AUTO_SAVE = "[name='./fd:enableAutoSave']",
+ AUTO_SAVE_STRATEGY_CONTAINER = ".cmp-adaptiveform-container__autoSaveStrategyContainer",
Utils = window.CQ.FormsCoreComponents.Utils.v1;
@@ -419,6 +421,31 @@
}
}
+ function showHideAutoSave(dialog) {
+ var enableAutoSave = dialog.find(ENABLE_AUTO_SAVE);
+ if (enableAutoSave[0]) {
+ var autoSaveStrategyContainer = dialog.find(AUTO_SAVE_STRATEGY_CONTAINER);
+ if (autoSaveStrategyContainer) {
+ if (enableAutoSave[0].checked) {
+ autoSaveStrategyContainer.show();
+ } else {
+ autoSaveStrategyContainer.hide();
+ }
+ }
+ }
+ }
+
+ function registerAutoSaveDialogAction(dialog) {
+ var $subDialogContent = dialog.find(SUB_DIALOG_CONTENT);
+ $subDialogContent.on('foundation-contentloaded', function() {
+ showHideAutoSave(dialog);
+ });
+ showHideAutoSave(dialog);
+ $(document).on('change', ENABLE_AUTO_SAVE, function () {
+ showHideAutoSave(dialog);
+ });
+ }
+
$(window).adaptTo("foundation-registry").register("foundation.validation.validator", {
selector : "[data-validation~='datamodel.config']",
validate : function (el) {
@@ -430,7 +457,7 @@
});
Utils.initializeEditDialog(EDIT_DIALOG_FORM)(handleAsyncSubmissionAndThankYouOption, handleSubmitAction,
- registerSubmitActionSubDialogClientLibs, registerRestEndPointDialogClientlibs, registerFDMDialogClientlibs, registerEmailDialogClientlibs, initialiseDataModel);
+ registerSubmitActionSubDialogClientLibs, registerRestEndPointDialogClientlibs, registerFDMDialogClientlibs, registerEmailDialogClientlibs, initialiseDataModel, registerAutoSaveDialogAction);
Utils.initializeEditDialog(EDIT_DIALOG_FRAGMENT)(initialiseDataModel);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/_cq_dialog/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/_cq_dialog/.content.xml
index a7b43d2dad..119e49ce73 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/_cq_dialog/.content.xml
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/_cq_dialog/.content.xml
@@ -177,6 +177,12 @@
+
{
+ formModel.dispatch(new FormView.Actions.Save({
+ 'action': saveEndPoint
+ }));
+ }, parseInt(autoSaveInterval) * 1000);
+ }
+ }
}
}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragmentcontainer/v1/fragmentcontainer/_cq_dialog/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragmentcontainer/v1/fragmentcontainer/_cq_dialog/.content.xml
index 0653eb0e64..25a29e6942 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragmentcontainer/v1/fragmentcontainer/_cq_dialog/.content.xml
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragmentcontainer/v1/fragmentcontainer/_cq_dialog/.content.xml
@@ -64,6 +64,9 @@
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/include"
path="core/fd/components/form/container/v2/container/cq:dialog/content/items/tabs/items/dataModel"/>
+
diff --git a/ui.frontend/src/index.js b/ui.frontend/src/index.js
index f9bc61b0f8..6d625af2bf 100644
--- a/ui.frontend/src/index.js
+++ b/ui.frontend/src/index.js
@@ -15,7 +15,7 @@
******************************************************************************/
import Utils from "./utils.js";
import LanguageUtils from "./LanguageUtils.js";
-import {createFormInstance, FileObject, extractFileInfo, Click, Change, Submit, Blur, AddItem, RemoveItem, CustomEvent, UIChange} from "@aemforms/af-core";
+import {createFormInstance, FileObject, extractFileInfo, Click, Change, Submit, Save, Blur, AddItem, RemoveItem, CustomEvent, UIChange} from "@aemforms/af-core";
import {FormField, FormContainer, FormFieldBase, FormPanel, FormTabs, FormFileInput, FormOptionFieldBase, FormCheckBox, FormFileInputWidgetBase, FormFileInputWidget} from "./view/index.js";
import {Constants} from "./constants.js";
import GuideBridge from "./GuideBridge.js";
@@ -46,9 +46,10 @@ window.guideBridge = new GuideBridge();
* @property {string} Blur - The action for a blur event.
* @property {string} AddItem - The action for adding an item.
* @property {string} RemoveItem - The action for removing an item.
+ * @property {string} Save - The action for save event.
*/
const Actions = {
- Click, Change, Submit, Blur, AddItem, RemoveItem, UIChange, CustomEvent
+ Click, Change, Submit, Blur, AddItem, RemoveItem, UIChange, Save, CustomEvent
}
/**
diff --git a/ui.tests/test-module/specs/autosave/autosave.runtime.spec.js b/ui.tests/test-module/specs/autosave/autosave.runtime.spec.js
new file mode 100644
index 0000000000..9c9c1e3d17
--- /dev/null
+++ b/ui.tests/test-module/specs/autosave/autosave.runtime.spec.js
@@ -0,0 +1,36 @@
+describe("Auto save handler runtime", () => {
+
+ let toggle_array = [];
+
+ before(() => {
+ cy.fetchFeatureToggles().then((response) => {
+ if (response.status === 200) {
+ toggle_array = response.body.enabled;
+ }
+ });
+ });
+
+ const autoSaveRunTime = "content/forms/af/core-components-it/samples/autosave.html"
+
+ it("should save formData after every 3 seconds", () => {
+ if (cy.af.isLatestAddon() && toggle_array.includes('FT_FORMS-14255')) {
+
+ const saveApiResponse = {
+ 'draftId': 'ABC'
+ };
+ // Rule when button is clicked then save call should trigger
+ cy.intercept('POST' , '**/adobe/forms/af/save/*', saveApiResponse).as('afSave');
+
+ cy.previewForm(autoSaveRunTime);
+
+ cy.wait('@afSave').then(({request, response}) => {
+ // Check the request payload
+ expect(request.body).to.be.not.null;
+
+ expect(response.statusCode).to.equal(200);
+ expect(response.body).to.be.not.null;
+ expect(response.body.draftId).to.equal('ABC');
+ });
+ }
+ })
+})
diff --git a/ui.tests/test-module/specs/formcontainer.spec.js b/ui.tests/test-module/specs/formcontainer.spec.js
index b32695b8d5..803df179b2 100644
--- a/ui.tests/test-module/specs/formcontainer.spec.js
+++ b/ui.tests/test-module/specs/formcontainer.spec.js
@@ -65,6 +65,19 @@ describe('Page/Form Authoring', function () {
cy.get("[name='./title'").should("have.value", "Adaptive Form V2 (IT)");
}
+ const checkAutoSaveTab = function(formContainerEditPathSelector) {
+ cy.openEditableToolbar(sitesSelectors.overlays.overlay.component + formContainerEditPathSelector);
+ cy.invokeEditableAction("[data-action='CONFIGURE']");
+ // Open auto save tab
+ cy.get('.cmp-adaptiveform-container'+'__editdialog').contains('Auto-save').click({force:true});
+ cy.get("coral-checkbox[name='./fd:enableAutoSave']").should("exist");
+ cy.get("coral-checkbox[name='./fd:enableAutoSave']").click({force:true});
+ cy.get("coral-select[name='./fd:autoSaveStrategyType']").should("exist");
+ cy.get("coral-numberinput[name='./fd:autoSaveInterval']").should("exist");
+ }
+
+
+
const checkAndSaveSubmitAction = function(formContainerEditPathSelector) {
// click configure action on adaptive form container component
cy.openEditableToolbar(sitesSelectors.overlays.overlay.component + formContainerEditPathSelector);
@@ -195,7 +208,14 @@ describe('Page/Form Authoring', function () {
it ('check title in edit dialog', {retries: 3}, function() {
checkTitleInEditDialog(formContainerEditPathSelector);
cy.get('.cq-dialog-cancel').click();
- })
+ });
+
+ it('open edit dialog, verify auto save tab in container edit dialog box', {retries: 3},function () {
+ if (cy.af.isLatestAddon() && toggle_array.includes("FT_FORMS-14255")) {
+ checkAutoSaveTab(formContainerEditPathSelector);
+ }
+ });
+
});
// commenting once we support adaptive form container in sites editor, uncomment this test