diff --git a/src/openapi.yaml b/src/openapi.yaml
index f62e7b9bbf..14e40ee9ec 100644
--- a/src/openapi.yaml
+++ b/src/openapi.yaml
@@ -7588,6 +7588,11 @@ components:
description: The content of the submission confirmation page. It can contain
variables that will be templated from the submitted form data. If not
specified, the global template will be used.
+ introductionPageContent:
+ type: string
+ title: Introduction page
+ description: Content for the introduction page that leads to the start page
+ of the form. Leave blank to disable the introduction page.
explanationTemplate:
type: string
description: Content that will be shown on the start page of the form, below
@@ -7999,6 +8004,12 @@ components:
the form is filled in correctly. Leave blank to get value from global
configuration.
maxLength: 50
+ introductionPageContent:
+ type: string
+ nullable: true
+ title: Introduction page [en]
+ description: Content for the introduction page that leads to the start page
+ of the form. Leave blank to disable the introduction page.
explanationTemplate:
type: string
nullable: true
@@ -8164,6 +8175,12 @@ components:
the form is filled in correctly. Leave blank to get value from global
configuration.
maxLength: 50
+ introductionPageContent:
+ type: string
+ nullable: true
+ title: Introduction page [nl]
+ description: Content for the introduction page that leads to the start page
+ of the form. Leave blank to disable the introduction page.
explanationTemplate:
type: string
nullable: true
@@ -9226,6 +9243,11 @@ components:
description: The content of the submission confirmation page. It can contain
variables that will be templated from the submitted form data. If not
specified, the global template will be used.
+ introductionPageContent:
+ type: string
+ title: Introduction page
+ description: Content for the introduction page that leads to the start page
+ of the form. Leave blank to disable the introduction page.
explanationTemplate:
type: string
description: Content that will be shown on the start page of the form, below
diff --git a/src/openforms/conf/tinymce_config.json b/src/openforms/conf/tinymce_config.json
index b41b1ed52c..659bbb4aab 100644
--- a/src/openforms/conf/tinymce_config.json
+++ b/src/openforms/conf/tinymce_config.json
@@ -21,10 +21,11 @@
"help",
"wordcount"
],
- "toolbar": "undo redo | formatselect | bold italic backcolor | alignleft aligncenter alignright alignjustify | table bullist numlist outdent indent | link unlink removeformat | help",
+ "toolbar": "undo redo | blocks | bold italic backcolor | alignleft aligncenter alignright alignjustify | table bullist numlist outdent indent | link unlink removeformat | help",
"content_style": "body { font-family:Helvetica,Arial,sans-serif; font-size:14px }",
"default_link_target": "_blank",
"link_default_protocol": "https",
"link_assume_external_targets": false,
- "convert_urls": false
+ "convert_urls": false,
+ "block_formats": "Paragraph=p; Heading 2=h2; Heading 3=h3; Heading 4=h4; Heading 5=h5; Heading 6=h6"
}
diff --git a/src/openforms/forms/api/serializers/form.py b/src/openforms/forms/api/serializers/form.py
index 9f354fe2a1..1f17dd00ac 100644
--- a/src/openforms/forms/api/serializers/form.py
+++ b/src/openforms/forms/api/serializers/form.py
@@ -272,6 +272,7 @@ class Meta:
"deactivate_on",
"is_deleted",
"submission_confirmation_template",
+ "introduction_page_content",
"explanation_template",
"submission_allowed",
"suspension_allowed",
@@ -296,6 +297,7 @@ class Meta:
public_fields = (
"uuid",
"name",
+ "introduction_page_content",
"explanation_template",
"login_required",
"authentication_backends",
diff --git a/src/openforms/forms/migrations/0098_form_introduction_page_content_and_more.py b/src/openforms/forms/migrations/0098_form_introduction_page_content_and_more.py
new file mode 100644
index 0000000000..56d92e5440
--- /dev/null
+++ b/src/openforms/forms/migrations/0098_form_introduction_page_content_and_more.py
@@ -0,0 +1,61 @@
+# Generated by Django 4.2.15 on 2024-09-04 16:35
+
+from django.db import migrations
+
+import tinymce.models
+
+import csp_post_processor.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("forms", "0097_v267_to_v270"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="form",
+ name="introduction_page_content",
+ field=csp_post_processor.fields.CSPPostProcessedWYSIWYGField(
+ base_field=tinymce.models.HTMLField(
+ blank=True,
+ help_text="Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page.",
+ verbose_name="introduction page",
+ ),
+ blank=True,
+ help_text="Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page.",
+ verbose_name="introduction page",
+ ),
+ ),
+ migrations.AddField(
+ model_name="form",
+ name="introduction_page_content_en",
+ field=csp_post_processor.fields.CSPPostProcessedWYSIWYGField(
+ base_field=tinymce.models.HTMLField(
+ blank=True,
+ help_text="Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page.",
+ verbose_name="introduction page",
+ ),
+ blank=True,
+ help_text="Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page.",
+ null=True,
+ verbose_name="introduction page",
+ ),
+ ),
+ migrations.AddField(
+ model_name="form",
+ name="introduction_page_content_nl",
+ field=csp_post_processor.fields.CSPPostProcessedWYSIWYGField(
+ base_field=tinymce.models.HTMLField(
+ blank=True,
+ help_text="Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page.",
+ verbose_name="introduction page",
+ ),
+ blank=True,
+ help_text="Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page.",
+ null=True,
+ verbose_name="introduction page",
+ ),
+ ),
+ ]
diff --git a/src/openforms/forms/models/form.py b/src/openforms/forms/models/form.py
index 3234eaf30b..30d4c0e854 100644
--- a/src/openforms/forms/models/form.py
+++ b/src/openforms/forms/models/form.py
@@ -165,6 +165,27 @@ class Form(models.Model):
),
default=True,
)
+ ask_privacy_consent = models.CharField(
+ _("ask privacy consent"),
+ max_length=50,
+ choices=StatementCheckboxChoices.choices,
+ default=StatementCheckboxChoices.global_setting,
+ help_text=_(
+ "If enabled, the user will have to agree to the privacy policy before submitting a form."
+ ),
+ )
+ ask_statement_of_truth = models.CharField(
+ _("ask statement of truth"),
+ max_length=50,
+ choices=StatementCheckboxChoices.choices,
+ default=StatementCheckboxChoices.global_setting,
+ help_text=_(
+ "If enabled, the user will have to agree that they filled out the form "
+ "truthfully before submitting it."
+ ),
+ )
+
+ # Content displayed to end users
begin_text = models.CharField(
_("begin text"),
max_length=50,
@@ -205,6 +226,16 @@ class Form(models.Model):
"Leave blank to get value from global configuration."
),
)
+ introduction_page_content = CSPPostProcessedWYSIWYGField(
+ HTMLField(
+ blank=True,
+ verbose_name=_("introduction page"),
+ help_text=_(
+ "Content for the introduction page that leads to the start page of the "
+ "form. Leave blank to disable the introduction page."
+ ),
+ ),
+ )
explanation_template = CSPPostProcessedWYSIWYGField(
HTMLField(
blank=True,
@@ -214,25 +245,6 @@ class Form(models.Model):
),
),
)
- ask_privacy_consent = models.CharField(
- _("ask privacy consent"),
- max_length=50,
- choices=StatementCheckboxChoices.choices,
- default=StatementCheckboxChoices.global_setting,
- help_text=_(
- "If enabled, the user will have to agree to the privacy policy before submitting a form."
- ),
- )
- ask_statement_of_truth = models.CharField(
- _("ask statement of truth"),
- max_length=50,
- choices=StatementCheckboxChoices.choices,
- default=StatementCheckboxChoices.global_setting,
- help_text=_(
- "If enabled, the user will have to agree that they filled out the form "
- "truthfully before submitting it."
- ),
- )
# life cycle management
active = models.BooleanField(_("active"), default=False)
diff --git a/src/openforms/forms/tests/test_api_forms.py b/src/openforms/forms/tests/test_api_forms.py
index 2967ebb494..c565f7b03e 100644
--- a/src/openforms/forms/tests/test_api_forms.py
+++ b/src/openforms/forms/tests/test_api_forms.py
@@ -1441,6 +1441,7 @@ def test_detail_staff_show_translations(self):
"begin_text": "start",
"change_text": "change",
"confirm_text": "confirm",
+ "introduction_page_content": "",
"explanation_template": "",
"name": "Form 1",
"previous_text": "prev",
@@ -1450,6 +1451,7 @@ def test_detail_staff_show_translations(self):
"begin_text": "",
"change_text": "",
"confirm_text": "",
+ "introduction_page_content": "",
"explanation_template": "",
"name": "",
"previous_text": "",
diff --git a/src/openforms/forms/translation.py b/src/openforms/forms/translation.py
index 231fd71137..9ed81ac3db 100644
--- a/src/openforms/forms/translation.py
+++ b/src/openforms/forms/translation.py
@@ -13,6 +13,7 @@ class FormTranslationOptions(TranslationOptions):
"change_text",
"confirm_text",
"explanation_template",
+ "introduction_page_content",
)
diff --git a/src/openforms/js/compiled-lang/en.json b/src/openforms/js/compiled-lang/en.json
index 32b7cf654a..075a3830ba 100644
--- a/src/openforms/js/compiled-lang/en.json
+++ b/src/openforms/js/compiled-lang/en.json
@@ -3519,6 +3519,12 @@
"value": "Are you sure you want to delete this?"
}
],
+ "Z5lydZ": [
+ {
+ "type": 0,
+ "value": "Introduction page"
+ }
+ ],
"ZB6mnn": [
{
"type": 0,
@@ -4147,6 +4153,12 @@
"value": "configured"
}
],
+ "dyBb9g": [
+ {
+ "type": 0,
+ "value": "Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page."
+ }
+ ],
"e6SsfR": [
{
"type": 0,
diff --git a/src/openforms/js/compiled-lang/nl.json b/src/openforms/js/compiled-lang/nl.json
index 6e81a9add1..5d1bef19bc 100644
--- a/src/openforms/js/compiled-lang/nl.json
+++ b/src/openforms/js/compiled-lang/nl.json
@@ -3536,6 +3536,12 @@
"value": "Weet u zeker dat u dit wilt verwijderen?"
}
],
+ "Z5lydZ": [
+ {
+ "type": 0,
+ "value": "Introduction page"
+ }
+ ],
"ZB6mnn": [
{
"type": 0,
@@ -4169,6 +4175,12 @@
"value": "configured"
}
],
+ "dyBb9g": [
+ {
+ "type": 0,
+ "value": "Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page."
+ }
+ ],
"e6SsfR": [
{
"type": 0,
diff --git a/src/openforms/js/components/admin/form_design/FormDetailFields.js b/src/openforms/js/components/admin/form_design/FormDetailFields.js
index cbe5105fd7..6c36b05452 100644
--- a/src/openforms/js/components/admin/form_design/FormDetailFields.js
+++ b/src/openforms/js/components/admin/form_design/FormDetailFields.js
@@ -63,35 +63,68 @@ const FormDetailFields = ({form: {slug, translations, appointmentOptions}, onCha
{!isAppointment && (
-
-
- }
- helpText={
-
+
+
+ }
+ helpText={
+
+ }
+ >
+
+ onChange({
+ target: {
+ name: `form.translations.${langCode}.introductionPageContent`,
+ value: newValue,
+ },
+ })
+ }
/>
- }
- >
-
- onChange({
- target: {
- name: `form.translations.${langCode}.explanationTemplate`,
- value: newValue,
- },
- })
+
+
+
+
+
}
- />
-
-
+ helpText={
+
+ }
+ >
+
+ onChange({
+ target: {
+ name: `form.translations.${langCode}.explanationTemplate`,
+ value: newValue,
+ },
+ })
+ }
+ />
+
+
+ >
)}
>
)}
diff --git a/src/openforms/js/components/admin/form_design/MissingTranslationsWarning.js b/src/openforms/js/components/admin/form_design/MissingTranslationsWarning.js
index 2a56eefc19..b01129e59e 100644
--- a/src/openforms/js/components/admin/form_design/MissingTranslationsWarning.js
+++ b/src/openforms/js/components/admin/form_design/MissingTranslationsWarning.js
@@ -98,9 +98,9 @@ const MissingTranslationsWarning = ({form, formSteps}) => {
extractMissingTranslations(
form.translations,
,
- ['name', 'explanationTemplate'],
+ ['name', 'introductionPageContent', 'explanationTemplate'],
undefined,
- ['explanationTemplate']
+ ['introductionPageContent', 'explanationTemplate']
),
extractMissingTranslations(
form.translations,
diff --git a/src/openforms/js/components/admin/form_design/form-creation-form.js b/src/openforms/js/components/admin/form_design/form-creation-form.js
index 88438bdb85..d9310aad5a 100644
--- a/src/openforms/js/components/admin/form_design/form-creation-form.js
+++ b/src/openforms/js/components/admin/form_design/form-creation-form.js
@@ -183,6 +183,7 @@ const FORM_FIELDS_TO_TAB_NAMES = {
const TRANSLATION_FIELD_TO_TAB_NAMES = {
name: 'form',
+ introductionPageContent: 'form',
explanationTemplate: 'form',
submissionConfirmationTemplate: 'submission-confirmation',
beginText: 'literals',
diff --git a/src/openforms/js/components/admin/form_design/translations.js b/src/openforms/js/components/admin/form_design/translations.js
index 946bd1e2f4..1d07ed456f 100644
--- a/src/openforms/js/components/admin/form_design/translations.js
+++ b/src/openforms/js/components/admin/form_design/translations.js
@@ -10,6 +10,7 @@ export const initialFormTranslations = {
previousText: '',
beginText: '',
submissionConfirmationTemplate: '',
+ introductionPageContent: '',
explanationTemplate: '',
};
diff --git a/src/openforms/js/lang/en.json b/src/openforms/js/lang/en.json
index 8fe29dbebf..d13e0d76d1 100644
--- a/src/openforms/js/lang/en.json
+++ b/src/openforms/js/lang/en.json
@@ -1589,6 +1589,11 @@
"description": "Default delete confirmation message",
"originalDefault": "Are you sure you want to delete this?"
},
+ "Z5lydZ": {
+ "defaultMessage": "Introduction page",
+ "description": "form.introductionPageContent label",
+ "originalDefault": "Introduction page"
+ },
"ZB6mnn": {
"defaultMessage": "The variable key must be unique within a form",
"description": "Unique key error message",
@@ -1839,6 +1844,11 @@
"description": "data type date",
"originalDefault": "Date"
},
+ "dyBb9g": {
+ "defaultMessage": "Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page.",
+ "description": "form.introductionPageContent help text",
+ "originalDefault": "Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page."
+ },
"eBk+W0": {
"defaultMessage": "Manage process variables",
"description": "Camunda process var selection modal title",
diff --git a/src/openforms/js/lang/nl.json b/src/openforms/js/lang/nl.json
index 4a7ef49ae1..c73c4afe5e 100644
--- a/src/openforms/js/lang/nl.json
+++ b/src/openforms/js/lang/nl.json
@@ -1604,6 +1604,11 @@
"description": "Default delete confirmation message",
"originalDefault": "Are you sure you want to delete this?"
},
+ "Z5lydZ": {
+ "defaultMessage": "Introduction page",
+ "description": "form.introductionPageContent label",
+ "originalDefault": "Introduction page"
+ },
"ZB6mnn": {
"defaultMessage": "De sleutel van een variabele moet uniek zijn binnen een formulier",
"description": "Unique key error message",
@@ -1857,6 +1862,11 @@
"description": "data type date",
"originalDefault": "Date"
},
+ "dyBb9g": {
+ "defaultMessage": "Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page.",
+ "description": "form.introductionPageContent help text",
+ "originalDefault": "Content for the introduction page that leads to the start page of the form. Leave blank to disable the introduction page."
+ },
"eBk+W0": {
"defaultMessage": "Beheer procesvariabelen",
"description": "Camunda process var selection modal title",