diff --git a/examples/nuxt-app/test/features/edge/edge-cases.feature b/examples/nuxt-app/test/features/edge/edge-cases.feature new file mode 100644 index 0000000000..2ff8f001ca --- /dev/null +++ b/examples/nuxt-app/test/features/edge/edge-cases.feature @@ -0,0 +1,12 @@ +Feature: Edge case testing + + Specific content-based edge cases + + Background: + Given the site endpoint returns fixture "/site/reference" with status 200 + And I am using a "macbook-16" device + + @mockserver + Example: Multi-step form + Given the page endpoint for path "/multi-step-webform" returns fixture "/case/multi-step-webform" with status 200 + Then I visit the page "/multi-step-webform" diff --git a/examples/nuxt-app/test/fixtures/case/multi-step-webform.json b/examples/nuxt-app/test/fixtures/case/multi-step-webform.json new file mode 100644 index 0000000000..057af8c422 --- /dev/null +++ b/examples/nuxt-app/test/fixtures/case/multi-step-webform.json @@ -0,0 +1,392 @@ +{ + "title": "Webform", + "changed": "2024-05-23T15:10:24+10:00", + "created": "2024-05-02T14:42:13+10:00", + "type": "landing_page", + "nid": "45fa8751-74af-43ee-9cb9-8a8fdee7e593", + "_sectionId": "8888", + "sidebar": { + "contacts": [], + "relatedLinks": [], + "whatsNext": [], + "socialShareNetworks": ["Facebook", "X", "LinkedIn"], + "siteSectionNav": null + }, + "status": "published", + "topicTags": [ + { + "text": "Demo Topic", + "url": "/topic/demo-topic" + } + ], + "siteSection": { + "id": 8888, + "name": "Demo Site" + }, + "meta": { + "url": "/webform", + "langcode": "en", + "description": "Testing the landing page webform mapping", + "additional": [ + { + "tag": "meta", + "attributes": { + "name": "title", + "content": "Webform | Single Digital Presence Content Management System" + } + }, + { + "tag": "link", + "attributes": { + "rel": "canonical", + "href": "http://content-sdp.docker.internal/webform" + } + }, + { + "tag": "meta", + "attributes": { + "property": "og:locale", + "content": "en-AU" + } + } + ], + "keywords": "", + "image": null + }, + "showContentRating": true, + "summary": "Testing the landing page webform mapping", + "showHeroAcknowledgement": false, + "showInPageNav": false, + "showHeroImageCaption": false, + "showTopicTags": true, + "inPageNavHeadingLevel": "h2", + "background": "default", + "header": { + "title": "Webform", + "summary": "", + "links": { + "title": "", + "items": [], + "more": null + }, + "backgroundImageCaption": "", + "theme": "default", + "logoImage": null, + "backgroundImage": null, + "cornerTop": null, + "cornerBottom": null, + "primaryAction": null, + "secondaryAction": null, + "secondaryActionLabel": "" + }, + "primaryCampaign": null, + "secondaryCampaign": null, + "headerComponents": [], + "bodyComponents": [ + { + "uuid": "2947c380-ab74-4b11-ac53-64ff91c760ff", + "component": "TideLandingPageWebForm", + "id": 1793, + "title": "Use the form", + "props": { + "title": "Use the form", + "formId": "multi_step_form", + "hideFormOnSubmit": false, + "successMessageTitle": "Form submitted", + "successMessageHTML": "Thank you! Your response has been submitted.", + "errorMessageTitle": "Form not submitted", + "errorMessageHTML": "We are experiencing a server error. Please try again, otherwise contact us.", + "schema": [ + { + "$formkit": "RplFormPage", + "key": "step_1", + "title": "Step 1 - Info", + "schema": [ + { + "$formkit": "RplFormText", + "key": "name", + "name": "name", + "label": "Name", + "id": "multi_step_form_name", + "validation": [["length", 0, 255], ["required"]], + "validationMessages": { + "required": "Name is required", + "accepted": "Name is required", + "length": "You can enter a maximum of 255 characters" + } + }, + { + "$formkit": "RplFormEmail", + "key": "email", + "name": "email", + "label": "Email", + "id": "multi_step_form_email", + "validation": [["email"], ["length", 0, 255], ["required"]], + "validationMessages": { + "required": "Email is required", + "accepted": "Email is required", + "email": "Email must be a valid email address", + "length": "You can enter a maximum of 255 characters" + } + }, + { + "$formkit": "RplFormNumber", + "key": "age", + "name": "age", + "label": "Age", + "id": "multi_step_form_age", + "validation": [["number"]], + "validationMessages": { + "required": "Age is required", + "accepted": "Age is required", + "number": "Age must be a number" + } + } + ] + }, + { + "$formkit": "RplFormPage", + "key": "step_2", + "title": "Step 2 - Address", + "schema": [ + { + "$formkit": "RplFormFieldset", + "legend": "Address", + "name": "address", + "children": [ + { + "$formkit": "RplFormText", + "id": "multi_step_form_address_organization", + "name": "organization", + "label": "Organization", + "validation": [], + "value": "" + }, + { + "$formkit": "RplFormText", + "id": "multi_step_form_address_given_name", + "name": "given_name", + "label": "Given name", + "validation": [], + "value": "" + }, + { + "$formkit": "RplFormText", + "id": "multi_step_form_address_family_name", + "name": "family_name", + "label": "Family name", + "validation": [], + "value": "" + }, + { + "$formkit": "RplFormText", + "id": "multi_step_form_address_address_line1", + "name": "address_line1", + "label": "Street address", + "validation": [["required"]], + "value": "" + }, + { + "$formkit": "RplFormText", + "id": "multi_step_form_address_address_line2", + "name": "address_line2", + "label": "Street address line 2", + "validation": [], + "value": "" + }, + { + "$formkit": "RplFormText", + "id": "multi_step_form_address_locality", + "name": "locality", + "label": "Suburb", + "columnClasses": "rpl-col-12 rpl-col-5-m", + "validation": [["required"]], + "value": "" + }, + { + "$formkit": "RplFormDropdown", + "id": "multi_step_form_address_administrative_area", + "name": "administrative_area", + "label": "State", + "columnClasses": "rpl-col-12 rpl-col-5-m", + "options": [ + { + "id": "VIC", + "value": "VIC", + "label": "Victoria" + }, + { + "id": "NSW", + "value": "NSW", + "label": "New South Wales" + }, + { + "id": "WA", + "value": "WA", + "label": "Western Australia" + }, + { + "id": "QLD", + "value": "QLD", + "label": "Queensland" + }, + { + "id": "ACT", + "value": "ACT", + "label": "Australian Capital Territory" + }, + { + "id": "NT", + "value": "NT", + "label": "Northern Territory" + }, + { + "id": "SA", + "value": "SA", + "label": "South Australia" + }, + { + "id": "TAS", + "value": "TAS", + "label": "Tasmania" + } + ], + "validation": [], + "value": "", + "pii": false + }, + { + "$formkit": "RplFormText", + "id": "multi_step_form_address_postal_code", + "name": "postal_code", + "label": "Postcode", + "columnClasses": "rpl-col-6 rpl-col-3-m", + "validation": [["required"]], + "value": "" + }, + { + "$formkit": "hidden", + "id": "multi_step_form_address_country_code", + "name": "country_code", + "value": "AU" + } + ] + } + ] + }, + { + "$formkit": "RplFormPage", + "key": "step_3_favourites", + "title": "Step 3 - Favourites", + "schema": [ + { + "$formkit": "RplFormCheckboxGroup", + "key": "foods", + "id": "multi_step_form_foods", + "name": "foods", + "label": "Foods", + "options": [ + { + "id": "ramen", + "value": "ramen", + "label": "Ramen" + }, + { + "id": "tacos", + "value": "tacos", + "label": "Tacos" + }, + { + "id": "pizza", + "value": "pizza", + "label": "Pizza" + } + ], + "pii": false, + "validation": [["required"]], + "validationMessages": { + "required": "Please select you favourite foods", + "accepted": "Please select you favourite foods" + } + }, + { + "$formkit": "RplFormRadioGroup", + "key": "drink", + "id": "multi_step_form_drink", + "name": "drink", + "label": "Drink", + "options": [ + { + "id": "water", + "value": "water", + "label": "Water" + }, + { + "id": "milk", + "value": "milk", + "label": "Milk" + }, + { + "id": "soft", + "value": "soft", + "label": "Soft Drink" + } + ], + "pii": false, + "validation": [["required"]], + "validationMessages": { + "required": "Please select you favourite drink", + "accepted": "Please select you favourite drink" + } + }, + { + "$formkit": "RplFormDropdown", + "key": "desserts", + "id": "multi_step_form_desserts", + "name": "desserts", + "label": "Desserts", + "multiple": true, + "options": [ + { + "id": "icecream", + "value": "icecream", + "label": "Icecream" + }, + { + "id": "cake", + "value": "cake", + "label": "Cake" + }, + { + "id": "pie", + "value": "pie", + "label": "Apple Pie" + } + ], + "pii": false, + "validation": [["required"]], + "validationMessages": { + "required": "Desserts is required", + "accepted": "Desserts is required" + } + }, + { + "$formkit": "RplFormActions", + "key": "actions", + "name": "submit", + "variant": "filled", + "id": "multi_step_form_actions", + "displayResetButton": false, + "validation": [], + "validationMessages": { + "required": "Submit is required", + "accepted": "Submit is required" + } + } + ] + } + ] + } + } + ] +} diff --git a/packages/ripple-tide-webform/mapping/webforms-mapping.ts b/packages/ripple-tide-webform/mapping/webforms-mapping.ts index 1ee6d27b65..b791fd488f 100644 --- a/packages/ripple-tide-webform/mapping/webforms-mapping.ts +++ b/packages/ripple-tide-webform/mapping/webforms-mapping.ts @@ -314,22 +314,25 @@ export const getFormSchemaFromMapping = async ( ...getInputIcons(field) } break - case 'webform_wizard_page': - const title = field['#title'] - const subformId = `${field['formId']}_${fieldKey}` + case 'webform_wizard_page': { + const title = field['#title'] const subform = webform delete field['#title'] delete field['#type'] delete field['formId'] - subform.elements = field - const subformSchema = await getFormSchemaFromMapping(subform, tidePageApi) + subform.elements = field as unknown as TideWebformElement[] + const subformSchema = await getFormSchemaFromMapping( + subform, + tidePageApi + ) mappedField = { $formkit: 'RplFormPage', key: fieldKey, title, - schema: subformSchema, + schema: subformSchema } break + } default: mappedField = { $el: 'div', diff --git a/packages/ripple-tide-webform/types.ts b/packages/ripple-tide-webform/types.ts index 7c0d2fcb7a..64e5ed021a 100644 --- a/packages/ripple-tide-webform/types.ts +++ b/packages/ripple-tide-webform/types.ts @@ -12,8 +12,8 @@ export interface TideWebform { } export interface TideWebformElement { - '#type': string - '#title': string + '#type'?: string + '#title'?: string '#required'?: boolean '#required_error'?: string '#description'?: string diff --git a/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue b/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue index 78d115bdd8..1908e82f72 100644 --- a/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue +++ b/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue @@ -27,7 +27,7 @@ interface Props { status: 'idle' | 'submitting' | 'success' | 'error' title: string message: string - }, + } stepStyle?: 'tab' | 'progress' | null } @@ -92,15 +92,17 @@ const submitHandler = (form, node: FormKitNode) => { submitCounter.value = 0 // Steps/page data gets nested - un-nest it. - let data = form; - node.children.filter(f => f.props.type === 'multi-step').forEach(ms => { - data = {...data, ...data[ms.name]} - delete data[ms.name] - ms.children?.forEach(s => { - data = {...data, ...data[s.name]} - delete data[s.name] + let data = form + node.children + .filter((f) => f.props.type === 'multi-step') + .forEach((ms) => { + data = { ...data, ...data[ms.name] } + delete data[ms.name] + ms.children?.forEach((s) => { + data = { ...data, ...data[s.name] } + delete data[s.name] + }) }) - }) emitRplEvent( 'submit', @@ -246,8 +248,12 @@ const data = reactive({ } }) -const pagesSchema = computed(() => props.schema.filter(f => f['$formkit'] === 'RplFormPage')) -const nonPagesSchema = computed(() => props.schema.filter(f => f['$formkit'] !== 'RplFormPage')) +const pagesSchema = computed(() => + props.schema.filter((f) => f['$formkit'] === 'RplFormPage') +) +const nonPagesSchema = computed(() => + props.schema.filter((f) => f['$formkit'] !== 'RplFormPage') +)