Enhance Iframe Integration in Form Builder
- Added new iframe parameters in FormBuilderFieldSettingsModal, allowing users to configure debug mode, hide completion messages, apply themes, and set custom URL parameters for button components linked to processes. - Updated ComponentPreview.vue to generate dynamic workflow URLs with iframe parameters based on user settings, improving the flexibility of iframe integration. - Implemented a URL preview feature in FormBuilderFieldSettingsModal to display the generated iframe URL based on the current configuration, enhancing user experience and usability. - Enhanced form builder interface to include new settings for iframe integration, ensuring a more comprehensive configuration for button actions.
This commit is contained in:
parent
3f452a46a3
commit
0023ddebcf
@ -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;
|
||||
|
@ -637,6 +637,62 @@
|
||||
help="Choose how the link should open"
|
||||
:classes="{ outer: 'field-wrapper' }"
|
||||
/>
|
||||
|
||||
<!-- Iframe Parameters -->
|
||||
<div class="mt-4 p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<h6 class="text-sm font-medium text-blue-800 mb-3">Iframe Integration Parameters</h6>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<FormKit
|
||||
type="switch"
|
||||
label="Debug Mode"
|
||||
name="iframeDebug"
|
||||
v-model="configModel.iframeDebug"
|
||||
help="Enable debug mode (show UI chrome) - OFF for iframe mode"
|
||||
:classes="{ outer: 'field-wrapper' }"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="switch"
|
||||
label="Hide Completion"
|
||||
name="iframeHideComplete"
|
||||
v-model="configModel.iframeHideComplete"
|
||||
help="Hide completion message (auto-advance)"
|
||||
:classes="{ outer: 'field-wrapper' }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mt-3">
|
||||
<FormKit
|
||||
type="select"
|
||||
label="Theme"
|
||||
name="iframeTheme"
|
||||
v-model="configModel.iframeTheme"
|
||||
:options="[
|
||||
{ label: 'Default', value: '' },
|
||||
{ label: 'Dark', value: 'dark' },
|
||||
{ label: 'Light', value: 'light' }
|
||||
]"
|
||||
help="Apply custom theme to the workflow"
|
||||
:classes="{ outer: 'field-wrapper' }"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Custom Parameters"
|
||||
name="iframeCustomParams"
|
||||
v-model="configModel.iframeCustomParams"
|
||||
help="Additional URL parameters (e.g., 'param1=value1¶m2=value2')"
|
||||
:classes="{ outer: 'field-wrapper' }"
|
||||
placeholder="param1=value1¶m2=value2"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 p-2 bg-gray-100 rounded text-xs text-gray-600">
|
||||
<strong>Generated URL Preview:</strong><br>
|
||||
<code class="text-blue-600">{{ getIframeUrlPreview() }}</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -559,6 +559,61 @@
|
||||
:classes="{ outer: 'mb-0', input: 'text-sm' }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Iframe Parameters (for button with process link) -->
|
||||
<div v-if="showQuickField('iframeDebug') && quickSettings.linkType === 'process'" class="space-y-2">
|
||||
<div class="setting-item">
|
||||
<label class="setting-toggle">
|
||||
<input
|
||||
type="checkbox"
|
||||
v-model="quickSettings.iframeDebug"
|
||||
@change="updateQuickSetting('iframeDebug', $event.target.checked)"
|
||||
class="toggle-input"
|
||||
/>
|
||||
<span class="toggle-slider"></span>
|
||||
<span class="toggle-label">Debug Mode (OFF = iframe)</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<label class="setting-toggle">
|
||||
<input
|
||||
type="checkbox"
|
||||
v-model="quickSettings.iframeHideComplete"
|
||||
@change="updateQuickSetting('iframeHideComplete', $event.target.checked)"
|
||||
class="toggle-input"
|
||||
/>
|
||||
<span class="toggle-slider"></span>
|
||||
<span class="toggle-label">Hide Completion</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<label class="setting-label">Theme</label>
|
||||
<FormKit
|
||||
type="select"
|
||||
v-model="quickSettings.iframeTheme"
|
||||
@input="updateQuickSetting('iframeTheme', $event)"
|
||||
:options="[
|
||||
{ label: 'Default', value: '' },
|
||||
{ label: 'Dark', value: 'dark' },
|
||||
{ label: 'Light', value: 'light' }
|
||||
]"
|
||||
:classes="{ outer: 'mb-0', input: 'text-sm' }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<label class="setting-label">Custom Params</label>
|
||||
<FormKit
|
||||
type="text"
|
||||
v-model="quickSettings.iframeCustomParams"
|
||||
@input="updateQuickSetting('iframeCustomParams', $event)"
|
||||
placeholder="param1=value1¶m2=value2"
|
||||
:classes="{ outer: 'mb-0', input: 'text-sm' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -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']
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user