From 02bd1f01b6c1f6bf1aa7bb7cd38ac728c64d8b68 Mon Sep 17 00:00:00 2001 From: Roly Gutierrez Date: Tue, 10 Feb 2026 19:15:29 -0400 Subject: [PATCH 01/16] =?UTF-8?q?FOUR-29250=20End=20Event=20=E2=80=93=20Ex?= =?UTF-8?q?ternal=20URL=20with=20Mustache/FEEL=20Support=20Description:=20?= =?UTF-8?q?feat(end=20event):=20support=20Mustache=20in=20external=20URL?= =?UTF-8?q?=20for=20element=20destination?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Resolve Mustache expressions in end event "External URL" when the token reaches the end event, using the same context as scripts/screens (APP_URL, _request, _user, process variables). - Add getElementDestinationMustacheContext() to build context via DataManager with fallback; normalize to plain array for Mustache. - Add resolveElementDestinationUrl() to decode HTML entities and render URL template with MustacheExpressionEvaluator. FEEL is not supported. - Apply resolution only for externalURL type; conditional redirect URLs also go through Mustache when destination is external URL. - Harden getElementDestinationAttribute(): ensure conditionalRedirectProp and elementDestinationProp are never null (json_decode ?? [], pass ?? []). - Modeler: allow URL validation when string contains {{ (Mustache); update helper and error copy to document _request.id, _user.id, process vars. Related tickets: https://processmaker.atlassian.net/browse/FOUR-29250 --- src/components/inspectors/ElementDestination.vue | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/inspectors/ElementDestination.vue b/src/components/inspectors/ElementDestination.vue index 5a907d1f1..f2d29e2cb 100644 --- a/src/components/inspectors/ElementDestination.vue +++ b/src/components/inspectors/ElementDestination.vue @@ -50,7 +50,7 @@ :error="getValidationErrorForURL(externalURL)" data-cy="events-add-id" :placeholder="urlPlaceholder" - :helper="$t('Determine the URL where the request will end')" + :helper="$t('URL where the request will redirect. Supports Mustache: {{APP_URL}}, {{_request.id}}, {{_user.id}}, process variables.')" data-test="external-url" /> Date: Wed, 11 Feb 2026 09:58:46 -0400 Subject: [PATCH 02/16] FOUR-29250 Add InspectorConfigViewer: collapsible card in modeler inspector to display element configuration data (formData) as key-value pairs with keyboard-accessible toggle. --- .../inspectors/InspectorConfigViewer.vue | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/components/inspectors/InspectorConfigViewer.vue diff --git a/src/components/inspectors/InspectorConfigViewer.vue b/src/components/inspectors/InspectorConfigViewer.vue new file mode 100644 index 000000000..e965c1e9c --- /dev/null +++ b/src/components/inspectors/InspectorConfigViewer.vue @@ -0,0 +1,134 @@ + + + + + From 1b5ac669d2c6af1b28e35b7660192acaf0aeb4be Mon Sep 17 00:00:00 2001 From: Roly Gutierrez Date: Wed, 11 Feb 2026 10:03:19 -0400 Subject: [PATCH 03/16] FOUR-29250 Remove InspectorConfigViewer and update ElementDestination. --- .../inspectors/ElementDestination.vue | 5 +- .../inspectors/InspectorConfigViewer.vue | 134 ------------------ 2 files changed, 4 insertions(+), 135 deletions(-) delete mode 100644 src/components/inspectors/InspectorConfigViewer.vue diff --git a/src/components/inspectors/ElementDestination.vue b/src/components/inspectors/ElementDestination.vue index f2d29e2cb..e5a51a37c 100644 --- a/src/components/inspectors/ElementDestination.vue +++ b/src/components/inspectors/ElementDestination.vue @@ -50,7 +50,7 @@ :error="getValidationErrorForURL(externalURL)" data-cy="events-add-id" :placeholder="urlPlaceholder" - :helper="$t('URL where the request will redirect. Supports Mustache: {{APP_URL}}, {{_request.id}}, {{_user.id}}, process variables.')" + :helper="externalUrlHelperText" data-test="external-url" /> { diff --git a/src/components/inspectors/InspectorConfigViewer.vue b/src/components/inspectors/InspectorConfigViewer.vue deleted file mode 100644 index e965c1e9c..000000000 --- a/src/components/inspectors/InspectorConfigViewer.vue +++ /dev/null @@ -1,134 +0,0 @@ - - - - - From 87098c804451688a677f4b7eb318735d43809ba2 Mon Sep 17 00:00:00 2001 From: Roly Gutierrez Date: Thu, 12 Feb 2026 15:41:34 -0400 Subject: [PATCH 04/16] FOUR-29250 Require URL when External URL is selected in ElementDestination. --- src/components/inspectors/ElementDestination.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/inspectors/ElementDestination.vue b/src/components/inspectors/ElementDestination.vue index e5a51a37c..c138a814a 100644 --- a/src/components/inspectors/ElementDestination.vue +++ b/src/components/inspectors/ElementDestination.vue @@ -177,7 +177,11 @@ export default { }, methods: { getValidationErrorForURL(url) { - if (!url || !url.trim()) { + const isEmpty = !url || !url.trim(); + if (isEmpty) { + if (this.destinationType === 'externalURL') { + return this.$t('URL is required when External URL is selected.'); + } return ''; } if (!this.isValidURL(url)) { From c02f982387c54a6899d3c27dfb1821da1eaf8454 Mon Sep 17 00:00:00 2001 From: Roly Gutierrez Date: Thu, 12 Feb 2026 16:08:13 -0400 Subject: [PATCH 05/16] FOUR-29250 ElementDestination: improve URL validation - Treat non-strings and empty/whitespace as invalid in isValidURL; use type-safe isEmpty in getValidationErrorForURL - Accept Mustache only when full {{ ... }} pattern matches (reject "{{", "{{invalid", etc.) --- src/components/inspectors/ElementDestination.vue | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/inspectors/ElementDestination.vue b/src/components/inspectors/ElementDestination.vue index c138a814a..caaf921dd 100644 --- a/src/components/inspectors/ElementDestination.vue +++ b/src/components/inspectors/ElementDestination.vue @@ -65,6 +65,9 @@ import ProcessFormSelect from '@/components/inspectors/ProcessFormSelect'; import debounce from 'lodash/debounce'; import isEqual from 'lodash/isEqual'; + +const MUSTACHE_PATTERN = /{{\s*[^}]+\s*}}/; + export default { components: { ProcessFormSelect }, props: { @@ -177,7 +180,7 @@ export default { }, methods: { getValidationErrorForURL(url) { - const isEmpty = !url || !url.trim(); + const isEmpty = typeof url !== 'string' || !url || !url.trim(); if (isEmpty) { if (this.destinationType === 'externalURL') { return this.$t('URL is required when External URL is selected.'); @@ -190,12 +193,12 @@ export default { return ''; }, isValidURL(string) { - if (!string || typeof string !== 'string') { - return true; + if (typeof string !== 'string' || !string.trim()) { + return false; } - // Allow Mustache: same context as backend (APP_URL, _request, _user, process variables) + // Allow Mustache: same context as backend ({{APP_URL}}, {{_request.id}}, {{_user.id}}, process variables) if (string.includes('{{')) { - return true; + return MUSTACHE_PATTERN.test(string); } try { new URL(string); From fc7402d981dd864c6ea8c4d752719357a18e1dc7 Mon Sep 17 00:00:00 2001 From: Roly Gutierrez Date: Thu, 12 Feb 2026 17:57:30 -0400 Subject: [PATCH 06/16] FOUR-29250 Fix ElementDestination URL validation message: keep Mustache examples outside $t() so {{APP_URL}}, {{_request.id}}, {{_user.id}} display correctly. --- src/components/inspectors/ElementDestination.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/inspectors/ElementDestination.vue b/src/components/inspectors/ElementDestination.vue index caaf921dd..afaa3ad0c 100644 --- a/src/components/inspectors/ElementDestination.vue +++ b/src/components/inspectors/ElementDestination.vue @@ -188,7 +188,7 @@ export default { return ''; } if (!this.isValidURL(url)) { - return this.$t('Must be a valid URL or Mustache expressions ({{APP_URL}}, {{_request.id}}, {{_user.id}}, process variables).'); + return this.$t('Must be a valid URL or Mustache expressions') + ' ({{APP_URL}}, {{_request.id}}, {{_user.id}}, ' + this.$t('process variables') + ').'; } return ''; }, From 80848ddd7e7c908eafa222ccce9784007ef4a4f4 Mon Sep 17 00:00:00 2001 From: Roly Gutierrez Date: Sun, 22 Feb 2026 13:05:30 -0400 Subject: [PATCH 07/16] FOUR-29250 Refactor URL validation in ElementDestination and TaskDestination components - Consolidate URL validation logic by utilizing isValidElementDestinationURL utility. - Update error messages for URL validation to improve clarity and user guidance. - Enhance helper text for external URL input to include Mustache expression support. --- .../ConditionalRedirect/TaskDestination.vue | 31 ++++++++++++------- .../inspectors/ElementDestination.vue | 17 ++-------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/components/inspectors/ConditionalRedirect/TaskDestination.vue b/src/components/inspectors/ConditionalRedirect/TaskDestination.vue index ecec1c2b1..96dc26a4b 100644 --- a/src/components/inspectors/ConditionalRedirect/TaskDestination.vue +++ b/src/components/inspectors/ConditionalRedirect/TaskDestination.vue @@ -50,9 +50,9 @@ v-if="taskDestination?.value === 'externalURL'" :label="$t('URL')" v-model="externalURL" - :error="getValidationErrorForCustomURL(externalURL)" + :error="getValidationErrorForURL(externalURL)" :placeholder="urlPlaceholder" - :helper="$t('Determine the URL where the request will end')" + :helper="externalUrlHelperText" data-test="conditional-task-external-url" /> @@ -79,6 +79,7 @@