@object-ui/plugin-form 3.0.3 → 3.1.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.
- package/.turbo/turbo-build.log +6 -6
- package/dist/index.js +1217 -861
- package/dist/index.umd.cjs +2 -2
- package/dist/plugin-form/src/EmbeddableForm.d.ts +49 -0
- package/dist/plugin-form/src/FormAnalytics.d.ts +38 -0
- package/dist/plugin-form/src/FormSection.d.ts +6 -0
- package/dist/plugin-form/src/autoLayout.d.ts +60 -0
- package/dist/plugin-form/src/index.d.ts +5 -0
- package/package.json +8 -8
- package/src/DrawerForm.tsx +49 -24
- package/src/EmbeddableForm.tsx +240 -0
- package/src/FormAnalytics.tsx +209 -0
- package/src/FormSection.tsx +9 -1
- package/src/ModalForm.tsx +145 -45
- package/src/ObjectForm.tsx +12 -4
- package/src/SplitForm.tsx +3 -2
- package/src/TabbedForm.tsx +3 -2
- package/src/WizardForm.tsx +3 -2
- package/src/__tests__/EmbeddableFormPrefill.test.tsx +186 -0
- package/src/__tests__/MobileUX.test.tsx +433 -0
- package/src/__tests__/NewVariants.test.tsx +196 -0
- package/src/__tests__/autoLayout.test.ts +342 -0
- package/src/autoLayout.ts +168 -0
- package/src/index.tsx +52 -0
package/dist/index.umd.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(_,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("react"),require("@object-ui/core"),require("@object-ui/react"),require("@object-ui/fields"),require("@object-ui/components"),require("lucide-react")):typeof define=="function"&&define.amd?define(["exports","react","@object-ui/core","@object-ui/react","@object-ui/fields","@object-ui/components","lucide-react"],i):(_=typeof globalThis<"u"?globalThis:_||self,i(_.ObjectUIPluginForm={},_.React,_.core,_.react,_.fields,_.components,_.lucideReact))})(this,(function(_,i,ee,H,W,u,J){"use strict";var te={exports:{}},Q={};var ae;function he(){if(ae)return Q;ae=1;var e=Symbol.for("react.transitional.element"),l=Symbol.for("react.fragment");function o(x,s,m){var g=null;if(m!==void 0&&(g=""+m),s.key!==void 0&&(g=""+s.key),"key"in s){m={};for(var E in s)E!=="key"&&(m[E]=s[E])}else m=s;return s=m.ref,{$$typeof:e,type:x,key:g,ref:s!==void 0?s:null,props:m}}return Q.Fragment=l,Q.jsx=o,Q.jsxs=o,Q}var Z={};var de;function Fe(){return de||(de=1,process.env.NODE_ENV!=="production"&&(function(){function e(r){if(r==null)return null;if(typeof r=="function")return r.$$typeof===j?null:r.displayName||r.name||null;if(typeof r=="string")return r;switch(r){case V:return"Fragment";case L:return"Profiler";case z:return"StrictMode";case n:return"Suspense";case d:return"SuspenseList";case T:return"Activity"}if(typeof r=="object")switch(typeof r.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),r.$$typeof){case I:return"Portal";case q:return r.displayName||"Context";case G:return(r._context.displayName||"Context")+".Consumer";case p:var S=r.render;return r=r.displayName,r||(r=S.displayName||S.name||"",r=r!==""?"ForwardRef("+r+")":"ForwardRef"),r;case a:return S=r.displayName||null,S!==null?S:e(r.type)||"Memo";case f:S=r._payload,r=r._init;try{return e(r(S))}catch{}}return null}function l(r){return""+r}function o(r){try{l(r);var S=!1}catch{S=!0}if(S){S=console;var M=S.error,R=typeof Symbol=="function"&&Symbol.toStringTag&&r[Symbol.toStringTag]||r.constructor.name||"Object";return M.call(S,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",R),l(r)}}function x(r){if(r===V)return"<>";if(typeof r=="object"&&r!==null&&r.$$typeof===f)return"<...>";try{var S=e(r);return S?"<"+S+">":"<...>"}catch{return"<...>"}}function s(){var r=c.A;return r===null?null:r.getOwner()}function m(){return Error("react-stack-top-frame")}function g(r){if(P.call(r,"key")){var S=Object.getOwnPropertyDescriptor(r,"key").get;if(S&&S.isReactWarning)return!1}return r.key!==void 0}function E(r,S){function M(){w||(w=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",S))}M.isReactWarning=!0,Object.defineProperty(r,"key",{get:M,configurable:!0})}function A(){var r=e(this.type);return y[r]||(y[r]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),r=this.props.ref,r!==void 0?r:null}function k(r,S,M,R,le,oe){var Y=M.ref;return r={$$typeof:C,type:r,key:S,props:M,_owner:R},(Y!==void 0?Y:null)!==null?Object.defineProperty(r,"ref",{enumerable:!1,get:A}):Object.defineProperty(r,"ref",{enumerable:!1,value:null}),r._store={},Object.defineProperty(r._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(r,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(r,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:le}),Object.defineProperty(r,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:oe}),Object.freeze&&(Object.freeze(r.props),Object.freeze(r)),r}function O(r,S,M,R,le,oe){var Y=S.children;if(Y!==void 0)if(R)if(h(Y)){for(R=0;R<Y.length;R++)v(Y[R]);Object.freeze&&Object.freeze(Y)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else v(Y);if(P.call(S,"key")){Y=e(r);var X=Object.keys(S).filter(function(Pe){return Pe!=="key"});R=0<X.length?"{key: someKey, "+X.join(": ..., ")+": ...}":"{key: someKey}",D[Y+R]||(X=0<X.length?"{"+X.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
2
2
|
let props = %s;
|
|
3
3
|
<%s {...props} />
|
|
4
4
|
React keys must be passed directly to JSX without using spread:
|
|
5
5
|
let props = %s;
|
|
6
|
-
<%s key={someKey} {...props} />`,h,P,U,P),be[P+h]=!0)}if(P=null,F!==void 0&&(c(F),P=""+F),C(y)&&(c(y.key),P=""+y.key),"key"in y){F={};for(var Z in y)Z!=="key"&&(F[Z]=y[Z])}else F=y;return P&&O(F,typeof r=="function"?r.displayName||r.name||"Unknown":r),E(r,P,F,v(),X,Q)}function x(r){N(r)?r._store&&(r._store.validated=1):typeof r=="object"&&r!==null&&r.$$typeof===n&&(r._payload.status==="fulfilled"?N(r._payload.value)&&r._payload.value._store&&(r._payload.value._store.validated=1):r._store&&(r._store.validated=1))}function N(r){return typeof r=="object"&&r!==null&&r.$$typeof===V}var D=o,V=Symbol.for("react.transitional.element"),$=Symbol.for("react.portal"),I=Symbol.for("react.fragment"),k=Symbol.for("react.strict_mode"),M=Symbol.for("react.profiler"),p=Symbol.for("react.consumer"),a=Symbol.for("react.context"),i=Symbol.for("react.forward_ref"),s=Symbol.for("react.suspense"),d=Symbol.for("react.suspense_list"),f=Symbol.for("react.memo"),n=Symbol.for("react.lazy"),S=Symbol.for("react.activity"),W=Symbol.for("react.client.reference"),b=D.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,w=Object.prototype.hasOwnProperty,_=Array.isArray,A=console.createTask?console.createTask:function(){return null};D={react_stack_bottom_frame:function(r){return r()}};var q,fe={},ce=D.react_stack_bottom_frame.bind(D,m)(),pe=A(u(m)),be={};J.Fragment=I,J.jsx=function(r,y,F){var h=1e4>b.recentlyCreatedOwnerStacks++;return g(r,y,F,!1,h?Error("react-stack-top-frame"):ce,h?A(u(r)):pe)},J.jsxs=function(r,y,F){var h=1e4>b.recentlyCreatedOwnerStacks++;return g(r,y,F,!0,h?Error("react-stack-top-frame"):ce,h?A(u(r)):pe)}})()),J}var re;function je(){return re||(re=1,process.env.NODE_ENV==="production"?G.exports=me():G.exports=ye()),G.exports}var t=je();const Y=({label:e,description:l,collapsible:c=!1,collapsed:u=!1,columns:v=1,children:m,className:C})=>{const[O,T]=o.useState(u),E={1:"grid-cols-1",2:"grid-cols-1 md:grid-cols-2",3:"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",4:"grid-cols-1 md:grid-cols-2 lg:grid-cols-4"},g=()=>{c&&T(!O)};return t.jsxs("div",{className:j.cn("form-section",C),children:[(e||l)&&t.jsxs("div",{className:j.cn("flex items-start gap-2 mb-4",c&&"cursor-pointer select-none"),onClick:g,role:c?"button":void 0,"aria-expanded":c?!O:void 0,children:[c&&t.jsx("span",{className:"mt-0.5 text-muted-foreground",children:O?t.jsx(H.ChevronRight,{className:"h-4 w-4"}):t.jsx(H.ChevronDown,{className:"h-4 w-4"})}),t.jsxs("div",{className:"flex-1",children:[e&&t.jsx("h3",{className:"text-base font-semibold text-foreground",children:e}),l&&t.jsx("p",{className:"text-sm text-muted-foreground mt-0.5",children:l})]})]}),!O&&t.jsx("div",{className:j.cn("grid gap-4",E[v]),children:m})]})},le=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,g]=o.useState(null),[x,N]=o.useState(e.defaultTab||e.sections[0]?.name||e.sections[0]?.label||"tab-0");o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const i=await l.getObjectSchema(e.objectName);v(i)}catch(i){g(i)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId||!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const i=await l.findOne(e.objectName,e.recordId);C(i||{})}catch(i){g(i)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const D=o.useCallback(a=>{const i=[];for(const s of a.fields){const d=typeof s=="string"?s:s.name;if(typeof s=="object")i.push(s);else if(u?.fields?.[d]){const f=u.fields[d];i.push({name:d,label:f.label||d,type:L.mapFieldTypeToFormType(f.type),required:f.required||!1,disabled:e.readOnly||e.mode==="view"||f.readonly,placeholder:f.placeholder,description:f.help||f.description,validation:L.buildValidationRules(f),field:f,options:f.options,multiple:f.multiple})}else i.push({name:d,label:d,type:"input"})}return i},[u,e.readOnly,e.mode]),V=o.useCallback(async a=>{if(!l)return e.onSuccess&&await e.onSuccess(a),a;try{let i;return e.mode==="create"?i=await l.create(e.objectName,a):e.mode==="edit"&&e.recordId&&(i=await l.update(e.objectName,e.recordId,a)),e.onSuccess&&await e.onSuccess(i),i}catch(i){throw e.onError&&e.onError(i),i}},[e,l]),$=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),I=(a,i)=>a.name||a.label||`tab-${i}`;if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const M={type:"form",fields:e.sections.flatMap(a=>D(a)),layout:"vertical",defaultValues:m,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:V,onCancel:$},p=e.tabPosition==="left"||e.tabPosition==="right";return t.jsx("div",{className:j.cn("w-full",c,e.className),children:t.jsxs(j.Tabs,{value:x,onValueChange:N,orientation:p?"vertical":"horizontal",className:j.cn(p&&"flex gap-4"),children:[t.jsx(j.TabsList,{className:j.cn(p?"flex-col h-auto":"",e.tabPosition==="bottom"&&"order-last",e.tabPosition==="right"&&"order-last"),children:e.sections.map((a,i)=>t.jsx(j.TabsTrigger,{value:I(a,i),className:p?"w-full justify-start":"",children:a.label||`Tab ${i+1}`},I(a,i)))}),t.jsx("div",{className:"flex-1",children:e.sections.map((a,i)=>t.jsx(j.TabsContent,{value:I(a,i),className:"mt-0",children:t.jsx(Y,{description:a.description,columns:a.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...M,fields:D(a),showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1}})})},I(a,i)))})]})})},ie=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,g]=o.useState(null),[x,N]=o.useState(0),[D,V]=o.useState(new Set),[$,I]=o.useState(!1),k=e.sections.length,M=x===0,p=x===k-1;o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const w=await l.getObjectSchema(e.objectName);v(w)}catch(w){g(w)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId||!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const w=await l.findOne(e.objectName,e.recordId);C(w||{})}catch(w){g(w)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const a=o.useCallback(b=>{const w=[];for(const _ of b.fields){const A=typeof _=="string"?_:_.name;if(typeof _=="object")w.push(_);else if(u?.fields?.[A]){const q=u.fields[A];w.push({name:A,label:q.label||A,type:L.mapFieldTypeToFormType(q.type),required:q.required||!1,disabled:e.readOnly||e.mode==="view"||q.readonly,placeholder:q.placeholder,description:q.help||q.description,validation:L.buildValidationRules(q),field:q,options:q.options,multiple:q.multiple})}else w.push({name:A,label:A,type:"input"})}return w},[u,e.readOnly,e.mode]),i=o.useMemo(()=>x>=0&&x<k?a(e.sections[x]):[],[x,k,e.sections,a]),s=o.useCallback(async b=>{const w={...m,...b};if(C(w),V(_=>new Set(_).add(x)),p){I(!0);try{if(!l)return e.onSuccess&&await e.onSuccess(w),w;let _;return e.mode==="create"?_=await l.create(e.objectName,w):e.mode==="edit"&&e.recordId&&(_=await l.update(e.objectName,e.recordId,w)),e.onSuccess&&await e.onSuccess(_),_}catch(_){throw e.onError&&e.onError(_),_}finally{I(!1)}}else d(x+1)},[m,x,p,e,l]),d=o.useCallback(b=>{b>=0&&b<k&&(N(b),e.onStepChange&&e.onStepChange(b))},[k,e]),f=o.useCallback(()=>{d(x-1)},[x,d]),n=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),S=o.useCallback(b=>{(e.allowSkip||D.has(b)||b<=x)&&d(b)},[e.allowSkip,D,x,d]);if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const W=e.sections[x];return t.jsxs("div",{className:j.cn("w-full",c,e.className),children:[e.showStepIndicator!==!1&&t.jsx("nav",{"aria-label":"Progress",className:"mb-8",children:t.jsx("ol",{className:"flex items-center",children:e.sections.map((b,w)=>{const _=w===x,A=D.has(w),q=e.allowSkip||A||w<=x;return t.jsxs("li",{className:j.cn("relative flex-1",w!==k-1&&"pr-8 sm:pr-12"),children:[w!==k-1&&t.jsx("div",{className:"absolute top-3 sm:top-4 left-6 -right-4 sm:left-10 sm:-right-2 h-0.5","aria-hidden":"true",children:t.jsx("div",{className:j.cn("h-full",A?"bg-primary":"bg-muted")})}),t.jsxs("button",{type:"button",className:j.cn("group relative flex items-center",q?"cursor-pointer":"cursor-not-allowed"),onClick:()=>S(w),disabled:!q,children:[t.jsx("span",{className:j.cn("flex h-6 w-6 sm:h-8 sm:w-8 items-center justify-center rounded-full text-xs sm:text-sm font-medium transition-colors",A&&"bg-primary text-primary-foreground",_&&!A&&"border-2 border-primary bg-background text-primary",!_&&!A&&"border-2 border-muted bg-background text-muted-foreground"),children:A?t.jsx(H.Check,{className:"h-3 w-3 sm:h-4 sm:w-4"}):w+1}),t.jsx("span",{className:"ml-2 sm:ml-3 text-xs sm:text-sm font-medium hidden sm:block",children:t.jsx("span",{className:j.cn(_?"text-foreground":"text-muted-foreground"),children:b.label||`Step ${w+1}`})})]})]},w)})})}),t.jsx("div",{className:"min-h-[200px]",children:W&&t.jsx(Y,{label:W.label,description:W.description,columns:W.columns||1,children:i.length>0?t.jsx(R.SchemaRenderer,{schema:{type:"form",fields:i,layout:"vertical",defaultValues:m,showSubmit:!1,showCancel:!1,onSubmit:s}}):t.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No fields configured for this step"})})}),t.jsxs("div",{className:"flex items-center justify-between mt-6 pt-4 border-t",children:[t.jsx("div",{children:e.showCancel!==!1&&t.jsx(j.Button,{variant:"ghost",onClick:n,children:e.cancelText||"Cancel"})}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsxs("span",{className:"text-sm text-muted-foreground mr-2",children:["Step ",x+1," of ",k]}),!M&&t.jsxs(j.Button,{variant:"outline",onClick:f,children:[t.jsx(H.ChevronLeft,{className:"h-4 w-4 mr-1"}),e.prevText||"Back"]}),p?t.jsx(j.Button,{onClick:()=>s(m),disabled:$||e.mode==="view",children:$?"Submitting...":e.submitText||(e.mode==="create"?"Create":"Update")}):t.jsxs(j.Button,{onClick:()=>s(m),children:[e.nextText||"Next",t.jsx(H.ChevronRight,{className:"h-4 w-4 ml-1"})]})]})]})]})},ne=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,g]=o.useState(null);o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const i=await l.getObjectSchema(e.objectName);v(i)}catch(i){g(i),T(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){C(e.initialData||e.initialValues||{}),T(!1);return}if(!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const i=await l.findOne(e.objectName,e.recordId);C(i||{})}catch(i){g(i)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const x=o.useCallback(a=>{const i=[];for(const s of a.fields){const d=typeof s=="string"?s:s.name;if(typeof s=="object")i.push(s);else if(u?.fields?.[d]){const f=u.fields[d];i.push({name:d,label:f.label||d,type:L.mapFieldTypeToFormType(f.type),required:f.required||!1,disabled:e.readOnly||e.mode==="view"||f.readonly,placeholder:f.placeholder,description:f.help||f.description,validation:L.buildValidationRules(f),field:f,options:f.options,multiple:f.multiple})}else i.push({name:d,label:d,type:"input"})}return i},[u,e.readOnly,e.mode]),N=o.useCallback(async a=>{if(!l)return e.onSuccess&&await e.onSuccess(a),a;try{let i;return e.mode==="create"?i=await l.create(e.objectName,a):e.mode==="edit"&&e.recordId&&(i=await l.update(e.objectName,e.recordId,a)),e.onSuccess&&await e.onSuccess(i),i}catch(i){throw e.onError&&e.onError(i),i}},[e,l]),D=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),V=o.useMemo(()=>e.sections.slice(0,1),[e.sections]),$=o.useMemo(()=>e.sections.slice(1),[e.sections]);o.useMemo(()=>e.sections.flatMap(a=>x(a)),[e.sections,x]);const I=e.splitDirection||"horizontal",k=e.splitSize||50;if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const M={type:"form",layout:"vertical",defaultValues:m,onSubmit:N,onCancel:D},p=(a,i)=>t.jsx("div",{className:"space-y-4 p-4",children:a.map((s,d)=>t.jsx(Y,{label:s.label,description:s.description,columns:s.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...M,fields:x(s),showSubmit:i&&e.showSubmit!==!1&&e.mode!=="view",showCancel:i&&e.showCancel!==!1,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText}})},s.name||s.label||d))});return t.jsx("div",{className:j.cn("w-full",c,e.className),children:t.jsxs(j.ResizablePanelGroup,{orientation:I,className:"min-h-[300px] rounded-lg border",children:[t.jsx(j.ResizablePanel,{defaultSize:k,minSize:20,children:p(V,$.length===0)}),$.length>0&&t.jsxs(t.Fragment,{children:[t.jsx(j.ResizableHandle,{withHandle:e.splitResizable!==!1}),t.jsx(j.ResizablePanel,{defaultSize:100-k,minSize:20,children:p($,!0)})]})]})})},oe=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState([]),[O,T]=o.useState({}),[E,g]=o.useState(!0),[x,N]=o.useState(null),D=e.open!==!1,V=e.drawerSide||"right";o.useEffect(()=>{(async()=>{if(!l){g(!1);return}try{const d=await l.getObjectSchema(e.objectName);v(d)}catch(d){N(d),g(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){T(e.initialData||e.initialValues||{}),g(!1);return}if(!l){T(e.initialData||e.initialValues||{}),g(!1);return}try{const d=await l.findOne(e.objectName,e.recordId);T(d||{})}catch(d){N(d)}finally{g(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const $=o.useCallback(s=>{const d=[];for(const f of s.fields){const n=typeof f=="string"?f:f.name;if(typeof f=="object")d.push(f);else if(u?.fields?.[n]){const S=u.fields[n];d.push({name:n,label:S.label||n,type:L.mapFieldTypeToFormType(S.type),required:S.required||!1,disabled:e.readOnly||e.mode==="view"||S.readonly,placeholder:S.placeholder,description:S.help||S.description,validation:L.buildValidationRules(S),field:S,options:S.options,multiple:S.multiple})}else d.push({name:n,label:n,type:"input"})}return d},[u,e.readOnly,e.mode]);o.useEffect(()=>{if(!u&&l)return;if(e.customFields?.length){C(e.customFields),g(!1);return}if(e.sections?.length){g(!1);return}if(!u)return;const s=e.fields||Object.keys(u.fields||{}),d=[];for(const f of s){const n=typeof f=="string"?f:f.name;if(!n)continue;const S=u.fields?.[n];S&&d.push({name:n,label:S.label||n,type:L.mapFieldTypeToFormType(S.type),required:S.required||!1,disabled:e.readOnly||e.mode==="view"||S.readonly,placeholder:S.placeholder,description:S.help||S.description,validation:L.buildValidationRules(S),field:S,options:S.options,multiple:S.multiple})}C(d),g(!1)},[u,e.fields,e.customFields,e.sections,e.readOnly,e.mode,l]);const I=o.useCallback(async s=>{if(!l)return e.onSuccess&&await e.onSuccess(s),e.onOpenChange?.(!1),s;try{let d;return e.mode==="create"?d=await l.create(e.objectName,s):e.mode==="edit"&&e.recordId&&(d=await l.update(e.objectName,e.recordId,s)),e.onSuccess&&await e.onSuccess(d),e.onOpenChange?.(!1),d}catch(d){throw e.onError&&e.onError(d),d}},[e,l]),k=o.useCallback(()=>{e.onCancel&&e.onCancel(),e.onOpenChange?.(!1)},[e]),M=o.useMemo(()=>e.drawerWidth?V==="left"||V==="right"?{width:e.drawerWidth,maxWidth:e.drawerWidth}:{height:e.drawerWidth,maxHeight:e.drawerWidth}:void 0,[e.drawerWidth,V]),a={type:"form",layout:e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical",defaultValues:O,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:I,onCancel:k},i=()=>x?t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:x.message})]}):E?t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]}):e.sections?.length?t.jsx("div",{className:"space-y-6",children:e.sections.map((s,d)=>t.jsx(Y,{label:s.label,description:s.description,columns:s.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...a,fields:$(s),showSubmit:d===e.sections.length-1&&a.showSubmit,showCancel:d===e.sections.length-1&&a.showCancel}})},s.name||s.label||d))}):t.jsx(R.SchemaRenderer,{schema:{...a,fields:m,columns:e.columns}});return t.jsx(j.Sheet,{open:D,onOpenChange:e.onOpenChange,children:t.jsxs(j.SheetContent,{side:V,className:j.cn("overflow-y-auto",c,e.className),style:M,children:[(e.title||e.description)&&t.jsxs(j.SheetHeader,{children:[e.title&&t.jsx(j.SheetTitle,{children:e.title}),e.description&&t.jsx(j.SheetDescription,{children:e.description})]}),t.jsx("div",{className:"py-4",children:i()})]})})},se={sm:"max-w-sm",default:"max-w-lg",lg:"max-w-2xl",xl:"max-w-4xl",full:"max-w-[95vw] w-full"},ae=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState([]),[O,T]=o.useState({}),[E,g]=o.useState(!0),[x,N]=o.useState(null),D=e.open!==!1,V=se[e.modalSize||"default"]||se.default;o.useEffect(()=>{(async()=>{if(!l){g(!1);return}try{const s=await l.getObjectSchema(e.objectName);v(s)}catch(s){N(s),g(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){T(e.initialData||e.initialValues||{}),g(!1);return}if(!l){T(e.initialData||e.initialValues||{}),g(!1);return}try{const s=await l.findOne(e.objectName,e.recordId);T(s||{})}catch(s){N(s)}finally{g(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const $=o.useCallback(i=>{const s=[];for(const d of i.fields){const f=typeof d=="string"?d:d.name;if(typeof d=="object")s.push(d);else if(u?.fields?.[f]){const n=u.fields[f];s.push({name:f,label:n.label||f,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n,options:n.options,multiple:n.multiple})}else s.push({name:f,label:f,type:"input"})}return s},[u,e.readOnly,e.mode]);o.useEffect(()=>{if(!u&&l)return;if(e.customFields?.length){C(e.customFields),g(!1);return}if(e.sections?.length){g(!1);return}if(!u)return;const i=e.fields||Object.keys(u.fields||{}),s=[];for(const d of i){const f=typeof d=="string"?d:d.name;if(!f)continue;const n=u.fields?.[f];n&&s.push({name:f,label:n.label||f,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n,options:n.options,multiple:n.multiple})}C(s),g(!1)},[u,e.fields,e.customFields,e.sections,e.readOnly,e.mode,l]);const I=o.useCallback(async i=>{if(!l)return e.onSuccess&&await e.onSuccess(i),e.onOpenChange?.(!1),i;try{let s;return e.mode==="create"?s=await l.create(e.objectName,i):e.mode==="edit"&&e.recordId&&(s=await l.update(e.objectName,e.recordId,i)),e.onSuccess&&await e.onSuccess(s),e.onOpenChange?.(!1),s}catch(s){throw e.onError&&e.onError(s),s}},[e,l]),k=o.useCallback(()=>{e.onCancel&&e.onCancel(),e.onOpenChange?.(!1)},[e]),p={type:"form",layout:e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical",defaultValues:O,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:I,onCancel:k},a=()=>x?t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:x.message})]}):E?t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]}):e.sections?.length?t.jsx("div",{className:"space-y-6",children:e.sections.map((i,s)=>t.jsx(Y,{label:i.label,description:i.description,columns:i.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...p,fields:$(i),showSubmit:s===e.sections.length-1&&p.showSubmit,showCancel:s===e.sections.length-1&&p.showCancel}})},i.name||i.label||s))}):t.jsx(R.SchemaRenderer,{schema:{...p,fields:m,columns:e.columns}});return t.jsx(j.Dialog,{open:D,onOpenChange:e.onOpenChange,children:t.jsxs(j.DialogContent,{className:j.cn(V,"max-h-[90vh] overflow-y-auto",c,e.className),children:[(e.title||e.description)&&t.jsxs(j.DialogHeader,{children:[e.title&&t.jsx(j.DialogTitle,{children:e.title}),e.description&&t.jsx(j.DialogDescription,{children:e.description})]}),t.jsx("div",{className:"py-2",children:a()})]})})},de=({schema:e,dataSource:l})=>{if(e.formType==="tabbed"&&e.sections?.length)return t.jsx(le,{schema:{...e,formType:"tabbed",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),defaultTab:e.defaultTab,tabPosition:e.tabPosition},dataSource:l,className:e.className});if(e.formType==="wizard"&&e.sections?.length)return t.jsx(ie,{schema:{...e,formType:"wizard",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),allowSkip:e.allowSkip,showStepIndicator:e.showStepIndicator,nextText:e.nextText,prevText:e.prevText,onStepChange:e.onStepChange},dataSource:l,className:e.className});if(e.formType==="split"&&e.sections?.length)return t.jsx(ne,{schema:{...e,formType:"split",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),splitDirection:e.splitDirection,splitSize:e.splitSize,splitResizable:e.splitResizable},dataSource:l,className:e.className});if(e.formType==="drawer"){const{layout:c,...u}=e,v=e.layout==="vertical"||e.layout==="horizontal"?e.layout:void 0;return t.jsx(oe,{schema:{...u,layout:v,formType:"drawer",sections:e.sections?.map(m=>({name:m.name,label:m.label,description:m.description,columns:m.columns,fields:m.fields})),open:e.open,onOpenChange:e.onOpenChange,drawerSide:e.drawerSide,drawerWidth:e.drawerWidth},dataSource:l,className:e.className})}if(e.formType==="modal"){const{layout:c,...u}=e,v=e.layout==="vertical"||e.layout==="horizontal"?e.layout:void 0;return t.jsx(ae,{schema:{...u,layout:v,formType:"modal",sections:e.sections?.map(m=>({name:m.name,label:m.label,description:m.description,columns:m.columns,fields:m.fields})),open:e.open,onOpenChange:e.onOpenChange,modalSize:e.modalSize,modalCloseButton:e.modalCloseButton},dataSource:l,className:e.className})}return t.jsx(xe,{schema:e,dataSource:l})},xe=({schema:e,dataSource:l})=>{const[c,u]=o.useState(null),[v,m]=o.useState([]),[C,O]=o.useState(null),[T,E]=o.useState(!0),[g,x]=o.useState(null),N=e.customFields&&e.customFields.length>0;o.useEffect(()=>{N&&(O(e.initialData||e.initialValues||{}),E(!1))},[N,e.initialData,e.initialValues]),o.useEffect(()=>{const p=async()=>{try{if(!l)throw new Error("DataSource is required when using ObjectQL schema fetching (inline fields not provided)");const a=await l.getObjectSchema(e.objectName);if(!a)throw new Error(`No schema found for object "${e.objectName}"`);u(a)}catch(a){x(a),E(!1)}};N?u({name:e.objectName,fields:{}}):e.objectName&&l?p():N||E(!1)},[e.objectName,l,N]),o.useEffect(()=>{c&&!N&&(async()=>{if(!e.recordId||e.mode==="create"){O(e.initialData||e.initialValues||{}),E(!1);return}if(!N){if(!l){x(new Error("DataSource is required for fetching record data (inline data not provided)")),E(!1);return}E(!0);try{const a=await l.findOne(e.objectName,e.recordId);O(a)}catch(a){console.error("Failed to fetch record:",a),x(a)}finally{E(!1)}}})()},[e.objectName,e.recordId,e.mode,e.initialValues,e.initialData,l,c,N]),o.useEffect(()=>{if(N&&e.customFields){m(e.customFields),E(!1);return}if(!c)return;const p=[],a=e.fields||Object.keys(c.fields||{});(Array.isArray(a)?a:Object.keys(a)).forEach(d=>{const f=typeof d=="string"?d:d.name;if(!f)return;const n=c.fields?.[f];if(!n&&!N)return;const S=!n?.permissions||n?.permissions.write!==!1;if(e.mode!=="view"&&!S)return;const W=e.customFields?.find(b=>b.name===f);if(W)p.push(W);else if(n){const b={name:f,label:n.label||d,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n};if((n.type==="select"||n.type==="lookup"||n.type==="master_detail")&&(b.options=n.options||[],b.multiple=n.multiple),(n.type==="number"||n.type==="currency"||n.type==="percent")&&(b.inputType="number",b.min=n.min,b.max=n.max,b.step=n.precision?Math.pow(10,-n.precision):void 0),n.type==="date"&&(b.inputType="date"),n.type==="datetime"&&(b.inputType="datetime-local"),(n.type==="text"||n.type==="textarea"||n.type==="markdown"||n.type==="html")&&(b.maxLength=n.max_length,b.minLength=n.min_length),(n.type==="file"||n.type==="image")&&(b.inputType="file",b.multiple=n.multiple,b.accept=n.accept?n.accept.join(","):void 0,n.max_size)){const w=`Max size: ${L.formatFileSize(n.max_size)}`;b.description=b.description?`${b.description} (${w})`:w}n.type==="email"&&(b.inputType="email"),n.type==="phone"&&(b.inputType="tel"),n.type==="url"&&(b.inputType="url"),n.type==="password"&&(b.inputType="password"),n.type==="time"&&(b.inputType="time"),(n.type==="formula"||n.type==="summary"||n.type==="auto_number")&&(b.disabled=!0),n.visible_on&&(b.visible=w=>L.evaluateCondition(n.visible_on,w)),p.push(b)}}),m(p),!N&&e.recordId&&e.mode!=="create"&&l||E(!1)},[c,e.fields,e.customFields,e.readOnly,e.mode,N,e.recordId,l]);const D=o.useCallback(async(p,a)=>{if(p&&(p.nativeEvent||p._reactName==="onSubmit")&&(console.warn("ObjectForm: Received Event instead of data in handleSubmit! This suggests a Form renderer issue."),a===void 0&&(a=p,p={})),N&&!l)return e.onSuccess&&await e.onSuccess(p),p;if(!l)throw new Error("DataSource is required for form submission (inline mode not configured)");try{let i;if(e.mode==="create")i=await l.create(e.objectName,p);else if(e.mode==="edit"&&e.recordId)i=await l.update(e.objectName,e.recordId,p);else throw new Error("Invalid form mode or missing record ID");return e.onSuccess&&await e.onSuccess(i),i}catch(i){throw console.error("Failed to submit form:",i),e.onError&&e.onError(i),i}},[e,l,N]),V=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),I={...o.useMemo(()=>{if(!c?.fields)return{};const p={};return Object.keys(c.fields).forEach(a=>{const i=c.fields[a];i.defaultValue!==void 0&&(p[a]=i.defaultValue)}),p},[c]),...C};if(g)return t.jsxs("div",{className:"p-3 sm:p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:g.message})]});if(T)return t.jsxs("div",{className:"p-4 sm:p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const k=e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical";if(e.sections?.length&&(!e.formType||e.formType==="simple"))return t.jsx("div",{className:"w-full space-y-6",children:e.sections.map((p,a)=>{const i=p.fields.map(d=>typeof d=="string"?d:d.name),s=v.filter(d=>i.includes(d.name));return t.jsx(Y,{label:p.label,description:p.description,collapsible:p.collapsible,collapsed:p.collapsed,columns:p.columns,children:t.jsx(R.SchemaRenderer,{schema:{type:"form",fields:s,layout:k,defaultValues:I,showSubmit:a===e.sections.length-1&&e.showSubmit!==!1&&e.mode!=="view",showCancel:a===e.sections.length-1&&e.showCancel!==!1,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,onSubmit:D,onCancel:V}})},p.name||p.label||a)})});const M={type:"form",fields:v,layout:k,columns:e.columns,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,resetOnSubmit:e.showReset,defaultValues:I,onSubmit:D,onCancel:V,className:e.className};return t.jsx("div",{className:"w-full",children:t.jsx(R.SchemaRenderer,{schema:M})})},ue=({schema:e})=>t.jsx(de,{schema:e});K.ComponentRegistry.register("object-form",ue,{namespace:"plugin-form",label:"Object Form",category:"plugin",inputs:[{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"fields",type:"array",label:"Fields"},{name:"mode",type:"enum",label:"Mode",enum:["create","edit","view"]},{name:"formType",type:"enum",label:"Form Type",enum:["simple","tabbed","wizard","split","drawer","modal"]},{name:"sections",type:"array",label:"Sections"},{name:"title",type:"string",label:"Title"},{name:"description",type:"string",label:"Description"},{name:"layout",type:"enum",label:"Layout",enum:["vertical","horizontal","inline","grid"]},{name:"columns",type:"number",label:"Columns"},{name:"defaultTab",type:"string",label:"Default Tab"},{name:"tabPosition",type:"enum",label:"Tab Position",enum:["top","bottom","left","right"]},{name:"allowSkip",type:"boolean",label:"Allow Skip Steps"},{name:"showStepIndicator",type:"boolean",label:"Show Step Indicator"},{name:"splitDirection",type:"enum",label:"Split Direction",enum:["horizontal","vertical"]},{name:"splitSize",type:"number",label:"Split Panel Size (%)"},{name:"splitResizable",type:"boolean",label:"Split Resizable"},{name:"drawerSide",type:"enum",label:"Drawer Side",enum:["top","bottom","left","right"]},{name:"drawerWidth",type:"string",label:"Drawer Width"},{name:"modalSize",type:"enum",label:"Modal Size",enum:["sm","default","lg","xl","full"]}]}),K.ComponentRegistry.register("form",ue,{namespace:"view",skipFallback:!0,label:"Data Form View",category:"view",inputs:[{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"fields",type:"array",label:"Fields"},{name:"mode",type:"enum",label:"Mode",enum:["create","edit","view"]}]}),z.DrawerForm=oe,z.FormSection=Y,z.ModalForm=ae,z.ObjectForm=de,z.SplitForm=ne,z.TabbedForm=le,z.WizardForm=ie,Object.defineProperty(z,Symbol.toStringTag,{value:"Module"})}));
|
|
6
|
+
<%s key={someKey} {...props} />`,R,Y,X,Y),D[Y+R]=!0)}if(Y=null,M!==void 0&&(o(M),Y=""+M),g(S)&&(o(S.key),Y=""+S.key),"key"in S){M={};for(var se in S)se!=="key"&&(M[se]=S[se])}else M=S;return Y&&E(M,typeof r=="function"?r.displayName||r.name||"Unknown":r),k(r,Y,M,s(),le,oe)}function v(r){N(r)?r._store&&(r._store.validated=1):typeof r=="object"&&r!==null&&r.$$typeof===f&&(r._payload.status==="fulfilled"?N(r._payload.value)&&r._payload.value._store&&(r._payload.value._store.validated=1):r._store&&(r._store.validated=1))}function N(r){return typeof r=="object"&&r!==null&&r.$$typeof===C}var F=i,C=Symbol.for("react.transitional.element"),I=Symbol.for("react.portal"),V=Symbol.for("react.fragment"),z=Symbol.for("react.strict_mode"),L=Symbol.for("react.profiler"),G=Symbol.for("react.consumer"),q=Symbol.for("react.context"),p=Symbol.for("react.forward_ref"),n=Symbol.for("react.suspense"),d=Symbol.for("react.suspense_list"),a=Symbol.for("react.memo"),f=Symbol.for("react.lazy"),T=Symbol.for("react.activity"),j=Symbol.for("react.client.reference"),c=F.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,P=Object.prototype.hasOwnProperty,h=Array.isArray,b=console.createTask?console.createTask:function(){return null};F={react_stack_bottom_frame:function(r){return r()}};var w,y={},$=F.react_stack_bottom_frame.bind(F,m)(),U=b(x(m)),D={};Z.Fragment=V,Z.jsx=function(r,S,M){var R=1e4>c.recentlyCreatedOwnerStacks++;return O(r,S,M,!1,R?Error("react-stack-top-frame"):$,R?b(x(r)):U)},Z.jsxs=function(r,S,M){var R=1e4>c.recentlyCreatedOwnerStacks++;return O(r,S,M,!0,R?Error("react-stack-top-frame"):$,R?b(x(r)):U)}})()),Z}var ue;function Ee(){return ue||(ue=1,process.env.NODE_ENV==="production"?te.exports=he():te.exports=Fe()),te.exports}var t=Ee();const B=({label:e,description:l,collapsible:o=!1,collapsed:x=!1,columns:s=1,children:m,className:g,gridClassName:E})=>{const[A,k]=i.useState(x),O={1:"grid-cols-1",2:"grid-cols-1 md:grid-cols-2",3:"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",4:"grid-cols-1 md:grid-cols-2 lg:grid-cols-4"},v=()=>{o&&k(!A)};return t.jsxs("div",{className:u.cn("form-section",g),children:[(e||l)&&t.jsxs("div",{className:u.cn("flex items-start gap-2 mb-4",o&&"cursor-pointer select-none"),onClick:v,role:o?"button":void 0,"aria-expanded":o?!A:void 0,children:[o&&t.jsx("span",{className:"mt-0.5 text-muted-foreground",children:A?t.jsx(J.ChevronRight,{className:"h-4 w-4"}):t.jsx(J.ChevronDown,{className:"h-4 w-4"})}),t.jsxs("div",{className:"flex-1",children:[e&&t.jsx("h3",{className:"text-base font-semibold text-foreground",children:e}),l&&t.jsx("p",{className:"text-sm text-muted-foreground mt-0.5",children:l})]})]}),!A&&t.jsx("div",{className:u.cn("grid gap-4",E||O[s]),children:m})]})},ce=({schema:e,dataSource:l,className:o})=>{const{fieldLabel:x}=H.useSafeFieldLabel(),[s,m]=i.useState(null),[g,E]=i.useState({}),[A,k]=i.useState(!0),[O,v]=i.useState(null),[N,F]=i.useState(e.defaultTab||e.sections[0]?.name||e.sections[0]?.label||"tab-0");i.useEffect(()=>{(async()=>{if(!l){k(!1);return}try{const n=await l.getObjectSchema(e.objectName);m(n)}catch(n){v(n)}})()},[e.objectName,l]),i.useEffect(()=>{(s||!l)&&(async()=>{if(e.mode==="create"||!e.recordId||!l){E(e.initialData||e.initialValues||{}),k(!1);return}try{const n=await l.findOne(e.objectName,e.recordId);E(n||{})}catch(n){v(n)}finally{k(!1)}})()},[s,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const C=i.useCallback(p=>{const n=[];for(const d of p.fields){const a=typeof d=="string"?d:d.name;if(typeof d=="object")n.push(d);else if(s?.fields?.[a]){const f=s.fields[a];n.push({name:a,label:x(e.objectName,a,f.label||a),type:W.mapFieldTypeToFormType(f.type),required:f.required||!1,disabled:e.readOnly||e.mode==="view"||f.readonly,placeholder:f.placeholder,description:f.help||f.description,validation:W.buildValidationRules(f),field:f,options:f.options,multiple:f.multiple})}else n.push({name:a,label:a,type:"input"})}return n},[s,e.readOnly,e.mode]),I=i.useCallback(async p=>{if(!l)return e.onSuccess&&await e.onSuccess(p),p;try{let n;return e.mode==="create"?n=await l.create(e.objectName,p):e.mode==="edit"&&e.recordId&&(n=await l.update(e.objectName,e.recordId,p)),e.onSuccess&&await e.onSuccess(n),n}catch(n){throw e.onError&&e.onError(n),n}},[e,l]),V=i.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),z=(p,n)=>p.name||p.label||`tab-${n}`;if(O)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:O.message})]});if(A)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const G={type:"form",fields:e.sections.flatMap(p=>C(p)),layout:"vertical",defaultValues:g,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:I,onCancel:V},q=e.tabPosition==="left"||e.tabPosition==="right";return t.jsx("div",{className:u.cn("w-full",o,e.className),children:t.jsxs(u.Tabs,{value:N,onValueChange:F,orientation:q?"vertical":"horizontal",className:u.cn(q&&"flex gap-4"),children:[t.jsx(u.TabsList,{className:u.cn(q?"flex-col h-auto":"",e.tabPosition==="bottom"&&"order-last",e.tabPosition==="right"&&"order-last"),children:e.sections.map((p,n)=>t.jsx(u.TabsTrigger,{value:z(p,n),className:q?"w-full justify-start":"",children:p.label||`Tab ${n+1}`},z(p,n)))}),t.jsx("div",{className:"flex-1",children:e.sections.map((p,n)=>t.jsx(u.TabsContent,{value:z(p,n),className:"mt-0",children:t.jsx(B,{description:p.description,columns:p.columns||1,children:t.jsx(H.SchemaRenderer,{schema:{...G,fields:C(p),showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1}})})},z(p,n)))})]})})},fe=({schema:e,dataSource:l,className:o})=>{const{fieldLabel:x}=H.useSafeFieldLabel(),[s,m]=i.useState(null),[g,E]=i.useState({}),[A,k]=i.useState(!0),[O,v]=i.useState(null),[N,F]=i.useState(0),[C,I]=i.useState(new Set),[V,z]=i.useState(!1),L=e.sections.length,G=N===0,q=N===L-1;i.useEffect(()=>{(async()=>{if(!l){k(!1);return}try{const h=await l.getObjectSchema(e.objectName);m(h)}catch(h){v(h)}})()},[e.objectName,l]),i.useEffect(()=>{(s||!l)&&(async()=>{if(e.mode==="create"||!e.recordId||!l){E(e.initialData||e.initialValues||{}),k(!1);return}try{const h=await l.findOne(e.objectName,e.recordId);E(h||{})}catch(h){v(h)}finally{k(!1)}})()},[s,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const p=i.useCallback(P=>{const h=[];for(const b of P.fields){const w=typeof b=="string"?b:b.name;if(typeof b=="object")h.push(b);else if(s?.fields?.[w]){const y=s.fields[w];h.push({name:w,label:x(e.objectName,w,y.label||w),type:W.mapFieldTypeToFormType(y.type),required:y.required||!1,disabled:e.readOnly||e.mode==="view"||y.readonly,placeholder:y.placeholder,description:y.help||y.description,validation:W.buildValidationRules(y),field:y,options:y.options,multiple:y.multiple})}else h.push({name:w,label:w,type:"input"})}return h},[s,e.readOnly,e.mode]),n=i.useMemo(()=>N>=0&&N<L?p(e.sections[N]):[],[N,L,e.sections,p]),d=i.useCallback(async P=>{const h={...g,...P};if(E(h),I(b=>new Set(b).add(N)),q){z(!0);try{if(!l)return e.onSuccess&&await e.onSuccess(h),h;let b;return e.mode==="create"?b=await l.create(e.objectName,h):e.mode==="edit"&&e.recordId&&(b=await l.update(e.objectName,e.recordId,h)),e.onSuccess&&await e.onSuccess(b),b}catch(b){throw e.onError&&e.onError(b),b}finally{z(!1)}}else a(N+1)},[g,N,q,e,l]),a=i.useCallback(P=>{P>=0&&P<L&&(F(P),e.onStepChange&&e.onStepChange(P))},[L,e]),f=i.useCallback(()=>{a(N-1)},[N,a]),T=i.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),j=i.useCallback(P=>{(e.allowSkip||C.has(P)||P<=N)&&a(P)},[e.allowSkip,C,N,a]);if(O)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:O.message})]});if(A)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const c=e.sections[N];return t.jsxs("div",{className:u.cn("w-full",o,e.className),children:[e.showStepIndicator!==!1&&t.jsx("nav",{"aria-label":"Progress",className:"mb-8",children:t.jsx("ol",{className:"flex items-center",children:e.sections.map((P,h)=>{const b=h===N,w=C.has(h),y=e.allowSkip||w||h<=N;return t.jsxs("li",{className:u.cn("relative flex-1",h!==L-1&&"pr-8 sm:pr-12"),children:[h!==L-1&&t.jsx("div",{className:"absolute top-3 sm:top-4 left-6 -right-4 sm:left-10 sm:-right-2 h-0.5","aria-hidden":"true",children:t.jsx("div",{className:u.cn("h-full",w?"bg-primary":"bg-muted")})}),t.jsxs("button",{type:"button",className:u.cn("group relative flex items-center",y?"cursor-pointer":"cursor-not-allowed"),onClick:()=>j(h),disabled:!y,children:[t.jsx("span",{className:u.cn("flex h-6 w-6 sm:h-8 sm:w-8 items-center justify-center rounded-full text-xs sm:text-sm font-medium transition-colors",w&&"bg-primary text-primary-foreground",b&&!w&&"border-2 border-primary bg-background text-primary",!b&&!w&&"border-2 border-muted bg-background text-muted-foreground"),children:w?t.jsx(J.Check,{className:"h-3 w-3 sm:h-4 sm:w-4"}):h+1}),t.jsx("span",{className:"ml-2 sm:ml-3 text-xs sm:text-sm font-medium hidden sm:block",children:t.jsx("span",{className:u.cn(b?"text-foreground":"text-muted-foreground"),children:P.label||`Step ${h+1}`})})]})]},h)})})}),t.jsx("div",{className:"min-h-[200px]",children:c&&t.jsx(B,{label:c.label,description:c.description,columns:c.columns||1,children:n.length>0?t.jsx(H.SchemaRenderer,{schema:{type:"form",fields:n,layout:"vertical",defaultValues:g,showSubmit:!1,showCancel:!1,onSubmit:d}}):t.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No fields configured for this step"})})}),t.jsxs("div",{className:"flex items-center justify-between mt-6 pt-4 border-t",children:[t.jsx("div",{children:e.showCancel!==!1&&t.jsx(u.Button,{variant:"ghost",onClick:T,children:e.cancelText||"Cancel"})}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsxs("span",{className:"text-sm text-muted-foreground mr-2",children:["Step ",N+1," of ",L]}),!G&&t.jsxs(u.Button,{variant:"outline",onClick:f,children:[t.jsx(J.ChevronLeft,{className:"h-4 w-4 mr-1"}),e.prevText||"Back"]}),q?t.jsx(u.Button,{onClick:()=>d(g),disabled:V||e.mode==="view",children:V?"Submitting...":e.submitText||(e.mode==="create"?"Create":"Update")}):t.jsxs(u.Button,{onClick:()=>d(g),children:[e.nextText||"Next",t.jsx(J.ChevronRight,{className:"h-4 w-4 ml-1"})]})]})]})]})},be=({schema:e,dataSource:l,className:o})=>{const{fieldLabel:x}=H.useSafeFieldLabel(),[s,m]=i.useState(null),[g,E]=i.useState({}),[A,k]=i.useState(!0),[O,v]=i.useState(null);i.useEffect(()=>{(async()=>{if(!l){k(!1);return}try{const n=await l.getObjectSchema(e.objectName);m(n)}catch(n){v(n),k(!1)}})()},[e.objectName,l]),i.useEffect(()=>{(s||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){E(e.initialData||e.initialValues||{}),k(!1);return}if(!l){E(e.initialData||e.initialValues||{}),k(!1);return}try{const n=await l.findOne(e.objectName,e.recordId);E(n||{})}catch(n){v(n)}finally{k(!1)}})()},[s,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const N=i.useCallback(p=>{const n=[];for(const d of p.fields){const a=typeof d=="string"?d:d.name;if(typeof d=="object")n.push(d);else if(s?.fields?.[a]){const f=s.fields[a];n.push({name:a,label:x(e.objectName,a,f.label||a),type:W.mapFieldTypeToFormType(f.type),required:f.required||!1,disabled:e.readOnly||e.mode==="view"||f.readonly,placeholder:f.placeholder,description:f.help||f.description,validation:W.buildValidationRules(f),field:f,options:f.options,multiple:f.multiple})}else n.push({name:a,label:a,type:"input"})}return n},[s,e.readOnly,e.mode]),F=i.useCallback(async p=>{if(!l)return e.onSuccess&&await e.onSuccess(p),p;try{let n;return e.mode==="create"?n=await l.create(e.objectName,p):e.mode==="edit"&&e.recordId&&(n=await l.update(e.objectName,e.recordId,p)),e.onSuccess&&await e.onSuccess(n),n}catch(n){throw e.onError&&e.onError(n),n}},[e,l]),C=i.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),I=i.useMemo(()=>e.sections.slice(0,1),[e.sections]),V=i.useMemo(()=>e.sections.slice(1),[e.sections]);i.useMemo(()=>e.sections.flatMap(p=>N(p)),[e.sections,N]);const z=e.splitDirection||"horizontal",L=e.splitSize||50;if(O)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:O.message})]});if(A)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const G={type:"form",layout:"vertical",defaultValues:g,onSubmit:F,onCancel:C},q=(p,n)=>t.jsx("div",{className:"space-y-4 p-4",children:p.map((d,a)=>t.jsx(B,{label:d.label,description:d.description,columns:d.columns||1,children:t.jsx(H.SchemaRenderer,{schema:{...G,fields:N(d),showSubmit:n&&e.showSubmit!==!1&&e.mode!=="view",showCancel:n&&e.showCancel!==!1,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText}})},d.name||d.label||a))});return t.jsx("div",{className:u.cn("w-full",o,e.className),children:t.jsxs(u.ResizablePanelGroup,{orientation:z,className:"min-h-[300px] rounded-lg border",children:[t.jsx(u.ResizablePanel,{defaultSize:L,minSize:20,children:q(I,V.length===0)}),V.length>0&&t.jsxs(t.Fragment,{children:[t.jsx(u.ResizableHandle,{withHandle:e.splitResizable!==!1}),t.jsx(u.ResizablePanel,{defaultSize:100-L,minSize:20,children:q(V,!0)})]})]})})},ke=new Set(["field:textarea","field:markdown","field:html","field:grid","field:rich-text","textarea","markdown","html","grid","rich-text"]),Oe=new Set(["formula","summary","auto_number","autonumber"]);function pe(e){return ke.has(e)}function me(e){return Oe.has(e)}function ye(e){return e<=3?1:2}function re(e,l){return l<=1?e:e.map(o=>o.colSpan!==void 0?o:o.type&&pe(o.type)?{...o,colSpan:l}:o)}function xe(e,l){return l?.fields?e.filter(o=>{const x=l.fields[o.name];return x?!me(x.type):!0}):e}function ie(e){return e<=1?"default":e===2?"lg":e===3?"xl":"full"}function K(e,l,o,x){let s=[...e];if(x==="create"&&(s=xe(s,l)),o!==void 0)return s=re(s,o),{fields:s,columns:o};const m=ye(s.length);return s=re(s,m),{fields:s,columns:m}}const ge={1:void 0,2:"grid gap-4 grid-cols-1 @md:grid-cols-2",3:"grid gap-4 grid-cols-1 @md:grid-cols-2 @2xl:grid-cols-3",4:"grid gap-4 grid-cols-1 @md:grid-cols-2 @2xl:grid-cols-3 @4xl:grid-cols-4"},je=({schema:e,dataSource:l,className:o})=>{const{fieldLabel:x}=H.useSafeFieldLabel(),[s,m]=i.useState(null),[g,E]=i.useState([]),[A,k]=i.useState({}),[O,v]=i.useState(!0),[N,F]=i.useState(null),C=e.open!==!1,I=e.drawerSide||"right";i.useEffect(()=>{(async()=>{if(!l){v(!1);return}try{const a=await l.getObjectSchema(e.objectName);m(a)}catch(a){F(a),v(!1)}})()},[e.objectName,l]),i.useEffect(()=>{(s||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){k(e.initialData||e.initialValues||{}),v(!1);return}if(!l){k(e.initialData||e.initialValues||{}),v(!1);return}try{const a=await l.findOne(e.objectName,e.recordId);k(a||{})}catch(a){F(a)}finally{v(!1)}})()},[s,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const V=i.useCallback(d=>{const a=[];for(const f of d.fields){const T=typeof f=="string"?f:f.name;if(typeof f=="object")a.push(f);else if(s?.fields?.[T]){const j=s.fields[T];a.push({name:T,label:x(e.objectName,T,j.label||T),type:W.mapFieldTypeToFormType(j.type),required:j.required||!1,disabled:e.readOnly||e.mode==="view"||j.readonly,placeholder:j.placeholder,description:j.help||j.description,validation:W.buildValidationRules(j),field:j,options:j.options,multiple:j.multiple})}else a.push({name:T,label:T,type:"input"})}return a},[s,e.readOnly,e.mode]);i.useEffect(()=>{if(!s&&l)return;if(e.customFields?.length){E(e.customFields),v(!1);return}if(e.sections?.length){v(!1);return}if(!s)return;const d=e.fields||Object.keys(s.fields||{}),a=[];for(const f of d){const T=typeof f=="string"?f:f.name;if(!T)continue;const j=s.fields?.[T];j&&a.push({name:T,label:x(e.objectName,T,j.label||T),type:W.mapFieldTypeToFormType(j.type),required:j.required||!1,disabled:e.readOnly||e.mode==="view"||j.readonly,placeholder:j.placeholder,description:j.help||j.description,validation:W.buildValidationRules(j),field:j,options:j.options,multiple:j.multiple})}E(a),v(!1)},[s,e.fields,e.customFields,e.sections,e.readOnly,e.mode,l]);const z=i.useCallback(async d=>{if(!l)return e.onSuccess&&await e.onSuccess(d),e.onOpenChange?.(!1),d;try{let a;return e.mode==="create"?a=await l.create(e.objectName,d):e.mode==="edit"&&e.recordId&&(a=await l.update(e.objectName,e.recordId,d)),e.onSuccess&&await e.onSuccess(a),e.onOpenChange?.(!1),a}catch(a){throw e.onError&&e.onError(a),a}},[e,l]),L=i.useCallback(()=>{e.onCancel&&e.onCancel(),e.onOpenChange?.(!1)},[e]),G=i.useMemo(()=>e.drawerWidth?I==="left"||I==="right"?{width:e.drawerWidth,maxWidth:e.drawerWidth}:{height:e.drawerWidth,maxHeight:e.drawerWidth}:void 0,[e.drawerWidth,I]),p={type:"form",layout:e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical",defaultValues:A,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:z,onCancel:L},n=()=>{if(N)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:N.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});if(e.sections?.length)return t.jsx("div",{className:"space-y-6",children:e.sections.map((f,T)=>{const j=f.columns||1;return t.jsx(B,{label:f.label,description:f.description,columns:j,gridClassName:ge[j],children:t.jsx(H.SchemaRenderer,{schema:{...p,fields:V(f),showSubmit:T===e.sections.length-1&&p.showSubmit,showCancel:T===e.sections.length-1&&p.showCancel}})},f.name||f.label||T)})});const d=K(g,s,e.columns,e.mode),a=ge[d.columns||1];return t.jsx(H.SchemaRenderer,{schema:{...p,fields:d.fields,columns:d.columns,...a?{fieldContainerClass:a}:{}}})};return t.jsx(u.Sheet,{open:C,onOpenChange:e.onOpenChange,children:t.jsxs(u.SheetContent,{side:I,className:u.cn("overflow-y-auto",o,e.className),style:G,children:[(e.title||e.description)&&t.jsxs(u.SheetHeader,{children:[e.title&&t.jsx(u.SheetTitle,{children:e.title}),e.description&&t.jsx(u.SheetDescription,{children:e.description})]}),t.jsx("div",{className:"@container py-4",children:n()})]})})},we={sm:"max-w-sm",default:"max-w-lg",lg:"max-w-2xl",xl:"max-w-4xl",full:"max-w-[95vw] w-full"},Ne={1:void 0,2:"grid gap-4 grid-cols-1 @md:grid-cols-2",3:"grid gap-4 grid-cols-1 @md:grid-cols-2 @2xl:grid-cols-3",4:"grid gap-4 grid-cols-1 @md:grid-cols-2 @2xl:grid-cols-3 @4xl:grid-cols-4"},Se=({schema:e,dataSource:l,className:o})=>{const{fieldLabel:x}=H.useSafeFieldLabel(),[s,m]=i.useState(null),[g,E]=i.useState([]),[A,k]=i.useState({}),[O,v]=i.useState(!0),[N,F]=i.useState(null),[C,I]=i.useState(!1),V=e.open!==!1,z=i.useId(),L=i.useMemo(()=>e.sections?.length||e.customFields?.length?null:K(g,s,e.columns,e.mode),[g,s,e.columns,e.mode,e.sections,e.customFields]),G=i.useMemo(()=>{if(e.modalSize)return e.modalSize;if(L?.columns&&L.columns>1)return ie(L.columns);if(e.sections?.length){const w=Math.max(...e.sections.map(y=>Number(y.columns)||1));if(w>1)return ie(w)}return"default"},[e.modalSize,L,e.sections]),q=we[G]||we.default;i.useEffect(()=>{(async()=>{if(!l){v(!1);return}try{const y=await l.getObjectSchema(e.objectName);m(y)}catch(y){F(y),v(!1)}})()},[e.objectName,l]),i.useEffect(()=>{(s||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){k(e.initialData||e.initialValues||{}),v(!1);return}if(!l){k(e.initialData||e.initialValues||{}),v(!1);return}try{const y=await l.findOne(e.objectName,e.recordId);k(y||{})}catch(y){F(y)}finally{v(!1)}})()},[s,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const p=i.useCallback(w=>{const y=[];for(const $ of w.fields){const U=typeof $=="string"?$:$.name;if(typeof $=="object")y.push($);else if(s?.fields?.[U]){const D=s.fields[U];y.push({name:U,label:x(e.objectName,U,D.label||U),type:W.mapFieldTypeToFormType(D.type),required:D.required||!1,disabled:e.readOnly||e.mode==="view"||D.readonly,placeholder:D.placeholder,description:D.help||D.description,validation:W.buildValidationRules(D),field:D,options:D.options,multiple:D.multiple})}else y.push({name:U,label:U,type:"input"})}return y},[s,e.readOnly,e.mode]);i.useEffect(()=>{if(!s&&l)return;if(e.customFields?.length){E(e.customFields),v(!1);return}if(e.sections?.length){v(!1);return}if(!s)return;const w=e.fields||Object.keys(s.fields||{}),y=[];for(const $ of w){const U=typeof $=="string"?$:$.name;if(!U)continue;const D=s.fields?.[U];D&&y.push({name:U,label:x(e.objectName,U,D.label||U),type:W.mapFieldTypeToFormType(D.type),required:D.required||!1,disabled:e.readOnly||e.mode==="view"||D.readonly,placeholder:D.placeholder,description:D.help||D.description,validation:W.buildValidationRules(D),field:D,options:D.options,multiple:D.multiple})}E(y),v(!1)},[s,e.fields,e.customFields,e.sections,e.readOnly,e.mode,l]);const n=i.useCallback(async w=>{I(!0);try{if(!l)return e.onSuccess&&await e.onSuccess(w),e.onOpenChange?.(!1),w;let y;return e.mode==="create"?y=await l.create(e.objectName,w):e.mode==="edit"&&e.recordId&&(y=await l.update(e.objectName,e.recordId,w)),e.onSuccess&&await e.onSuccess(y),e.onOpenChange?.(!1),y}catch(y){throw e.onError&&e.onError(y),y}finally{I(!1)}},[e,l]),d=i.useCallback(()=>{e.onCancel&&e.onCancel(),e.onOpenChange?.(!1)},[e]),a=e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical",f=e.showSubmit!==!1&&e.mode!=="view",T=e.showCancel!==!1,j=e.submitText||(e.mode==="create"?"Create":"Update"),c=e.cancelText||"Cancel",P={type:"form",layout:a,defaultValues:A,submitLabel:j,cancelLabel:c,showSubmit:f,showCancel:T,onSubmit:n,onCancel:d,showActions:!1,id:z},h=()=>{if(N)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:N.message})]});if(O)return t.jsx("div",{className:"space-y-4","data-testid":"modal-form-skeleton",children:[1,2,3].map($=>t.jsxs("div",{className:"space-y-2",children:[t.jsx(u.Skeleton,{className:"h-4 w-24"}),t.jsx(u.Skeleton,{className:"h-10 w-full"})]},$))});if(e.sections?.length)return t.jsx("div",{className:"space-y-6",children:e.sections.map(($,U)=>{const D=$.columns||1;return t.jsx(B,{label:$.label,description:$.description,columns:D,gridClassName:Ne[D],children:t.jsx(H.SchemaRenderer,{schema:{...P,fields:p($)}})},$.name||$.label||U)})});const w=L??K(g,s,e.columns,e.mode),y=Ne[w.columns||1];return t.jsx(H.SchemaRenderer,{schema:{...P,fields:w.fields,columns:w.columns,...y?{fieldContainerClass:y}:{}}})},b=!O&&!N&&(f||T);return t.jsx(u.Dialog,{open:V,onOpenChange:e.onOpenChange,children:t.jsxs(u.MobileDialogContent,{className:u.cn(q,"flex flex-col h-[100dvh] sm:h-auto sm:max-h-[90vh] overflow-hidden p-0",o,e.className),children:[(e.title||e.description)&&t.jsxs(u.DialogHeader,{className:"shrink-0 px-4 pt-4 sm:px-6 sm:pt-6 pb-2 border-b",children:[e.title&&t.jsx(u.DialogTitle,{children:e.title}),e.description&&t.jsx(u.DialogDescription,{children:e.description})]}),t.jsx("div",{className:"@container flex-1 overflow-y-auto px-4 sm:px-6 py-4",children:h()}),b&&t.jsx("div",{className:"shrink-0 border-t px-4 sm:px-6 py-3 bg-background","data-testid":"modal-form-footer",children:t.jsxs("div",{className:"flex flex-col sm:flex-row gap-2 sm:justify-end",children:[T&&t.jsx(u.Button,{type:"button",variant:"outline",onClick:d,disabled:C,className:"w-full sm:w-auto",children:c}),f&&t.jsxs(u.Button,{type:"submit",form:z,disabled:C,className:"w-full sm:w-auto",children:[C&&t.jsx(J.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),j]})]})})]})})},ne=({schema:e,dataSource:l})=>{if(e.formType==="tabbed"&&e.sections?.length)return t.jsx(ce,{schema:{...e,formType:"tabbed",sections:e.sections.map(o=>({name:o.name,label:o.label,description:o.description,columns:o.columns,fields:o.fields})),defaultTab:e.defaultTab,tabPosition:e.tabPosition},dataSource:l,className:e.className});if(e.formType==="wizard"&&e.sections?.length)return t.jsx(fe,{schema:{...e,formType:"wizard",sections:e.sections.map(o=>({name:o.name,label:o.label,description:o.description,columns:o.columns,fields:o.fields})),allowSkip:e.allowSkip,showStepIndicator:e.showStepIndicator,nextText:e.nextText,prevText:e.prevText,onStepChange:e.onStepChange},dataSource:l,className:e.className});if(e.formType==="split"&&e.sections?.length)return t.jsx(be,{schema:{...e,formType:"split",sections:e.sections.map(o=>({name:o.name,label:o.label,description:o.description,columns:o.columns,fields:o.fields})),splitDirection:e.splitDirection,splitSize:e.splitSize,splitResizable:e.splitResizable},dataSource:l,className:e.className});if(e.formType==="drawer"){const{layout:o,...x}=e,s=e.layout==="vertical"||e.layout==="horizontal"?e.layout:void 0;return t.jsx(je,{schema:{...x,layout:s,formType:"drawer",sections:e.sections?.map(m=>({name:m.name,label:m.label,description:m.description,columns:m.columns,fields:m.fields})),open:e.open,onOpenChange:e.onOpenChange,drawerSide:e.drawerSide,drawerWidth:e.drawerWidth},dataSource:l,className:e.className})}if(e.formType==="modal"){const{layout:o,...x}=e,s=e.layout==="vertical"||e.layout==="horizontal"?e.layout:void 0;return t.jsx(Se,{schema:{...x,layout:s,formType:"modal",sections:e.sections?.map(m=>({name:m.name,label:m.label,description:m.description,columns:m.columns,fields:m.fields})),open:e.open,onOpenChange:e.onOpenChange,modalSize:e.modalSize,modalCloseButton:e.modalCloseButton},dataSource:l,className:e.className})}return t.jsx(De,{schema:e,dataSource:l})},De=({schema:e,dataSource:l})=>{const{fieldLabel:o}=H.useSafeFieldLabel(),[x,s]=i.useState(null),[m,g]=i.useState([]),[E,A]=i.useState(null),[k,O]=i.useState(!0),[v,N]=i.useState(null),F=e.customFields&&e.customFields.length>0;i.useEffect(()=>{F&&(A(e.initialData||e.initialValues||{}),O(!1))},[F,e.initialData,e.initialValues]),i.useEffect(()=>{const n=async()=>{try{if(!l)throw new Error("DataSource is required when using ObjectQL schema fetching (inline fields not provided)");const d=await l.getObjectSchema(e.objectName);if(!d)throw new Error(`No schema found for object "${e.objectName}"`);s(d)}catch(d){N(d),O(!1)}};F?s({name:e.objectName,fields:{}}):e.objectName&&l?n():F||O(!1)},[e.objectName,l,F]),i.useEffect(()=>{x&&!F&&(async()=>{if(!e.recordId||e.mode==="create"){A(e.initialData||e.initialValues||{}),O(!1);return}if(!F){if(!l){N(new Error("DataSource is required for fetching record data (inline data not provided)")),O(!1);return}O(!0);try{const d=await l.findOne(e.objectName,e.recordId);A(d)}catch(d){console.error("Failed to fetch record:",d),N(d)}finally{O(!1)}}})()},[e.objectName,e.recordId,e.mode,e.initialValues,e.initialData,l,x,F]),i.useEffect(()=>{if(F&&e.customFields){g(e.customFields),O(!1);return}if(!x)return;const n=[],d=e.fields||Object.keys(x.fields||{});(Array.isArray(d)?d:Object.keys(d)).forEach(T=>{const j=typeof T=="string"?T:T.name;if(!j)return;const c=x.fields?.[j];if(!c&&!F)return;const P=!c?.permissions||c?.permissions.write!==!1;if(e.mode!=="view"&&!P)return;const h=e.customFields?.find(b=>b.name===j);if(h)n.push(h);else if(c){const b={name:j,label:o(e.objectName,j,c.label||T),type:W.mapFieldTypeToFormType(c.type),required:c.required||!1,disabled:e.readOnly||e.mode==="view"||c.readonly,placeholder:c.placeholder,description:c.help||c.description,validation:W.buildValidationRules(c),field:c};if((c.type==="select"||c.type==="lookup"||c.type==="master_detail")&&(b.options=c.options||[],b.multiple=c.multiple),(c.type==="number"||c.type==="currency"||c.type==="percent")&&(b.inputType="number",b.min=c.min,b.max=c.max,b.step=c.precision?Math.pow(10,-c.precision):void 0),c.type==="date"&&(b.inputType="date"),c.type==="datetime"&&(b.inputType="datetime-local"),(c.type==="text"||c.type==="textarea"||c.type==="markdown"||c.type==="html")&&(b.maxLength=c.max_length,b.minLength=c.min_length),(c.type==="file"||c.type==="image")&&(b.inputType="file",b.multiple=c.multiple,b.accept=c.accept?c.accept.join(","):void 0,c.max_size)){const w=`Max size: ${W.formatFileSize(c.max_size)}`;b.description=b.description?`${b.description} (${w})`:w}c.type==="email"&&(b.inputType="email"),c.type==="phone"&&(b.inputType="tel"),c.type==="url"&&(b.inputType="url"),c.type==="password"&&(b.inputType="password"),c.type==="time"&&(b.inputType="time"),(c.type==="formula"||c.type==="summary"||c.type==="auto_number")&&(b.disabled=!0),c.visible_on&&(b.visible=w=>W.evaluateCondition(c.visible_on,w)),n.push(b)}}),g(n),!F&&e.recordId&&e.mode!=="create"&&l||O(!1)},[x,e.fields,e.customFields,e.readOnly,e.mode,F,e.recordId,l]);const C=i.useCallback(async(n,d)=>{if(n&&(n.nativeEvent||n._reactName==="onSubmit")&&(console.warn("ObjectForm: Received Event instead of data in handleSubmit! This suggests a Form renderer issue."),d===void 0&&(d=n,n={})),F&&!l)return e.onSuccess&&await e.onSuccess(n),n;if(!l)throw new Error("DataSource is required for form submission (inline mode not configured)");try{let a;if(e.mode==="create")a=await l.create(e.objectName,n);else if(e.mode==="edit"&&e.recordId)a=await l.update(e.objectName,e.recordId,n);else throw new Error("Invalid form mode or missing record ID");return e.onSuccess&&await e.onSuccess(a),a}catch(a){throw console.error("Failed to submit form:",a),e.onError&&e.onError(a),a}},[e,l,F]),I=i.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),z={...i.useMemo(()=>{if(!x?.fields)return{};const n={};return Object.keys(x.fields).forEach(d=>{const a=x.fields[d];a.defaultValue!==void 0&&(n[d]=a.defaultValue)}),n},[x]),...E};if(v)return t.jsxs("div",{className:"p-3 sm:p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:v.message})]});if(k)return t.jsxs("div",{className:"p-4 sm:p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const L=e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical";if(e.sections?.length&&(!e.formType||e.formType==="simple"))return t.jsx("div",{className:"w-full space-y-6",children:e.sections.map((n,d)=>{const a=n.fields.map(T=>typeof T=="string"?T:T.name),f=m.filter(T=>a.includes(T.name));return t.jsx(B,{label:n.label,description:n.description,collapsible:n.collapsible,collapsed:n.collapsed,columns:n.columns,children:t.jsx(H.SchemaRenderer,{schema:{type:"form",fields:f,layout:L,defaultValues:z,showSubmit:d===e.sections.length-1&&e.showSubmit!==!1&&e.mode!=="view",showCancel:d===e.sections.length-1&&e.showCancel!==!1,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,onSubmit:C,onCancel:I}})},n.name||n.label||d)})});const q=e.sections?.length?{fields:m,columns:e.columns}:K(m,x,e.columns,e.mode),p={type:"form",fields:q.fields,layout:L,columns:q.columns,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,resetOnSubmit:e.showReset,defaultValues:z,onSubmit:C,onCancel:I,className:e.className};return t.jsx("div",{className:"w-full",children:t.jsx(H.SchemaRenderer,{schema:p})})},ve=({config:e,dataSource:l,prefillParams:o,className:x})=>{const[s,m]=i.useState(!1),[g,E]=i.useState(!1),[A,k]=i.useState(null),O=i.useMemo(()=>{const C={};if(o)for(const[I,V]of Object.entries(o))C[I]=V;return typeof window<"u"&&new URLSearchParams(window.location.search).forEach((V,z)=>{z in C||(C[z]=V)}),Object.keys(C).length>0?C:void 0},[o]),v=i.useCallback(async C=>{E(!0),k(null);try{if(l&&await l.create(e.objectName,C),m(!0),e.thankYouPage?.redirectUrl){const I=e.thankYouPage.redirectDelay??3e3;setTimeout(()=>{window.location.href=e.thankYouPage.redirectUrl},I)}}catch(I){k(I instanceof Error?I.message:"Failed to submit form. Please try again.")}finally{E(!1)}},[l,e]),N=i.useCallback(()=>{m(!1),k(null)},[]),F=i.useMemo(()=>{const C={};return e.branding?.backgroundColor&&(C.backgroundColor=e.branding.backgroundColor),C},[e.branding]);if(s){const C=e.thankYouPage;return t.jsx("div",{className:`min-h-screen flex items-center justify-center p-4 ${x||""}`,style:F,children:t.jsxs("div",{className:"max-w-md w-full bg-card rounded-lg shadow-lg p-8 text-center space-y-4",children:[t.jsx("div",{className:"text-4xl",children:"✓"}),t.jsx("h2",{className:"text-xl font-semibold text-foreground",children:C?.title||"Thank You!"}),t.jsx("p",{className:"text-muted-foreground",children:C?.message||"Your submission has been received successfully."}),e.allowMultiple&&t.jsx("button",{onClick:N,className:"mt-4 px-4 py-2 text-sm font-medium rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition-colors",children:"Submit Another Response"}),C?.redirectUrl&&t.jsxs("p",{className:"text-xs text-muted-foreground",children:["Redirecting in ",Math.ceil((C.redirectDelay??3e3)/1e3)," seconds..."]})]})})}return t.jsx("div",{className:`min-h-screen flex items-center justify-center p-4 ${x||""}`,style:F,children:t.jsxs("div",{className:"max-w-2xl w-full bg-card rounded-lg shadow-lg overflow-hidden",children:[t.jsxs("div",{className:"p-6 border-b",style:e.branding?.primaryColor?{borderBottomColor:e.branding.primaryColor}:void 0,children:[e.branding?.logo&&t.jsx("img",{src:e.branding.logo,alt:"Logo",className:"h-8 mb-4"}),e.title&&t.jsx("h1",{className:"text-xl font-semibold text-foreground",children:e.title}),e.description&&t.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:e.description})]}),t.jsxs("div",{className:"p-6",children:[A&&t.jsx("div",{className:"mb-4 p-3 bg-destructive/10 border border-destructive/30 rounded-md text-sm text-destructive",children:A}),t.jsx(ne,{schema:{type:"object-form",objectName:e.objectName,mode:"create",fields:e.fields,customFields:e.customFields,initialData:O,onSuccess:v,submitLabel:g?"Submitting...":"Submit"},dataSource:l})]}),t.jsx("div",{className:"px-6 py-3 border-t bg-muted/20 text-center",children:t.jsx("p",{className:"text-xs text-muted-foreground",children:"Powered by ObjectStack"})})]})})};function _e(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}const Ce=({formId:e,formTitle:l,metrics:o,className:x})=>{const s=i.useMemo(()=>{if(!o.abandonedSubmissions)return 100;const g=o.totalSubmissions+o.abandonedSubmissions;return g===0?0:Math.round(o.totalSubmissions/g*100)},[o.totalSubmissions,o.abandonedSubmissions]),m=i.useMemo(()=>o.dailySubmissions?.length?Math.max(...o.dailySubmissions.map(g=>g.count),1):1,[o.dailySubmissions]);return t.jsxs("div",{className:`space-y-4 ${x||""}`,children:[t.jsxs("div",{children:[t.jsx("h2",{className:"text-lg font-semibold text-foreground",children:l||"Form Analytics"}),t.jsxs("p",{className:"text-sm text-muted-foreground",children:["Form ID: ",e]})]}),t.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[t.jsx(u.Card,{children:t.jsxs(u.CardHeader,{className:"pb-2",children:[t.jsx(u.CardDescription,{children:"Total Submissions"}),t.jsx(u.CardTitle,{className:"text-2xl",children:o.totalSubmissions.toLocaleString()})]})}),t.jsxs(u.Card,{children:[t.jsxs(u.CardHeader,{className:"pb-2",children:[t.jsx(u.CardDescription,{children:"Fill Rate"}),t.jsxs(u.CardTitle,{className:"text-2xl",children:[s,"%"]})]}),t.jsx(u.CardContent,{children:t.jsx("div",{className:"w-full bg-muted rounded-full h-2",children:t.jsx("div",{className:"bg-primary rounded-full h-2 transition-all",style:{width:`${s}%`}})})})]}),t.jsx(u.Card,{children:t.jsxs(u.CardHeader,{className:"pb-2",children:[t.jsx(u.CardDescription,{children:"Avg. Completion Time"}),t.jsx(u.CardTitle,{className:"text-2xl",children:o.avgCompletionTime?_e(o.avgCompletionTime):"—"})]})})]}),o.dailySubmissions&&o.dailySubmissions.length>0&&t.jsxs(u.Card,{children:[t.jsx(u.CardHeader,{children:t.jsx(u.CardTitle,{className:"text-sm font-medium",children:"Daily Submissions"})}),t.jsx(u.CardContent,{children:t.jsx("div",{className:"flex items-end gap-1 h-32",children:o.dailySubmissions.map((g,E)=>t.jsxs("div",{className:"flex-1 flex flex-col items-center gap-1",children:[t.jsx("div",{className:"w-full bg-primary/80 rounded-t transition-all hover:bg-primary",style:{height:`${g.count/m*100}%`,minHeight:g.count>0?"4px":"0"},title:`${g.date}: ${g.count} submissions`}),t.jsx("span",{className:"text-[10px] text-muted-foreground truncate w-full text-center",children:g.date.slice(-5)})]},E))})})]}),o.fieldDropOff&&o.fieldDropOff.length>0&&t.jsxs(u.Card,{children:[t.jsxs(u.CardHeader,{children:[t.jsx(u.CardTitle,{className:"text-sm font-medium",children:"Field Completion Rates"}),t.jsx(u.CardDescription,{children:"Percentage of users who completed each field"})]}),t.jsx(u.CardContent,{children:t.jsx("div",{className:"space-y-3",children:o.fieldDropOff.map((g,E)=>t.jsxs("div",{className:"space-y-1",children:[t.jsxs("div",{className:"flex justify-between text-sm",children:[t.jsx("span",{className:"text-foreground",children:g.label}),t.jsxs("span",{className:"text-muted-foreground",children:[g.completionRate,"%"]})]}),t.jsx("div",{className:"w-full bg-muted rounded-full h-1.5",children:t.jsx("div",{className:`rounded-full h-1.5 transition-all ${g.completionRate>=80?"bg-green-500":g.completionRate>=50?"bg-yellow-500":"bg-destructive"}`,style:{width:`${g.completionRate}%`}})})]},E))})})]})]})},Te=({schema:e})=>t.jsx(ne,{schema:e});ee.ComponentRegistry.register("object-form",Te,{namespace:"plugin-form",label:"Object Form",category:"plugin",inputs:[{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"fields",type:"array",label:"Fields"},{name:"mode",type:"enum",label:"Mode",enum:["create","edit","view"]},{name:"formType",type:"enum",label:"Form Type",enum:["simple","tabbed","wizard","split","drawer","modal"]},{name:"sections",type:"array",label:"Sections"},{name:"title",type:"string",label:"Title"},{name:"description",type:"string",label:"Description"},{name:"layout",type:"enum",label:"Layout",enum:["vertical","horizontal","inline","grid"]},{name:"columns",type:"number",label:"Columns"},{name:"defaultTab",type:"string",label:"Default Tab"},{name:"tabPosition",type:"enum",label:"Tab Position",enum:["top","bottom","left","right"]},{name:"allowSkip",type:"boolean",label:"Allow Skip Steps"},{name:"showStepIndicator",type:"boolean",label:"Show Step Indicator"},{name:"splitDirection",type:"enum",label:"Split Direction",enum:["horizontal","vertical"]},{name:"splitSize",type:"number",label:"Split Panel Size (%)"},{name:"splitResizable",type:"boolean",label:"Split Resizable"},{name:"drawerSide",type:"enum",label:"Drawer Side",enum:["top","bottom","left","right"]},{name:"drawerWidth",type:"string",label:"Drawer Width"},{name:"modalSize",type:"enum",label:"Modal Size",enum:["sm","default","lg","xl","full"]}]}),ee.ComponentRegistry.register("form",Te,{namespace:"view",skipFallback:!0,label:"Data Form View",category:"view",inputs:[{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"fields",type:"array",label:"Fields"},{name:"mode",type:"enum",label:"Mode",enum:["create","edit","view"]}]});const Ie=({schema:e})=>t.jsx(ve,{config:e});ee.ComponentRegistry.register("embeddable-form",Ie,{namespace:"plugin-form",label:"Embeddable Form",category:"plugin",inputs:[{name:"formId",type:"string",label:"Form ID",required:!0},{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"title",type:"string",label:"Form Title"},{name:"description",type:"string",label:"Description"},{name:"fields",type:"array",label:"Fields"},{name:"allowMultiple",type:"boolean",label:"Allow Multiple Submissions"}]});const Le=({schema:e})=>t.jsx(Ce,{formId:e.formId,formTitle:e.formTitle,metrics:e.metrics||{totalSubmissions:0}});ee.ComponentRegistry.register("form-analytics",Le,{namespace:"plugin-form",label:"Form Analytics",category:"plugin",inputs:[{name:"formId",type:"string",label:"Form ID",required:!0},{name:"formTitle",type:"string",label:"Form Title"},{name:"metrics",type:"object",label:"Submission Metrics"}]}),_.DrawerForm=je,_.EmbeddableForm=ve,_.FormAnalytics=Ce,_.FormSection=B,_.ModalForm=Se,_.ObjectForm=ne,_.SplitForm=be,_.TabbedForm=ce,_.WizardForm=fe,_.applyAutoColSpan=re,_.applyAutoLayout=K,_.filterCreateModeFields=xe,_.inferColumns=ye,_.inferModalSize=ie,_.isAutoGeneratedFieldType=me,_.isWideFieldType=pe,Object.defineProperty(_,Symbol.toStringTag,{value:"Module"})}));
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { DataSource, FormField } from '../../types/src';
|
|
3
|
+
export interface EmbeddableFormConfig {
|
|
4
|
+
/** Unique form ID */
|
|
5
|
+
formId: string;
|
|
6
|
+
/** Object name to create records in */
|
|
7
|
+
objectName: string;
|
|
8
|
+
/** Form title displayed at the top */
|
|
9
|
+
title?: string;
|
|
10
|
+
/** Form description / instructions */
|
|
11
|
+
description?: string;
|
|
12
|
+
/** Fields to include in the form (subset of object fields) */
|
|
13
|
+
fields?: string[];
|
|
14
|
+
/** Custom field definitions for inline forms */
|
|
15
|
+
customFields?: FormField[];
|
|
16
|
+
/** Branding configuration */
|
|
17
|
+
branding?: {
|
|
18
|
+
logo?: string;
|
|
19
|
+
primaryColor?: string;
|
|
20
|
+
backgroundColor?: string;
|
|
21
|
+
};
|
|
22
|
+
/** Thank you page configuration */
|
|
23
|
+
thankYouPage?: {
|
|
24
|
+
title?: string;
|
|
25
|
+
message?: string;
|
|
26
|
+
redirectUrl?: string;
|
|
27
|
+
redirectDelay?: number;
|
|
28
|
+
};
|
|
29
|
+
/** Allow multiple submissions */
|
|
30
|
+
allowMultiple?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface EmbeddableFormProps {
|
|
33
|
+
/** Form configuration */
|
|
34
|
+
config: EmbeddableFormConfig;
|
|
35
|
+
/** Data source for creating records */
|
|
36
|
+
dataSource?: DataSource;
|
|
37
|
+
/** URL search parameters for prefilling fields */
|
|
38
|
+
prefillParams?: Record<string, string>;
|
|
39
|
+
/** Additional CSS class */
|
|
40
|
+
className?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* EmbeddableForm — Standalone form for external data collection.
|
|
44
|
+
*
|
|
45
|
+
* Can be rendered at a public URL (e.g., `/forms/:formId`) without auth.
|
|
46
|
+
* Submissions create records in the specified object via DataSource.
|
|
47
|
+
*/
|
|
48
|
+
export declare const EmbeddableForm: React.FC<EmbeddableFormProps>;
|
|
49
|
+
export default EmbeddableForm;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface FormSubmissionMetric {
|
|
3
|
+
/** Total number of form submissions */
|
|
4
|
+
totalSubmissions: number;
|
|
5
|
+
/** Number of forms started but not completed */
|
|
6
|
+
abandonedSubmissions?: number;
|
|
7
|
+
/** Average time to complete form in seconds */
|
|
8
|
+
avgCompletionTime?: number;
|
|
9
|
+
/** Submissions per day over the last N days */
|
|
10
|
+
dailySubmissions?: Array<{
|
|
11
|
+
date: string;
|
|
12
|
+
count: number;
|
|
13
|
+
}>;
|
|
14
|
+
/** Field-level drop-off data */
|
|
15
|
+
fieldDropOff?: Array<{
|
|
16
|
+
fieldName: string;
|
|
17
|
+
label: string;
|
|
18
|
+
completionRate: number;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
export interface FormAnalyticsProps {
|
|
22
|
+
/** Form identifier */
|
|
23
|
+
formId: string;
|
|
24
|
+
/** Form title */
|
|
25
|
+
formTitle?: string;
|
|
26
|
+
/** Submission metrics data */
|
|
27
|
+
metrics: FormSubmissionMetric;
|
|
28
|
+
/** Additional CSS class */
|
|
29
|
+
className?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* FormAnalytics — Basic form analytics dashboard showing submission metrics.
|
|
33
|
+
*
|
|
34
|
+
* Displays fill rate, completion time, and field-level drop-off data
|
|
35
|
+
* for embeddable forms and data collection workflows.
|
|
36
|
+
*/
|
|
37
|
+
export declare const FormAnalytics: React.FC<FormAnalyticsProps>;
|
|
38
|
+
export default FormAnalytics;
|
|
@@ -31,6 +31,12 @@ export interface FormSectionProps {
|
|
|
31
31
|
* Additional CSS classes
|
|
32
32
|
*/
|
|
33
33
|
className?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Override the default responsive grid classes.
|
|
36
|
+
* When provided, replaces the viewport-based grid-cols classes
|
|
37
|
+
* (e.g. with container-query-based classes like `@md:grid-cols-2`).
|
|
38
|
+
*/
|
|
39
|
+
gridClassName?: string;
|
|
34
40
|
}
|
|
35
41
|
/**
|
|
36
42
|
* FormSection Component
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { FormField } from '../../types/src';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a field type is "wide" (should span full row in multi-column layout).
|
|
4
|
+
*/
|
|
5
|
+
export declare function isWideFieldType(type: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Check if an object field type is auto-generated (formula, summary, auto_number).
|
|
8
|
+
*/
|
|
9
|
+
export declare function isAutoGeneratedFieldType(type: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Infer optimal number of columns based on the number of visible fields
|
|
12
|
+
* and whether any wide fields are present.
|
|
13
|
+
*
|
|
14
|
+
* Rules:
|
|
15
|
+
* - 0-3 fields → 1 column
|
|
16
|
+
* - 4+ fields → 2 columns
|
|
17
|
+
*/
|
|
18
|
+
export declare function inferColumns(fieldCount: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Apply colSpan to wide fields so they span the full row.
|
|
21
|
+
* Only sets colSpan if the field does not already have one explicitly set.
|
|
22
|
+
*
|
|
23
|
+
* @returns A new array of fields with colSpan applied where needed.
|
|
24
|
+
*/
|
|
25
|
+
export declare function applyAutoColSpan(fields: FormField[], columns: number): FormField[];
|
|
26
|
+
/**
|
|
27
|
+
* Filter out auto-generated/readonly fields for create mode.
|
|
28
|
+
* These fields (formula, summary, auto_number) are computed server-side
|
|
29
|
+
* and should not appear in create forms.
|
|
30
|
+
*
|
|
31
|
+
* @param fields - The form fields array
|
|
32
|
+
* @param objectSchema - The object schema with original field metadata
|
|
33
|
+
* @returns Filtered fields array
|
|
34
|
+
*/
|
|
35
|
+
export declare function filterCreateModeFields(fields: FormField[], objectSchema: any): FormField[];
|
|
36
|
+
/**
|
|
37
|
+
* Infer an appropriate modal size based on the number of layout columns.
|
|
38
|
+
* Used to auto-upgrade the modal width when auto-layout detects multi-column forms.
|
|
39
|
+
*
|
|
40
|
+
* Mapping:
|
|
41
|
+
* - 1 column → 'default' (max-w-lg)
|
|
42
|
+
* - 2 columns → 'lg' (max-w-2xl)
|
|
43
|
+
* - 3 columns → 'xl' (max-w-4xl)
|
|
44
|
+
* - 4+ columns → 'full' (max-w-[95vw])
|
|
45
|
+
*/
|
|
46
|
+
export declare function inferModalSize(columns: number): 'sm' | 'default' | 'lg' | 'xl' | 'full';
|
|
47
|
+
/**
|
|
48
|
+
* Main auto-layout orchestrator.
|
|
49
|
+
* Applies intelligent defaults only when the user has not explicitly configured layout.
|
|
50
|
+
*
|
|
51
|
+
* @param formFields - Generated form fields
|
|
52
|
+
* @param objectSchema - The original object schema (with field types)
|
|
53
|
+
* @param schemaColumns - User-provided columns (from ObjectFormSchema)
|
|
54
|
+
* @param mode - Form mode ('create' | 'edit' | 'view')
|
|
55
|
+
* @returns Object with processed fields and inferred columns
|
|
56
|
+
*/
|
|
57
|
+
export declare function applyAutoLayout(formFields: FormField[], objectSchema: any, schemaColumns: number | undefined, mode: string | undefined): {
|
|
58
|
+
fields: FormField[];
|
|
59
|
+
columns: number | undefined;
|
|
60
|
+
};
|
|
@@ -3,6 +3,7 @@ export { ObjectForm };
|
|
|
3
3
|
export type { ObjectFormProps } from './ObjectForm';
|
|
4
4
|
export { FormSection } from './FormSection';
|
|
5
5
|
export type { FormSectionProps } from './FormSection';
|
|
6
|
+
export { applyAutoLayout, inferColumns, inferModalSize, isWideFieldType, isAutoGeneratedFieldType, applyAutoColSpan, filterCreateModeFields, } from './autoLayout';
|
|
6
7
|
export { TabbedForm } from './TabbedForm';
|
|
7
8
|
export type { TabbedFormProps, TabbedFormSchema, FormSectionConfig } from './TabbedForm';
|
|
8
9
|
export { WizardForm } from './WizardForm';
|
|
@@ -13,3 +14,7 @@ export { DrawerForm } from './DrawerForm';
|
|
|
13
14
|
export type { DrawerFormProps, DrawerFormSchema } from './DrawerForm';
|
|
14
15
|
export { ModalForm } from './ModalForm';
|
|
15
16
|
export type { ModalFormProps, ModalFormSchema } from './ModalForm';
|
|
17
|
+
export { EmbeddableForm } from './EmbeddableForm';
|
|
18
|
+
export type { EmbeddableFormProps, EmbeddableFormConfig } from './EmbeddableForm';
|
|
19
|
+
export { FormAnalytics } from './FormAnalytics';
|
|
20
|
+
export type { FormAnalyticsProps, FormSubmissionMetric } from './FormAnalytics';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-form",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Form plugin for Object UI",
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"lucide-react": "^0.
|
|
19
|
-
"@object-ui/components": "3.0
|
|
20
|
-
"@object-ui/core": "3.0
|
|
21
|
-
"@object-ui/fields": "3.0
|
|
22
|
-
"@object-ui/react": "3.0
|
|
23
|
-
"@object-ui/types": "3.0
|
|
18
|
+
"lucide-react": "^0.576.0",
|
|
19
|
+
"@object-ui/components": "3.1.0",
|
|
20
|
+
"@object-ui/core": "3.1.0",
|
|
21
|
+
"@object-ui/fields": "3.1.0",
|
|
22
|
+
"@object-ui/react": "3.1.0",
|
|
23
|
+
"@object-ui/types": "3.1.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"typescript": "^5.9.3",
|
|
33
33
|
"vite": "^7.3.1",
|
|
34
34
|
"vite-plugin-dts": "^4.5.4",
|
|
35
|
-
"@object-ui/data-objectstack": "3.0
|
|
35
|
+
"@object-ui/data-objectstack": "3.1.0"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "vite build",
|
package/src/DrawerForm.tsx
CHANGED
|
@@ -24,8 +24,21 @@ import {
|
|
|
24
24
|
cn,
|
|
25
25
|
} from '@object-ui/components';
|
|
26
26
|
import { FormSection } from './FormSection';
|
|
27
|
-
import { SchemaRenderer } from '@object-ui/react';
|
|
27
|
+
import { SchemaRenderer, useSafeFieldLabel } from '@object-ui/react';
|
|
28
28
|
import { mapFieldTypeToFormType, buildValidationRules } from '@object-ui/fields';
|
|
29
|
+
import { applyAutoLayout } from './autoLayout';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Container-query-based grid classes for form field layout.
|
|
33
|
+
* Uses @container / @md: / @2xl: / @4xl: variants so that the grid
|
|
34
|
+
* responds to the drawer's actual width instead of the viewport.
|
|
35
|
+
*/
|
|
36
|
+
const CONTAINER_GRID_COLS: Record<number, string | undefined> = {
|
|
37
|
+
1: undefined,
|
|
38
|
+
2: 'grid gap-4 grid-cols-1 @md:grid-cols-2',
|
|
39
|
+
3: 'grid gap-4 grid-cols-1 @md:grid-cols-2 @2xl:grid-cols-3',
|
|
40
|
+
4: 'grid gap-4 grid-cols-1 @md:grid-cols-2 @2xl:grid-cols-3 @4xl:grid-cols-4',
|
|
41
|
+
};
|
|
29
42
|
|
|
30
43
|
export interface DrawerFormSectionConfig {
|
|
31
44
|
name?: string;
|
|
@@ -98,6 +111,7 @@ export const DrawerForm: React.FC<DrawerFormProps> = ({
|
|
|
98
111
|
dataSource,
|
|
99
112
|
className,
|
|
100
113
|
}) => {
|
|
114
|
+
const { fieldLabel } = useSafeFieldLabel();
|
|
101
115
|
const [objectSchema, setObjectSchema] = useState<any>(null);
|
|
102
116
|
const [formFields, setFormFields] = useState<FormField[]>([]);
|
|
103
117
|
const [formData, setFormData] = useState<Record<string, any>>({});
|
|
@@ -168,7 +182,7 @@ export const DrawerForm: React.FC<DrawerFormProps> = ({
|
|
|
168
182
|
const field = objectSchema.fields[fieldName];
|
|
169
183
|
fields.push({
|
|
170
184
|
name: fieldName,
|
|
171
|
-
label: field.label || fieldName,
|
|
185
|
+
label: fieldLabel(schema.objectName, fieldName, field.label || fieldName),
|
|
172
186
|
type: mapFieldTypeToFormType(field.type),
|
|
173
187
|
required: field.required || false,
|
|
174
188
|
disabled: schema.readOnly || schema.mode === 'view' || field.readonly,
|
|
@@ -220,7 +234,7 @@ export const DrawerForm: React.FC<DrawerFormProps> = ({
|
|
|
220
234
|
|
|
221
235
|
generated.push({
|
|
222
236
|
name,
|
|
223
|
-
label: field.label || name,
|
|
237
|
+
label: fieldLabel(schema.objectName, name, field.label || name),
|
|
224
238
|
type: mapFieldTypeToFormType(field.type),
|
|
225
239
|
required: field.required || false,
|
|
226
240
|
disabled: schema.readOnly || schema.mode === 'view' || field.readonly,
|
|
@@ -327,34 +341,45 @@ export const DrawerForm: React.FC<DrawerFormProps> = ({
|
|
|
327
341
|
if (schema.sections?.length) {
|
|
328
342
|
return (
|
|
329
343
|
<div className="space-y-6">
|
|
330
|
-
{schema.sections.map((section, index) =>
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
344
|
+
{schema.sections.map((section, index) => {
|
|
345
|
+
const sectionCols = section.columns || 1;
|
|
346
|
+
return (
|
|
347
|
+
<FormSection
|
|
348
|
+
key={section.name || section.label || index}
|
|
349
|
+
label={section.label}
|
|
350
|
+
description={section.description}
|
|
351
|
+
columns={sectionCols}
|
|
352
|
+
gridClassName={CONTAINER_GRID_COLS[sectionCols]}
|
|
353
|
+
>
|
|
354
|
+
<SchemaRenderer
|
|
355
|
+
schema={{
|
|
356
|
+
...baseFormSchema,
|
|
357
|
+
fields: buildSectionFields(section),
|
|
358
|
+
showSubmit: index === schema.sections!.length - 1 && baseFormSchema.showSubmit,
|
|
359
|
+
showCancel: index === schema.sections!.length - 1 && baseFormSchema.showCancel,
|
|
360
|
+
}}
|
|
361
|
+
/>
|
|
362
|
+
</FormSection>
|
|
363
|
+
);
|
|
364
|
+
})}
|
|
347
365
|
</div>
|
|
348
366
|
);
|
|
349
367
|
}
|
|
350
368
|
|
|
351
|
-
//
|
|
369
|
+
// Apply auto-layout for flat fields (infer columns + colSpan)
|
|
370
|
+
const autoLayoutResult = applyAutoLayout(formFields, objectSchema, schema.columns, schema.mode);
|
|
371
|
+
|
|
372
|
+
// Flat fields layout — use container-query grid classes so the form
|
|
373
|
+
// responds to the drawer width, not the viewport width.
|
|
374
|
+
const containerFieldClass = CONTAINER_GRID_COLS[autoLayoutResult.columns || 1];
|
|
375
|
+
|
|
352
376
|
return (
|
|
353
377
|
<SchemaRenderer
|
|
354
378
|
schema={{
|
|
355
379
|
...baseFormSchema,
|
|
356
|
-
fields:
|
|
357
|
-
columns:
|
|
380
|
+
fields: autoLayoutResult.fields,
|
|
381
|
+
columns: autoLayoutResult.columns,
|
|
382
|
+
...(containerFieldClass ? { fieldContainerClass: containerFieldClass } : {}),
|
|
358
383
|
}}
|
|
359
384
|
/>
|
|
360
385
|
);
|
|
@@ -374,7 +399,7 @@ export const DrawerForm: React.FC<DrawerFormProps> = ({
|
|
|
374
399
|
</SheetHeader>
|
|
375
400
|
)}
|
|
376
401
|
|
|
377
|
-
<div className="py-4">
|
|
402
|
+
<div className="@container py-4">
|
|
378
403
|
{renderContent()}
|
|
379
404
|
</div>
|
|
380
405
|
</SheetContent>
|