diff --git a/components/ComponentPreview.vue b/components/ComponentPreview.vue
index ca0b492..d9d04d7 100644
--- a/components/ComponentPreview.vue
+++ b/components/ComponentPreview.vue
@@ -1265,15 +1265,42 @@ const saveNestedComponentSettings = (updatedComponent) => {
const getButtonLink = () => {
if (!props.component || props.component.type !== 'button') return null;
- const { linkType, linkUrl, linkProcessId, linkTarget } = props.component.props;
+ const { linkType, linkUrl, linkProcessId, linkTarget, iframeDebug, iframeHideComplete, iframeTheme, iframeCustomParams } = props.component.props;
if (linkType === 'url' && linkUrl) {
return linkUrl;
}
if (linkType === 'process' && linkProcessId) {
- // Generate the process workflow URL
- return `${window.location.origin}/workflow/${linkProcessId}`;
+ // Generate the process workflow URL with iframe parameters
+ const baseUrl = `${window.location.origin}/workflow/${linkProcessId}`;
+ const params = new URLSearchParams();
+
+ // Add debug parameter (false = iframe mode, true = debug mode)
+ if (iframeDebug !== undefined) {
+ params.append('debug', iframeDebug ? 'true' : 'false');
+ }
+
+ // Add hideComplete parameter
+ if (iframeHideComplete) {
+ params.append('hideComplete', 'true');
+ }
+
+ // Add theme parameter
+ if (iframeTheme) {
+ params.append('theme', iframeTheme);
+ }
+
+ // Add custom parameters
+ if (iframeCustomParams) {
+ const customParams = new URLSearchParams(iframeCustomParams);
+ customParams.forEach((value, key) => {
+ params.append(key, value);
+ });
+ }
+
+ const queryString = params.toString();
+ return queryString ? `${baseUrl}?${queryString}` : baseUrl;
}
return null;
diff --git a/components/FormBuilderFieldSettingsModal.vue b/components/FormBuilderFieldSettingsModal.vue
index 012601b..cd1f8b2 100644
--- a/components/FormBuilderFieldSettingsModal.vue
+++ b/components/FormBuilderFieldSettingsModal.vue
@@ -637,6 +637,62 @@
help="Choose how the link should open"
:classes="{ outer: 'field-wrapper' }"
/>
+
+
+
+
Iframe Integration Parameters
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Generated URL Preview:
+ {{ getIframeUrlPreview() }}
+
+
@@ -2007,6 +2063,42 @@ watch(() => props.component, (newComponent) => {
}
}, { immediate: true })
+// Generate iframe URL preview
+const getIframeUrlPreview = () => {
+ if (!configModel.value.linkProcessId) {
+ return 'Select a process first...'
+ }
+
+ const baseUrl = `${window.location.origin}/workflow/${configModel.value.linkProcessId}`
+ const params = new URLSearchParams()
+
+ // Add debug parameter (false = iframe mode, true = debug mode)
+ if (configModel.value.iframeDebug !== undefined) {
+ params.append('debug', configModel.value.iframeDebug ? 'true' : 'false')
+ }
+
+ // Add hideComplete parameter
+ if (configModel.value.iframeHideComplete) {
+ params.append('hideComplete', 'true')
+ }
+
+ // Add theme parameter
+ if (configModel.value.iframeTheme) {
+ params.append('theme', configModel.value.iframeTheme)
+ }
+
+ // Add custom parameters
+ if (configModel.value.iframeCustomParams) {
+ const customParams = new URLSearchParams(configModel.value.iframeCustomParams)
+ customParams.forEach((value, key) => {
+ params.append(key, value)
+ })
+ }
+
+ const queryString = params.toString()
+ return queryString ? `${baseUrl}?${queryString}` : baseUrl
+}
+
// Type changing functionality
const compatibilityGroups = {
// Text-based inputs (can switch between each other)
@@ -2738,7 +2830,11 @@ const getDefaultPropsForType = (type) => {
linkType: 'none', // 'none', 'url', 'process'
linkUrl: '',
linkProcessId: '',
- linkTarget: '_self' // '_self', '_blank'
+ linkTarget: '_self', // '_self', '_blank'
+ iframeDebug: false, // Show/hide debug UI
+ iframeHideComplete: false, // Hide completion message
+ iframeTheme: '', // Custom theme
+ iframeCustomParams: '' // Additional URL parameters
}
}
diff --git a/pages/form-builder/index.vue b/pages/form-builder/index.vue
index acf52cb..f147fa6 100644
--- a/pages/form-builder/index.vue
+++ b/pages/form-builder/index.vue
@@ -559,6 +559,61 @@
:classes="{ outer: 'mb-0', input: 'text-sm' }"
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2867,6 +2922,10 @@ watch(() => formStore.selectedComponent, (newComponent) => {
linkType: newComponent.props.linkType || 'none',
linkUrl: newComponent.props.linkUrl || '',
linkProcessId: newComponent.props.linkProcessId || '',
+ iframeDebug: newComponent.props.iframeDebug || false,
+ iframeHideComplete: newComponent.props.iframeHideComplete || false,
+ iframeTheme: newComponent.props.iframeTheme || '',
+ iframeCustomParams: newComponent.props.iframeCustomParams || '',
required: newComponent.props.validation?.includes('required') || false
};
@@ -2894,6 +2953,10 @@ const showQuickField = (fieldName) => {
linkType: ['button'],
linkUrl: ['button'],
linkProcessId: ['button'],
+ iframeDebug: ['button'],
+ iframeHideComplete: ['button'],
+ iframeTheme: ['button'],
+ iframeCustomParams: ['button'],
width: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'heading', 'paragraph', 'info-display'],
required: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'select', 'checkbox', 'radio', 'date', 'time', 'datetime-local', 'file', 'otp', 'dropzone']
};