domma-cms 0.14.8 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
- import{apiRequest as S}from"/admin/js/api.js";const B=[{value:"string",label:"Text (single line)"},{value:"email",label:"Email"},{value:"tel",label:"Phone"},{value:"number",label:"Number"},{value:"textarea",label:"Textarea (multi-line)"},{value:"select",label:"Dropdown (select)"},{value:"radio",label:"Radio buttons"},{value:"checkbox",label:"Single checkbox"},{value:"checkbox-group",label:"Checkbox group"},{value:"date",label:"Date"},{value:"time",label:"Time"},{value:"url",label:"URL"},{value:"password",label:"Password"},{value:"file",label:"File upload"},{value:"hidden",label:"Hidden field"}],z=new Set(["select","radio","checkbox-group"]);let b=[],x=null,T=null,q=null;function I(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")}function P(e){return B.find(t=>t.value===e)?.label||e}function M(e){return e?!!(e.visibility?.conditions?.length||e.requirement?.conditions?.length||e.validation?.length||e.cascade?.sourceField):!1}function D(e){const t={...b[e]};if(t.type==="spacer")return t;if(t.type==="page-break"){const g=document.getElementById(`fb-pb-label-${e}`),h=document.getElementById(`fb-pb-desc-${e}`);return g&&(t.label=g.value.trim()||t.label),h&&(t.description=h.value.trim()),t}const o=document.getElementById(`fb-label-${e}`),n=document.getElementById(`fb-name-${e}`),a=document.getElementById(`fb-type-${e}`),l=document.getElementById(`fb-required-${e}`),r=document.getElementById(`fb-placeholder-${e}`),i=document.getElementById(`fb-helper-${e}`);if(o&&(t.label=o.value.trim()||t.label),n&&(t.name=n.value.trim()||t.name),a&&(t.type=a.value||t.type),l&&(t.required=l.checked),r&&(t.placeholder=r.value.trim()),i&&(t.helper=i.value.trim()),z.has(t.type)){const g=document.getElementById(`fb-options-${e}`);g&&(t.options=g.value.split(`
2
- `).filter(h=>h.trim()).map(h=>{const[w,...$]=h.split(":");return{value:w.trim(),label:$.join(":").trim()||w.trim()}}))}if(t.type==="textarea"){const g=parseInt(document.getElementById(`fb-rows-${e}`)?.value,10);g>0&&(t.formConfig={...t.formConfig||{},rows:g})}const p=document.getElementById(`fb-span-${e}`),d=document.getElementById(`fb-fullwidth-${e}`);if(p||d){const g={...t.formConfig||{}};if(d?.checked)g.span="full";else{const h=parseInt(p?.value,10);h>1?g.span=h:delete g.span}t.formConfig=Object.keys(g).length?g:void 0}const m=document.getElementById(`fb-minlength-${e}`)?.value;m&&(t.minLength=parseInt(m,10));const c=document.getElementById(`fb-maxlength-${e}`)?.value;c&&(t.maxLength=parseInt(c,10));const u=document.getElementById(`fb-min-${e}`)?.value;u!==""&&u!==void 0&&(t.min=parseFloat(u));const s=document.getElementById(`fb-max-${e}`)?.value;s!==""&&s!==void 0&&(t.max=parseFloat(s));const f=V(e);return f?t.logic=f:delete t.logic,t}function V(e){const t=document.querySelector(`.fb-field-card[data-index="${e}"]`);if(!t)return;const o=t.querySelector(".fb-field-logic");if(!o)return;const n={};let a=!1;const l=o.querySelector('[data-logic-section="visibility"]');if(l){const d=l.querySelector(".fb-logic-vis-default"),m=l.querySelector(".fb-logic-vis-transition"),c=Array.from(l.querySelectorAll(".fb-logic-cond-row")).map(f=>{const g=f.querySelector(".fb-logic-cond-field"),h=f.querySelector(".fb-logic-cond-op"),w=f.querySelector(".fb-logic-cond-val"),$=f.querySelector(".fb-logic-vis-then");return g?.value?{when:{all:[{field:g.value,operator:h.value,value:w.value}]},then:$.value}:null}).filter(Boolean),u=d?.value||"visible",s=m?.value||"none";(u!=="visible"||c.length>0||s!=="none")&&(n.visibility={default:u,conditions:c},s!=="none"&&(n.visibility.transition=s),a=!0)}const r=o.querySelector('[data-logic-section="requirement"]');if(r){const d=r.querySelector(".fb-logic-req-default"),m=Array.from(r.querySelectorAll(".fb-logic-cond-row")).map(c=>{const u=c.querySelector(".fb-logic-cond-field"),s=c.querySelector(".fb-logic-cond-op"),f=c.querySelector(".fb-logic-cond-val"),g=c.querySelector(".fb-logic-req-then");return u?.value?{when:{all:[{field:u.value,operator:s.value,value:f.value}]},then:g.value==="true"}:null}).filter(Boolean);m.length>0&&(n.requirement={default:d?.checked===!0,conditions:m},a=!0)}const i=o.querySelector('[data-logic-section="validation"]');if(i){const d=Array.from(i.querySelectorAll(".fb-logic-val-rule")).map(m=>{const c=m.querySelector(".fb-logic-val-type"),u=m.querySelector(".fb-logic-val-pattern"),s=m.querySelector(".fb-logic-val-flags"),f=m.querySelector(".fb-logic-val-message");if(!u?.value.trim())return null;const g=c?.value||"regex",h={type:g,message:f?.value.trim()||"Invalid value."};return g==="regex"?(h.pattern=u.value.trim(),s?.value.trim()&&(h.flags=s.value.trim())):h.field=u.value.trim(),h}).filter(Boolean);d.length>0&&(n.validation=d,a=!0)}const p=o.querySelector('[data-logic-section="cascade"]');if(p){const d=p.querySelector(".fb-logic-cascade-source"),m=p.querySelector(".fb-logic-cascade-mapping"),c=p.querySelector(".fb-logic-cascade-defaults"),u=d?.value?.trim();if(u){let s={};try{s=JSON.parse(m?.value||"{}")}catch{}const f=(c?.value||"").split(`
3
- `).filter(g=>g.trim()).map(g=>{const[h,...w]=g.split(":");return{value:h.trim(),label:w.join(":").trim()||h.trim()}});n.cascade={sourceField:u,mapping:s,defaultOptions:f},a=!0}}return a?n:void 0}function y(){b=b.map((e,t)=>D(t))}function v(e){const t=e.find("#fields-list").get(0),o=e.find("#fields-empty-msg").get(0);if(t){if(Array.from(t.querySelectorAll(".fb-field-card")).forEach(n=>n.remove()),b.length===0){o&&(o.style.display="");return}o&&(o.style.display="none"),b.forEach((n,a)=>{const l=n.type==="page-break"?W(n,a,e):n.type==="spacer"?Y(n,a,e):G(n,a,e);t.appendChild(l)})}}function W(e,t,o){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:2px dashed var(--border-color,#444);border-radius:6px;overflow:hidden;margin-bottom:.5rem;background:var(--card-bg,rgba(255,255,255,.02));";const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.6rem .8rem;cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent="\u2014 Page Break \u2014",l.style.cssText="font-size:.7rem;padding:.15rem .5rem;border-radius:999px;background:rgba(120,120,120,.2);color:var(--text-muted,#888);white-space:nowrap;flex-shrink:0;font-style:italic;";const r=document.createElement("span");r.textContent=e.label||"Untitled Step",r.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-muted,#888);";const i=document.createElement("div");if(i.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;",t>0){const s=document.createElement("button");s.className="btn btn-xs btn-ghost",s.title="Move up",s.textContent="\u2191",s.addEventListener("click",f=>{f.stopPropagation(),y(),[b[t-1],b[t]]=[b[t],b[t-1]],v(o)}),i.appendChild(s)}if(t<b.length-1){const s=document.createElement("button");s.className="btn btn-xs btn-ghost",s.title="Move down",s.textContent="\u2193",s.addEventListener("click",f=>{f.stopPropagation(),y(),[b[t],b[t+1]]=[b[t+1],b[t]],v(o)}),i.appendChild(s)}const p=document.createElement("button");p.className="btn btn-xs btn-ghost",p.title="Edit step",p.textContent="\u22EF",p.addEventListener("click",s=>{s.stopPropagation(),m.style.display=m.style.display==="none"?"":"none"}),i.appendChild(p);const d=document.createElement("button");d.className="btn btn-xs btn-danger",d.title="Remove page break",d.textContent="\u2715",d.addEventListener("click",async s=>{s.stopPropagation(),await E.confirm("Remove this page break?")&&(y(),b.splice(t,1),v(o))}),i.appendChild(d),a.appendChild(l),a.appendChild(r),a.appendChild(i),a.addEventListener("click",()=>{m.style.display=m.style.display==="none"?"":"none"});const m=document.createElement("div");m.className="fb-field-body",m.style.cssText="padding:.8rem;border-top:1px dashed var(--border-color,#444);display:none;";const c=k([C("Step Title",`fb-pb-label-${t}`,"text",e.label||"","Shown as the wizard step heading"),C("Step Description",`fb-pb-desc-${t}`,"text",e.description||"","Optional sub-heading")]),u=c.querySelector(`#fb-pb-label-${t}`);return u&&u.addEventListener("input",()=>{r.textContent=u.value||"Untitled Step"}),m.appendChild(c),n.appendChild(a),n.appendChild(m),n}function Y(e,t,o){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:1px dashed var(--border-color,#444);border-radius:6px;margin-bottom:.5rem;background:transparent;";const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.4rem .8rem;";const l=document.createElement("div");l.style.cssText="flex:1;height:1px;background:var(--border-color,#444);";const r=document.createElement("span");r.textContent="Spacer",r.style.cssText="font-size:.7rem;color:var(--text-muted,#888);white-space:nowrap;padding:0 .4rem;font-style:italic;";const i=document.createElement("div");i.style.cssText="flex:1;height:1px;background:var(--border-color,#444);";const p=document.createElement("div");if(p.style.cssText="display:flex;gap:.25rem;flex-shrink:0;",t>0){const m=document.createElement("button");m.className="btn btn-xs btn-ghost",m.title="Move up",m.textContent="\u2191",m.addEventListener("click",c=>{c.stopPropagation(),y(),[b[t-1],b[t]]=[b[t],b[t-1]],v(o)}),p.appendChild(m)}if(t<b.length-1){const m=document.createElement("button");m.className="btn btn-xs btn-ghost",m.title="Move down",m.textContent="\u2193",m.addEventListener("click",c=>{c.stopPropagation(),y(),[b[t],b[t+1]]=[b[t+1],b[t]],v(o)}),p.appendChild(m)}const d=document.createElement("button");return d.className="btn btn-xs btn-danger",d.title="Remove spacer",d.textContent="\u2715",d.addEventListener("click",async m=>{m.stopPropagation(),y(),b.splice(t,1),v(o)}),p.appendChild(d),a.appendChild(l),a.appendChild(r),a.appendChild(i),a.appendChild(p),n.appendChild(a),n}function G(e,t,o){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:1px solid var(--border-color,#333);border-radius:6px;overflow:hidden;margin-bottom:.5rem;";const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.6rem .8rem;background:var(--card-header-bg,rgba(255,255,255,.04));cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent=P(e.type),l.style.cssText="font-size:.7rem;padding:.15rem .45rem;border-radius:999px;background:var(--primary-soft,rgba(99,102,241,.15));color:var(--primary,#6366f1);white-space:nowrap;flex-shrink:0;";const r=document.createElement("span");r.textContent=e.label||"(unlabelled)",r.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;";const i=document.createElement("div");if(i.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;",t>0){const c=document.createElement("button");c.className="btn btn-xs btn-ghost",c.title="Move up",c.textContent="\u2191",c.addEventListener("click",u=>{u.stopPropagation(),y(),[b[t-1],b[t]]=[b[t],b[t-1]],v(o)}),i.appendChild(c)}if(t<b.length-1){const c=document.createElement("button");c.className="btn btn-xs btn-ghost",c.title="Move down",c.textContent="\u2193",c.addEventListener("click",u=>{u.stopPropagation(),y(),[b[t],b[t+1]]=[b[t+1],b[t]],v(o)}),i.appendChild(c)}const p=document.createElement("button");p.className="btn btn-xs btn-ghost",p.title="Edit field",p.textContent="\u22EF",p.addEventListener("click",c=>{c.stopPropagation(),m.style.display=m.style.display==="none"?"":"none"}),i.appendChild(p);const d=document.createElement("button");if(d.className="btn btn-xs btn-danger",d.title="Remove field",d.textContent="\u2715",d.addEventListener("click",async c=>{c.stopPropagation(),await E.confirm("Remove this field?")&&(y(),b.splice(t,1),v(o))}),i.appendChild(d),a.appendChild(l),a.appendChild(r),e.required){const c=document.createElement("span");c.textContent="required",c.style.cssText="font-size:.7rem;color:var(--danger,#ef4444);flex-shrink:0;",a.appendChild(c)}if(M(e.logic)){const c=document.createElement("span");c.textContent="\u26A1",c.title="Has conditional logic",c.style.cssText="font-size:.75rem;color:var(--primary,#6366f1);flex-shrink:0;",a.appendChild(c)}a.appendChild(i),a.addEventListener("click",()=>{m.style.display=m.style.display==="none"?"":"none"});const m=K(e,t,r);return m.style.display="none",n.appendChild(a),n.appendChild(m),n}function K(e,t,o){const n=document.createElement("div");n.className="fb-field-body",n.style.cssText="padding:.8rem;border-top:1px solid var(--border-color,#333);";const a=k([C("Label",`fb-label-${t}`,"text",e.label||"","Shown above the field"),C("Field Name",`fb-name-${t}`,"text",e.name||"","Used as data key")]),l=k([le("Type",`fb-type-${t}`,B,e.type||"string"),j("Required",`fb-required-${t}`,e.required||!1)]),r=k([C("Placeholder",`fb-placeholder-${t}`,"text",e.placeholder||"","Hint text inside the field"),C("Helper Text",`fb-helper-${t}`,"text",e.helper||"","Shown below the field")]),i=e.formConfig?.span,p=k([C("Column Span",`fb-span-${t}`,"number",i&&i!=="full"?String(i):"1","Columns to span (grid only)"),j("Full Width",`fb-fullwidth-${t}`,i==="full")]);p.classList.add("fb-grid-row"),p.style.display=document.getElementById("setting-layout")?.value==="grid"?"flex":"none",n.appendChild(a),n.appendChild(l),n.appendChild(r),n.appendChild(p);const d=n.querySelector(`#fb-label-${t}`),m=n.querySelector(`#fb-name-${t}`);d&&d.addEventListener("input",()=>{o&&(o.textContent=d.value||"(unlabelled)"),m&&!m.dataset.manuallyEdited&&(m.value=I(d.value))}),m&&m.addEventListener("input",()=>{m.dataset.manuallyEdited="1"});const c=n.querySelector(`#fb-type-${t}`);c&&c.addEventListener("change",()=>{const s=n.closest(".fb-field-card");if(s){const h=s.querySelector("span");h&&(h.textContent=P(c.value))}const f=n.querySelector(".fb-field-extras");f&&f.remove();const g=O(c.value,e,t);g&&n.appendChild(g)});const u=O(e.type,e,t);return u&&n.appendChild(u),n.appendChild(ne(e,t)),n}const Q=[{value:"equals",label:"equals"},{value:"not_equals",label:"does not equal"},{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"},{value:"starts_with",label:"starts with"},{value:"ends_with",label:"ends with"},{value:"greater_than",label:"is greater than"},{value:"less_than",label:"is less than"},{value:"is_empty",label:"is empty"},{value:"is_not_empty",label:"is not empty"},{value:"in",label:"is one of (comma sep)"},{value:"not_in",label:"is not one of (comma sep)"},{value:"matches_regex",label:"matches regex"}],_=new Set(["is_empty","is_not_empty"]);function N(e){const t=document.createElement("p");return t.textContent=e,t.style.cssText="font-size:.75rem;font-weight:700;color:var(--text-muted,#888);margin:.6rem 0 .3rem;text-transform:uppercase;letter-spacing:.04em;",t}function L(e,t,o,n,a){const l=document.createElement("div");l.className="fb-logic-cond-row",l.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const r=document.createElement("span");r.textContent="When",r.style.cssText="font-size:.73rem;color:var(--text-muted,#888);flex-shrink:0;";const i=document.createElement("select");i.className="form-input fb-logic-cond-field",i.style.cssText="flex:2;min-width:80px;font-size:.78rem;padding:.2rem .35rem;",t.forEach(s=>{const f=document.createElement("option");f.value=s.value,f.textContent=s.label,e&&s.value===e.field&&(f.selected=!0),i.appendChild(f)});const p=document.createElement("select");p.className="form-input fb-logic-cond-op",p.style.cssText="flex:2;min-width:80px;font-size:.78rem;padding:.2rem .35rem;",Q.forEach(s=>{const f=document.createElement("option");f.value=s.value,f.textContent=s.label,e&&s.value===e.operator&&(f.selected=!0),p.appendChild(f)});const d=document.createElement("input");d.type="text",d.className="form-input fb-logic-cond-val",d.placeholder="value",d.style.cssText="flex:2;min-width:60px;font-size:.78rem;padding:.2rem .35rem;",d.value=e?.value||"",e&&_.has(e.operator)&&(d.style.display="none"),p.addEventListener("change",()=>{d.style.display=_.has(p.value)?"none":""});const m=document.createElement("span");m.textContent="\u2192",m.style.cssText="font-size:.73rem;color:var(--text-muted,#888);flex-shrink:0;";const c=document.createElement("select");c.className=`form-input ${n}`,c.style.cssText="flex:2;min-width:80px;font-size:.78rem;padding:.2rem .35rem;",o.forEach(s=>{const f=document.createElement("option");f.value=s.value,f.textContent=s.label,s.value===a&&(f.selected=!0),c.appendChild(f)});const u=document.createElement("button");return u.type="button",u.className="btn btn-xs btn-danger",u.textContent="\u2715",u.style.flexShrink="0",u.addEventListener("click",()=>l.remove()),l.appendChild(r),l.appendChild(i),l.appendChild(p),l.appendChild(d),l.appendChild(m),l.appendChild(c),l.appendChild(u),l}function X(e,t,o){const n=document.createElement("div");n.dataset.logicSection="visibility",n.appendChild(N("Visibility"));const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const l=document.createElement("span");l.textContent="Default:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const r=document.createElement("select");r.className="form-input fb-logic-vis-default",r.style.cssText="font-size:.8rem;padding:.25rem .4rem;",[{value:"visible",label:"Visible"},{value:"hidden",label:"Hidden"}].forEach(s=>{const f=document.createElement("option");f.value=s.value,f.textContent=s.label,s.value===(e.default||"visible")&&(f.selected=!0),r.appendChild(f)}),a.appendChild(l),a.appendChild(r),n.appendChild(a);const i=document.createElement("div");i.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const p=document.createElement("span");p.textContent="Transition:",p.style.cssText="font-size:.8rem;flex-shrink:0;";const d=document.createElement("select");d.className="form-input fb-logic-vis-transition",d.style.cssText="font-size:.8rem;padding:.25rem .4rem;",[{value:"none",label:"None (instant)"},{value:"fade",label:"Fade"},{value:"slide",label:"Slide"},{value:"scale",label:"Scale"}].forEach(s=>{const f=document.createElement("option");f.value=s.value,f.textContent=s.label,s.value===(e.transition||"none")&&(f.selected=!0),d.appendChild(f)}),i.appendChild(p),i.appendChild(d),n.appendChild(i);const m=document.createElement("div");m.className="fb-logic-vis-rules";const c=o.map(s=>({value:s.name,label:s.label||s.name})),u=[{value:"visible",label:"Show"},{value:"hidden",label:"Hide"}];if((e.conditions||[]).forEach(s=>{const f=(s.when?.all||s.when?.any||[])[0],g=s.then==="hidden"?"hidden":"visible";c.length>0&&m.appendChild(L(f,c,u,"fb-logic-vis-then",g))}),n.appendChild(m),c.length>0){const s=document.createElement("button");s.type="button",s.className="btn btn-xs btn-ghost",s.style.cssText="font-size:.73rem;margin-top:.2rem;",s.textContent="+ Add visibility rule",s.addEventListener("click",()=>m.appendChild(L(null,c,u,"fb-logic-vis-then","visible"))),n.appendChild(s)}return n}function Z(e,t,o){const n=document.createElement("div");n.dataset.logicSection="requirement",n.appendChild(N("Conditional Requirement"));const a=document.createElement("label");a.style.cssText="display:flex;align-items:center;gap:.4rem;font-size:.8rem;cursor:pointer;margin-bottom:.4rem;";const l=document.createElement("input");l.type="checkbox",l.className="fb-logic-req-default",l.checked=e.default===!0,a.appendChild(l),a.appendChild(document.createTextNode("Required by default")),n.appendChild(a);const r=document.createElement("div");r.className="fb-logic-req-rules";const i=o.map(d=>({value:d.name,label:d.label||d.name})),p=[{value:"true",label:"Make required"},{value:"false",label:"Make optional"}];if((e.conditions||[]).forEach(d=>{const m=(d.when?.all||d.when?.any||[])[0],c=d.then===!0?"true":"false";i.length>0&&r.appendChild(L(m,i,p,"fb-logic-req-then",c))}),n.appendChild(r),i.length>0){const d=document.createElement("button");d.type="button",d.className="btn btn-xs btn-ghost",d.style.cssText="font-size:.73rem;margin-top:.2rem;",d.textContent="+ Add requirement rule",d.addEventListener("click",()=>r.appendChild(L(null,i,p,"fb-logic-req-then","true"))),n.appendChild(d)}return n}function A(e){const t=document.createElement("div");t.className="fb-logic-val-rule",t.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const o=document.createElement("select");o.className="form-input fb-logic-val-type",o.style.cssText="flex:0 0 auto;font-size:.78rem;padding:.2rem .35rem;",[{value:"regex",label:"Regex"},{value:"match",label:"Match field"}].forEach(i=>{const p=document.createElement("option");p.value=i.value,p.textContent=i.label,i.value===(e?.type||"regex")&&(p.selected=!0),o.appendChild(p)});const n=document.createElement("input");n.type="text",n.className="form-input fb-logic-val-pattern",n.placeholder=e?.type==="match"?"field name":"pattern",n.value=e?.pattern||e?.field||"",n.style.cssText="flex:3;font-size:.78rem;padding:.2rem .35rem;";const a=document.createElement("input");a.type="text",a.className="form-input fb-logic-val-flags",a.placeholder="flags",a.value=e?.flags||"",a.style.cssText="flex:0 0 55px;font-size:.78rem;padding:.2rem .35rem;",e?.type==="match"&&(a.style.display="none"),o.addEventListener("change",()=>{a.style.display=o.value==="match"?"none":"",n.placeholder=o.value==="match"?"field name":"pattern"});const l=document.createElement("input");l.type="text",l.className="form-input fb-logic-val-message",l.placeholder="Error message",l.value=e?.message||"",l.style.cssText="flex:4;font-size:.78rem;padding:.2rem .35rem;";const r=document.createElement("button");return r.type="button",r.className="btn btn-xs btn-danger",r.textContent="\u2715",r.style.flexShrink="0",r.addEventListener("click",()=>t.remove()),t.appendChild(o),t.appendChild(n),t.appendChild(a),t.appendChild(l),t.appendChild(r),t}function ee(e,t,o){const n=document.createElement("div");n.dataset.logicSection="validation",n.appendChild(N("Custom Validation"));const a=document.createElement("div");a.className="fb-logic-val-rules",(e||[]).forEach(r=>a.appendChild(A(r))),n.appendChild(a);const l=document.createElement("button");return l.type="button",l.className="btn btn-xs btn-ghost",l.style.cssText="font-size:.73rem;margin-top:.2rem;",l.textContent="+ Add validation rule",l.addEventListener("click",()=>a.appendChild(A(null))),n.appendChild(l),n}function te(e,t,o){const n=document.createElement("div");n.dataset.logicSection="cascade",n.appendChild(N("Cascade Options"));const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;";const l=document.createElement("span");l.textContent="Source field:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const r=document.createElement("select");r.className="form-input fb-logic-cascade-source",r.style.cssText="flex:1;font-size:.8rem;padding:.25rem .4rem;";const i=document.createElement("option");i.value="",i.textContent="\u2014 none \u2014",r.appendChild(i),o.forEach(u=>{const s=document.createElement("option");s.value=u.name,s.textContent=u.label||u.name,u.name===e.sourceField&&(s.selected=!0),r.appendChild(s)}),a.appendChild(l),a.appendChild(r),n.appendChild(a);const p=document.createElement("p");p.textContent='Mapping JSON \u2014 {"value":[{"value":"...","label":"..."}]}',p.style.cssText="font-size:.73rem;color:var(--text-muted,#888);margin:.3rem 0 .2rem;";const d=document.createElement("textarea");d.className="form-input fb-logic-cascade-mapping",d.rows=4,d.style.cssText="font-family:monospace;font-size:.78rem;",d.placeholder='{"uk": [{"value": "london", "label": "London"}]}',d.value=e.mapping?JSON.stringify(e.mapping,null,2):"",n.appendChild(p),n.appendChild(d);const m=document.createElement("p");m.textContent="Default options (one per line: value:Label)",m.style.cssText="font-size:.73rem;color:var(--text-muted,#888);margin:.3rem 0 .2rem;";const c=document.createElement("textarea");return c.className="form-input fb-logic-cascade-defaults",c.rows=3,c.style.cssText="font-family:monospace;font-size:.78rem;",c.placeholder=`option1:Option 1
4
- option2:Option 2`,c.value=(e.defaultOptions||[]).map(u=>{const s=typeof u=="string"?u:u.value??"",f=typeof u=="string"?u:u.label??s;return s===f?s:`${s}:${f}`}).join(`
5
- `),n.appendChild(m),n.appendChild(c),n}function ne(e,t){const o=e.logic||{},n=b.filter((c,u)=>u!==t&&c.type!=="page-break"&&c.type!=="spacer"),a=document.createElement("div");a.className="fb-field-logic",a.style.cssText="margin-top:.75rem;border-top:1px solid var(--border-color,#333);padding-top:.5rem;";const l=document.createElement("div");l.style.cssText="display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:.15rem 0;";const r=document.createElement("span");r.style.cssText="font-size:.8rem;font-weight:600;color:var(--text-muted,#888);",r.textContent="\u26A1 Conditional Logic";const i=M(o),p=document.createElement("button");p.type="button",p.className="btn btn-xs btn-ghost",p.textContent=i?"\u25BE":"\u25B8";const d=document.createElement("div");d.className="fb-logic-body",d.style.cssText="padding:.25rem 0 .25rem;"+(i?"":"display:none;"),l.addEventListener("click",()=>{const c=d.style.display==="none";d.style.display=c?"":"none",p.textContent=c?"\u25BE":"\u25B8"}),l.appendChild(r),l.appendChild(p),a.appendChild(l),d.appendChild(X(o.visibility||{},t,n)),d.appendChild(Z(o.requirement||{},t,n)),d.appendChild(ee(o.validation||[],t,n));const m=document.getElementById(`fb-type-${t}`)?.value||e.type;return z.has(m)&&d.appendChild(te(o.cascade||{},t,n)),a.appendChild(d),a}function O(e,t,o){const n=document.createElement("div");return n.className="fb-field-extras",z.has(e)&&n.appendChild(ae(t.options||[],o)),e==="textarea"&&n.appendChild(k([C("Rows",`fb-rows-${o}`,"number",t.formConfig?.rows||4,"Height of textarea")])),(e==="string"||e==="textarea")&&n.appendChild(k([C("Min Length",`fb-minlength-${o}`,"number",t.minLength||"",""),C("Max Length",`fb-maxlength-${o}`,"number",t.maxLength||"","")])),e==="number"&&n.appendChild(k([C("Min",`fb-min-${o}`,"number",t.min??"",""),C("Max",`fb-max-${o}`,"number",t.max??"","")])),n.children.length?n:null}function k(e){const t=document.createElement("div");return t.style.cssText="display:flex;gap:.75rem;margin-bottom:.6rem;",e.forEach(o=>{o&&t.appendChild(o)}),t}function C(e,t,o,n,a){const l=document.createElement("div");l.style.flex="1";const r=document.createElement("label");r.htmlFor=t,r.className="form-label",r.textContent=e,r.style.fontSize=".8rem";const i=document.createElement("input");if(i.id=t,i.type=o||"text",i.className="form-input",i.value=n??"",l.appendChild(r),l.appendChild(i),a){const p=document.createElement("p");p.className="form-hint text-muted",p.textContent=a,p.style.cssText="font-size:.73rem;margin-top:.2rem;",l.appendChild(p)}return l}function le(e,t,o,n){const a=document.createElement("div");a.style.flex="1";const l=document.createElement("label");l.htmlFor=t,l.className="form-label",l.textContent=e,l.style.fontSize=".8rem";const r=document.createElement("select");return r.id=t,r.className="form-input",o.forEach(i=>{const p=document.createElement("option");p.value=i.value,p.textContent=i.label,i.value===n&&(p.selected=!0),r.appendChild(p)}),a.appendChild(l),a.appendChild(r),a}function j(e,t,o){const n=document.createElement("div");n.style.cssText="flex:0;min-width:80px;display:flex;flex-direction:column;justify-content:flex-end;";const a=document.createElement("label");a.style.cssText="display:flex;align-items:center;gap:.4rem;cursor:pointer;font-size:.8rem;white-space:nowrap;";const l=document.createElement("input");return l.id=t,l.type="checkbox",l.checked=o,a.appendChild(l),a.appendChild(document.createTextNode(e)),n.appendChild(a),n}function ae(e,t){const o=document.createElement("div");o.style.cssText="margin-top:.4rem;";const n=document.createElement("p");n.textContent="Options (one per line: value or value:Label)",n.style.cssText="font-size:.8rem;font-weight:600;margin-bottom:.3rem;";const a=document.createElement("textarea");return a.id=`fb-options-${t}`,a.className="form-input",a.rows=4,a.placeholder=`yes:Yes
1
+ import{apiRequest as T}from"/admin/js/api.js";const B=[{value:"string",label:"Text (single line)"},{value:"email",label:"Email"},{value:"tel",label:"Phone"},{value:"number",label:"Number"},{value:"textarea",label:"Textarea (multi-line)"},{value:"select",label:"Dropdown (select)"},{value:"radio",label:"Radio buttons"},{value:"checkbox",label:"Single checkbox"},{value:"checkbox-group",label:"Checkbox group"},{value:"date",label:"Date"},{value:"time",label:"Time"},{value:"url",label:"URL"},{value:"password",label:"Password"},{value:"file",label:"File upload"},{value:"hidden",label:"Hidden field"}],z=new Set(["select","radio","checkbox-group"]);let b=[],w=null,q=null,N=null;function I(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")}function P(e){return B.find(t=>t.value===e)?.label||e}function M(e){return e?!!(e.visibility?.conditions?.length||e.requirement?.conditions?.length||e.validation?.length||e.cascade?.sourceField):!1}function V(e){const t={...b[e]};if(t.type==="spacer")return t;if(t.type==="page-break"){const g=document.getElementById(`fb-pb-label-${e}`),y=document.getElementById(`fb-pb-desc-${e}`);return g&&(t.label=g.value.trim()||t.label),y&&(t.description=y.value.trim()),t}const o=document.getElementById(`fb-label-${e}`),n=document.getElementById(`fb-name-${e}`),a=document.getElementById(`fb-type-${e}`),l=document.getElementById(`fb-required-${e}`),c=document.getElementById(`fb-placeholder-${e}`),s=document.getElementById(`fb-helper-${e}`),p=document.getElementById(`fb-tooltip-${e}`);if(o&&(t.label=o.value.trim()||t.label),n&&(t.name=n.value.trim()||t.name),a&&(t.type=a.value||t.type),l&&(t.required=l.checked),c&&(t.placeholder=c.value.trim()),s&&(t.helper=s.value.trim()),p&&(t.tooltip=p.value.trim()),z.has(t.type)){const g=document.getElementById(`fb-options-${e}`);g&&(t.options=g.value.split(`
2
+ `).filter(y=>y.trim()).map(y=>{const[S,...D]=y.split(":");return{value:S.trim(),label:D.join(":").trim()||S.trim()}}))}if(t.type==="textarea"){const g=parseInt(document.getElementById(`fb-rows-${e}`)?.value,10);g>0&&(t.formConfig={...t.formConfig||{},rows:g})}const d=document.getElementById(`fb-span-${e}`),m=document.getElementById(`fb-fullwidth-${e}`);if(d||m){const g={...t.formConfig||{}};if(m?.checked)g.span="full";else{const y=parseInt(d?.value,10);y>1?g.span=y:delete g.span}t.formConfig=Object.keys(g).length?g:void 0}const r=document.getElementById(`fb-minlength-${e}`)?.value;r&&(t.minLength=parseInt(r,10));const u=document.getElementById(`fb-maxlength-${e}`)?.value;u&&(t.maxLength=parseInt(u,10));const i=document.getElementById(`fb-min-${e}`)?.value;i!==""&&i!==void 0&&(t.min=parseFloat(i));const f=document.getElementById(`fb-max-${e}`)?.value;f!==""&&f!==void 0&&(t.max=parseFloat(f));const h=W(e);return h?t.logic=h:delete t.logic,t}function W(e){const t=document.querySelector(`.fb-field-card[data-index="${e}"]`);if(!t)return;const o=t.querySelector(".fb-field-logic");if(!o)return;const n={};let a=!1;const l=o.querySelector('[data-logic-section="visibility"]');if(l){const d=l.querySelector(".fb-logic-vis-default"),m=l.querySelector(".fb-logic-vis-transition"),r=Array.from(l.querySelectorAll(".fb-logic-cond-row")).map(f=>{const h=f.querySelector(".fb-logic-cond-field"),g=f.querySelector(".fb-logic-cond-op"),y=f.querySelector(".fb-logic-cond-val"),S=f.querySelector(".fb-logic-vis-then");return h?.value?{when:{all:[{field:h.value,operator:g.value,value:y.value}]},then:S.value}:null}).filter(Boolean),u=d?.value||"visible",i=m?.value||"none";(u!=="visible"||r.length>0||i!=="none")&&(n.visibility={default:u,conditions:r},i!=="none"&&(n.visibility.transition=i),a=!0)}const c=o.querySelector('[data-logic-section="requirement"]');if(c){const d=c.querySelector(".fb-logic-req-default"),m=Array.from(c.querySelectorAll(".fb-logic-cond-row")).map(r=>{const u=r.querySelector(".fb-logic-cond-field"),i=r.querySelector(".fb-logic-cond-op"),f=r.querySelector(".fb-logic-cond-val"),h=r.querySelector(".fb-logic-req-then");return u?.value?{when:{all:[{field:u.value,operator:i.value,value:f.value}]},then:h.value==="true"}:null}).filter(Boolean);m.length>0&&(n.requirement={default:d?.checked===!0,conditions:m},a=!0)}const s=o.querySelector('[data-logic-section="validation"]');if(s){const d=Array.from(s.querySelectorAll(".fb-logic-val-rule")).map(m=>{const r=m.querySelector(".fb-logic-val-type"),u=m.querySelector(".fb-logic-val-pattern"),i=m.querySelector(".fb-logic-val-flags"),f=m.querySelector(".fb-logic-val-message");if(!u?.value.trim())return null;const h=r?.value||"regex",g={type:h,message:f?.value.trim()||"Invalid value."};return h==="regex"?(g.pattern=u.value.trim(),i?.value.trim()&&(g.flags=i.value.trim())):g.field=u.value.trim(),g}).filter(Boolean);d.length>0&&(n.validation=d,a=!0)}const p=o.querySelector('[data-logic-section="cascade"]');if(p){const d=p.querySelector(".fb-logic-cascade-source"),m=p.querySelector(".fb-logic-cascade-mapping"),r=p.querySelector(".fb-logic-cascade-defaults"),u=d?.value?.trim();if(u){let i={};try{i=JSON.parse(m?.value||"{}")}catch{}const f=(r?.value||"").split(`
3
+ `).filter(h=>h.trim()).map(h=>{const[g,...y]=h.split(":");return{value:g.trim(),label:y.join(":").trim()||g.trim()}});n.cascade={sourceField:u,mapping:i,defaultOptions:f},a=!0}}return a?n:void 0}function v(){b=b.map((e,t)=>V(t))}function x(e){const t=e.find("#fields-list").get(0),o=e.find("#fields-empty-msg").get(0);if(t){if(Array.from(t.querySelectorAll(".fb-field-card")).forEach(n=>n.remove()),b.length===0){o&&(o.style.display="");return}o&&(o.style.display="none"),b.forEach((n,a)=>{const l=n.type==="page-break"?Y(n,a,e):n.type==="spacer"?G(n,a,e):K(n,a,e);t.appendChild(l)})}}function Y(e,t,o){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:2px dashed var(--border-color,#444);border-radius:6px;overflow:hidden;margin-bottom:.5rem;background:var(--card-bg,rgba(255,255,255,.02));";const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.6rem .8rem;cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent="\u2014 Page Break \u2014",l.style.cssText="font-size:.7rem;padding:.15rem .5rem;border-radius:999px;background:rgba(120,120,120,.2);color:var(--text-muted,#888);white-space:nowrap;flex-shrink:0;font-style:italic;";const c=document.createElement("span");c.textContent=e.label||"Untitled Step",c.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-muted,#888);";const s=document.createElement("div");if(s.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;",t>0){const i=document.createElement("button");i.className="btn btn-xs btn-ghost",i.title="Move up",i.textContent="\u2191",i.addEventListener("click",f=>{f.stopPropagation(),v(),[b[t-1],b[t]]=[b[t],b[t-1]],x(o)}),s.appendChild(i)}if(t<b.length-1){const i=document.createElement("button");i.className="btn btn-xs btn-ghost",i.title="Move down",i.textContent="\u2193",i.addEventListener("click",f=>{f.stopPropagation(),v(),[b[t],b[t+1]]=[b[t+1],b[t]],x(o)}),s.appendChild(i)}const p=document.createElement("button");p.className="btn btn-xs btn-ghost",p.title="Edit step",p.textContent="\u22EF",p.addEventListener("click",i=>{i.stopPropagation(),m.style.display=m.style.display==="none"?"":"none"}),s.appendChild(p);const d=document.createElement("button");d.className="btn btn-xs btn-danger",d.title="Remove page break",d.textContent="\u2715",d.addEventListener("click",async i=>{i.stopPropagation(),await E.confirm("Remove this page break?")&&(v(),b.splice(t,1),x(o))}),s.appendChild(d),a.appendChild(l),a.appendChild(c),a.appendChild(s),a.addEventListener("click",()=>{m.style.display=m.style.display==="none"?"":"none"});const m=document.createElement("div");m.className="fb-field-body",m.style.cssText="padding:.8rem;border-top:1px dashed var(--border-color,#444);display:none;";const r=k([C("Step Title",`fb-pb-label-${t}`,"text",e.label||"","Shown as the wizard step heading"),C("Step Description",`fb-pb-desc-${t}`,"text",e.description||"","Optional sub-heading")]),u=r.querySelector(`#fb-pb-label-${t}`);return u&&u.addEventListener("input",()=>{c.textContent=u.value||"Untitled Step"}),m.appendChild(r),n.appendChild(a),n.appendChild(m),n}function G(e,t,o){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:1px dashed var(--border-color,#444);border-radius:6px;margin-bottom:.5rem;background:transparent;";const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.4rem .8rem;";const l=document.createElement("div");l.style.cssText="flex:1;height:1px;background:var(--border-color,#444);";const c=document.createElement("span");c.textContent="Spacer",c.style.cssText="font-size:.7rem;color:var(--text-muted,#888);white-space:nowrap;padding:0 .4rem;font-style:italic;";const s=document.createElement("div");s.style.cssText="flex:1;height:1px;background:var(--border-color,#444);";const p=document.createElement("div");if(p.style.cssText="display:flex;gap:.25rem;flex-shrink:0;",t>0){const m=document.createElement("button");m.className="btn btn-xs btn-ghost",m.title="Move up",m.textContent="\u2191",m.addEventListener("click",r=>{r.stopPropagation(),v(),[b[t-1],b[t]]=[b[t],b[t-1]],x(o)}),p.appendChild(m)}if(t<b.length-1){const m=document.createElement("button");m.className="btn btn-xs btn-ghost",m.title="Move down",m.textContent="\u2193",m.addEventListener("click",r=>{r.stopPropagation(),v(),[b[t],b[t+1]]=[b[t+1],b[t]],x(o)}),p.appendChild(m)}const d=document.createElement("button");return d.className="btn btn-xs btn-danger",d.title="Remove spacer",d.textContent="\u2715",d.addEventListener("click",async m=>{m.stopPropagation(),v(),b.splice(t,1),x(o)}),p.appendChild(d),a.appendChild(l),a.appendChild(c),a.appendChild(s),a.appendChild(p),n.appendChild(a),n}function K(e,t,o){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:1px solid var(--border-color,#333);border-radius:6px;overflow:hidden;margin-bottom:.5rem;";const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.6rem .8rem;background:var(--card-header-bg,rgba(255,255,255,.04));cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent=P(e.type),l.style.cssText="font-size:.7rem;padding:.15rem .45rem;border-radius:999px;background:var(--primary-soft,rgba(99,102,241,.15));color:var(--primary,#6366f1);white-space:nowrap;flex-shrink:0;";const c=document.createElement("span");c.textContent=e.label||"(unlabelled)",c.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;";const s=document.createElement("div");if(s.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;",t>0){const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Move up",r.textContent="\u2191",r.addEventListener("click",u=>{u.stopPropagation(),v(),[b[t-1],b[t]]=[b[t],b[t-1]],x(o)}),s.appendChild(r)}if(t<b.length-1){const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Move down",r.textContent="\u2193",r.addEventListener("click",u=>{u.stopPropagation(),v(),[b[t],b[t+1]]=[b[t+1],b[t]],x(o)}),s.appendChild(r)}const p=document.createElement("button");p.className="btn btn-xs btn-ghost",p.title="Edit field",p.textContent="\u22EF",p.addEventListener("click",r=>{r.stopPropagation(),m.style.display=m.style.display==="none"?"":"none"}),s.appendChild(p);const d=document.createElement("button");if(d.className="btn btn-xs btn-danger",d.title="Remove field",d.textContent="\u2715",d.addEventListener("click",async r=>{r.stopPropagation(),await E.confirm("Remove this field?")&&(v(),b.splice(t,1),x(o))}),s.appendChild(d),a.appendChild(l),a.appendChild(c),e.required){const r=document.createElement("span");r.textContent="required",r.style.cssText="font-size:.7rem;color:var(--danger,#ef4444);flex-shrink:0;",a.appendChild(r)}if(M(e.logic)){const r=document.createElement("span");r.textContent="\u26A1",r.title="Has conditional logic",r.style.cssText="font-size:.75rem;color:var(--primary,#6366f1);flex-shrink:0;",a.appendChild(r)}a.appendChild(s),a.addEventListener("click",()=>{m.style.display=m.style.display==="none"?"":"none"});const m=Q(e,t,c);return m.style.display="none",n.appendChild(a),n.appendChild(m),n}function Q(e,t,o){const n=document.createElement("div");n.className="fb-field-body",n.style.cssText="padding:.8rem;border-top:1px solid var(--border-color,#333);";const a=k([C("Label",`fb-label-${t}`,"text",e.label||"","Shown above the field"),C("Field Name",`fb-name-${t}`,"text",e.name||"","Used as data key")]),l=k([ae("Type",`fb-type-${t}`,B,e.type||"string"),j("Required",`fb-required-${t}`,e.required||!1)]),c=k([C("Placeholder",`fb-placeholder-${t}`,"text",e.placeholder||"","Hint text inside the field")]),s=k([C("Helper Text",`fb-helper-${t}`,"text",e.helper||"","Shown below the field"),C("Tooltip",`fb-tooltip-${t}`,"text",e.tooltip||"","Shown on hover via a help icon next to the label")]),p=e.formConfig?.span,d=k([C("Column Span",`fb-span-${t}`,"number",p&&p!=="full"?String(p):"1","Columns to span (grid only)"),j("Full Width",`fb-fullwidth-${t}`,p==="full")]);d.classList.add("fb-grid-row"),d.style.display=document.getElementById("setting-layout")?.value==="grid"?"flex":"none",n.appendChild(a),n.appendChild(l),n.appendChild(c),n.appendChild(s),n.appendChild(d);const m=n.querySelector(`#fb-label-${t}`),r=n.querySelector(`#fb-name-${t}`);m&&m.addEventListener("input",()=>{o&&(o.textContent=m.value||"(unlabelled)"),r&&!r.dataset.manuallyEdited&&(r.value=I(m.value))}),r&&r.addEventListener("input",()=>{r.dataset.manuallyEdited="1"});const u=n.querySelector(`#fb-type-${t}`);u&&u.addEventListener("change",()=>{const f=n.closest(".fb-field-card");if(f){const y=f.querySelector("span");y&&(y.textContent=P(u.value))}const h=n.querySelector(".fb-field-extras");h&&h.remove();const g=O(u.value,e,t);g&&n.appendChild(g)});const i=O(e.type,e,t);return i&&n.appendChild(i),n.appendChild(le(e,t)),n}const X=[{value:"equals",label:"equals"},{value:"not_equals",label:"does not equal"},{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"},{value:"starts_with",label:"starts with"},{value:"ends_with",label:"ends with"},{value:"greater_than",label:"is greater than"},{value:"less_than",label:"is less than"},{value:"is_empty",label:"is empty"},{value:"is_not_empty",label:"is not empty"},{value:"in",label:"is one of (comma sep)"},{value:"not_in",label:"is not one of (comma sep)"},{value:"matches_regex",label:"matches regex"}],_=new Set(["is_empty","is_not_empty"]);function $(e){const t=document.createElement("p");return t.textContent=e,t.style.cssText="font-size:.75rem;font-weight:700;color:var(--text-muted,#888);margin:.6rem 0 .3rem;text-transform:uppercase;letter-spacing:.04em;",t}function L(e,t,o,n,a){const l=document.createElement("div");l.className="fb-logic-cond-row",l.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const c=document.createElement("span");c.textContent="When",c.style.cssText="font-size:.73rem;color:var(--text-muted,#888);flex-shrink:0;";const s=document.createElement("select");s.className="form-select fb-logic-cond-field",s.style.cssText="flex:1 1 140px;min-width:140px;",t.forEach(i=>{const f=document.createElement("option");f.value=i.value,f.textContent=i.label,e&&i.value===e.field&&(f.selected=!0),s.appendChild(f)});const p=document.createElement("select");p.className="form-select fb-logic-cond-op",p.style.cssText="flex:1 1 160px;min-width:140px;",X.forEach(i=>{const f=document.createElement("option");f.value=i.value,f.textContent=i.label,e&&i.value===e.operator&&(f.selected=!0),p.appendChild(f)});const d=document.createElement("input");d.type="text",d.className="form-input fb-logic-cond-val",d.placeholder="value",d.style.cssText="flex:1 1 120px;min-width:100px;",d.value=e?.value||"",e&&_.has(e.operator)&&(d.style.display="none"),p.addEventListener("change",()=>{d.style.display=_.has(p.value)?"none":""});const m=document.createElement("span");m.textContent="\u2192",m.style.cssText="font-size:.73rem;color:var(--text-muted,#888);flex-shrink:0;";const r=document.createElement("select");r.className=`form-select ${n}`,r.style.cssText="flex:1 1 140px;min-width:120px;",o.forEach(i=>{const f=document.createElement("option");f.value=i.value,f.textContent=i.label,i.value===a&&(f.selected=!0),r.appendChild(f)});const u=document.createElement("button");return u.type="button",u.className="btn btn-xs btn-danger",u.textContent="\u2715",u.style.flexShrink="0",u.addEventListener("click",()=>l.remove()),l.appendChild(c),l.appendChild(s),l.appendChild(p),l.appendChild(d),l.appendChild(m),l.appendChild(r),l.appendChild(u),l}function Z(e,t,o){const n=document.createElement("div");n.dataset.logicSection="visibility",n.appendChild($("Visibility"));const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const l=document.createElement("span");l.textContent="Default:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const c=document.createElement("select");c.className="form-select fb-logic-vis-default",c.style.cssText="max-width:240px;",[{value:"visible",label:"Visible"},{value:"hidden",label:"Hidden"}].forEach(i=>{const f=document.createElement("option");f.value=i.value,f.textContent=i.label,i.value===(e.default||"visible")&&(f.selected=!0),c.appendChild(f)}),a.appendChild(l),a.appendChild(c),n.appendChild(a);const s=document.createElement("div");s.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const p=document.createElement("span");p.textContent="Transition:",p.style.cssText="font-size:.8rem;flex-shrink:0;";const d=document.createElement("select");d.className="form-select fb-logic-vis-transition",d.style.cssText="max-width:240px;",[{value:"none",label:"None (instant)"},{value:"fade",label:"Fade"},{value:"slide",label:"Slide"},{value:"scale",label:"Scale"}].forEach(i=>{const f=document.createElement("option");f.value=i.value,f.textContent=i.label,i.value===(e.transition||"none")&&(f.selected=!0),d.appendChild(f)}),s.appendChild(p),s.appendChild(d),n.appendChild(s);const m=document.createElement("div");m.className="fb-logic-vis-rules";const r=o.map(i=>({value:i.name,label:i.label||i.name})),u=[{value:"visible",label:"Show"},{value:"hidden",label:"Hide"}];if((e.conditions||[]).forEach(i=>{const f=(i.when?.all||i.when?.any||[])[0],h=i.then==="hidden"?"hidden":"visible";r.length>0&&m.appendChild(L(f,r,u,"fb-logic-vis-then",h))}),n.appendChild(m),r.length>0){const i=document.createElement("button");i.type="button",i.className="btn btn-xs btn-ghost",i.style.cssText="font-size:.73rem;margin-top:.2rem;",i.textContent="+ Add visibility rule",i.addEventListener("click",()=>m.appendChild(L(null,r,u,"fb-logic-vis-then","visible"))),n.appendChild(i)}return n}function ee(e,t,o){const n=document.createElement("div");n.dataset.logicSection="requirement",n.appendChild($("Conditional Requirement"));const a=document.createElement("label");a.style.cssText="display:flex;align-items:center;gap:.4rem;font-size:.8rem;cursor:pointer;margin-bottom:.4rem;";const l=document.createElement("input");l.type="checkbox",l.className="fb-logic-req-default",l.checked=e.default===!0,a.appendChild(l),a.appendChild(document.createTextNode("Required by default")),n.appendChild(a);const c=document.createElement("div");c.className="fb-logic-req-rules";const s=o.map(d=>({value:d.name,label:d.label||d.name})),p=[{value:"true",label:"Make required"},{value:"false",label:"Make optional"}];if((e.conditions||[]).forEach(d=>{const m=(d.when?.all||d.when?.any||[])[0],r=d.then===!0?"true":"false";s.length>0&&c.appendChild(L(m,s,p,"fb-logic-req-then",r))}),n.appendChild(c),s.length>0){const d=document.createElement("button");d.type="button",d.className="btn btn-xs btn-ghost",d.style.cssText="font-size:.73rem;margin-top:.2rem;",d.textContent="+ Add requirement rule",d.addEventListener("click",()=>c.appendChild(L(null,s,p,"fb-logic-req-then","true"))),n.appendChild(d)}return n}function A(e){const t=document.createElement("div");t.className="fb-logic-val-rule",t.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const o=document.createElement("select");o.className="form-select fb-logic-val-type",o.style.cssText="flex:0 0 140px;",[{value:"regex",label:"Regex"},{value:"match",label:"Match field"}].forEach(s=>{const p=document.createElement("option");p.value=s.value,p.textContent=s.label,s.value===(e?.type||"regex")&&(p.selected=!0),o.appendChild(p)});const n=document.createElement("input");n.type="text",n.className="form-input fb-logic-val-pattern",n.placeholder=e?.type==="match"?"field name":"pattern",n.value=e?.pattern||e?.field||"",n.style.cssText="flex:3;";const a=document.createElement("input");a.type="text",a.className="form-input fb-logic-val-flags",a.placeholder="flags",a.value=e?.flags||"",a.style.cssText="flex:0 0 55px;",e?.type==="match"&&(a.style.display="none"),o.addEventListener("change",()=>{a.style.display=o.value==="match"?"none":"",n.placeholder=o.value==="match"?"field name":"pattern"});const l=document.createElement("input");l.type="text",l.className="form-input fb-logic-val-message",l.placeholder="Error message",l.value=e?.message||"",l.style.cssText="flex:4;";const c=document.createElement("button");return c.type="button",c.className="btn btn-xs btn-danger",c.textContent="\u2715",c.style.flexShrink="0",c.addEventListener("click",()=>t.remove()),t.appendChild(o),t.appendChild(n),t.appendChild(a),t.appendChild(l),t.appendChild(c),t}function te(e,t,o){const n=document.createElement("div");n.dataset.logicSection="validation",n.appendChild($("Custom Validation"));const a=document.createElement("div");a.className="fb-logic-val-rules",(e||[]).forEach(c=>a.appendChild(A(c))),n.appendChild(a);const l=document.createElement("button");return l.type="button",l.className="btn btn-xs btn-ghost",l.style.cssText="font-size:.73rem;margin-top:.2rem;",l.textContent="+ Add validation rule",l.addEventListener("click",()=>a.appendChild(A(null))),n.appendChild(l),n}function ne(e,t,o){const n=document.createElement("div");n.dataset.logicSection="cascade",n.appendChild($("Cascade Options"));const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;";const l=document.createElement("span");l.textContent="Source field:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const c=document.createElement("select");c.className="form-select fb-logic-cascade-source",c.style.cssText="flex:1;";const s=document.createElement("option");s.value="",s.textContent="\u2014 none \u2014",c.appendChild(s),o.forEach(u=>{const i=document.createElement("option");i.value=u.name,i.textContent=u.label||u.name,u.name===e.sourceField&&(i.selected=!0),c.appendChild(i)}),a.appendChild(l),a.appendChild(c),n.appendChild(a);const p=document.createElement("p");p.textContent='Mapping JSON \u2014 {"value":[{"value":"...","label":"..."}]}',p.style.cssText="font-size:.73rem;color:var(--text-muted,#888);margin:.3rem 0 .2rem;";const d=document.createElement("textarea");d.className="form-input fb-logic-cascade-mapping",d.rows=4,d.style.cssText="font-family:monospace;",d.placeholder='{"uk": [{"value": "london", "label": "London"}]}',d.value=e.mapping?JSON.stringify(e.mapping,null,2):"",n.appendChild(p),n.appendChild(d);const m=document.createElement("p");m.textContent="Default options (one per line: value:Label)",m.style.cssText="font-size:.73rem;color:var(--text-muted,#888);margin:.3rem 0 .2rem;";const r=document.createElement("textarea");return r.className="form-input fb-logic-cascade-defaults",r.rows=3,r.style.cssText="font-family:monospace;",r.placeholder=`option1:Option 1
4
+ option2:Option 2`,r.value=(e.defaultOptions||[]).map(u=>{const i=typeof u=="string"?u:u.value??"",f=typeof u=="string"?u:u.label??i;return i===f?i:`${i}:${f}`}).join(`
5
+ `),n.appendChild(m),n.appendChild(r),n}function le(e,t){const o=e.logic||{},n=b.filter((r,u)=>u!==t&&r.type!=="page-break"&&r.type!=="spacer"),a=document.createElement("div");a.className="fb-field-logic",a.style.cssText="margin-top:.75rem;border-top:1px solid var(--border-color,#333);padding-top:.5rem;";const l=document.createElement("div");l.style.cssText="display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:.15rem 0;";const c=document.createElement("span");c.style.cssText="font-size:.8rem;font-weight:600;color:var(--text-muted,#888);",c.textContent="\u26A1 Conditional Logic";const s=M(o),p=document.createElement("button");p.type="button",p.className="btn btn-xs btn-ghost",p.textContent=s?"\u25BE":"\u25B8";const d=document.createElement("div");d.className="fb-logic-body",d.style.cssText="padding:.25rem 0 .25rem;"+(s?"":"display:none;"),l.addEventListener("click",()=>{const r=d.style.display==="none";d.style.display=r?"":"none",p.textContent=r?"\u25BE":"\u25B8"}),l.appendChild(c),l.appendChild(p),a.appendChild(l),d.appendChild(Z(o.visibility||{},t,n)),d.appendChild(ee(o.requirement||{},t,n)),d.appendChild(te(o.validation||[],t,n));const m=document.getElementById(`fb-type-${t}`)?.value||e.type;return z.has(m)&&d.appendChild(ne(o.cascade||{},t,n)),a.appendChild(d),a}function O(e,t,o){const n=document.createElement("div");return n.className="fb-field-extras",z.has(e)&&n.appendChild(oe(t.options||[],o)),e==="textarea"&&n.appendChild(k([C("Rows",`fb-rows-${o}`,"number",t.formConfig?.rows||4,"Height of textarea")])),(e==="string"||e==="textarea")&&n.appendChild(k([C("Min Length",`fb-minlength-${o}`,"number",t.minLength||"",""),C("Max Length",`fb-maxlength-${o}`,"number",t.maxLength||"","")])),e==="number"&&n.appendChild(k([C("Min",`fb-min-${o}`,"number",t.min??"",""),C("Max",`fb-max-${o}`,"number",t.max??"","")])),n.children.length?n:null}function k(e){const t=document.createElement("div");return t.style.cssText="display:flex;gap:.75rem;margin-bottom:.6rem;",e.forEach(o=>{o&&t.appendChild(o)}),t}function C(e,t,o,n,a){const l=document.createElement("div");l.style.flex="1";const c=document.createElement("label");c.htmlFor=t,c.className="form-label",c.textContent=e,c.style.fontSize=".8rem";const s=document.createElement("input");if(s.id=t,s.type=o||"text",s.className="form-input",s.value=n??"",l.appendChild(c),l.appendChild(s),a){const p=document.createElement("p");p.className="form-hint text-muted",p.textContent=a,p.style.cssText="font-size:.73rem;margin-top:.2rem;",l.appendChild(p)}return l}function ae(e,t,o,n){const a=document.createElement("div");a.style.flex="1";const l=document.createElement("label");l.htmlFor=t,l.className="form-label",l.textContent=e,l.style.fontSize=".8rem";const c=document.createElement("select");return c.id=t,c.className="form-select",o.forEach(s=>{const p=document.createElement("option");p.value=s.value,p.textContent=s.label,s.value===n&&(p.selected=!0),c.appendChild(p)}),a.appendChild(l),a.appendChild(c),a}function j(e,t,o){const n=document.createElement("div");n.style.cssText="flex:0;min-width:80px;display:flex;flex-direction:column;justify-content:flex-end;";const a=document.createElement("label");a.style.cssText="display:flex;align-items:center;gap:.4rem;cursor:pointer;font-size:.8rem;white-space:nowrap;";const l=document.createElement("input");return l.id=t,l.type="checkbox",l.checked=o,a.appendChild(l),a.appendChild(document.createTextNode(e)),n.appendChild(a),n}function oe(e,t){const o=document.createElement("div");o.style.cssText="margin-top:.4rem;";const n=document.createElement("p");n.textContent="Options (one per line: value or value:Label)",n.style.cssText="font-size:.8rem;font-weight:600;margin-bottom:.3rem;";const a=document.createElement("textarea");return a.id=`fb-options-${t}`,a.className="form-input",a.rows=4,a.placeholder=`yes:Yes
6
6
  no:No
7
- maybe:Maybe`,a.value=(e||[]).map(l=>{const r=typeof l=="string"?l:l.value??"",i=typeof l=="string"?l:l.label??r;return r===i?r:`${r}:${i}`}).join(`
8
- `),a.style.fontFamily="monospace",o.appendChild(n),o.appendChild(a),o}function H(e){return y(),{title:e.find("#field-title").val().trim(),slug:e.find("#field-slug").val().trim(),description:e.find("#field-description").val().trim(),...e.find("#field-bundled").is(":checked")?{bundled:!0}:{},fields:b,settings:{submitText:e.find("#setting-submit-text").val().trim()||"Submit",successMessage:e.find("#setting-success-message").val().trim()||"Thank you.",layout:e.find("#setting-layout").val()||"stacked",columns:parseInt(e.find("#setting-columns").val(),10)||2,submitSpan:e.find("#setting-submit-span").val()||"",honeypot:e.find("#setting-honeypot").prop("checked"),rateLimitPerMinute:parseInt(e.find("#setting-rate-limit").val(),10)||3,successRedirect:e.find("#setting-success-redirect").val().trim()||null,actionSlug:e.find("#action-cms-slug").val()||null},actions:{email:{enabled:e.find("#action-email-enabled").prop("checked"),recipients:e.find("#action-email-recipients").val().trim(),subjectPrefix:e.find("#action-email-subject-prefix").val().trim()},webhook:{enabled:e.find("#action-webhook-enabled").prop("checked"),url:e.find("#action-webhook-url").val().trim(),method:e.find("#action-webhook-method").val()},...T!==null&&{collection:T}}}}function oe(e){const t=[];let o=[],n="Step 1",a="";return e.forEach(l=>{l.type==="page-break"?(t.push({title:n,description:a,fields:o}),o=[],n=l.label||`Step ${t.length+1}`,a=l.description||""):l.type!=="spacer"&&o.push(l)}),(o.length||t.length===0)&&t.push({title:n,description:a,fields:o}),t}function J(e,t){const o={};return e.forEach(n=>{if(n.type==="page-break"||n.type==="spacer")return;const a={...n.formConfig||{}};a.span==="full"&&t&&(a.span=t);const l=n.type==="checkbox"?"boolean":n.type==="date"?"string":n.type;o[n.name]={type:l,label:n.label,required:n.required,options:n.options,formConfig:{...n.placeholder&&{placeholder:n.placeholder},...n.helper&&{hint:n.helper},...a}}}),o}function U(e,t){const o=typeof e=="string"?document.querySelector(e):e;o&&(t||[]).forEach(n=>{if(n.type!=="date"||!n.name)return;const a=o.querySelector(`[name="${n.name}"]`);a&&a.type!=="date"&&(a.type="date")})}export const formEditorView={templateUrl:"/admin/js/templates/form-editor.html",async onMount(e){b=[],x=null,T=null;const t=window.location.hash.match(/\/forms\/edit\/([^/?#]+)/);x=t?t[1]:null;let o=null;if(x)try{o=await S(`/forms/${x}`),b=o.fields||[],T=o.actions?.collection??null}catch{E.toast("Could not load form.",{type:"error"})}if(o?e.find("#editor-title").get(0).textContent=`Edit: ${o.title}`:e.find("#editor-title").get(0).textContent="New Form",x||e.find("#field-title").get(0).addEventListener("input",function(){e.find("#field-slug").val(I(this.value))}),E.tabs(e.find("#editor-tabs").get(0)),o){e.find("#field-title").val(o.title),e.find("#field-slug").val(o.slug),e.find("#field-description").val(o.description||""),e.find("#field-bundled").prop("checked",!!o.bundled);const l=o.settings||{};e.find("#setting-submit-text").val(l.submitText||"Submit"),e.find("#setting-success-message").val(l.successMessage||""),e.find("#setting-layout").val(l.layout||"stacked"),e.find("#setting-columns").val(l.columns||2),e.find("#setting-submit-span").val(l.submitSpan||""),e.find("#columns-group").get(0).style.display=l.layout==="grid"?"":"none",e.find("#setting-honeypot").prop("checked",l.honeypot!==!1),e.find("#setting-rate-limit").val(l.rateLimitPerMinute||3),e.find("#setting-success-redirect").val(l.successRedirect||"");const r=o.actions?.email||{};e.find("#action-email-enabled").prop("checked",r.enabled||!1),e.find("#action-email-recipients").val(r.recipients||""),e.find("#action-email-subject-prefix").val(r.subjectPrefix||"");const i=o.actions?.webhook||{};e.find("#action-webhook-enabled").prop("checked",i.enabled||!1),e.find("#action-webhook-url").val(i.url||""),e.find("#action-webhook-method").val(i.method||"POST")}const n=o?.settings?.actionSlug||"";try{const l=await S("/actions").catch(()=>[]),r=e.find("#action-cms-slug").get(0);if((Array.isArray(l)?l:[]).forEach(i=>{const p=document.createElement("option");p.value=i.slug,p.textContent=i.title||i.slug,i.slug===n&&(p.selected=!0),r.appendChild(p)}),!l.length){const i=document.createElement("option");i.value="",i.textContent="No actions available",i.disabled=!0,r.appendChild(i)}}catch{}e.find("#setting-layout").get(0)?.addEventListener("change",function(){const l=this.value==="grid";e.find("#columns-group").get(0).style.display=l?"":"none",document.querySelectorAll(".fb-grid-row").forEach(r=>{r.style.display=l?"flex":"none"})}),v(e);const a=e.find("#add-element-menu").get(0);e.find("#add-element-btn").get(0).addEventListener("click",l=>{l.stopPropagation(),a.style.display=a.style.display==="none"?"":"none"}),q&&document.removeEventListener("click",q),q=()=>{a&&(a.style.display="none")},document.addEventListener("click",q),e.find("#add-field-btn").get(0).addEventListener("click",()=>{a&&(a.style.display="none"),y();const l=b.length;b.push({name:`field_${l+1}`,type:"string",label:"New Field",required:!1,placeholder:""}),v(e);const r=e.find("#fields-list").get(0)?.lastElementChild;if(r){const i=r.querySelector(".fb-field-body");i&&(i.style.display="")}}),e.find("#add-spacer-btn").get(0).addEventListener("click",()=>{a&&(a.style.display="none"),y(),b.push({type:"spacer"}),v(e)}),e.find("#add-page-break-btn").get(0).addEventListener("click",()=>{a&&(a.style.display="none"),y();const l=b.filter(r=>r.type==="page-break").length+2;b.push({type:"page-break",label:`Step ${l}`,description:""}),v(e)}),e.find("#save-form-btn").get(0).addEventListener("click",async()=>{const l=H(e);if(!l.title){E.toast("Please enter a form title.",{type:"error"});return}try{x?(await S(`/forms/${x}`,{method:"PUT",body:JSON.stringify(l)}),E.toast("Form saved.",{type:"success"})):(x=(await S("/forms",{method:"POST",body:JSON.stringify(l)})).slug,R.navigate(`/forms/edit/${x}`),E.toast("Form created.",{type:"success"}))}catch(r){E.toast(r.message||"Failed to save form.",{type:"error"})}}),e.find("#preview-btn").get(0).addEventListener("click",()=>{const l=H(e),r=e.find("#preview-container").get(0);if(!r)return;const i=e.find("#preview-test-result").get(0),p=e.find("#preview-test-badge").get(0);i&&(i.style.display="none",i.textContent=""),p&&(p.style.display=x?"":"none"),e.find("#preview-card").get(0).style.display="",r.textContent="";const d=document.createElement("div");d.id="fb-preview-form",r.appendChild(d);const m=x?async u=>{i&&(i.style.display="none",i.textContent="");try{const s=await fetch(`/api/forms/submit/${x}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}),f=await s.json();if(!s.ok)throw new Error(f.error||"Submission failed.");i&&(i.textContent=f.message||l.settings?.successMessage||"Submitted successfully.",i.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:rgba(34,197,94,.12);color:var(--success,#22c55e);"),E.toast("Test submission stored.",{type:"success"})}catch(s){i&&(i.textContent=s.message,i.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:rgba(239,68,68,.12);color:var(--danger,#ef4444);"),E.toast(s.message,{type:"error"})}return!1}:()=>!1,c=l.fields.some(u=>u.type==="page-break");if(typeof F<"u"){const u=l.settings?.columns||2,s=l.settings?.layout||"stacked";if(c&&F.wizard){const f=oe(l.fields).map(g=>({title:g.title,description:g.description,fields:J(g.fields,u)}));F.wizard("#fb-preview-form",{schema:{steps:f},onSubmit:m}),U("#fb-preview-form",l.fields)}else if(F.render){const f=J(l.fields,u),g={};if(l.fields.forEach(h=>{if(!(!h.name||h.type==="page-break"||h.type==="spacer")&&(h.type==="select"||h.type==="multiselect")&&h.required){const w=(h.options||[])[0];w&&(g[h.name]=typeof w=="object"?w.value:w)}}),F.render("#fb-preview-form",f,g,{submitText:l.settings?.submitText||"Submit",layout:s,columns:u,onSubmit:m}),s==="grid"&&l.settings?.submitSpan==="full"){const h=document.querySelector("#fb-preview-form .form-buttons");h&&h.classList.add("col-span-full")}U("#fb-preview-form",l.fields)}window.FormLogicEngine&&l.fields.some(f=>f.logic)&&requestAnimationFrame(()=>{new window.FormLogicEngine.FormLogicRuntime({fields:l.fields},d).init()})}else{const u=document.createElement("p");u.textContent=`${l.fields.filter(s=>s.type!=="page-break").length} field(s): ${l.fields.filter(s=>s.type!=="page-break").map(s=>s.label).join(", ")}`,u.style.cssText="color:var(--muted);font-style:italic;",d.appendChild(u)}e.find("#preview-card").get(0).scrollIntoView({behavior:"smooth",block:"start"})})}};
7
+ maybe:Maybe`,a.value=(e||[]).map(l=>{const c=typeof l=="string"?l:l.value??"",s=typeof l=="string"?l:l.label??c;return c===s?c:`${c}:${s}`}).join(`
8
+ `),a.style.fontFamily="monospace",o.appendChild(n),o.appendChild(a),o}function H(e){return v(),{title:e.find("#field-title").val().trim(),slug:e.find("#field-slug").val().trim(),description:e.find("#field-description").val().trim(),...e.find("#field-bundled").is(":checked")?{bundled:!0}:{},fields:b,settings:{submitText:e.find("#setting-submit-text").val().trim()||"Submit",successMessage:e.find("#setting-success-message").val().trim()||"Thank you.",layout:e.find("#setting-layout").val()||"stacked",columns:parseInt(e.find("#setting-columns").val(),10)||2,submitSpan:e.find("#setting-submit-span").val()||"",honeypot:e.find("#setting-honeypot").prop("checked"),rateLimitPerMinute:parseInt(e.find("#setting-rate-limit").val(),10)||3,successRedirect:e.find("#setting-success-redirect").val().trim()||null,actionSlug:e.find("#action-cms-slug").val()||null},actions:{email:{enabled:e.find("#action-email-enabled").prop("checked"),recipients:e.find("#action-email-recipients").val().trim(),subjectPrefix:e.find("#action-email-subject-prefix").val().trim()},webhook:{enabled:e.find("#action-webhook-enabled").prop("checked"),url:e.find("#action-webhook-url").val().trim(),method:e.find("#action-webhook-method").val()},...q!==null&&{collection:q}}}}function ie(e){const t=[];let o=[],n="Step 1",a="";return e.forEach(l=>{l.type==="page-break"?(t.push({title:n,description:a,fields:o}),o=[],n=l.label||`Step ${t.length+1}`,a=l.description||""):l.type!=="spacer"&&o.push(l)}),(o.length||t.length===0)&&t.push({title:n,description:a,fields:o}),t}function J(e,t){const o={};return e.forEach(n=>{if(n.type==="page-break"||n.type==="spacer")return;const a={...n.formConfig||{}};a.span==="full"&&t&&(a.span=t);const l=n.type==="checkbox"?"boolean":n.type==="date"?"string":n.type;o[n.name]={type:l,label:n.label,required:n.required,options:n.options,formConfig:{...n.placeholder&&{placeholder:n.placeholder},...n.helper&&{helperText:n.helper},...n.tooltip&&{tooltip:n.tooltip},...a}}}),o}function U(e,t){const o=typeof e=="string"?document.querySelector(e):e;o&&(t||[]).forEach(n=>{if(n.type!=="date"||!n.name)return;const a=o.querySelector(`[name="${n.name}"]`);a&&a.type!=="date"&&(a.type="date")})}export const formEditorView={templateUrl:"/admin/js/templates/form-editor.html",async onMount(e){b=[],w=null,q=null;const t=window.location.hash.match(/\/forms\/edit\/([^/?#]+)/);w=t?t[1]:null;let o=null;if(w)try{o=await T(`/forms/${w}`),b=o.fields||[],q=o.actions?.collection??null}catch{E.toast("Could not load form.",{type:"error"})}if(o?e.find("#editor-title").get(0).textContent=`Edit: ${o.title}`:e.find("#editor-title").get(0).textContent="New Form",w||e.find("#field-title").get(0).addEventListener("input",function(){e.find("#field-slug").val(I(this.value))}),E.tabs(e.find("#editor-tabs").get(0)),o){e.find("#field-title").val(o.title),e.find("#field-slug").val(o.slug),e.find("#field-description").val(o.description||""),e.find("#field-bundled").prop("checked",!!o.bundled);const l=o.settings||{};e.find("#setting-submit-text").val(l.submitText||"Submit"),e.find("#setting-success-message").val(l.successMessage||""),e.find("#setting-layout").val(l.layout||"stacked"),e.find("#setting-columns").val(l.columns||2),e.find("#setting-submit-span").val(l.submitSpan||""),e.find("#columns-group").get(0).style.display=l.layout==="grid"?"":"none",e.find("#setting-honeypot").prop("checked",l.honeypot!==!1),e.find("#setting-rate-limit").val(l.rateLimitPerMinute||3),e.find("#setting-success-redirect").val(l.successRedirect||"");const c=o.actions?.email||{};e.find("#action-email-enabled").prop("checked",c.enabled||!1),e.find("#action-email-recipients").val(c.recipients||""),e.find("#action-email-subject-prefix").val(c.subjectPrefix||"");const s=o.actions?.webhook||{};e.find("#action-webhook-enabled").prop("checked",s.enabled||!1),e.find("#action-webhook-url").val(s.url||""),e.find("#action-webhook-method").val(s.method||"POST")}const n=o?.settings?.actionSlug||"";try{const l=await T("/actions").catch(()=>[]),c=e.find("#action-cms-slug").get(0);if((Array.isArray(l)?l:[]).forEach(s=>{const p=document.createElement("option");p.value=s.slug,p.textContent=s.title||s.slug,s.slug===n&&(p.selected=!0),c.appendChild(p)}),!l.length){const s=document.createElement("option");s.value="",s.textContent="No actions available",s.disabled=!0,c.appendChild(s)}}catch{}e.find("#setting-layout").get(0)?.addEventListener("change",function(){const l=this.value==="grid";e.find("#columns-group").get(0).style.display=l?"":"none",document.querySelectorAll(".fb-grid-row").forEach(c=>{c.style.display=l?"flex":"none"})}),x(e);const a=e.find("#add-element-menu").get(0);e.find("#add-element-btn").get(0).addEventListener("click",l=>{l.stopPropagation(),a.style.display=a.style.display==="none"?"":"none"}),N&&document.removeEventListener("click",N),N=()=>{a&&(a.style.display="none")},document.addEventListener("click",N),e.find("#add-field-btn").get(0).addEventListener("click",()=>{a&&(a.style.display="none"),v();const l=b.length;b.push({name:`field_${l+1}`,type:"string",label:"New Field",required:!1,placeholder:""}),x(e);const c=e.find("#fields-list").get(0)?.lastElementChild;if(c){const s=c.querySelector(".fb-field-body");s&&(s.style.display="")}}),e.find("#add-spacer-btn").get(0).addEventListener("click",()=>{a&&(a.style.display="none"),v(),b.push({type:"spacer"}),x(e)}),e.find("#add-page-break-btn").get(0).addEventListener("click",()=>{a&&(a.style.display="none"),v();const l=b.filter(c=>c.type==="page-break").length+2;b.push({type:"page-break",label:`Step ${l}`,description:""}),x(e)}),e.find("#save-form-btn").get(0).addEventListener("click",async()=>{const l=H(e);if(!l.title){E.toast("Please enter a form title.",{type:"error"});return}try{w?(await T(`/forms/${w}`,{method:"PUT",body:JSON.stringify(l)}),E.toast("Form saved.",{type:"success"})):(w=(await T("/forms",{method:"POST",body:JSON.stringify(l)})).slug,R.navigate(`/forms/edit/${w}`),E.toast("Form created.",{type:"success"}))}catch(c){E.toast(c.message||"Failed to save form.",{type:"error"})}}),e.find("#preview-btn").get(0).addEventListener("click",()=>{const l=H(e),c=e.find("#preview-container").get(0);if(!c)return;const s=e.find("#preview-test-result").get(0),p=e.find("#preview-test-badge").get(0);s&&(s.style.display="none",s.textContent=""),p&&(p.style.display=w?"":"none"),e.find("#preview-card").get(0).style.display="",c.textContent="";const d=document.createElement("div");d.id="fb-preview-form",c.appendChild(d);const m=w?async u=>{s&&(s.style.display="none",s.textContent="");try{const i=await fetch(`/api/forms/submit/${w}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}),f=await i.json();if(!i.ok)throw new Error(f.error||"Submission failed.");s&&(s.textContent=f.message||l.settings?.successMessage||"Submitted successfully.",s.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:rgba(34,197,94,.12);color:var(--success,#22c55e);"),E.toast("Test submission stored.",{type:"success"})}catch(i){s&&(s.textContent=i.message,s.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:rgba(239,68,68,.12);color:var(--danger,#ef4444);"),E.toast(i.message,{type:"error"})}return!1}:()=>!1,r=l.fields.some(u=>u.type==="page-break");if(typeof F<"u"){const u=l.settings?.columns||2,i=l.settings?.layout||"stacked";if(r&&F.wizard){const f=ie(l.fields).map(h=>({title:h.title,description:h.description,fields:J(h.fields,u)}));F.wizard("#fb-preview-form",{schema:{steps:f},onSubmit:m}),U("#fb-preview-form",l.fields)}else if(F.render){const f=J(l.fields,u),h={};if(l.fields.forEach(g=>{if(!(!g.name||g.type==="page-break"||g.type==="spacer")&&(g.type==="select"||g.type==="multiselect")&&g.required){const y=(g.options||[])[0];y&&(h[g.name]=typeof y=="object"?y.value:y)}}),F.render("#fb-preview-form",f,h,{submitText:l.settings?.submitText||"Submit",layout:i,columns:u,onSubmit:m}),i==="grid"&&l.settings?.submitSpan==="full"){const g=document.querySelector("#fb-preview-form .form-buttons");g&&g.classList.add("col-span-full")}U("#fb-preview-form",l.fields)}window.FormLogicEngine&&l.fields.some(f=>f.logic)&&requestAnimationFrame(()=>{new window.FormLogicEngine.FormLogicRuntime({fields:l.fields},d).init()})}else{const u=document.createElement("p");u.textContent=`${l.fields.filter(i=>i.type!=="page-break").length} field(s): ${l.fields.filter(i=>i.type!=="page-break").map(i=>i.label).join(", ")}`,u.style.cssText="color:var(--muted);font-style:italic;",d.appendChild(u)}e.find("#preview-card").get(0).scrollIntoView({behavior:"smooth",block:"start"})})}};
@@ -1 +1 @@
1
- import{dashboardView as o}from"./dashboard.js";import{pagesView as i}from"./pages.js";import{pageEditorView as r}from"./page-editor.js?v=20260422-2";import{settingsView as t}from"./settings.js";import{navigationView as e}from"./navigation.js";import{notificationsView as m}from"./notifications.js";import{layoutsView as s}from"./layouts.js";import{mediaView as f}from"./media.js";import{loginView as p}from"./login.js";import{usersView as w}from"./users.js";import{userEditorView as n}from"./user-editor.js";import{pluginsView as c}from"./plugins.js";import{documentationView as V}from"./documentation.js";import{tutorialsView as l}from"./tutorials.js";import{apiReferenceView as a}from"./api-reference.js";import{collectionsView as d}from"./collections.js";import{collectionEditorView as E}from"./collection-editor.js";import{collectionEntriesView as u}from"./collection-entries.js";import{formsView as g}from"./forms.js";import{formEditorView as v}from"./form-editor.js";import{formSubmissionsView as b}from"./form-submissions.js";import{viewsListView as k}from"./views-list.js";import{viewEditorView as y}from"./view-editor.js";import{viewPreviewView as L}from"./view-preview.js";import{actionsListView as P}from"./actions-list.js";import{actionEditorView as h}from"./action-editor.js";import{proDocsView as D}from"./pro-docs.js";import{blocksView as R}from"./blocks.js?v=3";import{blockEditorView as S}from"./block-editor.js?v=7";import"./block-editor-enhance.js?v=2";import{componentsView as x}from"./components.js?v=3";import{componentEditorView as j}from"./component-editor.js?v=7";import{myProfileView as q}from"./my-profile.js";import{rolesView as z}from"./roles.js";import{roleEditorView as A}from"./role-editor.js";import{effectsView as B}from"./effects.js";export const views={dashboard:o,pages:i,pageEditor:r,settings:t,navigation:e,layouts:s,media:f,login:p,users:w,userEditor:n,plugins:c,documentation:V,tutorials:l,apiReference:a,collections:d,collectionEditor:E,collectionEntries:u,forms:g,formEditor:v,formSubmissions:b,viewsList:k,viewEditor:y,viewPreview:L,actionsList:P,actionEditor:h,proDocs:D,blocks:R,blockEditor:S,components:x,componentEditor:j,myProfile:q,roles:z,roleEditor:A,effects:B,notifications:m};
1
+ import{dashboardView as o}from"./dashboard.js";import{pagesView as i}from"./pages.js";import{pageEditorView as r}from"./page-editor.js?v=20260422-2";import{settingsView as t}from"./settings.js";import{navigationView as e}from"./navigation.js";import{notificationsView as m}from"./notifications.js";import{layoutsView as s}from"./layouts.js";import{mediaView as f}from"./media.js";import{loginView as p}from"./login.js";import{usersView as w}from"./users.js";import{userEditorView as n}from"./user-editor.js";import{pluginsView as c}from"./plugins.js";import{documentationView as V}from"./documentation.js";import{tutorialsView as l}from"./tutorials.js";import{apiReferenceView as a}from"./api-reference.js";import{collectionsView as d}from"./collections.js";import{collectionEditorView as E}from"./collection-editor.js";import{collectionEntriesView as u}from"./collection-entries.js";import{formsView as g}from"./forms.js";import{formEditorView as v}from"./form-editor.js?v=20260422-4";import{formSubmissionsView as b}from"./form-submissions.js";import{viewsListView as k}from"./views-list.js";import{viewEditorView as y}from"./view-editor.js";import{viewPreviewView as L}from"./view-preview.js";import{actionsListView as P}from"./actions-list.js";import{actionEditorView as h}from"./action-editor.js";import{proDocsView as D}from"./pro-docs.js";import{blocksView as R}from"./blocks.js?v=3";import{blockEditorView as S}from"./block-editor.js?v=7";import"./block-editor-enhance.js?v=2";import{componentsView as x}from"./components.js?v=3";import{componentEditorView as j}from"./component-editor.js?v=7";import{myProfileView as q}from"./my-profile.js";import{rolesView as z}from"./roles.js";import{roleEditorView as A}from"./role-editor.js";import{effectsView as B}from"./effects.js";export const views={dashboard:o,pages:i,pageEditor:r,settings:t,navigation:e,layouts:s,media:f,login:p,users:w,userEditor:n,plugins:c,documentation:V,tutorials:l,apiReference:a,collections:d,collectionEditor:E,collectionEntries:u,forms:g,formEditor:v,formSubmissions:b,viewsList:k,viewEditor:y,viewPreview:L,actionsList:P,actionEditor:h,proDocs:D,blocks:R,blockEditor:S,components:x,componentEditor:j,myProfile:q,roles:z,roleEditor:A,effects:B,notifications:m};