feat(lead-forms): public form matches builder preview; live unsaved preview in new tab
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -13,6 +13,7 @@ import type {
|
||||
LeadFormFieldType,
|
||||
LeadFormMapTo,
|
||||
LeadFormSubmissionDto,
|
||||
PublicLeadFormDto,
|
||||
LeadStageDto,
|
||||
OrgUserDto,
|
||||
PipelineDto,
|
||||
@@ -437,9 +438,47 @@ async function copyText(text: string) {
|
||||
ok.value = 'کپی شد.';
|
||||
}
|
||||
|
||||
const previewDraft = computed<PublicLeadFormDto | null>(() => {
|
||||
if (!form.value) return null;
|
||||
return {
|
||||
name: name.value.trim() || 'عنوان فرم',
|
||||
description: description.value.trim() || null,
|
||||
thankYouMessage: thankYouMessage.value.trim() || null,
|
||||
redirectUrl: null,
|
||||
submitLabel: submitLabel.value.trim() || 'ارسال درخواست',
|
||||
submitColor: submitColor.value,
|
||||
hasCover: form.value.hasCover,
|
||||
coverPath: coverSrc.value || null,
|
||||
fields: fields.value.map((f) => ({
|
||||
key: f.key,
|
||||
label: f.label,
|
||||
fieldType: f.fieldType,
|
||||
required: f.required,
|
||||
placeholder: f.placeholder || null,
|
||||
options: f.options,
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
function previewKey() {
|
||||
return `lead-form-preview:${form.value?.publicToken ?? ''}`;
|
||||
}
|
||||
|
||||
function writePreviewDraft() {
|
||||
if (!previewDraft.value) return;
|
||||
try {
|
||||
localStorage.setItem(previewKey(), JSON.stringify(previewDraft.value));
|
||||
} catch {
|
||||
/* storage full / disabled — preview falls back to saved version */
|
||||
}
|
||||
}
|
||||
|
||||
watch(previewDraft, writePreviewDraft, { deep: true });
|
||||
|
||||
function openPreview() {
|
||||
if (!form.value?.publicPath) return;
|
||||
window.open(form.value.publicPath, '_blank', 'noopener');
|
||||
writePreviewDraft();
|
||||
window.open(`${form.value.publicPath}?preview=1`, '_blank', 'noopener');
|
||||
}
|
||||
|
||||
function toggleAssignee(uid: string) {
|
||||
@@ -515,7 +554,7 @@ onMounted(load);
|
||||
<template v-for="f in fields" :key="f.key">
|
||||
<p v-if="f.fieldType === 'heading'" class="heading">{{ f.label }}</p>
|
||||
<label v-else>
|
||||
{{ f.label }}
|
||||
<span>{{ f.label }}<span v-if="f.required" class="req">*</span></span>
|
||||
<textarea v-if="f.fieldType === 'textarea'" rows="3" :placeholder="f.placeholder || ''" disabled />
|
||||
<select v-else-if="f.fieldType === 'select'" disabled>
|
||||
<option>{{ f.placeholder || 'انتخاب کنید' }}</option>
|
||||
@@ -845,7 +884,7 @@ onMounted(load);
|
||||
<template v-for="f in fields" :key="'d-' + f.key">
|
||||
<p v-if="f.fieldType === 'heading'" class="heading wide">{{ f.label }}</p>
|
||||
<label v-else :class="{ wide: f.fieldType === 'textarea' || f.fieldType === 'checkbox' }">
|
||||
{{ f.label }}
|
||||
<span>{{ f.label }}<span v-if="f.required" class="req">*</span></span>
|
||||
<textarea v-if="f.fieldType === 'textarea'" rows="3" :placeholder="f.placeholder || ''" disabled />
|
||||
<select v-else-if="f.fieldType === 'select'" disabled>
|
||||
<option>{{ f.placeholder || 'انتخاب کنید' }}</option>
|
||||
|
||||
Reference in New Issue
Block a user