diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/FragmentImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/FragmentImpl.java index 99e5f69eef..9cff4e983f 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/FragmentImpl.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/FragmentImpl.java @@ -160,6 +160,7 @@ public List getTitleListOfChildren() { public Map getProperties() { Map properties = super.getProperties(); properties.put(CUSTOM_FRAGMENT_PROPERTY_WRAPPER, true); + properties.put(ReservedProperties.PN_VIEWTYPE, "fragment"); return properties; } diff --git a/bundles/af-core/src/test/resources/form/fragment/exporter-fragment-dampath.json b/bundles/af-core/src/test/resources/form/fragment/exporter-fragment-dampath.json index bf5289929b..14471df334 100644 --- a/bundles/af-core/src/test/resources/form/fragment/exporter-fragment-dampath.json +++ b/bundles/af-core/src/test/resources/form/fragment/exporter-fragment-dampath.json @@ -21,7 +21,8 @@ "dorExcludeDescription": false }, "fd:path": "/content/fragment-dampath", - "fd:fragment": true + "fd:fragment": true, + "fd:viewType": "fragment" }, ":itemsOrder": [ "textinput" diff --git a/bundles/af-core/src/test/resources/form/fragment/exporter-fragment.json b/bundles/af-core/src/test/resources/form/fragment/exporter-fragment.json index 7f410c1e4a..54d400f6f8 100644 --- a/bundles/af-core/src/test/resources/form/fragment/exporter-fragment.json +++ b/bundles/af-core/src/test/resources/form/fragment/exporter-fragment.json @@ -22,6 +22,7 @@ }, "fd:path": "/content/fragment", "fd:fragment": true, + "fd:viewType": "fragment", "customProp": "customPropValue" }, ":itemsOrder": [ diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/fragment/_cq_template.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/fragment/_cq_template.xml index 4794e5d10c..59adb5fbd1 100644 --- a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/fragment/_cq_template.xml +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/fragment/_cq_template.xml @@ -1,5 +1,6 @@ - diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/af-commons/v1/clientlibs/editor/utils/datamodel.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/af-commons/v1/clientlibs/editor/utils/datamodel.js new file mode 100644 index 0000000000..686e074bea --- /dev/null +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/af-commons/v1/clientlibs/editor/utils/datamodel.js @@ -0,0 +1,386 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ 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. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +(function($, channel, Coral) { + "use strict"; + + // TODO: For now this file is beign picked, while moving to FAR make sure both file are synced + + window.CQ = window.CQ || {}; + window.CQ.FormsCoreComponents = window.CQ.FormsCoreComponents || {}; + window.CQ.FormsCoreComponents.Utils = window.CQ.FormsCoreComponents.Utils || {}; + const DataModel = window.CQ.FormsCoreComponents.Utils.DataModel = window.CQ.FormsCoreComponents.Utils.DataModel || {}; + + var FORM_CONTAINER_SELECTOR = "[data-cmp-is='adaptiveFormContainer']"; + + var JSON_SCHEMA = 'jsonschema', + NONE = 'none', + FORM_DATA_MODEL = "formdatamodel", + FORM_TEMPLATE = 'formtemplates', + CONNECTOR = "connector", + SCHEMA_REF = "input[name='./schemaRef']", + XDP_REF = "input[name='./xdpRef']", + SCHEMA_TYPE = "input[name='./schemaType']", + SCHEMA_CONTAINER = ".cmp-adaptiveform-container__schemaselectorcontainer", + FDM_CONTAINER = ".cmp-adaptiveform-container__fdmselectorcontainer", + CONNECTOR_CONTAINER = ".cmp-adaptiveform-container__marketoselectorcontainer", + FORM_TEMPLATE_CONTAINER = ".cmp-adaptiveform-container__formtemplateselectorcontainer", + SCHEMA_DROPDOWN_SELECTOR = ".cmp-adaptiveform-container__schemaselector", + FDM_DROPDOWN_SELECTOR = ".cmp-adaptiveform-container__fdmselector", + CONNECTOR_DROPDOWN_SELECTOR = ".cmp-adaptiveform-container__marketoselector", + FORM_TEMPLATE_DROPDOWN_SELECTOR = ".cmp-adaptiveform-container__formtemplateselector", + FORM_MODEL_SELECTOR = ".cmp-adaptiveform-container__selectformmodel", + FM_AF_ROOT = "/content/forms/af/", + FM_DAM_ROOT ="/content/dam/formsanddocuments/", + DAM_SCHEMA_TYPE, + DAM_SCHEMA_REF; + + var configuredFormModel, + toBeConfiguredFormModel, + isConfirmationDialogAccept = false, + doNotShowDialogFlag = false, + isSchemaChanged = false, + dialogHeader = Granite.I18n.get("Form Model"), + dialogContent = "

" + Granite.I18n.get("When you replace the old data model with a new model, some data bindings might break and lead to form submission errors.") + "

" + "" + Granite.I18n.get("Don't show this again") + "", + dialogFooter = ''; + + var formModelChangeConfirmationDialog = new Coral.Dialog().set({ + id: 'formModelChange', + header: { + innerHTML: dialogHeader + }, + content: { + innerHTML: dialogContent + }, + footer: { + innerHTML: dialogFooter + }, + variant : 'warning' + }); + + channel.on("dialog-success", function (e) { + configuredFormModel = toBeConfiguredFormModel; + isConfirmationDialogAccept = false; + if(isForm() && isSchemaChanged){ + var customEvent = document.createEvent("CustomEvent"); + customEvent.initCustomEvent("data-model-selected", true, true); + window.dispatchEvent(customEvent); + } + }); + + channel.on('change', '#doNotShowDialogCheckBox', function(e) { + if (this.checked) { + doNotShowDialogFlag = true; + } else { + doNotShowDialogFlag = false; + } + }); + + function selectFormModelOnLoad(dialog) { + var schemaType = dialog.find(FORM_MODEL_SELECTOR); + if(schemaType.length > 0){ + schemaType = schemaType[0].value; + hideContainersExcept(schemaType); + if (isForm()){ + var afAssetPath = getAfAssetMetadataPath(); + DAM_SCHEMA_TYPE = "[name='" + afAssetPath + "/formmodel']"; + addFormParameter(afAssetPath + '/formmodel', schemaType); + if(schemaType == JSON_SCHEMA){ + DAM_SCHEMA_REF = "[name='" + afAssetPath + "/schemaRef']"; + addFormParameter(afAssetPath + '/schemaRef'); + } else if(schemaType == FORM_TEMPLATE){ + DAM_SCHEMA_REF = "[name='" + afAssetPath + "/xdpRef']"; + addFormParameter(afAssetPath + '/xdpRef'); + // we don't want user to change the data model if form template has been selected + dialog.find('coral-selectlist-item[value="none"]').remove(); + dialog.find('coral-selectlist-item[value="jsonschema"]').remove(); + dialog.find('coral-selectlist-item[value="formdatamodel"]').remove(); + dialog.find('coral-selectlist-item[value="connector"]').remove(); + } + } else { + // when there is no dam asset, remove XFA from selection dynamically + dialog.find('coral-selectlist-item[value="formtemplates"]').remove(); + // always hide form template container + $(FORM_TEMPLATE_CONTAINER).hide(); + } + document.body.appendChild(formModelChangeConfirmationDialog); + prefillSchema(schemaType, dialog); + } + }; + + function selectFormModelOnChanged(dialog) { + var schemaTypeSelected = dialog.find(FORM_MODEL_SELECTOR); + if(schemaTypeSelected.length > 0){ + schemaTypeSelected = schemaTypeSelected[0].value; + setElementValue(dialog, DAM_SCHEMA_TYPE, schemaTypeSelected) + hideContainersExcept(schemaTypeSelected); + + // Clear previous form parameters if schema type changes + if (isForm()) { + var afAssetPath = getAfAssetMetadataPath(); + if (schemaTypeSelected == FORM_TEMPLATE) { + // When changing to form template, ensure xdpRef parameter is added + setElementValue(dialog, XDP_REF, "") + addFormParameter(afAssetPath + '/xdpRef', ""); + } + } + } + }; + + function prefillSchema(schemaType, dialog){ + var schemaRef = dialog.find(SCHEMA_REF); + // for formtemplates we don't have schemaRef instead xdpRef + if(schemaType == FORM_TEMPLATE){ + schemaRef = dialog.find(XDP_REF); + } + if(schemaRef.length > 0){ + schemaRef = schemaRef[0].value; + configuredFormModel = schemaRef; + setElementValue(dialog, DAM_SCHEMA_REF, schemaRef); + if (schemaType == JSON_SCHEMA) { + $(SCHEMA_DROPDOWN_SELECTOR).val(schemaRef); + } else if (schemaType == FORM_DATA_MODEL) { + $(FDM_DROPDOWN_SELECTOR).val(schemaRef); + } else if (schemaType == CONNECTOR) { + $(CONNECTOR_DROPDOWN_SELECTOR).val(schemaRef); + } else if (schemaType == FORM_TEMPLATE) { + $(FORM_TEMPLATE_DROPDOWN_SELECTOR).val(schemaRef); + // Also set the form parameter for xdpRef when prefilling + if (isForm()) { + var afAssetPath = getAfAssetMetadataPath(); + addFormParameter(afAssetPath + '/xdpRef', schemaRef); + } + } + } + }; + + function schemaSelectorOnChanged(dialog) { + var selectedSchema = dialog.find(SCHEMA_DROPDOWN_SELECTOR); + if(selectedSchema.length > 0){ + selectedSchema = selectedSchema[0].value; + setElementValue(dialog, SCHEMA_REF, selectedSchema); + setElementValue(dialog, DAM_SCHEMA_REF, selectedSchema); + isSchemaChanged = true; + if (configuredFormModel) { + confirmFormModelChange(selectedSchema, $(SCHEMA_DROPDOWN_SELECTOR)); + } else { + toBeConfiguredFormModel = selectedSchema; + } + } + }; + + function fdmSelectorOnChanged(dialog) { + var selectedSchema = dialog.find(FDM_DROPDOWN_SELECTOR); + if(selectedSchema.length > 0) { + selectedSchema = selectedSchema[0].value; + setElementValue(dialog, SCHEMA_REF, selectedSchema); + setElementValue(dialog, DAM_SCHEMA_REF, selectedSchema); + isSchemaChanged = true; + if (configuredFormModel) { + confirmFormModelChange(selectedSchema, $(FDM_DROPDOWN_SELECTOR)); + } else { + toBeConfiguredFormModel = selectedSchema; + } + } + }; + + function connectorSelectorOnChanged(dialog) { + var selectedSchema = dialog.find(CONNECTOR_DROPDOWN_SELECTOR); + if(selectedSchema.length > 0) { + selectedSchema = selectedSchema[0].value; + setElementValue(dialog, SCHEMA_REF, selectedSchema); + setElementValue(dialog, DAM_SCHEMA_REF, selectedSchema); + isSchemaChanged = true; + if (configuredFormModel) { + confirmFormModelChange(selectedSchema, $(CONNECTOR_DROPDOWN_SELECTOR)); + } else { + toBeConfiguredFormModel = selectedSchema; + } + } + }; + + function formTemplateSelectorOnChanged(dialog) { + var selectedSchema = dialog.find(FORM_TEMPLATE_DROPDOWN_SELECTOR); + if(selectedSchema.length > 0) { + selectedSchema = selectedSchema[0].value; + setElementValue(dialog, SCHEMA_REF, selectedSchema); + setElementValue(dialog, XDP_REF, selectedSchema); + setElementValue(dialog, DAM_SCHEMA_REF, selectedSchema); + if (isForm()) { + var afAssetPath = getAfAssetMetadataPath(); + addFormParameter(afAssetPath + '/xdpRef', selectedSchema); + } + isSchemaChanged = true; + if (configuredFormModel) { + confirmFormModelChange(selectedSchema, $(FORM_TEMPLATE_DROPDOWN_SELECTOR)); + } else { + toBeConfiguredFormModel = selectedSchema; + } + } + }; + + function setElementValue(dialog, elementRef, value){ + var element = dialog.find(elementRef); + if(element.length > 0){ + element[0].value = value; + } + } + + function getAfAssetMetadataPath() { + return getGuideContainerPath().replace(FM_AF_ROOT, FM_DAM_ROOT).replace("/guideContainer", "/metadata"); + } + + function getGuideContainerPath() { + var afWindow = (Granite.author ? Granite.author.ContentFrame.contentWindow : window); + return afWindow.$(FORM_CONTAINER_SELECTOR).data("cmp-path"); + }; + + function isForm(){ + return Granite.author.page.path.startsWith(FM_AF_ROOT); + } + + function addFormParameter(name, value) { + var input = channel[0].createElement('input'); + input.setAttribute("type", "hidden"); + input.setAttribute("name", name); + if(value) { + input.setAttribute("value", value); + } + $("#formmodelparameters").append(input); + } + + function hideContainersExcept(selectedSchemaType) { + if (selectedSchemaType == JSON_SCHEMA) { + $(FDM_CONTAINER).hide(); + $(FORM_TEMPLATE_CONTAINER).hide(); + $(CONNECTOR_CONTAINER).hide(); + $(SCHEMA_CONTAINER).show(); + } else if (selectedSchemaType == FORM_DATA_MODEL) { + $(SCHEMA_CONTAINER).hide(); + $(FORM_TEMPLATE_CONTAINER).hide(); + $(CONNECTOR_CONTAINER).hide(); + $(FDM_CONTAINER).show(); + } else if (selectedSchemaType == CONNECTOR) { + $(SCHEMA_CONTAINER).hide(); + $(FDM_CONTAINER).hide(); + $(FORM_TEMPLATE_CONTAINER).hide(); + $(CONNECTOR_CONTAINER).show(); + } else if (selectedSchemaType == FORM_TEMPLATE) { + $(FDM_CONTAINER).hide(); + $(CONNECTOR_CONTAINER).hide(); + $(SCHEMA_CONTAINER).hide(); + $(FORM_TEMPLATE_CONTAINER).show(); + } else if (selectedSchemaType == NONE) { + $(FDM_CONTAINER).hide(); + $(SCHEMA_CONTAINER).hide(); + $(CONNECTOR_CONTAINER).hide(); + $(FORM_TEMPLATE_CONTAINER).hide(); + } + }; + + function confirmFormModelChange(selectedSchema, dataModelSelector) { + if (!isConfirmationDialogAccept && Granite.author.preferences.cookie.get("form-model-change-dialog") !== "disabled") { + if (configuredFormModel !== selectedSchema) { + formModelChangeConfirmationDialog.show(); + $("#formModelDialogCancelButton").on("click", function () { + dataModelSelector.val(configuredFormModel); + }); + $("#formModelDialogAcceptButton").on("click", function () { + if (doNotShowDialogFlag) { + Granite.author.preferences.cookie.set("form-model-change-dialog","disabled"); + } else { + Granite.author.preferences.cookie.set("form-model-change-dialog","enabled"); + } + isConfirmationDialogAccept = true; + }); + } + } + toBeConfiguredFormModel = selectedSchema; + } + + $(window).adaptTo("foundation-registry").register("foundation.validation.validator", { + selector : "[data-validation~='datamodel.config']", + validate : function (el) { + let $el = $(el); + if($el.is(":visible") && $el[0].value === '') { + return Granite.I18n.getMessage("This is a required field"); + } + } + }); + + DataModel.initialiseDataModel = function (dialog) { + var formModelSelector = dialog.find(FORM_MODEL_SELECTOR)[0], + schemaSelector = dialog.find(SCHEMA_DROPDOWN_SELECTOR)[0], + fdmSelector = dialog.find(FDM_DROPDOWN_SELECTOR)[0], + connectorSelector = dialog.find(CONNECTOR_DROPDOWN_SELECTOR)[0]; + if (formModelSelector) { + formModelSelector.on("change", function() { + selectFormModelOnChanged(dialog); + }); + } + if (schemaSelector) { + schemaSelector.on("change", function() { + schemaSelectorOnChanged(dialog); + }); + } + if (fdmSelector) { + fdmSelector.on("change", function() { + fdmSelectorOnChanged(dialog); + }); + } + if (connectorSelector) { + connectorSelector.on("change", function() { + connectorSelectorOnChanged(dialog); + }); + }; + selectFormModelOnLoad(dialog); + } + + DataModel.initialiseDataModel = function (dialog) { + var formModelSelector = dialog.find(FORM_MODEL_SELECTOR)[0], + schemaSelector = dialog.find(SCHEMA_DROPDOWN_SELECTOR)[0], + fdmSelector = dialog.find(FDM_DROPDOWN_SELECTOR)[0], + connectorSelector = dialog.find(CONNECTOR_DROPDOWN_SELECTOR)[0], + formTemplateSelector = dialog.find(FORM_TEMPLATE_DROPDOWN_SELECTOR)[0]; + if (formModelSelector) { + formModelSelector.on("change", function() { + selectFormModelOnChanged(dialog); + }); + }; + if (schemaSelector) { + schemaSelector.on("change", function() { + schemaSelectorOnChanged(dialog); + }); + }; + if (fdmSelector) { + fdmSelector.on("change", function() { + fdmSelectorOnChanged(dialog); + }); + }; + if (connectorSelector) { + connectorSelector.on("change", function() { + connectorSelectorOnChanged(dialog); + }); + }; + if(formTemplateSelector) { + formTemplateSelector.on("change", function() { + formTemplateSelectorOnChanged(dialog); + }); + } + selectFormModelOnLoad(dialog); + } + +})(jQuery, jQuery(document), Coral); \ No newline at end of file diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/af-commons/v1/clientlibs/editor/utils/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/af-commons/v1/clientlibs/editor/utils/js.txt index 8435e4eff5..eacfce1f74 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/af-commons/v1/clientlibs/editor/utils/js.txt +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/af-commons/v1/clientlibs/editor/utils/js.txt @@ -14,4 +14,5 @@ # limitations under the License. ############################################################################### -utils.js \ No newline at end of file +utils.js +datamodel.js \ No newline at end of file diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/accordion/v1/accordion/_cq_editConfig.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/accordion/v1/accordion/_cq_editConfig.xml index 66246a04ce..527a291cfc 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/accordion/v1/accordion/_cq_editConfig.xml +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/accordion/v1/accordion/_cq_editConfig.xml @@ -37,6 +37,11 @@ handler="CQ.FormsCoreComponents.editorhooks.replace" icon="shuffle" text="Replace"/> + " + "" + Granite.I18n.get("Don't show this again") + "", - dialogFooter = ''; - - var formModelChangeConfirmationDialog = new Coral.Dialog().set({ - id: 'formModelChange', - header: { - innerHTML: dialogHeader - }, - content: { - innerHTML: dialogContent - }, - footer: { - innerHTML: dialogFooter - }, - variant : 'warning' - }); - - channel.on("dialog-success", function (e) { - configuredFormModel = toBeConfiguredFormModel; - isConfirmationDialogAccept = false; - if(isForm() && isSchemaChanged){ - var customEvent = document.createEvent("CustomEvent"); - customEvent.initCustomEvent("data-model-selected", true, true); - window.dispatchEvent(customEvent); - } - }); - - channel.on('change', '#doNotShowDialogCheckBox', function(e) { - if (this.checked) { - doNotShowDialogFlag = true; - } else { - doNotShowDialogFlag = false; - } - }); - - function selectFormModelOnLoad(dialog) { - var schemaType = dialog.find(FORM_MODEL_SELECTOR); - if(schemaType.length > 0){ - schemaType = schemaType[0].value; - hideContainersExcept(schemaType); - if (isForm()){ - var afAssetPath = getAfAssetMetadataPath(); - DAM_SCHEMA_TYPE = "[name='" + afAssetPath + "/formmodel']"; - addFormParameter(afAssetPath + '/formmodel', schemaType); - if(schemaType == JSON_SCHEMA){ - DAM_SCHEMA_REF = "[name='" + afAssetPath + "/schemaRef']"; - addFormParameter(afAssetPath + '/schemaRef'); - } else if(schemaType == FORM_TEMPLATE){ - DAM_SCHEMA_REF = "[name='" + afAssetPath + "/xdpRef']"; - addFormParameter(afAssetPath + '/xdpRef'); - // we don't want user to change the data model if form template has been selected - dialog.find('coral-selectlist-item[value="none"]').remove(); - dialog.find('coral-selectlist-item[value="jsonschema"]').remove(); - dialog.find('coral-selectlist-item[value="formdatamodel"]').remove(); - dialog.find('coral-selectlist-item[value="connector"]').remove(); - } - } else { - // when there is no dam asset, remove XFA from selection dynamically - dialog.find('coral-selectlist-item[value="formtemplates"]').remove(); - // always hide form template container - $(FORM_TEMPLATE_CONTAINER).hide(); - } - document.body.appendChild(formModelChangeConfirmationDialog); - prefillSchema(schemaType, dialog); - } - }; - - function selectFormModelOnChanged(dialog) { - var schemaTypeSelected = dialog.find(FORM_MODEL_SELECTOR); - if(schemaTypeSelected.length > 0){ - schemaTypeSelected = schemaTypeSelected[0].value; - setElementValue(dialog, DAM_SCHEMA_TYPE, schemaTypeSelected) - hideContainersExcept(schemaTypeSelected); - - // Clear previous form parameters if schema type changes - if (isForm()) { - var afAssetPath = getAfAssetMetadataPath(); - if (schemaTypeSelected == FORM_TEMPLATE) { - // When changing to form template, ensure xdpRef parameter is added - setElementValue(dialog, XDP_REF, "") - addFormParameter(afAssetPath + '/xdpRef', ""); - } - } - } - }; - - function prefillSchema(schemaType, dialog){ - var schemaRef = dialog.find(SCHEMA_REF); - // for formtemplates we don't have schemaRef instead xdpRef - if(schemaType == FORM_TEMPLATE){ - schemaRef = dialog.find(XDP_REF); - } - if(schemaRef.length > 0){ - schemaRef = schemaRef[0].value; - configuredFormModel = schemaRef; - setElementValue(dialog, DAM_SCHEMA_REF, schemaRef); - if (schemaType == JSON_SCHEMA) { - $(SCHEMA_DROPDOWN_SELECTOR).val(schemaRef); - } else if (schemaType == FORM_DATA_MODEL) { - $(FDM_DROPDOWN_SELECTOR).val(schemaRef); - } else if (schemaType == CONNECTOR) { - $(CONNECTOR_DROPDOWN_SELECTOR).val(schemaRef); - } else if (schemaType == FORM_TEMPLATE) { - $(FORM_TEMPLATE_DROPDOWN_SELECTOR).val(schemaRef); - // Also set the form parameter for xdpRef when prefilling - if (isForm()) { - var afAssetPath = getAfAssetMetadataPath(); - addFormParameter(afAssetPath + '/xdpRef', schemaRef); - } - } - } - }; - - function schemaSelectorOnChanged(dialog) { - var selectedSchema = dialog.find(SCHEMA_DROPDOWN_SELECTOR); - if(selectedSchema.length > 0){ - selectedSchema = selectedSchema[0].value; - setElementValue(dialog, SCHEMA_REF, selectedSchema); - setElementValue(dialog, DAM_SCHEMA_REF, selectedSchema); - isSchemaChanged = true; - if (configuredFormModel) { - confirmFormModelChange(selectedSchema, $(SCHEMA_DROPDOWN_SELECTOR)); - } else { - toBeConfiguredFormModel = selectedSchema; - } - } - }; - - function fdmSelectorOnChanged(dialog) { - var selectedSchema = dialog.find(FDM_DROPDOWN_SELECTOR); - if(selectedSchema.length > 0) { - selectedSchema = selectedSchema[0].value; - setElementValue(dialog, SCHEMA_REF, selectedSchema); - setElementValue(dialog, DAM_SCHEMA_REF, selectedSchema); - isSchemaChanged = true; - if (configuredFormModel) { - confirmFormModelChange(selectedSchema, $(FDM_DROPDOWN_SELECTOR)); - } else { - toBeConfiguredFormModel = selectedSchema; - } - } - }; - - function connectorSelectorOnChanged(dialog) { - var selectedSchema = dialog.find(CONNECTOR_DROPDOWN_SELECTOR); - if(selectedSchema.length > 0) { - selectedSchema = selectedSchema[0].value; - setElementValue(dialog, SCHEMA_REF, selectedSchema); - setElementValue(dialog, DAM_SCHEMA_REF, selectedSchema); - isSchemaChanged = true; - if (configuredFormModel) { - confirmFormModelChange(selectedSchema, $(CONNECTOR_DROPDOWN_SELECTOR)); - } else { - toBeConfiguredFormModel = selectedSchema; - } - } - }; - - function formTemplateSelectorOnChanged(dialog) { - var selectedSchema = dialog.find(FORM_TEMPLATE_DROPDOWN_SELECTOR); - if(selectedSchema.length > 0) { - selectedSchema = selectedSchema[0].value; - setElementValue(dialog, SCHEMA_REF, selectedSchema); - setElementValue(dialog, XDP_REF, selectedSchema); - setElementValue(dialog, DAM_SCHEMA_REF, selectedSchema); - if (isForm()) { - var afAssetPath = getAfAssetMetadataPath(); - addFormParameter(afAssetPath + '/xdpRef', selectedSchema); - } - isSchemaChanged = true; - if (configuredFormModel) { - confirmFormModelChange(selectedSchema, $(FORM_TEMPLATE_DROPDOWN_SELECTOR)); - } else { - toBeConfiguredFormModel = selectedSchema; - } - } - }; - - function setElementValue(dialog, elementRef, value){ - var element = dialog.find(elementRef); - if(element.length > 0){ - element[0].value = value; - } - } - - function getAfAssetMetadataPath() { - return getGuideContainerPath().replace(FM_AF_ROOT, FM_DAM_ROOT).replace("/guideContainer", "/metadata"); - } - - function getGuideContainerPath() { - var afWindow = (Granite.author ? Granite.author.ContentFrame.contentWindow : window); - return afWindow.$(GUIDE_CONTAINER_SELECTOR).data("cmp-path"); - }; - - function isForm(){ - return Granite.author.page.path.startsWith(FM_AF_ROOT); - } - - function addFormParameter(name, value) { - var input = channel[0].createElement('input'); - input.setAttribute("type", "hidden"); - input.setAttribute("name", name); - if(value) { - input.setAttribute("value", value); - } - $("#formmodelparameters").append(input); - }; - - function hideContainersExcept(selectedSchemaType) { - if (selectedSchemaType == JSON_SCHEMA) { - $(FDM_CONTAINER).hide(); - $(FORM_TEMPLATE_CONTAINER).hide(); - $(CONNECTOR_CONTAINER).hide(); - $(SCHEMA_CONTAINER).show(); - } else if (selectedSchemaType == FORM_DATA_MODEL) { - $(SCHEMA_CONTAINER).hide(); - $(FORM_TEMPLATE_CONTAINER).hide(); - $(CONNECTOR_CONTAINER).hide(); - $(FDM_CONTAINER).show(); - } else if (selectedSchemaType == CONNECTOR) { - $(SCHEMA_CONTAINER).hide(); - $(FDM_CONTAINER).hide(); - $(FORM_TEMPLATE_CONTAINER).hide(); - $(CONNECTOR_CONTAINER).show(); - } else if (selectedSchemaType == FORM_TEMPLATE) { - $(FDM_CONTAINER).hide(); - $(CONNECTOR_CONTAINER).hide(); - $(SCHEMA_CONTAINER).hide(); - $(FORM_TEMPLATE_CONTAINER).show(); - } else if (selectedSchemaType == NONE) { - $(FDM_CONTAINER).hide(); - $(SCHEMA_CONTAINER).hide(); - $(CONNECTOR_CONTAINER).hide(); - $(FORM_TEMPLATE_CONTAINER).hide(); - } - }; - - function confirmFormModelChange(selectedSchema, dataModelSelector) { - if (!isConfirmationDialogAccept && Granite.author.preferences.cookie.get("form-model-change-dialog") !== "disabled") { - if (configuredFormModel !== selectedSchema) { - formModelChangeConfirmationDialog.show(); - $("#formModelDialogCancelButton").on("click", function () { - dataModelSelector.val(configuredFormModel); - }); - $("#formModelDialogAcceptButton").on("click", function () { - if (doNotShowDialogFlag) { - Granite.author.preferences.cookie.set("form-model-change-dialog","disabled"); - } else { - Granite.author.preferences.cookie.set("form-model-change-dialog","enabled"); - } - isConfirmationDialogAccept = true; - }); - } - } - toBeConfiguredFormModel = selectedSchema; - } - - function initialiseDataModel(dialog) { - var formModelSelector = dialog.find(FORM_MODEL_SELECTOR)[0], - schemaSelector = dialog.find(SCHEMA_DROPDOWN_SELECTOR)[0], - fdmSelector = dialog.find(FDM_DROPDOWN_SELECTOR)[0], - connectorSelector = dialog.find(CONNECTOR_DROPDOWN_SELECTOR)[0], - formTemplateSelector = dialog.find(FORM_TEMPLATE_DROPDOWN_SELECTOR)[0]; - if (formModelSelector) { - formModelSelector.on("change", function() { - selectFormModelOnChanged(dialog); - }); - }; - if (schemaSelector) { - schemaSelector.on("change", function() { - schemaSelectorOnChanged(dialog); - }); - }; - if (fdmSelector) { - fdmSelector.on("change", function() { - fdmSelectorOnChanged(dialog); - }); - }; - if (connectorSelector) { - connectorSelector.on("change", function() { - connectorSelectorOnChanged(dialog); - }); - }; - if(formTemplateSelector) { - formTemplateSelector.on("change", function() { - formTemplateSelectorOnChanged(dialog); - }); - } - selectFormModelOnLoad(dialog); - } - function handleAsyncSubmissionAndThankYouOption(dialog) { var containerAsyncSubmission = dialog.find(CONTAINER_ENABLEASYNCSUBMISSION)[0]; var containerThankYouOption = dialog.find(CONTAINER_THANKYOUOPTION); @@ -558,15 +238,7 @@ }); } - $(window).adaptTo("foundation-registry").register("foundation.validation.validator", { - selector : "[data-validation~='datamodel.config']", - validate : function (el) { - let $el = $(el); - if($el.is(":visible") && $el[0].value === '') { - return Granite.I18n.getMessage("This is a required field"); - } - } - }); + const initialiseDataModel = window.CQ.FormsCoreComponents.Utils.DataModel.initialiseDataModel; function registerRestEndpointUrlValidator() { $(window).adaptTo("foundation-registry").register("foundation.validation.validator", { diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js.txt index 40008b700d..3c95876c44 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js.txt +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js.txt @@ -23,3 +23,4 @@ copypastehook.js toolbaractionhook.js qualifiedNameHook.js panelselect.js +fragmentshook.js diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/componentutils.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/componentutils.js index 24210d0ea3..7350a1cd49 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/componentutils.js +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/componentutils.js @@ -15,6 +15,9 @@ ******************************************************************************/ (function (window, author, Coral, channel) { "use strict"; + window.CQ = window.CQ || {}; + window.CQ.FormsCoreComponents = window.CQ.FormsCoreComponents || {}; + window.CQ.FormsCoreComponents.editorhooks = window.CQ.FormsCoreComponents.editorhooks || {}; /** * Send a request to replace an existing component @@ -171,4 +174,34 @@ window.CQ.FormsCoreComponents.editorhooks.allowedCompFieldTypes = []; + window.CQ.FormsCoreComponents.editorhooks.getComponentProperties = (editablePath) => { + const result = $.ajax({ + type: 'GET', + async: false, + url: Granite.HTTP.externalize( editablePath + ".0.json"), + cache: false, + dataType: "json" + }); + return result.responseJSON; + }; + + function getFormContainerFromDom(editable) { + let selector = "[data-cmp-is='adaptiveFormContainer']"; + let elem = $(editable.dom[0]).closest(selector); + let path = null; + if (elem.length > 0) { + path = elem.data("cmp-path"); + } + return path; + } + + window.CQ.FormsCoreComponents.editorhooks.getFormContainerPath = (editable) => { + let path = editable.dom.find("[data-cmp-adaptiveformcontainer-path]").data("cmpAdaptiveformcontainerPath"); + if (typeof path !== 'string' || !path) { + path = getFormContainerFromDom(editable); + + } + return path; + } + })(window, Granite.author, Coral, jQuery(document)); diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/dorhook.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/dorhook.js index 3cea815657..f923ffd06a 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/dorhook.js +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/dorhook.js @@ -80,25 +80,12 @@ } window.CQ.FormsCoreComponents.editorhooks.isAutoGenerateDoRConfigured = function(editable) { - var guideContainer = getGuideContainerProperties(editable.path); - if (guideContainer != null && guideContainer != "") { - var item = JSON.parse(guideContainer), - dorType = item['dorType']; + const formContainer = window.CQ.FormsCoreComponents.editorhooks.getComponentProperties(editable.path); + let dorType; + if (formContainer) { + dorType = formContainer['dorType']; } - if (dorType == "generate") { - return true; - } else - return false; - } - - function getGuideContainerProperties(editablePath) { - var result = $.ajax({ - type: 'GET', - async: false, - url: Granite.HTTP.externalize( editablePath + ".0.json"), - cache: false - }); - return result.responseText; + return dorType === "generate"; } function getStrongMarkup(strValue) { diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/fragmentshook.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/fragmentshook.js new file mode 100644 index 0000000000..e5b784fd0f --- /dev/null +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/fragmentshook.js @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ + +(function (window, ns, Coral, channel) { + const FRAGMENT_CREATION_DIALOG_PATH = "fd/af/authoring/dialog/saveasfragment/cq:dialog.html"; + + const fragmentCreationDialogConfig = function (editable) { + const path = `/mnt/overlay/${FRAGMENT_CREATION_DIALOG_PATH}`; + return { + src : Granite.HTTP.externalize(path + editable.path + "?formContainerPath=" + window.CQ.FormsCoreComponents.editorhooks.getFormContainerPath(editable)), + isFloating : false, + loadingMode : "auto", + layout : "auto" + }; + }; + + const fragmentCreationDialogDef = (editable) => { + return { + getConfig : function getConfig() { + return fragmentCreationDialogConfig(editable); + }, + getRequestedData : function getRequestedData() { + return { + resourceType : FRAGMENT_CREATION_DIALOG_PATH + }; + }, + onOpen : ns.DialogFrame.openDialog, + onReady : function onReady() { + + }, + onFocus : function onFocus() { + + }, + onClose : ns.DialogFrame.clearDialog, + resourceType : FRAGMENT_CREATION_DIALOG_PATH + } + }; + + + window.CQ.FormsCoreComponents.editorhooks.saveAsFragment = function (editable) { + const saveAsFragmentDialog = new ns.ui.Dialog(fragmentCreationDialogDef(editable)); + ns.DialogFrame.openDialog(function getDialog() { + saveAsFragmentDialog.editable = editable; + return saveAsFragmentDialog; + }()); + } + + +})(window, Granite.author, Coral, jQuery(document)); diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/ruleeditorhook.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/ruleeditorhook.js index cff67ac417..771fe819c0 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/ruleeditorhook.js +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/ruleeditorhook.js @@ -31,11 +31,11 @@ } let ruleEditorFrame = document.createElement('iframe'); ruleEditorFrame.setAttribute('id', 'af-rule-editor'); - let formContainerPath = getFormContainerPath(editable); + let formContainerPath = window.CQ.FormsCoreComponents.editorhooks.getFormContainerPath (editable); if (!formContainerPath) { showAlert(); } else { - const ruleEditorUri = '/aem/af/expeditor.html' + getFormContainerPath(editable) + "?fieldPath=" + editable.path + "&fieldId=" + getFieldId(editable); + const ruleEditorUri = '/aem/af/expeditor.html' + window.CQ.FormsCoreComponents.editorhooks.getFormContainerPath(editable) + "?fieldPath=" + editable.path + "&fieldId=" + getFieldId(editable); ruleEditorFrame.setAttribute('src', ruleEditorUri); ruleEditorFrame.setAttribute('title', 'AF Rule Editor'); const styles = { @@ -54,25 +54,6 @@ } } - function getFormContainerPath(editable) { - let path = editable.dom.find("[data-cmp-adaptiveformcontainer-path]").data("cmpAdaptiveformcontainerPath"); - if (typeof path !== 'string' || !path) { - path = getFormContainerFromDom(editable); - - } - return path; - } - - function getFormContainerFromDom(editable) { - let selector = "[data-cmp-is='adaptiveFormContainer']"; - let elem = $(editable.dom[0]).closest(selector); - let path = null; - if (elem.length > 0) { - path = elem.data("cmp-path"); - } - return path; - } - function getFieldId(editable) { return editable.dom.find("[data-cmp-adaptiveformcontainer-path]").attr('id'); } diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/_cq_template.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/_cq_template.xml index 6958ceaf28..28fe569e13 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/_cq_template.xml +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/_cq_template.xml @@ -1,6 +1,7 @@ - diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/clientlibs/site/css/fragmentview.css b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/clientlibs/site/css/fragmentview.css index 316b44357a..c653e6a81d 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/clientlibs/site/css/fragmentview.css +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/clientlibs/site/css/fragmentview.css @@ -70,7 +70,7 @@ textarea.cmp-adaptiveform-fragment__widget { .cmp-adaptiveform-fragment__fragmentTitle { text-align: left; color: #4b4b4b; - background-image: url("/libs/core/fd/components/form/fragment/v1/fragment/clientlibs/site/resources/placeholderIcon.png"); + background-image: url("../resources/placeholderIcon.png"); background-position: left center; background-repeat: no-repeat; padding-left: 25px; diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/_cq_editConfig.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/_cq_editConfig.xml index 428607e492..31f8b44838 100755 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/_cq_editConfig.xml +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/_cq_editConfig.xml @@ -20,6 +20,11 @@ handler="CQ.FormsCoreComponents.editorhooks.replace" icon="shuffle" text="Replace"/> + + + + { + if (isSites) { + dropPanelInSites(); + } else { + dropPanelInContainer(); + } + cy.openEditableToolbar(sitesSelectors.overlays.overlay.component + panelContainerEditPathSelector); + cy.invokeEditableAction("[data-action='saveAsFragment']"); // this line is causing frame busting which is causing cypress to fail + // Check If Dialog Options Are Visible + cy.get("[name='name']") + .should("be.visible"); + cy.get("[name='jcr:title']") + .should("exist"); + cy.get("[name='targetPath']") + .should("be.visible") + .invoke('val', "/content/dam/formsanddocuments"); + cy.get("[name='./schemaType']") + .should("exist"); + cy.get("[name='templatePath']") + .should("be.visible"); + // Assuming there is one fragment component (in most cases) so this field should not be visible + cy.get("[name='fragmentComponent']").should("not.be.visible"); + + cy.intercept('POST' , '**/adobe/forms/fm/v1/saveasfragment').as('saveAsFragment'); + cy.get("[name='name']").clear().type("panel-saved-as-fragment"); + // Coral autocomplete component is taking some time to initialisation + cy.get('.cmp-adaptiveform-saveasfragment__templateselector') + .should(($el) => { + expect($el.data('autocomplete')).to.exist; + }); + cy.get("[name='templatePath']") + .invoke("val", "/conf/core-components-examples/settings/wcm/templates/afv2frag-template") + .trigger("change"); + cy.get(".cq-dialog-submit").click(); + cy.wait('@saveAsFragment').then(({request, response}) => { + expect(response.statusCode).to.equal(200); + expect(response.body).to.have.property('formPath', '/content/dam/formsanddocuments/panel-saved-as-fragment'); + }); + cy.openSiteAuthoring(pagePath); + cy.deleteComponentByPath(panelContainerPath) + } + + const deleteSavedFragment = () => { + cy.openPage("/aem/forms.html/content/dam/formsanddocuments", {noLogin: true}); + cy.get("body").then(($body) => { + const selector = "[data-foundation-collection-item-id='/content/dam/formsanddocuments/panel-saved-as-fragment']"; + if ($body.find(selector).length > 0) { + cy.get(selector) + .trigger('mouseenter') + .trigger('mouseover'); + cy.get(`${selector} [title='Select']`).click({ force: true }); + cy.get(".formsmanager-admin-action-delete").click(); + cy.get("#fmbase-id-modal-template button[variant='warning']").click(); + } + }); } context('Open Forms Editor', function () { @@ -94,7 +151,7 @@ describe('Page - Authoring', function () { it('open edit dialog of Panel', function () { testPanelBehaviour(panelContainerPathSelector, panelEditPath); - }); + }) it('check rich text support for label', function(){ dropPanelInContainer(); @@ -108,6 +165,17 @@ describe('Page - Authoring', function () { cy.get('.cq-dialog-cancel').click(); cy.deleteComponentByPath(panelEditPath); }); + + if (cy.af.isLatestAddon()) { + it('Save panel as fragment via toolbar', { retries: 3}, function () { + cy.cleanTest(panelEditPath).then(function () { + deleteSavedFragment(); + cy.openSiteAuthoring(pagePath); + testSaveAsFragmentBehaviour(pagePath, panelContainerPathSelector, panelEditPath); + deleteSavedFragment(); + }) + }) + } }) context('Open Sites Editor', function () { @@ -129,5 +197,15 @@ describe('Page - Authoring', function () { testPanelBehaviour(panelContainerEditPathSelector, panelContainerEditPath, true); }); + if (cy.af.isLatestAddon()) { + it('Save panel as fragment via toolbar', { retries: 3}, function () { + cy.cleanTest(panelContainerEditPath).then(function () { + deleteSavedFragment(); + cy.openSiteAuthoring(pagePath); + testSaveAsFragmentBehaviour(pagePath, panelContainerEditPathSelector, panelContainerEditPath, true); + deleteSavedFragment(); + }) + }); + } }); }); \ No newline at end of file diff --git a/ui.tests/test-module/specs/tabsontop/tabsontop.authoring.cy.js b/ui.tests/test-module/specs/tabsontop/tabsontop.authoring.cy.js index c9f47339ed..ff1bde5f95 100644 --- a/ui.tests/test-module/specs/tabsontop/tabsontop.authoring.cy.js +++ b/ui.tests/test-module/specs/tabsontop/tabsontop.authoring.cy.js @@ -24,7 +24,7 @@ const commons = require('../../libs/commons/commons'), /** * Testing Tabs on top Container with Sites Editor */ -describe.only('Page - Authoring', function () { +describe('Page - Authoring', function () { const dropComponent = function (responsiveGridDropZoneSelector, componentTitle, componentType) { cy.selectLayer("Edit"); @@ -89,6 +89,63 @@ describe.only('Page - Authoring', function () { cy.get('.cq-dialog-cancel').click(); cy.deleteComponentByPath(tabsContainerDrop); } + + const testSaveAsFragmentBehaviour = function(pagePath, tabsEditPathSelector, tabsPath, isSites) { + if (isSites) { + dropTabsInSites(); + } else { + dropTabsInContainer(); + } + cy.openEditableToolbar(sitesSelectors.overlays.overlay.component + tabsEditPathSelector); + cy.invokeEditableAction("[data-action='saveAsFragment']"); // this line is causing frame busting which is causing cypress to fail + // Check If Dialog Options Are Visible + cy.get("[name='name']") + .should("be.visible"); + cy.get("[name='jcr:title']") + .should("exist"); + cy.get("[name='targetPath']") + .should("be.visible") + .invoke('val', "/content/dam/formsanddocuments"); + cy.get("[name='./schemaType']") + .should("exist"); + cy.get("[name='templatePath']") + .should("be.visible"); + // Assuming there is one fragment component (in most cases) so this field should not be visible + cy.get("[name='fragmentComponent']").should("not.be.visible"); + + cy.intercept('POST' , '**/adobe/forms/fm/v1/saveasfragment').as('saveAsFragment'); + cy.get("[name='name']").clear().type("panel-saved-as-fragment"); + // Coral autocomplete component is taking some time to initialisation + cy.get('.cmp-adaptiveform-saveasfragment__templateselector') + .should(($el) => { + expect($el.data('autocomplete')).to.exist; + }); + cy.get("[name='templatePath']") + .invoke("val", "/conf/core-components-examples/settings/wcm/templates/afv2frag-template") + .trigger("change"); + cy.get(".cq-dialog-submit").click(); + cy.wait('@saveAsFragment').then(({request, response}) => { + expect(response.statusCode).to.equal(200); + expect(response.body).to.have.property('formPath', '/content/dam/formsanddocuments/panel-saved-as-fragment'); + }); + cy.openSiteAuthoring(pagePath); + cy.deleteComponentByPath(tabsPath); + }; + + const deleteSavedFragment = () => { + cy.openPage("/aem/forms.html/content/dam/formsanddocuments", {noLogin: true}); + cy.get("body").then(($body) => { + const selector = "[data-foundation-collection-item-id='/content/dam/formsanddocuments/panel-saved-as-fragment']"; + if ($body.find(selector).length > 0) { + cy.get(selector) + .trigger('mouseenter') + .trigger('mouseover'); + cy.get(`${selector} [title='Select']`).click({ force: true }); + cy.get(".formsmanager-admin-action-delete").click(); + cy.get("#fmbase-id-modal-template button[variant='warning']").click(); + } + }); + } context('Open Forms Editor', function () { const pagePath = "/content/forms/af/core-components-it/blank", @@ -130,6 +187,7 @@ describe.only('Page - Authoring', function () { }); }); + // todo: flaky it('switch tabs using dialog select panel button in toolbar', {retries: 3}, function () { cy.cleanTest(tabsPath).then(function () { @@ -154,6 +212,7 @@ describe.only('Page - Authoring', function () { }); }); + it('open edit dialog of Tab on top', {retries: 3}, function () { cy.cleanTest(tabsPath).then(function () { testPanelBehaviour(tabsContainerPathSelector, tabsPath); @@ -183,6 +242,16 @@ describe.only('Page - Authoring', function () { }); }); + if(cy.af.isLatestAddon()) { + it('open and save tab as fragment dialog of Tab on top',{ retries: 3}, function(){ + cy.cleanTest(tabsPath).then(function () { + deleteSavedFragment(); + cy.openSiteAuthoring(pagePath); + testSaveAsFragmentBehaviour(pagePath, tabsContainerPathSelector, tabsPath); + deleteSavedFragment(); + }) + }); + } }); context('Open Sites Editor', function () { @@ -200,11 +269,22 @@ describe.only('Page - Authoring', function () { cy.deleteComponentByPath(panelContainerEditPath); }); + it('open edit dialog of tabs on top of form', {retries: 3}, function () { cy.cleanTest(panelContainerEditPath).then(function () { testPanelBehaviour(tabsEditPathSelector, panelContainerEditPath, true); }); }); + if (cy.af.isLatestAddon()) { + it('open and save tab as fragment dialog of Tab on top', {retries: 3}, function(){ + cy.cleanTest(panelContainerEditPath).then(function () { + deleteSavedFragment(); + cy.openSiteAuthoring(pagePath); + testSaveAsFragmentBehaviour(pagePath, tabsEditPathSelector, panelContainerEditPath, true); + deleteSavedFragment(); + }) + }); + } }); }); diff --git a/ui.tests/test-module/specs/wizard/wizard.authoring.cy.js b/ui.tests/test-module/specs/wizard/wizard.authoring.cy.js index bb43bd769a..f0ad902c9a 100644 --- a/ui.tests/test-module/specs/wizard/wizard.authoring.cy.js +++ b/ui.tests/test-module/specs/wizard/wizard.authoring.cy.js @@ -54,6 +54,63 @@ describe('Page - Authoring', function () { cy.get('body').click(0, 0); } + const testSaveAsFragment = function (pagePath, wizardEditPathSelector, wizardPath, isSites) { + if (isSites) { + dropWizardInSites(); + } else { + dropWizardInContainer(); + } + cy.openEditableToolbar(sitesSelectors.overlays.overlay.component + wizardEditPathSelector); + cy.invokeEditableAction("[data-action='saveAsFragment']"); // this line is causing frame busting which is causing cypress to fail + // Check If Dialog Options Are Visible + cy.get("[name='name']") + .should("be.visible"); + cy.get("[name='jcr:title']") + .should("exist"); + cy.get("[name='targetPath']") + .should("be.visible") + .invoke('val', "/content/dam/formsanddocuments"); + cy.get("[name='./schemaType']") + .should("exist"); + cy.get("[name='templatePath']") + .should("be.visible"); + // Assuming there is one fragment component (in most cases) so this field should not be visible + cy.get("[name='fragmentComponent']").should("not.be.visible"); + + cy.intercept('POST' , '**/adobe/forms/fm/v1/saveasfragment').as('saveAsFragment'); + cy.get("[name='name']").clear().type("panel-saved-as-fragment"); + // Coral autocomplete component is taking some time to initialisation + cy.get('.cmp-adaptiveform-saveasfragment__templateselector') + .should(($el) => { + expect($el.data('autocomplete')).to.exist; + }); + cy.get("[name='templatePath']") + .invoke("val", "/conf/core-components-examples/settings/wcm/templates/afv2frag-template") + .trigger("change"); + cy.get(".cq-dialog-submit").click(); + cy.wait('@saveAsFragment').then(({request, response}) => { + expect(response.statusCode).to.equal(200); + expect(response.body).to.have.property('formPath', '/content/dam/formsanddocuments/panel-saved-as-fragment'); + }); + cy.openSiteAuthoring(pagePath); + cy.deleteComponentByPath(wizardPath); + } + + const deleteSavedFragment = () => { + cy.openPage("/aem/forms.html/content/dam/formsanddocuments", {noLogin: true}); + cy.get("body").then(($body) => { + const selector = "[data-foundation-collection-item-id='/content/dam/formsanddocuments/panel-saved-as-fragment']"; + if ($body.find(selector).length > 0) { + cy.get(selector) + .trigger('mouseenter') + .trigger('mouseover'); + cy.get(`${selector} [title='Select']`).click({ force: true }); + cy.get(".formsmanager-admin-action-delete").click(); + cy.get("#fmbase-id-modal-template button[variant='warning']").click(); + } + }); + } + context('Open Forms Editor', function () { const pagePath = "/content/forms/af/core-components-it/blank", @@ -168,6 +225,17 @@ describe('Page - Authoring', function () { cy.deleteComponentByPath(wizardLayoutDrop); }); }); + + if (cy.af.isLatestAddon()) { + it('save as fragment in Wizard', {retries: 3}, function () { + cy.cleanTest(wizardLayoutDrop).then(function () { + deleteSavedFragment(); + cy.openSiteAuthoring(pagePath); + testSaveAsFragment(pagePath, wizardEditPathSelector, wizardLayoutDrop); + deleteSavedFragment(); + }) + }) + } }); context('Open Sites Editor', function () { @@ -231,5 +299,15 @@ describe('Page - Authoring', function () { }); }); + if (cy.af.isLatestAddon()) { + it('save as fragment in Wizard', { retries: 3 }, function() { + cy.cleanTest(wizardEditPath).then(function () { + deleteSavedFragment(); + cy.openSiteAuthoring(pagePath); + testSaveAsFragment(pagePath, wizardEditPathSelector, wizardEditPath, true); + deleteSavedFragment(); + }) + }); + } }); }) \ No newline at end of file